|
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 "formlayoutmenu_p.h" |
|
43 #include "layoutinfo_p.h" |
|
44 #include "qdesigner_command_p.h" |
|
45 #include "qdesigner_utils_p.h" |
|
46 #include "qdesigner_propertycommand_p.h" |
|
47 #include "ui_formlayoutrowdialog.h" |
|
48 |
|
49 #include <QtDesigner/QDesignerFormWindowInterface> |
|
50 #include <QtDesigner/QDesignerFormEditorInterface> |
|
51 #include <QtDesigner/QDesignerWidgetFactoryInterface> |
|
52 #include <QtDesigner/QDesignerPropertySheetExtension> |
|
53 #include <QtDesigner/QExtensionManager> |
|
54 #include <QtDesigner/QDesignerWidgetDataBaseInterface> |
|
55 #include <QtDesigner/QDesignerLanguageExtension> |
|
56 |
|
57 #include <QtGui/QAction> |
|
58 #include <QtGui/QWidget> |
|
59 #include <QtGui/QFormLayout> |
|
60 #include <QtGui/QUndoStack> |
|
61 #include <QtGui/QDialog> |
|
62 #include <QtGui/QPushButton> |
|
63 #include <QtGui/QRegExpValidator> |
|
64 |
|
65 #include <QtCore/QPair> |
|
66 #include <QtCore/QCoreApplication> |
|
67 #include <QtCore/QRegExp> |
|
68 #include <QtCore/QMultiHash> |
|
69 #include <QtCore/QDebug> |
|
70 |
|
71 static const char *buddyPropertyC = "buddy"; |
|
72 static const char *fieldWidgetBaseClasses[] = { |
|
73 "QLineEdit", "QComboBox", "QSpinBox", "QDoubleSpinBox", "QCheckBox", |
|
74 "QDateEdit", "QTimeEdit", "QDateTimeEdit", "QDial", "QWidget" |
|
75 }; |
|
76 |
|
77 QT_BEGIN_NAMESPACE |
|
78 |
|
79 namespace qdesigner_internal { |
|
80 |
|
81 // Struct that describes a row of controls (descriptive label and control) to |
|
82 // be added to a form layout. |
|
83 struct FormLayoutRow { |
|
84 FormLayoutRow() : buddy(false) {} |
|
85 |
|
86 QString labelName; |
|
87 QString labelText; |
|
88 QString fieldClassName; |
|
89 QString fieldName; |
|
90 bool buddy; |
|
91 }; |
|
92 |
|
93 // A Dialog to edit a FormLayoutRow. Lets the user input a label text, label |
|
94 // name, field widget type, field object name and buddy setting. As the |
|
95 // user types the label text; the object names to be used for label and field |
|
96 // are updated. It also checks the buddy setting depending on whether the |
|
97 // label text contains a buddy marker. |
|
98 class FormLayoutRowDialog : public QDialog { |
|
99 Q_DISABLE_COPY(FormLayoutRowDialog) |
|
100 Q_OBJECT |
|
101 public: |
|
102 explicit FormLayoutRowDialog(QDesignerFormEditorInterface *core, |
|
103 QWidget *parent); |
|
104 |
|
105 FormLayoutRow formLayoutRow() const; |
|
106 |
|
107 bool buddy() const; |
|
108 void setBuddy(bool); |
|
109 |
|
110 // Accessors for form layout row numbers using 0..[n-1] convention |
|
111 int row() const; |
|
112 void setRow(int); |
|
113 void setRowRange(int, int); |
|
114 |
|
115 QString fieldClass() const; |
|
116 QString labelText() const; |
|
117 |
|
118 static QStringList fieldWidgetClasses(QDesignerFormEditorInterface *core); |
|
119 |
|
120 private slots: |
|
121 void labelTextEdited(const QString &text); |
|
122 void labelNameEdited(const QString &text); |
|
123 void fieldNameEdited(const QString &text); |
|
124 void buddyClicked(); |
|
125 void fieldClassChanged(int); |
|
126 |
|
127 private: |
|
128 bool isValid() const; |
|
129 void updateObjectNames(bool updateLabel, bool updateField); |
|
130 void updateOkButton(); |
|
131 |
|
132 // Check for buddy marker in string |
|
133 const QRegExp m_buddyMarkerRegexp; |
|
134 |
|
135 Ui::FormLayoutRowDialog m_ui; |
|
136 bool m_labelNameEdited; |
|
137 bool m_fieldNameEdited; |
|
138 bool m_buddyClicked; |
|
139 }; |
|
140 |
|
141 FormLayoutRowDialog::FormLayoutRowDialog(QDesignerFormEditorInterface *core, |
|
142 QWidget *parent) : |
|
143 QDialog(parent), |
|
144 m_buddyMarkerRegexp(QLatin1String("\\&[^&]")), |
|
145 m_labelNameEdited(false), |
|
146 m_fieldNameEdited(false), |
|
147 m_buddyClicked(false) |
|
148 { |
|
149 Q_ASSERT(m_buddyMarkerRegexp.isValid()); |
|
150 |
|
151 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); |
|
152 setModal(true); |
|
153 m_ui.setupUi(this); |
|
154 connect(m_ui.labelTextLineEdit, SIGNAL(textEdited(QString)), this, SLOT(labelTextEdited(QString))); |
|
155 |
|
156 QRegExpValidator *nameValidator = new QRegExpValidator(QRegExp(QLatin1String("^[a-zA-Z0-9_]+$")), this); |
|
157 Q_ASSERT(nameValidator->regExp().isValid()); |
|
158 |
|
159 m_ui.labelNameLineEdit->setValidator(nameValidator); |
|
160 connect(m_ui.labelNameLineEdit, SIGNAL(textEdited(QString)), |
|
161 this, SLOT(labelNameEdited(QString))); |
|
162 |
|
163 m_ui.fieldNameLineEdit->setValidator(nameValidator); |
|
164 connect(m_ui.fieldNameLineEdit, SIGNAL(textEdited(QString)), |
|
165 this, SLOT(fieldNameEdited(QString))); |
|
166 |
|
167 connect(m_ui.buddyCheckBox, SIGNAL(clicked()), this, SLOT(buddyClicked())); |
|
168 |
|
169 m_ui.fieldClassComboBox->addItems(fieldWidgetClasses(core)); |
|
170 m_ui.fieldClassComboBox->setCurrentIndex(0); |
|
171 connect(m_ui.fieldClassComboBox, SIGNAL(currentIndexChanged(int)), |
|
172 this, SLOT(fieldClassChanged(int))); |
|
173 |
|
174 updateOkButton(); |
|
175 } |
|
176 |
|
177 FormLayoutRow FormLayoutRowDialog::formLayoutRow() const |
|
178 { |
|
179 FormLayoutRow rc; |
|
180 rc.labelText = labelText(); |
|
181 rc.labelName = m_ui.labelNameLineEdit->text(); |
|
182 rc.fieldClassName = fieldClass(); |
|
183 rc.fieldName = m_ui.fieldNameLineEdit->text(); |
|
184 rc.buddy = buddy(); |
|
185 return rc; |
|
186 } |
|
187 |
|
188 bool FormLayoutRowDialog::buddy() const |
|
189 { |
|
190 return m_ui.buddyCheckBox->checkState() == Qt::Checked; |
|
191 } |
|
192 |
|
193 void FormLayoutRowDialog::setBuddy(bool b) |
|
194 { |
|
195 m_ui.buddyCheckBox->setCheckState(b ? Qt::Checked : Qt::Unchecked); |
|
196 } |
|
197 |
|
198 // Convert rows to 1..n convention for users |
|
199 int FormLayoutRowDialog::row() const |
|
200 { |
|
201 return m_ui.rowSpinBox->value() - 1; |
|
202 } |
|
203 |
|
204 void FormLayoutRowDialog::setRow(int row) |
|
205 { |
|
206 m_ui.rowSpinBox->setValue(row + 1); |
|
207 } |
|
208 |
|
209 void FormLayoutRowDialog::setRowRange(int from, int to) |
|
210 { |
|
211 m_ui.rowSpinBox->setMinimum(from + 1); |
|
212 m_ui.rowSpinBox->setMaximum(to + 1); |
|
213 m_ui.rowSpinBox->setEnabled(to - from > 0); |
|
214 } |
|
215 |
|
216 QString FormLayoutRowDialog::fieldClass() const |
|
217 { |
|
218 return m_ui.fieldClassComboBox->itemText(m_ui.fieldClassComboBox->currentIndex()); |
|
219 } |
|
220 |
|
221 QString FormLayoutRowDialog::labelText() const |
|
222 { |
|
223 return m_ui.labelTextLineEdit->text(); |
|
224 } |
|
225 |
|
226 bool FormLayoutRowDialog::isValid() const |
|
227 { |
|
228 // Check for non-empty names and presence of buddy marker if checked |
|
229 const QString name = labelText(); |
|
230 if (name.isEmpty() || m_ui.labelNameLineEdit->text().isEmpty() || m_ui.fieldNameLineEdit->text().isEmpty()) |
|
231 return false; |
|
232 if (buddy() && !name.contains(m_buddyMarkerRegexp)) |
|
233 return false; |
|
234 return true; |
|
235 } |
|
236 |
|
237 void FormLayoutRowDialog::updateOkButton() |
|
238 { |
|
239 m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid()); |
|
240 } |
|
241 |
|
242 void FormLayoutRowDialog::labelTextEdited(const QString &text) |
|
243 { |
|
244 updateObjectNames(true, true); |
|
245 // Set buddy if '&' is present unless the user changed it |
|
246 if (!m_buddyClicked) |
|
247 setBuddy(text.contains(m_buddyMarkerRegexp)); |
|
248 |
|
249 updateOkButton(); |
|
250 } |
|
251 |
|
252 // Get a suitable object name postfix from a class name: |
|
253 // "namespace::QLineEdit"->"LineEdit" |
|
254 static inline QString postFixFromClassName(QString className) |
|
255 { |
|
256 const int index = className.lastIndexOf(QLatin1String("::")); |
|
257 if (index != -1) |
|
258 className.remove(0, index + 2); |
|
259 if (className.size() > 2) |
|
260 if (className.at(0) == QLatin1Char('Q') || className.at(0) == QLatin1Char('K')) |
|
261 if (className.at(1).isUpper()) |
|
262 className.remove(0, 1); |
|
263 return className; |
|
264 } |
|
265 |
|
266 // Helper routines to filter out characters for converting texts into |
|
267 // class name prefixes. Only accepts ASCII characters/digits and underscores. |
|
268 |
|
269 enum PrefixCharacterKind { PC_Digit, PC_UpperCaseLetter, PC_LowerCaseLetter, |
|
270 PC_Other, PC_Invalid }; |
|
271 |
|
272 static inline PrefixCharacterKind prefixCharacterKind(const QChar &c) |
|
273 { |
|
274 switch (c.category()) { |
|
275 case QChar::Number_DecimalDigit: |
|
276 return PC_Digit; |
|
277 case QChar::Letter_Lowercase: { |
|
278 const char a = c.toAscii(); |
|
279 if (a >= 'a' && a <= 'z') |
|
280 return PC_LowerCaseLetter; |
|
281 } |
|
282 break; |
|
283 case QChar::Letter_Uppercase: { |
|
284 const char a = c.toAscii(); |
|
285 if (a >= 'A' && a <= 'Z') |
|
286 return PC_UpperCaseLetter; |
|
287 } |
|
288 break; |
|
289 case QChar::Punctuation_Connector: |
|
290 if (c.toAscii() == '_') |
|
291 return PC_Other; |
|
292 break; |
|
293 default: |
|
294 break; |
|
295 } |
|
296 return PC_Invalid; |
|
297 } |
|
298 |
|
299 // Convert the text the user types into a usable class name prefix by filtering |
|
300 // characters, lower-casing the first character and camel-casing subsequent |
|
301 // words. ("zip code:") --> ("zipCode"). |
|
302 |
|
303 static QString prefixFromLabel(const QString &prefix) |
|
304 { |
|
305 QString rc; |
|
306 const int length = prefix.size(); |
|
307 bool lastWasAcceptable = false; |
|
308 for (int i = 0 ; i < length; i++) { |
|
309 const QChar c = prefix.at(i); |
|
310 const PrefixCharacterKind kind = prefixCharacterKind(c); |
|
311 const bool acceptable = kind != PC_Invalid; |
|
312 if (acceptable) { |
|
313 if (rc.isEmpty()) { |
|
314 // Lower-case first character |
|
315 rc += kind == PC_UpperCaseLetter ? c.toLower() : c; |
|
316 } else { |
|
317 // Camel-case words |
|
318 rc += !lastWasAcceptable && kind == PC_LowerCaseLetter ? c.toUpper() : c; |
|
319 } |
|
320 } |
|
321 lastWasAcceptable = acceptable; |
|
322 } |
|
323 return rc; |
|
324 } |
|
325 |
|
326 void FormLayoutRowDialog::updateObjectNames(bool updateLabel, bool updateField) |
|
327 { |
|
328 // Generate label + field object names from the label text, that is, |
|
329 // "&Zip code:" -> "zipcodeLabel", "zipcodeLineEdit" unless the user |
|
330 // edited it. |
|
331 const bool doUpdateLabel = !m_labelNameEdited && updateLabel; |
|
332 const bool doUpdateField = !m_fieldNameEdited && updateField; |
|
333 if (!doUpdateLabel && !doUpdateField) |
|
334 return; |
|
335 |
|
336 const QString prefix = prefixFromLabel(labelText()); |
|
337 // Set names |
|
338 if (doUpdateLabel) |
|
339 m_ui.labelNameLineEdit->setText(prefix + QLatin1String("Label")); |
|
340 if (doUpdateField) |
|
341 m_ui.fieldNameLineEdit->setText(prefix + postFixFromClassName(fieldClass())); |
|
342 } |
|
343 |
|
344 void FormLayoutRowDialog::fieldClassChanged(int) |
|
345 { |
|
346 updateObjectNames(false, true); |
|
347 } |
|
348 |
|
349 void FormLayoutRowDialog::labelNameEdited(const QString & /*text*/) |
|
350 { |
|
351 m_labelNameEdited = true; // stop auto-updating after user change |
|
352 updateOkButton(); |
|
353 } |
|
354 |
|
355 void FormLayoutRowDialog::fieldNameEdited(const QString & /*text*/) |
|
356 { |
|
357 m_fieldNameEdited = true; // stop auto-updating after user change |
|
358 updateOkButton(); |
|
359 } |
|
360 |
|
361 void FormLayoutRowDialog::buddyClicked() |
|
362 { |
|
363 m_buddyClicked = true; // stop auto-updating after user change |
|
364 updateOkButton(); |
|
365 } |
|
366 |
|
367 /* Create a list of classes suitable for field widgets. Take the fixed base |
|
368 * classes provided and look in the widget database for custom widgets derived |
|
369 * from them ("QLineEdit", "CustomLineEdit", "QComboBox"...). */ |
|
370 QStringList FormLayoutRowDialog::fieldWidgetClasses(QDesignerFormEditorInterface *core) |
|
371 { |
|
372 // Base class -> custom widgets map |
|
373 typedef QMultiHash<QString, QString> ClassMap; |
|
374 |
|
375 static QStringList rc; |
|
376 if (rc.empty()) { |
|
377 const int fwCount = sizeof(fieldWidgetBaseClasses)/sizeof(const char*); |
|
378 // Turn known base classes into list |
|
379 QStringList baseClasses; |
|
380 for (int i = 0; i < fwCount; i++) |
|
381 baseClasses.push_back(QLatin1String(fieldWidgetBaseClasses[i])); |
|
382 // Scan for custom widgets that inherit them and store them in a |
|
383 // multimap of base class->custom widgets unless we have a language |
|
384 // extension installed which might do funny things with custom widgets. |
|
385 ClassMap customClassMap; |
|
386 if (qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core) == 0) { |
|
387 const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase(); |
|
388 const int wdbCount = wdb->count(); |
|
389 for (int w = 0; w < wdbCount; ++w) { |
|
390 // Check for non-container custom types that extend the |
|
391 // respective base class. |
|
392 const QDesignerWidgetDataBaseItemInterface *dbItem = wdb->item(w); |
|
393 if (!dbItem->isPromoted() && !dbItem->isContainer() && dbItem->isCustom()) { |
|
394 const int index = baseClasses.indexOf(dbItem->extends()); |
|
395 if (index != -1) |
|
396 customClassMap.insert(baseClasses.at(index), dbItem->name()); |
|
397 } |
|
398 } |
|
399 } |
|
400 // Compile final list, taking each base class and append custom widgets |
|
401 // based on it. |
|
402 for (int i = 0; i < fwCount; i++) { |
|
403 rc.push_back(baseClasses.at(i)); |
|
404 rc += customClassMap.values(baseClasses.at(i)); |
|
405 } |
|
406 } |
|
407 return rc; |
|
408 } |
|
409 |
|
410 // ------------------ Utilities |
|
411 |
|
412 static QFormLayout *managedFormLayout(const QDesignerFormEditorInterface *core, const QWidget *w) |
|
413 { |
|
414 QLayout *l = 0; |
|
415 if (LayoutInfo::managedLayoutType(core, w, &l) == LayoutInfo::Form) |
|
416 return qobject_cast<QFormLayout *>(l); |
|
417 return 0; |
|
418 } |
|
419 |
|
420 // Create the widgets of a control row and apply text properties contained |
|
421 // in the struct, called by addFormLayoutRow() |
|
422 static QPair<QWidget *,QWidget *> |
|
423 createWidgets(const FormLayoutRow &row, QWidget *parent, |
|
424 QDesignerFormWindowInterface *formWindow) |
|
425 { |
|
426 QDesignerFormEditorInterface *core = formWindow->core(); |
|
427 QDesignerWidgetFactoryInterface *wf = core->widgetFactory(); |
|
428 |
|
429 QPair<QWidget *,QWidget *> rc = QPair<QWidget *,QWidget *>(wf->createWidget(QLatin1String("QLabel"), parent), |
|
430 wf->createWidget(row.fieldClassName, parent)); |
|
431 // Set up properties of the label |
|
432 const QString objectNameProperty = QLatin1String("objectName"); |
|
433 QDesignerPropertySheetExtension *labelSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.first); |
|
434 int nameIndex = labelSheet->indexOf(objectNameProperty); |
|
435 labelSheet->setProperty(nameIndex, qVariantFromValue(PropertySheetStringValue(row.labelName))); |
|
436 labelSheet->setChanged(nameIndex, true); |
|
437 formWindow->ensureUniqueObjectName(rc.first); |
|
438 const int textIndex = labelSheet->indexOf(QLatin1String("text")); |
|
439 labelSheet->setProperty(textIndex, qVariantFromValue(PropertySheetStringValue(row.labelText))); |
|
440 labelSheet->setChanged(textIndex, true); |
|
441 // Set up properties of the control |
|
442 QDesignerPropertySheetExtension *controlSheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), rc.second); |
|
443 nameIndex = controlSheet->indexOf(objectNameProperty); |
|
444 controlSheet->setProperty(nameIndex, qVariantFromValue(PropertySheetStringValue(row.fieldName))); |
|
445 controlSheet->setChanged(nameIndex, true); |
|
446 formWindow->ensureUniqueObjectName(rc.second); |
|
447 return rc; |
|
448 } |
|
449 |
|
450 // Create a command sequence on the undo stack of the form window that creates |
|
451 // the widgets of the row and inserts them into the form layout. |
|
452 static void addFormLayoutRow(const FormLayoutRow &formLayoutRow, int row, QWidget *w, |
|
453 QDesignerFormWindowInterface *formWindow) |
|
454 { |
|
455 QFormLayout *formLayout = managedFormLayout(formWindow->core(), w); |
|
456 Q_ASSERT(formLayout); |
|
457 QUndoStack *undoStack = formWindow->commandHistory(); |
|
458 const QString macroName = QCoreApplication::translate("Command", "Add '%1' to '%2'").arg(formLayoutRow.labelText, formLayout->objectName()); |
|
459 undoStack->beginMacro(macroName); |
|
460 |
|
461 // Create a list of widget insertion commands and pass them a cell position |
|
462 const QPair<QWidget *,QWidget *> widgetPair = createWidgets(formLayoutRow, w, formWindow); |
|
463 |
|
464 InsertWidgetCommand *labelCmd = new InsertWidgetCommand(formWindow); |
|
465 labelCmd->init(widgetPair.first, false, row, 0); |
|
466 undoStack->push(labelCmd); |
|
467 InsertWidgetCommand *controlCmd = new InsertWidgetCommand(formWindow); |
|
468 controlCmd->init(widgetPair.second, false, row, 1); |
|
469 undoStack->push(controlCmd); |
|
470 if (formLayoutRow.buddy) { |
|
471 SetPropertyCommand *buddyCommand = new SetPropertyCommand(formWindow); |
|
472 buddyCommand->init(widgetPair.first, QLatin1String(buddyPropertyC), widgetPair.second->objectName()); |
|
473 undoStack->push(buddyCommand); |
|
474 } |
|
475 undoStack->endMacro(); |
|
476 } |
|
477 |
|
478 // ---------------- FormLayoutMenu |
|
479 FormLayoutMenu::FormLayoutMenu(QObject *parent) : |
|
480 QObject(parent), |
|
481 m_separator1(new QAction(this)), |
|
482 m_populateFormAction(new QAction(tr("Add form layout row..."), this)), |
|
483 m_separator2(new QAction(this)) |
|
484 { |
|
485 m_separator1->setSeparator(true); |
|
486 connect(m_populateFormAction, SIGNAL(triggered()), this, SLOT(slotAddRow())); |
|
487 m_separator2->setSeparator(true); |
|
488 } |
|
489 |
|
490 void FormLayoutMenu::populate(QWidget *w, QDesignerFormWindowInterface *fw, ActionList &actions) |
|
491 { |
|
492 switch (LayoutInfo::managedLayoutType(fw->core(), w)) { |
|
493 case LayoutInfo::Form: |
|
494 if (!actions.empty() && !actions.back()->isSeparator()) |
|
495 actions.push_back(m_separator1); |
|
496 actions.push_back(m_populateFormAction); |
|
497 actions.push_back(m_separator2); |
|
498 m_widget = w; |
|
499 break; |
|
500 default: |
|
501 m_widget = 0; |
|
502 break; |
|
503 } |
|
504 } |
|
505 |
|
506 void FormLayoutMenu::slotAddRow() |
|
507 { |
|
508 QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(m_widget); |
|
509 Q_ASSERT(m_widget && fw); |
|
510 const int rowCount = managedFormLayout(fw->core(), m_widget)->rowCount(); |
|
511 |
|
512 FormLayoutRowDialog dialog(fw->core(), fw); |
|
513 dialog.setRowRange(0, rowCount); |
|
514 dialog.setRow(rowCount); |
|
515 |
|
516 if (dialog.exec() != QDialog::Accepted) |
|
517 return; |
|
518 addFormLayoutRow(dialog.formLayoutRow(), dialog.row(), m_widget, fw); |
|
519 } |
|
520 |
|
521 QAction *FormLayoutMenu::preferredEditAction(QWidget *w, QDesignerFormWindowInterface *fw) |
|
522 { |
|
523 if (LayoutInfo::managedLayoutType(fw->core(), w) == LayoutInfo::Form) { |
|
524 m_widget = w; |
|
525 return m_populateFormAction; |
|
526 } |
|
527 return 0; |
|
528 } |
|
529 } |
|
530 |
|
531 QT_END_NAMESPACE |
|
532 |
|
533 #include "formlayoutmenu.moc" |
|
534 |