00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "umloperationdialog.h"
00014
00015
00016 #include <qlayout.h>
00017 #include <qgroupbox.h>
00018 #include <qlistbox.h>
00019 #include <qbuttongroup.h>
00020 #include <qpushbutton.h>
00021 #include <qradiobutton.h>
00022 #include <qlabel.h>
00023 #include <qcheckbox.h>
00024 #include <qlineedit.h>
00025
00026
00027 #include <kcombobox.h>
00028 #include <kdebug.h>
00029 #include <klocale.h>
00030 #include <kmessagebox.h>
00031 #include <kbuttonbox.h>
00032 #include <karrowbutton.h>
00033
00034
00035 #include "../uml.h"
00036 #include "../umldoc.h"
00037 #include "../operation.h"
00038 #include "../classifier.h"
00039 #include "../template.h"
00040 #include "../listpopupmenu.h"
00041 #include "../umlattributelist.h"
00042 #include "../classifierlistitem.h"
00043 #include "../umlclassifierlistitemlist.h"
00044 #include "../dialog_utils.h"
00045 #include "parmpropdlg.h"
00046 #include "../stereotype.h"
00047 #include "../uniqueid.h"
00048
00049 UMLOperationDialog::UMLOperationDialog( QWidget * parent, UMLOperation * pOperation )
00050 : KDialogBase( Plain, i18n("Operation Properties"), Help | Ok | Cancel , Ok, parent, "_UMLOPERATIONDLG_", true, true) {
00051 m_pOperation = pOperation;
00052 m_doc = UMLApp::app()->getDocument();
00053 m_pMenu = 0;
00054 setupDialog();
00055 }
00056
00057 UMLOperationDialog::~UMLOperationDialog() {}
00058
00059 void UMLOperationDialog::setupDialog() {
00060
00061 int margin = fontMetrics().height();
00062 QVBoxLayout * topLayout = new QVBoxLayout( plainPage() );
00063
00064 m_pGenGB = new QGroupBox(i18n("General Properties"), plainPage() );
00065 QGridLayout * genLayout = new QGridLayout(m_pGenGB, 3, 4 );
00066 genLayout -> setColStretch(1, 1);
00067 genLayout -> setColStretch(3, 1);
00068 genLayout -> addColSpacing(1, 200);
00069 genLayout -> addColSpacing(3, 200);
00070 genLayout -> setMargin(margin);
00071 genLayout -> setSpacing(10);
00072
00073 Dialog_Utils::makeLabeledEditField( m_pGenGB, genLayout, 0,
00074 m_pNameL, i18n("&Name:"),
00075 m_pNameLE, m_pOperation->getName() );
00076
00077 m_pRtypeL = new QLabel(i18n("&Type:"), m_pGenGB );
00078 genLayout -> addWidget(m_pRtypeL, 0, 2);
00079
00080 m_pRtypeCB = new KComboBox(true, m_pGenGB );
00081 genLayout -> addWidget(m_pRtypeCB, 0, 3);
00082 m_pRtypeL->setBuddy(m_pRtypeCB);
00083
00084 m_pStereoTypeL = new QLabel( i18n("Stereotype name:"), m_pGenGB );
00085 genLayout -> addWidget(m_pStereoTypeL, 1, 0);
00086 m_pStereoTypeCB = new KComboBox(true, m_pGenGB );
00087 genLayout -> addWidget(m_pStereoTypeCB, 1, 1);
00088
00089 m_pAbstractCB = new QCheckBox( i18n("&Abstract operation"), m_pGenGB );
00090 m_pAbstractCB -> setChecked( m_pOperation->getAbstract() );
00091 genLayout -> addWidget( m_pAbstractCB, 2, 0 );
00092 m_pStaticCB = new QCheckBox( i18n("Classifier &scope (\"static\")"), m_pGenGB );
00093 m_pStaticCB -> setChecked( m_pOperation->getStatic() );
00094 genLayout -> addWidget( m_pStaticCB, 2, 1 );
00095 m_pQueryCB = new QCheckBox( i18n("&Query (\"const\")"), m_pGenGB );
00096 m_pQueryCB -> setChecked( m_pOperation->getConst() );
00097 genLayout -> addWidget( m_pQueryCB, 2, 2 );
00098
00099 topLayout -> addWidget( m_pGenGB );
00100
00101 m_pScopeBG = new QButtonGroup(i18n("Visibility"), plainPage() );
00102
00103 QHBoxLayout * scopeLayout = new QHBoxLayout(m_pScopeBG);
00104 scopeLayout -> setMargin(margin);
00105
00106 m_pPublicRB = new QRadioButton(i18n("P&ublic"), m_pScopeBG);
00107 scopeLayout -> addWidget(m_pPublicRB);
00108
00109 m_pPrivateRB = new QRadioButton(i18n("P&rivate"), m_pScopeBG);
00110 scopeLayout -> addWidget(m_pPrivateRB);
00111
00112 m_pProtectedRB = new QRadioButton(i18n("Prot&ected"), m_pScopeBG);
00113 scopeLayout -> addWidget(m_pProtectedRB);
00114
00115 m_pImplementationRB = new QRadioButton(i18n("I&mplementation"), m_pScopeBG);
00116 scopeLayout -> addWidget(m_pImplementationRB);
00117
00118 topLayout -> addWidget(m_pScopeBG);
00119
00120 m_pParmsGB = new QGroupBox(i18n("Parameters"), plainPage() );
00121 QVBoxLayout* parmsLayout = new QVBoxLayout(m_pParmsGB);
00122 parmsLayout->setMargin(margin);
00123 parmsLayout->setSpacing(10);
00124
00125
00126 QHBoxLayout* parmsHBoxLayout = new QHBoxLayout(parmsLayout);
00127 m_pParmsLB = new QListBox(m_pParmsGB);
00128 parmsHBoxLayout->addWidget(m_pParmsLB);
00129
00130
00131 QVBoxLayout* buttonLayout = new QVBoxLayout( parmsHBoxLayout );
00132 m_pUpButton = new KArrowButton( m_pParmsGB );
00133 m_pUpButton->setEnabled( false );
00134 buttonLayout->addWidget( m_pUpButton );
00135
00136 m_pDownButton = new KArrowButton( m_pParmsGB, Qt::DownArrow );
00137 m_pDownButton->setEnabled( false );
00138 buttonLayout->addWidget( m_pDownButton );
00139
00140 KButtonBox* buttonBox = new KButtonBox(m_pParmsGB);
00141 buttonBox->addButton( i18n("Ne&w Parameter..."), this, SLOT(slotNewParameter()) );
00142 m_pDeleteButton = buttonBox->addButton( i18n("&Delete"), this, SLOT(slotDeleteParameter()) );
00143 m_pPropertiesButton = buttonBox->addButton( i18n("&Properties"), this,
00144 SLOT(slotParameterProperties()) );
00145 parmsLayout->addWidget(buttonBox);
00146
00147 topLayout -> addWidget(m_pParmsGB);
00148
00149 m_pDeleteButton->setEnabled(false);
00150 m_pPropertiesButton->setEnabled(false);
00151 m_pUpButton->setEnabled(false);
00152 m_pDownButton->setEnabled(false);
00153
00154
00155
00156
00157
00158
00159 insertType( "void" );
00160
00161 m_pRtypeCB->setDuplicatesEnabled(false);
00162 m_pRtypeCB->setCompletionMode( KGlobalSettings::CompletionPopup );
00163
00164
00165 UMLClassifier *classifier = dynamic_cast<UMLClassifier*>(m_pOperation->parent());
00166 if (classifier) {
00167 UMLClassifierListItemList tmplParams( classifier->getFilteredList(Uml::ot_Template) );
00168 for (UMLClassifierListItem *li = tmplParams.first(); li; li = tmplParams.next())
00169 insertType( li->getName() );
00170 }
00171
00172 UMLClassifierList namesList( m_doc->getConcepts() );
00173 UMLClassifier* pConcept = 0;
00174 for(pConcept=namesList.first(); pConcept!=0 ;pConcept=namesList.next()) {
00175 insertType( pConcept->getFullyQualifiedName() );
00176 }
00177
00178
00179 int returnBoxCount = 0;
00180 bool foundReturnType = false;
00181 while (returnBoxCount < m_pRtypeCB->count() && foundReturnType == false) {
00182 QString returnBoxString = m_pRtypeCB->text(returnBoxCount);
00183 if ( returnBoxString == m_pOperation->getTypeName() ) {
00184 foundReturnType = true;
00185 m_pRtypeCB->setCurrentItem(returnBoxCount);
00186 break;
00187 }
00188 returnBoxCount++;
00189 }
00190
00191 if (!foundReturnType) {
00192 insertType( m_pOperation->getTypeName(), 0 );
00193 m_pRtypeCB->setCurrentItem(0);
00194 }
00195
00196
00197 UMLAttributeList list = m_pOperation->getParmList();
00198 UMLAttribute * pAtt = 0;
00199 for (pAtt = list.first(); pAtt; pAtt = list.next())
00200 m_pParmsLB->insertItem( pAtt->getName() );
00201
00202
00203 Uml::Visibility scope = m_pOperation -> getVisibility();
00204 if( scope == Uml::Visibility::Public )
00205 m_pPublicRB -> setChecked( true );
00206 else if( scope == Uml::Visibility::Private )
00207 m_pPrivateRB -> setChecked( true );
00208 else if( scope == Uml::Visibility::Protected )
00209 m_pProtectedRB -> setChecked( true );
00210 else if( scope == Uml::Visibility::Implementation )
00211 m_pImplementationRB -> setChecked( true );
00212
00213
00214 m_pStereoTypeCB -> setDuplicatesEnabled(false);
00215 m_pStereoTypeCB->setCompletionMode( KGlobalSettings::CompletionPopup );
00216 insertStereotype (QString(""));
00217 int defaultStereotype=0;
00218 bool foundDefaultStereotype = false;
00219 for (UMLStereotypeListIt it(m_doc->getStereotypes()); it.current(); ++it) {
00220 if (!foundDefaultStereotype) {
00221 if ( m_pOperation->getStereotype() == it.current()->getName()) {
00222 foundDefaultStereotype = true;
00223 }
00224 defaultStereotype++;
00225 }
00226 insertStereotype (it.current()->getName());
00227 }
00228
00229 if (foundDefaultStereotype)
00230 m_pStereoTypeCB->setCurrentItem(defaultStereotype);
00231 else
00232 m_pStereoTypeCB->setCurrentItem(-1);
00233
00234
00235 connect( m_pUpButton, SIGNAL( clicked() ), this, SLOT( slotParameterUp() ) );
00236 connect( m_pDownButton, SIGNAL( clicked() ), this, SLOT( slotParameterDown() ) );
00237
00238 connect(m_pParmsLB, SIGNAL(clicked(QListBoxItem*)),
00239 this, SLOT(slotParamsBoxClicked(QListBoxItem*)));
00240
00241 connect(m_pParmsLB, SIGNAL(rightButtonPressed(QListBoxItem *, const QPoint &)),
00242 this, SLOT(slotParmRightButtonPressed(QListBoxItem *, const QPoint &)));
00243
00244 connect(m_pParmsLB, SIGNAL(rightButtonClicked(QListBoxItem *, const QPoint &)),
00245 this, SLOT(slotParmRightButtonClicked(QListBoxItem *, const QPoint &)));
00246
00247
00248 connect(m_pParmsLB, SIGNAL(doubleClicked(QListBoxItem *)),
00249 this, SLOT(slotParmDoubleClick(QListBoxItem *)));
00250
00251 m_pNameLE->setFocus();
00252 connect( m_pNameLE, SIGNAL( textChanged ( const QString & ) ), SLOT( slotNameChanged( const QString & ) ) );
00253 slotNameChanged(m_pNameLE->text() );
00254
00255 }
00256
00257 void UMLOperationDialog::slotNameChanged( const QString &_text )
00258 {
00259 enableButtonOK( !_text.isEmpty() );
00260 }
00261
00262
00263 void UMLOperationDialog::slotParmRightButtonPressed(QListBoxItem *item, const QPoint &p) {
00264 ListPopupMenu::Menu_Type type = ListPopupMenu::mt_Undefined;
00265 if(item)
00266 {
00267 type = ListPopupMenu::mt_Parameter_Selected;
00268 } else
00269 {
00270 type = ListPopupMenu::mt_New_Parameter;
00271 }
00272 if(m_pMenu) {
00273 m_pMenu -> hide();
00274 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotParmPopupMenuSel(int)));
00275 delete m_pMenu;
00276 m_pMenu = 0;
00277 }
00278 m_pMenu = new ListPopupMenu(this, type);
00279 m_pMenu->popup(p);
00280 connect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotParmPopupMenuSel(int)));
00281
00282 }
00283
00284 void UMLOperationDialog::slotParmRightButtonClicked(QListBoxItem *, const QPoint &) {
00285 if(m_pMenu) {
00286 m_pMenu -> hide();
00287 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotParmPopupMenuSel(int)));
00288 delete m_pMenu;
00289 m_pMenu = 0;
00290 }
00291 }
00292
00293 void UMLOperationDialog::slotParmDoubleClick(QListBoxItem *item) {
00294 if(!item)
00295 return;
00296 slotParmPopupMenuSel(ListPopupMenu::mt_Properties);
00297 }
00298
00299 void UMLOperationDialog::slotParmPopupMenuSel(int id) {
00300 if( id == ListPopupMenu::mt_Rename || id == ListPopupMenu::mt_Properties ) {
00301 slotParameterProperties();
00302 } else if( id == ListPopupMenu::mt_New_Parameter ) {
00303 slotNewParameter();
00304 }
00305 else if( id == ListPopupMenu::mt_Delete ) {
00306 slotDeleteParameter();
00307 }
00308 }
00309
00310 void UMLOperationDialog::slotNewParameter() {
00311 int result = 0;
00312 UMLAttribute* pAtt = 0;
00313
00314 QString currentName = m_pOperation->getUniqueParameterName();
00315 UMLAttribute* newAttribute = new UMLAttribute(m_pOperation, currentName, Uml::id_Reserved);
00316
00317 ParmPropDlg dlg(this, m_doc, newAttribute);
00318 result = dlg.exec();
00319 QString name = dlg.getName();
00320 pAtt = m_pOperation -> findParm( name );
00321 if( result ) {
00322 if( name.length() == 0 ) {
00323 KMessageBox::error(this, i18n("You have entered an invalid parameter name."),
00324 i18n("Parameter Name Invalid"), false);
00325 delete newAttribute;
00326 return;
00327 }
00328 if( !pAtt ) {
00329 newAttribute->setID( UniqueID::gen() );
00330 newAttribute->setName( name );
00331 newAttribute->setTypeName( dlg.getTypeName() );
00332 newAttribute->setInitialValue( dlg.getInitialValue() );
00333 newAttribute->setDoc( dlg.getDoc() );
00334 newAttribute->setParmKind( dlg.getParmKind() );
00335 m_pOperation->addParm( newAttribute );
00336 m_pParmsLB -> insertItem( name );
00337 m_doc -> setModified( true );
00338 } else {
00339 KMessageBox::sorry(this, i18n("The parameter name you have chosen\nis already being used in this operation."),
00340 i18n("Parameter Name Not Unique"), false);
00341 delete newAttribute;
00342 }
00343 } else {
00344 delete newAttribute;
00345 }
00346 }
00347
00348 void UMLOperationDialog::slotDeleteParameter() {
00349 UMLAttribute* pOldAtt = m_pOperation->findParm( m_pParmsLB->currentText() );
00350
00351 m_pOperation->removeParm( pOldAtt );
00352 m_pParmsLB->removeItem( m_pParmsLB->currentItem() );
00353 m_doc->setModified(true);
00354
00355 m_pDeleteButton->setEnabled(false);
00356 m_pPropertiesButton->setEnabled(false);
00357 m_pUpButton->setEnabled(false);
00358 m_pDownButton->setEnabled(false);
00359 }
00360
00361 void UMLOperationDialog::slotParameterProperties() {
00362 int result = 0;
00363 UMLAttribute* pAtt = 0, * pOldAtt = 0;
00364 pOldAtt = m_pOperation->findParm( m_pParmsLB->currentText() );
00365
00366 if( !pOldAtt ) {
00367 kDebug() << "THE impossible has occurred for:" << m_pParmsLB->currentText() << endl;
00368 return;
00369 }
00370 ParmPropDlg dlg(this, m_doc, pOldAtt);
00371 result = dlg.exec();
00372 QString name = dlg.getName();
00373 pAtt = m_pOperation->findParm( name );
00374 if( result ) {
00375 if( name.length() == 0 ) {
00376 KMessageBox::error(this, i18n("You have entered an invalid parameter name."),
00377 i18n("Parameter Name Invalid"), false);
00378 return;
00379 }
00380 if ( !pAtt || pOldAtt->getTypeName() != dlg.getTypeName() ||
00381 pOldAtt->getDoc() != dlg.getDoc() ||
00382 pOldAtt->getInitialValue() != dlg.getInitialValue() ) {
00383 pOldAtt->setName( name );
00384 QString typeName = dlg.getTypeName();
00385 if (pOldAtt->getTypeName() != typeName) {
00386 UMLClassifierList namesList( m_doc->getConcepts() );
00387 UMLClassifier* obj = NULL;
00388 for (obj=namesList.first(); obj!=0; obj=namesList.next()) {
00389 if (typeName == obj->getFullyQualifiedName()) {
00390 pOldAtt->setType( obj );
00391 break;
00392 }
00393 }
00394 if (obj == NULL) {
00395
00396 kDebug() << "UMLOperationDialog::slotParameterProperties: "
00397 << typeName << " not found." << endl;
00398 pOldAtt->setTypeName( typeName );
00399 }
00400 }
00401 m_pParmsLB->changeItem( dlg.getName(), m_pParmsLB -> currentItem() );
00402 pOldAtt->setDoc( dlg.getDoc() );
00403 pOldAtt->setInitialValue( dlg.getInitialValue() );
00404 m_doc->setModified( true );
00405 } else if( pAtt != pOldAtt ) {
00406 KMessageBox::error(this, i18n("The parameter name you have chosen is already being used in this operation."),
00407 i18n("Parameter Name Not Unique"), false);
00408 }
00409 }
00410 }
00411
00412 void UMLOperationDialog::slotParameterUp()
00413 {
00414 kDebug() << k_funcinfo << endl;
00415 UMLAttribute* pOldAtt = m_pOperation->findParm( m_pParmsLB->currentText() );
00416
00417 m_pOperation->moveParmLeft( pOldAtt );
00418 QString tmp = m_pParmsLB->currentText();
00419 m_pParmsLB->changeItem( m_pParmsLB->item( m_pParmsLB->currentItem() - 1 )->text(), m_pParmsLB->currentItem() );
00420 m_pParmsLB->changeItem( tmp, m_pParmsLB->currentItem() - 1 );
00421 m_doc->setModified(true);
00422 slotParamsBoxClicked( m_pParmsLB->selectedItem() );
00423 }
00424
00425 void UMLOperationDialog::slotParameterDown()
00426 {
00427 UMLAttribute* pOldAtt = m_pOperation->findParm( m_pParmsLB->currentText() );
00428
00429 m_pOperation->moveParmRight( pOldAtt );
00430 QString tmp = m_pParmsLB->currentText();
00431 m_pParmsLB->changeItem( m_pParmsLB->item( m_pParmsLB->currentItem() + 1 )->text(), m_pParmsLB->currentItem() );
00432 m_pParmsLB->changeItem( tmp, m_pParmsLB->currentItem() + 1 );
00433
00434 m_doc->setModified(true);
00435 slotParamsBoxClicked( m_pParmsLB->selectedItem() );
00436 }
00437
00438 void UMLOperationDialog::slotParamsBoxClicked(QListBoxItem* parameterItem) {
00439 if (parameterItem) {
00440 m_pDeleteButton->setEnabled(true);
00441 m_pPropertiesButton->setEnabled(true);
00442 m_pUpButton->setEnabled( parameterItem->prev() );
00443 m_pDownButton->setEnabled( parameterItem->next() );
00444 } else {
00445 m_pDeleteButton->setEnabled(false);
00446 m_pPropertiesButton->setEnabled(false);
00447 m_pUpButton->setEnabled(false);
00448 m_pDownButton->setEnabled(false);
00449 }
00450 }
00451
00452 bool UMLOperationDialog::apply()
00453 {
00454 QString name = m_pNameLE -> text();
00455 if( name.length() == 0 ) {
00456 KMessageBox::error(this, i18n("You have entered an invalid operation name."),
00457 i18n("Operation Name Invalid"), false);
00458 m_pNameLE -> setText( m_pOperation -> getName() );
00459 return false;
00460 }
00461
00462 UMLClassifier *classifier = dynamic_cast<UMLClassifier*>( m_pOperation->parent() );
00463 if( classifier != 0L &&
00464 classifier->checkOperationSignature(name, m_pOperation->getParmList(), m_pOperation) )
00465 {
00466 QString msg = QString(i18n("An operation with that signature already exists in %1.\n")).arg(classifier->getName())
00467 +
00468 QString(i18n("Choose a different name or parameter list." ));
00469 KMessageBox::error(this, msg, i18n("Operation Name Invalid"), false);
00470 return false;
00471 }
00472 m_pOperation -> setName( name );
00473
00474 if( m_pPublicRB -> isChecked() )
00475 m_pOperation -> setVisibility( Uml::Visibility::Public );
00476 else if( m_pPrivateRB -> isChecked() )
00477 m_pOperation -> setVisibility( Uml::Visibility::Private );
00478 else if (m_pProtectedRB -> isChecked() )
00479 m_pOperation -> setVisibility( Uml::Visibility::Protected );
00480 else if (m_pImplementationRB -> isChecked() )
00481 m_pOperation -> setVisibility( Uml::Visibility::Implementation );
00482
00483 QString typeName = m_pRtypeCB->currentText();
00484 UMLTemplate *tmplParam = classifier->findTemplate(typeName);
00485 if (tmplParam)
00486 m_pOperation->setType(tmplParam);
00487 else
00488 m_pOperation->setTypeName(typeName);
00489
00490 m_pOperation->setStereotype( m_pStereoTypeCB->currentText() );
00491
00492 bool isAbstract = m_pAbstractCB->isChecked();
00493 m_pOperation -> setAbstract( isAbstract );
00494 if (isAbstract) {
00495
00496
00497
00498
00499
00500 classifier->setAbstract(true);
00501 }
00502 m_pOperation->setStatic( m_pStaticCB->isChecked() );
00503 m_pOperation->setConst( m_pQueryCB->isChecked() );
00504
00505 return true;
00506 }
00507
00508 void UMLOperationDialog::slotApply() {
00509 apply();
00510 }
00511
00512 void UMLOperationDialog::slotOk() {
00513 if ( apply() ) {
00514 accept();
00515 }
00516 }
00517
00518 void UMLOperationDialog::insertType( const QString& type, int index )
00519 {
00520 m_pRtypeCB->insertItem( type, index );
00521 m_pRtypeCB->completionObject()->addItem( type );
00522 }
00523
00524 void UMLOperationDialog::insertStereotype( const QString& type, int index )
00525 {
00526 m_pStereoTypeCB->insertItem( type, index );
00527 m_pStereoTypeCB->completionObject()->addItem( type );
00528 }
00529
00530 #include "umloperationdialog.moc"