1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3     SPDX-FileCopyrightText: 2002-2020 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
4 */
5 
6 // own header
7 #include "classoptionspage.h"
8 
9 // local includes
10 #include "umlscene.h"
11 #include "umlview.h"
12 #include "classifierwidget.h"
13 #include "entitywidget.h"
14 #include "widgetbase.h"
15 
16 // kde includes
17 #include <KLocalizedString>
18 #include <KComboBox>
19 
20 // qt includes
21 #include <QCheckBox>
22 #include <QGridLayout>
23 #include <QGroupBox>
24 #include <QLabel>
25 #include <QVBoxLayout>
26 
27 /**
28  * Constructor - observe and modify a Widget
29  */
ClassOptionsPage(QWidget * pParent,ClassifierWidget * pWidget)30 ClassOptionsPage::ClassOptionsPage(QWidget* pParent, ClassifierWidget* pWidget)
31   : QWidget(pParent),
32     m_isDiagram(false)
33 {
34     init();
35     //WidgetType type = pWidget->baseType();
36     m_pWidget = pWidget;
37     setupPage();
38 }
39 
ClassOptionsPage(QWidget * pParent,UMLScene * scene)40 ClassOptionsPage::ClassOptionsPage(QWidget *pParent, UMLScene *scene)
41   : QWidget(pParent),
42     m_isDiagram(true)
43 {
44     init();
45 
46     m_scene = scene;
47 
48     // class diagram uses full UIState
49     if (scene->isClassDiagram()) {
50         m_options = &scene->optionState();
51         setupClassPageOption();
52     }
53     else {
54         setupPageFromScene();
55     }
56 }
57 
58 /**
59  * Constructor - observe and modify an OptionState structure
60  *
61  * @param pParent Parent widget
62  * @param options Settings to read from/save into
63  * @param isDiagram Flag if object is for display diagram class options
64  */
ClassOptionsPage(QWidget * pParent,Settings::OptionState * options,bool isDiagram)65 ClassOptionsPage::ClassOptionsPage(QWidget* pParent, Settings::OptionState *options, bool isDiagram)
66   : QWidget(pParent),
67     m_isDiagram(isDiagram)
68 {
69     init();
70     m_options = options;
71     setupClassPageOption();
72 }
73 
ClassOptionsPage(QWidget * pParent,EntityWidget * widget)74 ClassOptionsPage::ClassOptionsPage(QWidget *pParent, EntityWidget *widget)
75   : QWidget(pParent),
76     m_isDiagram(false)
77 {
78     init();
79     m_entityWidget = widget;
80     setupPageFromEntityWidget();
81 }
82 
83 /**
84  * Destructor
85  */
~ClassOptionsPage()86 ClassOptionsPage::~ClassOptionsPage()
87 {
88 }
89 
setDefaults()90 void ClassOptionsPage::setDefaults()
91 {
92     m_showVisibilityCB->setChecked(false);
93     m_showAttsCB->setChecked(true);
94 #ifdef ENABLE_WIDGET_SHOW_DOC
95     m_showDocumentationCB->setChecked(false);
96 #endif
97     m_showOpsCB->setChecked(true);
98     m_showStereotypeCB->setCurrentIndex(2); // Tags
99     m_showAttSigCB->setChecked(false);
100     m_showOpSigCB->setChecked(false);
101     m_showPackageCB->setChecked(false);
102     m_showPublicOnlyCB->setChecked(true);
103     m_attribScopeCB->setCurrentIndex(1); // Private
104     m_operationScopeCB->setCurrentIndex(0); // Public
105 }
106 
107 /**
108  * apply changes
109  */
apply()110 void ClassOptionsPage::apply()
111 {
112     if (m_pWidget) {
113         applyWidget();
114     } else if (m_scene) {
115         applyScene();
116     } else if (m_options) {
117         applyOptionState();
118     } else if (m_entityWidget) {
119         applyEntityWidget();
120     }
121 }
122 
123 /**
124  * Set related uml widget
125  */
setWidget(ClassifierWidget * pWidget)126 void ClassOptionsPage::setWidget(ClassifierWidget * pWidget)
127 {
128     m_pWidget = pWidget;
129 }
130 
131 /**
132  * Creates the page with the correct options for the class/interface
133  */
setupPage()134 void ClassOptionsPage::setupPage()
135 {
136     int margin = fontMetrics().height();
137 
138     bool sig = false;
139     Uml::SignatureType::Enum sigtype;
140 
141     QVBoxLayout * topLayout = new QVBoxLayout(this);
142 
143     topLayout->setSpacing(6);
144     m_visibilityGB = new QGroupBox(i18n("Show"), this);
145     topLayout->addWidget(m_visibilityGB);
146     QGridLayout * visibilityLayout = new QGridLayout(m_visibilityGB);
147     visibilityLayout->setSpacing(10);
148     visibilityLayout->setMargin(margin);
149     visibilityLayout->setRowStretch(3, 1);
150 
151 #ifdef ENABLE_WIDGET_SHOW_DOC
152     m_showDocumentationCB = new QCheckBox(i18n("&Documentation"), m_visibilityGB);
153     m_showDocumentationCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowDocumentation));
154     visibilityLayout->addWidget(m_showDocumentationCB, 0, 0);
155 #endif
156 
157     m_showOpsCB = new QCheckBox(i18n("Operatio&ns"), m_visibilityGB);
158     m_showOpsCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowOperations));
159     visibilityLayout->addWidget(m_showOpsCB, 1, 0);
160 
161     m_showVisibilityCB = new QCheckBox(i18n("&Visibility"), m_visibilityGB);
162     m_showVisibilityCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowVisibility));
163     visibilityLayout->addWidget(m_showVisibilityCB, 1, 1);
164 
165     sigtype = m_pWidget->operationSignature();
166     if (sigtype == Uml::SignatureType::NoSig || sigtype == Uml::SignatureType::NoSigNoVis)
167         sig = false;
168     else
169         sig = true;
170     m_showOpSigCB = new QCheckBox(i18n("O&peration signature"), m_visibilityGB);
171     m_showOpSigCB->setChecked(sig);
172     visibilityLayout->addWidget(m_showOpSigCB, 2, 0);
173 
174     m_showPackageCB = new QCheckBox(i18n("Pac&kage"), m_visibilityGB);
175     m_showPackageCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowPackage));
176     visibilityLayout->addWidget(m_showPackageCB, 2, 1);
177 
178     WidgetBase::WidgetType type = m_pWidget->baseType();
179 
180     if (type == WidgetBase::wt_Class) {
181         m_showAttsCB = new QCheckBox(i18n("Att&ributes"), m_visibilityGB);
182         m_showAttsCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowAttributes));
183         visibilityLayout->addWidget(m_showAttsCB, 3, 0);
184 
185         m_showStereotypeCB = createShowStereotypeCB(m_visibilityGB);
186         m_showStereotypeCB->setCurrentIndex(m_pWidget->showStereotype());
187         visibilityLayout->addWidget(m_showStereotypeCB, 3, 1);
188 
189         m_showAttSigCB = new QCheckBox(i18n("Attr&ibute signature"), m_visibilityGB);
190         sigtype = m_pWidget->attributeSignature();
191         if (sigtype == Uml::SignatureType::NoSig || sigtype == Uml::SignatureType::NoSigNoVis)
192             sig = false;
193         else
194             sig = true;
195         m_showAttSigCB->setChecked(sig);
196         visibilityLayout->addWidget(m_showAttSigCB, 4, 0);
197 
198         m_showPublicOnlyCB = new QCheckBox(i18n("&Public Only"), m_visibilityGB);
199         m_showPublicOnlyCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::ShowPublicOnly));
200         visibilityLayout->addWidget(m_showPublicOnlyCB, 4, 1);
201 
202 
203     } else if (type == WidgetBase::wt_Interface) {
204         m_drawAsCircleCB = new QCheckBox(i18n("Draw as circle"), m_visibilityGB);
205         m_drawAsCircleCB->setChecked(m_pWidget->visualProperty(ClassifierWidget::DrawAsCircle));
206         visibilityLayout->addWidget(m_drawAsCircleCB, 3, 0);
207     }
208 }
209 
setupPageFromScene()210 void ClassOptionsPage::setupPageFromScene()
211 {
212     int margin = fontMetrics().height();
213 
214     QVBoxLayout * topLayout = new QVBoxLayout(this);
215 
216     topLayout->setSpacing(6);
217     m_visibilityGB = new QGroupBox(i18n("Show"), this);
218     topLayout->addWidget(m_visibilityGB);
219     QGridLayout * visibilityLayout = new QGridLayout(m_visibilityGB);
220     visibilityLayout->setSpacing(10);
221     visibilityLayout->setMargin(margin);
222     visibilityLayout->setRowStretch(3, 1);
223 
224     m_showOpSigCB = new QCheckBox(i18n("O&peration signature"), m_visibilityGB);
225     m_showOpSigCB->setChecked(m_scene->showOpSig());
226     visibilityLayout->addWidget(m_showOpSigCB, 1, 0);
227 }
228 
229 /**
230  * Creates the page based on the OptionState
231  */
setupClassPageOption()232 void ClassOptionsPage::setupClassPageOption()
233 {
234     int margin = fontMetrics().height();
235 
236     QVBoxLayout * topLayout = new QVBoxLayout(this);
237 
238     topLayout->setSpacing(6);
239     m_visibilityGB = new QGroupBox(i18n("Show"), this);
240     topLayout->addWidget(m_visibilityGB);
241     QGridLayout * visibilityLayout = new QGridLayout(m_visibilityGB);
242     visibilityLayout->setSpacing(10);
243     visibilityLayout->setMargin(margin);
244 
245 #ifdef ENABLE_WIDGET_SHOW_DOC
246     m_showDocumentationCB = new QCheckBox(i18n("&Documentation"), m_visibilityGB);
247     m_showDocumentationCB->setChecked(m_options->classState.showDocumentation);
248     visibilityLayout->addWidget(m_showDocumentationCB, 0, 0);
249 #endif
250 
251     m_showOpsCB = new QCheckBox(i18n("Operatio&ns"), m_visibilityGB);
252     m_showOpsCB->setChecked(m_options->classState.showOps);
253     visibilityLayout->addWidget(m_showOpsCB, 1, 0);
254 
255     m_showOpSigCB = new QCheckBox(i18n("O&peration signature"), m_visibilityGB);
256     m_showOpSigCB->setChecked(m_options->classState.showOpSig);
257     visibilityLayout->addWidget(m_showOpSigCB, 2, 0);
258     visibilityLayout->setRowStretch(3, 1);
259 
260     m_showAttsCB = new QCheckBox(i18n("Att&ributes"), m_visibilityGB);
261     m_showAttsCB->setChecked(m_options->classState.showAtts);
262     visibilityLayout->addWidget(m_showAttsCB, 3, 0);
263 
264     m_showAttSigCB = new QCheckBox(i18n("Attr&ibute signature"), m_visibilityGB);
265     m_showAttSigCB->setChecked(m_options->classState.showAttSig);
266     visibilityLayout->addWidget(m_showAttSigCB, 4, 0);
267 
268     m_showVisibilityCB = new QCheckBox(i18n("&Visibility"), m_visibilityGB);
269     m_showVisibilityCB->setChecked(m_options->classState.showVisibility);
270     visibilityLayout->addWidget(m_showVisibilityCB, 1, 1);
271 
272     m_showPackageCB = new QCheckBox(i18n("Pac&kage"), m_visibilityGB);
273     m_showPackageCB->setChecked(m_options->classState.showPackage);
274     visibilityLayout->addWidget(m_showPackageCB, 2, 1);
275 
276     m_showStereotypeCB = createShowStereotypeCB(m_visibilityGB);
277     m_showStereotypeCB->setCurrentIndex(m_options->classState.showStereoType);
278     visibilityLayout->addWidget(m_showStereotypeCB, 3, 1);
279 
280     m_showAttribAssocsCB = new QCheckBox(i18n("&Attribute associations"), m_visibilityGB);
281     m_showAttribAssocsCB->setChecked(m_options->classState.showAttribAssocs);
282     visibilityLayout->addWidget(m_showAttribAssocsCB, 4, 1);
283 
284     m_showPublicOnlyCB = new QCheckBox(i18n("&Public Only"), m_visibilityGB);
285     m_showPublicOnlyCB->setChecked(m_options->classState.showPublicOnly);
286     visibilityLayout->addWidget(m_showPublicOnlyCB, 5, 1);
287 
288     if (!m_isDiagram) {
289         m_scopeGB = new QGroupBox(i18n("Starting Scope"));
290         topLayout->addWidget(m_scopeGB);
291 
292         QGridLayout * scopeLayout = new QGridLayout(m_scopeGB);
293         scopeLayout->setSpacing(10);
294         scopeLayout->setMargin(fontMetrics().height());
295 
296         m_attributeLabel = new QLabel(i18n("Default attribute scope:"), m_scopeGB);
297         scopeLayout->addWidget(m_attributeLabel, 0, 0);
298 
299         m_operationLabel = new QLabel(i18n("Default operation scope:"), m_scopeGB);
300         scopeLayout->addWidget(m_operationLabel, 1, 0);
301 
302         m_attribScopeCB = new KComboBox(m_scopeGB);
303         insertAttribScope(i18n("Public"));
304         insertAttribScope(i18n("Private"));
305         insertAttribScope(i18n("Protected"));
306         m_attribScopeCB->setCurrentIndex(m_options->classState.defaultAttributeScope);
307 #if QT_VERSION < 0x050000
308         m_attribScopeCB->setCompletionMode(KGlobalSettings::CompletionPopup);
309 #endif
310         scopeLayout->addWidget(m_attribScopeCB, 0, 1);
311 
312         m_operationScopeCB = new KComboBox(m_scopeGB);
313         insertOperationScope(i18n("Public"));
314         insertOperationScope(i18n("Private"));
315         insertOperationScope(i18n("Protected"));
316         m_operationScopeCB->setCurrentIndex(m_options->classState.defaultOperationScope);
317 #if QT_VERSION < 0x050000
318         m_operationScopeCB->setCompletionMode(KGlobalSettings::CompletionPopup);
319 #endif
320         scopeLayout->addWidget(m_operationScopeCB, 1, 1);
321         topLayout->addWidget(m_scopeGB);
322     }
323 }
324 
setupPageFromEntityWidget()325 void ClassOptionsPage::setupPageFromEntityWidget()
326 {
327     int margin = fontMetrics().height();
328 
329     QVBoxLayout * topLayout = new QVBoxLayout(this);
330 
331     topLayout->setSpacing(6);
332     m_visibilityGB = new QGroupBox(i18n("Show"), this);
333     topLayout->addWidget(m_visibilityGB);
334     QGridLayout * visibilityLayout = new QGridLayout(m_visibilityGB);
335     visibilityLayout->setSpacing(10);
336     visibilityLayout->setMargin(margin);
337     visibilityLayout->setRowStretch(3, 1);
338 
339     m_showAttSigCB = new QCheckBox(i18n("Attribute Signatures"), m_visibilityGB);
340     m_showAttSigCB->setChecked(m_entityWidget->showAttributeSignature());
341     visibilityLayout->addWidget(m_showAttSigCB, 1, 0);
342 
343     m_showStereotypeCB = createShowStereotypeCB(m_visibilityGB);
344     m_showStereotypeCB->setCurrentIndex(m_entityWidget->showStereotype());
345     visibilityLayout->addWidget(m_showStereotypeCB, 2, 0);
346 }
347 
348 /**
349  * Sets the ClassifierWidget's properties to those selected in this dialog page.
350  */
applyWidget()351 void ClassOptionsPage::applyWidget()
352 {
353 #ifdef ENABLE_WIDGET_SHOW_DOC
354     m_pWidget->setVisualProperty(ClassifierWidget::ShowDocumentation, m_showDocumentationCB->isChecked());
355 #endif
356     m_pWidget->setVisualProperty(ClassifierWidget::ShowPackage, m_showPackageCB->isChecked());
357     m_pWidget->setVisualProperty(ClassifierWidget::ShowVisibility, m_showVisibilityCB->isChecked());
358     m_pWidget->setVisualProperty(ClassifierWidget::ShowOperations, m_showOpsCB->isChecked());
359     m_pWidget->setVisualProperty(ClassifierWidget::ShowOperationSignature, m_showOpSigCB->isChecked());
360     WidgetBase::WidgetType type = m_pWidget->baseType();
361     if (type == WidgetBase::wt_Class) {
362         m_pWidget->setShowStereotype(Uml::ShowStereoType::Enum(m_showStereotypeCB->currentIndex()));
363         m_pWidget->setVisualProperty(ClassifierWidget::ShowAttributes, m_showAttsCB->isChecked());
364         m_pWidget->setVisualProperty(ClassifierWidget::ShowAttributeSignature, m_showAttSigCB->isChecked());
365         m_pWidget->setVisualProperty(ClassifierWidget::ShowPublicOnly, m_showPublicOnlyCB->isChecked());
366     } else if (type == WidgetBase::wt_Interface) {
367         if (m_drawAsCircleCB)
368             m_pWidget->setVisualProperty(ClassifierWidget::DrawAsCircle, m_drawAsCircleCB->isChecked());
369     }
370 }
371 
372 /**
373  * Sets the OptionState to the values selected in this dialog page.
374  */
applyOptionState()375 void ClassOptionsPage::applyOptionState()
376 {
377 #ifdef ENABLE_WIDGET_SHOW_DOC
378     m_options->classState.showDocumentation = m_showDocumentationCB->isChecked();
379 #endif
380     m_options->classState.showVisibility = m_showVisibilityCB->isChecked();
381     if (m_showAttsCB)
382         m_options->classState.showAtts = m_showAttsCB->isChecked();
383     m_options->classState.showOps = m_showOpsCB->isChecked();
384     if (m_showStereotypeCB)
385         m_options->classState.showStereoType = Uml::ShowStereoType::Enum(m_showStereotypeCB->currentIndex());
386     m_options->classState.showPackage = m_showPackageCB->isChecked();
387     if (m_showAttribAssocsCB)
388         m_options->classState.showAttribAssocs = m_showAttribAssocsCB->isChecked();
389     if (m_showAttSigCB)
390         m_options->classState.showAttSig = m_showAttSigCB->isChecked();
391     m_options->classState.showOpSig = m_showOpSigCB->isChecked();
392     m_options->classState.showPublicOnly = m_showPublicOnlyCB->isChecked();
393     if (!m_isDiagram) {
394         m_options->classState.defaultAttributeScope = Uml::Visibility::fromInt(m_attribScopeCB->currentIndex());
395         m_options->classState.defaultOperationScope = Uml::Visibility::fromInt(m_operationScopeCB->currentIndex());
396     }
397 }
398 
399 /**
400  * Sets the UMLScene's properties to those selected in this dialog page.
401  */
applyScene()402 void ClassOptionsPage::applyScene()
403 {
404     if (m_scene->isClassDiagram()) {
405         applyOptionState();
406         m_scene->setClassWidgetOptions(this);
407     }
408     else
409         m_scene->setShowOpSig(m_showOpSigCB->isChecked());
410 }
411 
applyEntityWidget()412 void ClassOptionsPage::applyEntityWidget()
413 {
414     Q_ASSERT(m_entityWidget);
415     m_entityWidget->setShowStereotype(Uml::ShowStereoType::Enum(m_showStereotypeCB->currentIndex()));
416     m_entityWidget->setShowAttributeSignature(m_showAttSigCB->isChecked());
417 }
418 
419 /**
420  * Initialize optional items
421  */
init()422 void ClassOptionsPage::init()
423 {
424     m_scene = 0;
425     m_options = 0;
426     m_pWidget = 0;
427     m_entityWidget = 0;
428     m_showStereotypeCB = 0;
429     m_showAttsCB = 0;
430     m_showAttSigCB = 0;
431     m_showAttribAssocsCB = 0;
432     m_showDocumentationCB = 0;
433     m_showPublicOnlyCB = 0;
434     m_drawAsCircleCB = 0;
435 }
436 
437 /**
438  * This need not be a member method, it can be made "static" or be moved to Dialog_Utils
439  */
createShowStereotypeCB(QGroupBox * grpBox)440 KComboBox * ClassOptionsPage::createShowStereotypeCB(QGroupBox * grpBox)
441 {
442     KComboBox * cobox = new KComboBox(grpBox);
443     cobox->setEditable(false);
444     cobox->addItem(i18n("No Stereotype"));
445     cobox->addItem(i18n("Stereotype Name"));
446     cobox->addItem(i18n("Stereotype with Tags"));
447     return cobox;
448 }
449 
450 /**
451  * Inserts @p type into the type-combobox as well as its completion object.
452  */
insertAttribScope(const QString & type,int index)453 void ClassOptionsPage::insertAttribScope(const QString& type, int index)
454 {
455     m_attribScopeCB->insertItem(index, type);
456     m_attribScopeCB->completionObject()->addItem(type);
457 }
458 
459 /**
460  * Inserts @p type into the type-combobox as well as its completion object.
461  */
insertOperationScope(const QString & type,int index)462 void ClassOptionsPage::insertOperationScope(const QString& type, int index)
463 {
464     m_operationScopeCB->insertItem(index, type);
465     m_operationScopeCB->completionObject()->addItem(type);
466 }
467