00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "classifierlistpage.h"
00013 #include "../classifierlistitem.h"
00014 #include "../umldoc.h"
00015 #include "../classifier.h"
00016 #include "../enum.h"
00017 #include "../entity.h"
00018 #include "../attribute.h"
00019 #include "../operation.h"
00020 #include "../template.h"
00021 #include "../enumliteral.h"
00022 #include "../entityattribute.h"
00023 #include "../object_factory.h"
00024 #include <kapplication.h>
00025 #include <kbuttonbox.h>
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <qlayout.h>
00029
00030 using namespace Uml;
00031
00032 ClassifierListPage::ClassifierListPage(QWidget* parent, UMLClassifier* classifier,
00033 UMLDoc* doc, Object_Type type) : QWidget(parent) {
00034 m_itemType = type;
00035 QString typeName("");
00036 QString newItemType("");
00037 if (type == ot_Attribute) {
00038 typeName = i18n("Attributes");
00039 newItemType = i18n("N&ew Attribute...");
00040 } else if (type == ot_Operation) {
00041 typeName = i18n("Operations");
00042 newItemType = i18n("N&ew Operation...");
00043 } else if (type == ot_Template) {
00044 typeName = i18n("Templates");
00045 newItemType = i18n("N&ew Template...");
00046 } else if (type == ot_EnumLiteral) {
00047 typeName = i18n("Enum Literals");
00048 newItemType = i18n("N&ew Enum Literal...");
00049 } else if (type == ot_EntityAttribute) {
00050 typeName = i18n("Entity Attributes");
00051 newItemType = i18n("N&ew Entity Attribute...");
00052 } else {
00053 kWarning() << "unknown listItem type in ClassifierListPage" << endl;
00054 }
00055
00056 m_bSigWaiting = false;
00057 m_pDoc = doc;
00058 m_pClassifier = classifier;
00059 m_pMenu = 0;
00060 int margin = fontMetrics().height();
00061 setMinimumSize(310,330);
00062
00063
00064 QVBoxLayout* mainLayout = new QVBoxLayout( this );
00065 mainLayout->setSpacing(10);
00066
00067
00068 m_pItemListGB = new QGroupBox(typeName, this );
00069 QVBoxLayout* listVBoxLayout = new QVBoxLayout( m_pItemListGB );
00070 listVBoxLayout->setMargin(margin);
00071 listVBoxLayout->setSpacing ( 10 );
00072
00073
00074 QHBoxLayout* listHBoxLayout = new QHBoxLayout( listVBoxLayout );
00075 m_pItemListLB = new QListBox(m_pItemListGB);
00076 listHBoxLayout->addWidget(m_pItemListLB);
00077
00078
00079 QVBoxLayout* buttonLayout = new QVBoxLayout( listHBoxLayout );
00080 m_pTopArrowB = new KArrowButton( m_pItemListGB );
00081 m_pTopArrowB->setEnabled( false );
00082 buttonLayout->addWidget( m_pTopArrowB );
00083
00084 m_pUpArrowB = new KArrowButton( m_pItemListGB );
00085 m_pUpArrowB->setEnabled( false );
00086 buttonLayout->addWidget( m_pUpArrowB );
00087
00088 m_pDownArrowB = new KArrowButton( m_pItemListGB, Qt::DownArrow );
00089 m_pDownArrowB->setEnabled( false );
00090 buttonLayout->addWidget( m_pDownArrowB );
00091
00092 m_pBottomArrowB = new KArrowButton( m_pItemListGB, Qt::DownArrow );
00093 m_pBottomArrowB->setEnabled( false );
00094 buttonLayout->addWidget( m_pBottomArrowB );
00095
00096
00097 KButtonBox* buttonBox = new KButtonBox(m_pItemListGB);
00098 buttonBox->addButton( newItemType, this, SLOT(slotNewListItem()) );
00099 m_pDeleteListItemButton = buttonBox->addButton( i18n("&Delete"),
00100 this, SLOT(slotDelete()) );
00101 m_pPropertiesButton = buttonBox->addButton( i18n("&Properties"), this, SLOT(slotProperties()) );
00102 listVBoxLayout->addWidget(buttonBox);
00103
00104 mainLayout->addWidget(m_pItemListGB);
00105
00106 m_pDocGB = new QGroupBox(i18n("Documentation"), this);
00107 QVBoxLayout* docLayout = new QVBoxLayout( m_pDocGB );
00108 m_pDocTE = new QTextEdit( m_pDocGB );
00109 docLayout->setMargin(margin);
00110 docLayout->setSpacing ( 10 );
00111 docLayout->addWidget( m_pDocTE );
00112 mainLayout->addWidget(m_pDocGB);
00113
00114 UMLClassifierListItemList itemList(getItemList());
00115
00116
00117
00118 for (UMLClassifierListItem* listItem = itemList.first(); listItem != 0; listItem = itemList.next() ) {
00119 m_pItemListLB->insertItem(listItem->toString(Uml::st_SigNoVis));
00120 connect( listItem, SIGNAL(modified()),this,SLOT(slotListItemModified()) );
00121 }
00122
00123 enableWidgets(false);
00124 m_pOldListItem = 0;
00125 connect(m_pItemListLB, SIGNAL(clicked(QListBoxItem*)), this, SLOT(slotClicked(QListBoxItem*)));
00126 connect(m_pItemListLB, SIGNAL(selectionChanged(QListBoxItem*)), this, SLOT(slotClicked(QListBoxItem*)));
00127
00128 connect(m_pItemListLB, SIGNAL(rightButtonPressed(QListBoxItem*, const QPoint&)),
00129 this, SLOT(slotRightButtonPressed(QListBoxItem*, const QPoint&)));
00130
00131 connect(m_pItemListLB, SIGNAL(rightButtonClicked(QListBoxItem*, const QPoint&)),
00132 this, SLOT(slotRightButtonClicked(QListBoxItem*, const QPoint&)));
00133 connect(m_pDoc, SIGNAL(sigObjectCreated(UMLObject*)), this, SLOT(slotListItemCreated(UMLObject*)));
00134
00135 connect( m_pTopArrowB, SIGNAL( clicked() ), this, SLOT( slotTopClicked() ) );
00136 connect( m_pUpArrowB, SIGNAL( clicked() ), this, SLOT( slotUpClicked() ) );
00137 connect( m_pDownArrowB, SIGNAL( clicked() ), this, SLOT( slotDownClicked() ) );
00138 connect( m_pBottomArrowB, SIGNAL( clicked() ), this, SLOT( slotBottomClicked() ) );
00139 connect( m_pItemListLB, SIGNAL( doubleClicked( QListBoxItem* ) ),
00140 this, SLOT( slotDoubleClick( QListBoxItem* ) ) );
00141 }
00142
00143 ClassifierListPage::~ClassifierListPage() {
00144
00145 }
00146
00147 void ClassifierListPage::enableWidgets(bool state) {
00148 m_pDocTE->setEnabled( state );
00149
00150 if( !state ) {
00151 m_pDocTE->setText( "" );
00152 m_pTopArrowB->setEnabled( false );
00153 m_pUpArrowB->setEnabled( false );
00154 m_pDownArrowB->setEnabled( false );
00155 m_pBottomArrowB->setEnabled( false );
00156 m_pDeleteListItemButton->setEnabled(false);
00157 m_pPropertiesButton->setEnabled(false);
00158 return;
00159 }
00160
00161
00162
00163
00164
00165
00166 int index = m_pItemListLB->currentItem();
00167 if( m_pItemListLB->count() == 1 || index == -1 ) {
00168 m_pTopArrowB->setEnabled( false );
00169 m_pUpArrowB->setEnabled( false );
00170 m_pDownArrowB->setEnabled( false );
00171 m_pBottomArrowB->setEnabled( false );
00172 } else if( index == 0 ) {
00173 m_pTopArrowB->setEnabled( false );
00174 m_pUpArrowB->setEnabled( false );
00175 m_pDownArrowB->setEnabled( true );
00176 m_pBottomArrowB->setEnabled( true );
00177 } else if( index == (int)m_pItemListLB->count() - 1 ) {
00178 m_pTopArrowB->setEnabled( true );
00179 m_pUpArrowB->setEnabled( true );
00180 m_pDownArrowB->setEnabled( false );
00181 m_pBottomArrowB->setEnabled( false );
00182 } else {
00183 m_pTopArrowB->setEnabled( true );
00184 m_pUpArrowB->setEnabled( true );
00185 m_pDownArrowB->setEnabled( true );
00186 m_pBottomArrowB->setEnabled( true );
00187 }
00188 m_pDeleteListItemButton->setEnabled(true);
00189 m_pPropertiesButton->setEnabled(true);
00190 }
00191
00192 void ClassifierListPage::slotClicked(QListBoxItem*item) {
00193
00194
00195 if(m_pOldListItem) {
00196 m_pOldListItem->setDoc( m_pDocTE->text() );
00197 }
00198
00199
00200
00201
00202
00203
00204
00205 UMLClassifierListItem* listItem;
00206 if (item == NULL) {
00207 if (m_pItemListLB->count() == 0) {
00208 enableWidgets(false);
00209 m_pOldListItem = 0;
00210 m_pItemListLB->clearSelection();
00211 return;
00212 }
00213 m_pItemListLB->setSelected(0, true);
00214 listItem = getItemList().at(0);
00215 } else {
00216 listItem = getItemList().at( m_pItemListLB->index(item) );
00217 }
00218
00219 if (listItem) {
00220
00221 m_pDocTE->setText( listItem->getDoc() );
00222 enableWidgets(true);
00223 m_pOldListItem = listItem;
00224 }
00225 }
00226
00227 void ClassifierListPage::updateObject() {
00228 saveCurrentItemDocumentation();
00229 QListBoxItem*i = m_pItemListLB->item(m_pItemListLB->currentItem());
00230 slotClicked(i);
00231
00232
00233 QStringList stringList;
00234 int count = m_pItemListLB->count();
00235 for( int j = 0; j < count ; j++ )
00236 stringList.append( m_pItemListLB->text( j ) );
00237 }
00238
00239 void ClassifierListPage::slotListItemCreated(UMLObject* object) {
00240 if(!m_bSigWaiting) {
00241 return;
00242 }
00243 UMLClassifierListItem *listItem = dynamic_cast<UMLClassifierListItem*>(object);
00244 if (listItem == NULL) {
00245 return;
00246 }
00247 int index = m_pItemListLB->count();
00248 m_pItemListLB->insertItem(listItem->toString(Uml::st_SigNoVis), index);
00249 m_bSigWaiting = false;
00250
00251
00252
00253 m_pItemListLB->setSelected(index, true);
00254 slotClicked(m_pItemListLB->item(index));
00255 }
00256
00257 void ClassifierListPage::slotListItemModified() {
00258 if(!m_bSigWaiting) {
00259 return;
00260 }
00261
00262 UMLClassifierListItem* object = const_cast<UMLClassifierListItem*>(dynamic_cast<const UMLClassifierListItem*>(sender()));
00263 if (object == NULL)
00264 return;
00265 int index = m_pItemListLB->currentItem();
00266 m_pItemListLB->changeItem(object->toString(Uml::st_SigNoVis), index);
00267 m_bSigWaiting = false;
00268 }
00269
00270 void ClassifierListPage::slotRightButtonClicked(QListBoxItem* , const QPoint& ) {
00271 if (m_pMenu) {
00272 m_pMenu->hide();
00273 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotPopupMenuSel(int)));
00274 delete m_pMenu;
00275 m_pMenu = 0;
00276 }
00277 }
00278
00279 void ClassifierListPage::slotRightButtonPressed(QListBoxItem* item, const QPoint& p) {
00280 ListPopupMenu::Menu_Type type = ListPopupMenu::mt_Undefined;
00281 if (item) {
00282 if (m_itemType == ot_Attribute) {
00283 type = ListPopupMenu::mt_Attribute_Selected;
00284 } else if (m_itemType == ot_Operation) {
00285 type = ListPopupMenu::mt_Operation_Selected;
00286 } else if (m_itemType == ot_Template) {
00287 type = ListPopupMenu::mt_Template_Selected;
00288 } else if (m_itemType == ot_EnumLiteral) {
00289 type = ListPopupMenu::mt_EnumLiteral_Selected;
00290 } else if (m_itemType == ot_EntityAttribute) {
00291 type = ListPopupMenu::mt_EntityAttribute_Selected;
00292 } else {
00293 kWarning() << "unknown type in ClassifierListPage" << endl;
00294 }
00295 } else {
00296 if (m_itemType == ot_Attribute) {
00297 type = ListPopupMenu::mt_New_Attribute;
00298 } else if (m_itemType == ot_Operation) {
00299 type = ListPopupMenu::mt_New_Operation;
00300 } else if (m_itemType == ot_Template) {
00301 type = ListPopupMenu::mt_New_Template;
00302 } else if (m_itemType == ot_EnumLiteral) {
00303 type = ListPopupMenu::mt_New_EnumLiteral;
00304 } else if (m_itemType == ot_EntityAttribute) {
00305 type = ListPopupMenu::mt_New_EntityAttribute;
00306 } else {
00307 kWarning() << "unknown type in ClassifierListPage" << endl;
00308 }
00309 }
00310 if(m_pMenu) {
00311 m_pMenu->hide();
00312 disconnect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotPopupMenuSel(int)));
00313 delete m_pMenu;
00314 m_pMenu = 0;
00315 }
00316 m_pMenu = new ListPopupMenu(this, type);
00317
00318 m_pMenu->popup(p);
00319 connect(m_pMenu, SIGNAL(activated(int)), this, SLOT(slotPopupMenuSel(int)));
00320 }
00321
00322 void ClassifierListPage::slotPopupMenuSel(int id) {
00323 UMLClassifierListItem* listItem = getItemList().at( m_pItemListLB->currentItem() );
00324 if(!listItem && id != ListPopupMenu::mt_New_Attribute) {
00325 kDebug() << "can't find att from selection" << endl;
00326 return;
00327 }
00328 switch(id) {
00329 case ListPopupMenu::mt_New_Attribute:
00330 case ListPopupMenu::mt_New_Operation:
00331 case ListPopupMenu::mt_New_Template:
00332 case ListPopupMenu::mt_New_EnumLiteral:
00333 case ListPopupMenu::mt_New_EntityAttribute:
00334 slotNewListItem();
00335 break;
00336
00337 case ListPopupMenu::mt_Delete:
00338 slotDelete();
00339 break;
00340
00341 case ListPopupMenu::mt_Rename:
00342 m_bSigWaiting = true;
00343 m_pDoc->renameChildUMLObject(listItem);
00344 break;
00345
00346 case ListPopupMenu::mt_Properties:
00347 slotProperties();
00348 break;
00349 }
00350 }
00351
00352 void ClassifierListPage::printItemList(QString prologue) {
00353 #ifdef VERBOSE_DEBUGGING
00354 UMLClassifierListItem* item;
00355 QString buf;
00356 UMLClassifierListItemList itemList = getItemList();
00357 for (UMLClassifierListItemListIt it(itemList); (item = it.current()) != NULL; ++it)
00358 buf.append(' ' + item->getName());
00359 kDebug() << prologue << buf << endl;
00360 #endif
00361 }
00362
00363 void ClassifierListPage::slotTopClicked() {
00364 int count = m_pItemListLB->count();
00365 int index = m_pItemListLB->currentItem();
00366
00367 if( count <= 1 || index <= 0 )
00368 return;
00369 m_pOldListItem = NULL;
00370
00371
00372 QString currentString = m_pItemListLB->text( index );
00373 m_pItemListLB->removeItem( index );
00374 m_pItemListLB->insertItem( currentString, 0 );
00375
00376 QListBoxItem* item = m_pItemListLB->item( 0 );
00377 m_pItemListLB->setSelected( item, true );
00378
00379
00380 printItemList("itemList before change: ");
00381 UMLClassifierListItem* currentAtt = getItemList().at(index);
00382
00383
00384
00385
00386 takeItem(currentAtt, true, index);
00387 kDebug() << "ClassifierListPage::slotTopClicked(" << currentAtt->getName()
00388 << "): peer index in UMLCanvasItem::m_List is " << index << endl;
00389 addClassifier(currentAtt, 0);
00390 printItemList("itemList after change: ");
00391 slotClicked(item);
00392 }
00393
00394 void ClassifierListPage::slotUpClicked() {
00395 int count = m_pItemListLB->count();
00396 int index = m_pItemListLB->currentItem();
00397
00398 if( count <= 1 || index <= 0 )
00399 return;
00400 m_pOldListItem = NULL;
00401
00402
00403 QString aboveString = m_pItemListLB->text( index - 1 );
00404 QString currentString = m_pItemListLB->text( index );
00405 m_pItemListLB->changeItem( currentString, index -1 );
00406 m_pItemListLB->changeItem( aboveString, index );
00407
00408 QListBoxItem* item = m_pItemListLB->item( index - 1 );
00409 m_pItemListLB->setSelected( item, true );
00410
00411
00412 printItemList("itemList before change: ");
00413 UMLClassifierListItem* currentAtt = getItemList().at(index);
00414
00415
00416
00417
00418 takeItem(currentAtt, true, index);
00419 kDebug() << "ClassifierListPage::slotUpClicked(" << currentAtt->getName()
00420 << "): peer index in UMLCanvasItem::m_List is " << index << endl;
00421 if (index == -1)
00422 index = 0;
00423 addClassifier(currentAtt, index);
00424 printItemList("itemList after change: ");
00425 slotClicked( item );
00426 }
00427
00428 void ClassifierListPage::slotDownClicked() {
00429 int count = m_pItemListLB->count();
00430 int index = m_pItemListLB->currentItem();
00431
00432 if( count <= 1 || index >= count - 1 )
00433 return;
00434 m_pOldListItem = NULL;
00435
00436
00437 QString belowString = m_pItemListLB->text( index + 1 );
00438 QString currentString = m_pItemListLB->text( index );
00439 m_pItemListLB->changeItem( currentString, index + 1 );
00440 m_pItemListLB->changeItem( belowString, index );
00441
00442 QListBoxItem* item = m_pItemListLB->item( index + 1 );
00443 m_pItemListLB->setSelected( item, true );
00444
00445 printItemList("itemList before change: ");
00446 UMLClassifierListItem* currentAtt = getItemList().at(index);
00447
00448
00449
00450
00451 takeItem(currentAtt, false, index);
00452 kDebug() << "ClassifierListPage::slotDownClicked(" << currentAtt->getName()
00453 << "): peer index in UMLCanvasItem::m_List is " << index << endl;
00454 if (index != -1)
00455 index++;
00456 addClassifier(currentAtt, index);
00457 printItemList("itemList after change: ");
00458 slotClicked( item );
00459 }
00460
00461 void ClassifierListPage::slotBottomClicked() {
00462 int count = m_pItemListLB->count();
00463 int index = m_pItemListLB->currentItem();
00464
00465 if( count <= 1 || index >= count - 1 )
00466 return;
00467 m_pOldListItem = NULL;
00468
00469
00470 QString currentString = m_pItemListLB->text( index );
00471 m_pItemListLB->removeItem( index );
00472 m_pItemListLB->insertItem( currentString, m_pItemListLB->count() );
00473
00474 QListBoxItem* item = m_pItemListLB->item( m_pItemListLB->count() - 1 );
00475 m_pItemListLB->setSelected( item, true );
00476
00477
00478 printItemList("itemList before change: ");
00479 UMLClassifierListItem* currentAtt = getItemList().at(index);
00480
00481
00482
00483
00484 takeItem(currentAtt, false, index);
00485 kDebug() << "ClassifierListPage::slotDownClicked(" << currentAtt->getName()
00486 << "): peer index in UMLCanvasItem::m_List is " << index << endl;
00487 addClassifier(currentAtt, getItemList().count());
00488 printItemList("itemList after change: ");
00489 slotClicked( item );
00490 }
00491
00492 void ClassifierListPage::slotDoubleClick( QListBoxItem* item ) {
00493 if( !item )
00494 return;
00495
00496 UMLClassifierListItem* listItem = getItemList().at( m_pItemListLB->index( item ) );
00497 if( !listItem ) {
00498 kDebug() << "can't find att from selection" << endl;
00499 return;
00500 }
00501
00502 if( listItem->showPropertiesDialog(this) ) {
00503 m_pItemListLB->changeItem( listItem->toString(Uml::st_SigNoVis), m_pItemListLB->index(item) );
00504 }
00505 }
00506
00507 void ClassifierListPage::slotDelete() {
00508 UMLClassifierListItem* selectedItem = getItemList().at( m_pItemListLB->currentItem() );
00509
00510
00511 m_pDoc->removeUMLObject(selectedItem);
00512 m_pItemListLB->removeItem( m_pItemListLB->currentItem());
00513 m_pOldListItem = 0;
00514 slotClicked(0);
00515 }
00516
00517 void ClassifierListPage::slotProperties() {
00518 saveCurrentItemDocumentation();
00519 slotDoubleClick( m_pItemListLB->item( m_pItemListLB->currentItem() ) );
00520 }
00521
00522 void ClassifierListPage::slotNewListItem() {
00523 saveCurrentItemDocumentation();
00524 m_bSigWaiting = true;
00525 Object_Factory::createChildObject(m_pClassifier, m_itemType);
00526 }
00527
00528 void ClassifierListPage::saveCurrentItemDocumentation() {
00529 UMLClassifierListItem* selectedItem = getItemList().at( m_pItemListLB->currentItem() );
00530 if (selectedItem) {
00531 selectedItem->setDoc( m_pDocTE->text() );
00532 }
00533 }
00534
00535 UMLClassifierListItemList ClassifierListPage::getItemList() {
00536 return m_pClassifier->getFilteredList(m_itemType);
00537 }
00538
00539 bool ClassifierListPage::addClassifier(UMLClassifierListItem* listitem, int position) {
00540 switch (m_itemType) {
00541 case ot_Attribute: {
00542 UMLAttribute *att = dynamic_cast<UMLAttribute*>(listitem);
00543 return m_pClassifier->addAttribute(att, NULL, position);
00544 }
00545 case ot_Operation: {
00546 UMLOperation *op = dynamic_cast<UMLOperation*>(listitem);
00547 return m_pClassifier->addOperation(op, position);
00548 }
00549 case ot_Template: {
00550 UMLTemplate* t = dynamic_cast<UMLTemplate*>(listitem);
00551 return m_pClassifier->addTemplate(t, position);
00552 }
00553 case ot_EnumLiteral: {
00554 UMLEnum* c = dynamic_cast<UMLEnum*>(m_pClassifier);
00555 if (c) {
00556 return c->addEnumLiteral(dynamic_cast<UMLEnumLiteral*>(listitem), position);
00557 }
00558 break;
00559 }
00560 case ot_EntityAttribute: {
00561 UMLEntity* c = dynamic_cast<UMLEntity*>(m_pClassifier);
00562 if (c) {
00563 return c->addEntityAttribute(dynamic_cast<UMLEntityAttribute*>(listitem), position);
00564 }
00565 break;
00566 }
00567 default: {
00568 kWarning() << "unknown type in ClassifierListPage" << endl;
00569 return false;
00570 }
00571 }
00572 kError() << "ClassifierListPage::addClassifier unable to handle listitem type in current state" << endl;
00573 return false;
00574 }
00575
00576 bool ClassifierListPage::takeItem(UMLClassifierListItem* listItem,
00577 bool seekPeerBefore, int &peerIndex) {
00578 int wasAtIndex = m_pClassifier->takeItem(listItem);
00579 if (wasAtIndex == -1)
00580 return false;
00581 kapp->processEvents();
00582 peerIndex = -1;
00583 UMLObject *o;
00584 const Uml::Object_Type seekType = listItem->getBaseType();
00585 UMLObjectList listItems = m_pClassifier->subordinates();
00586 UMLObjectListIt it(listItems);
00587 for (int i = 0; (o = it.current()) != NULL; ++i, ++it) {
00588 if (seekPeerBefore) {
00589 if (i >= wasAtIndex)
00590 break;
00591 if (o->getBaseType() == seekType)
00592 peerIndex = i;
00593 } else {
00594 if (i < wasAtIndex)
00595 continue;
00596 if (o->getBaseType() == seekType) {
00597 peerIndex = i;
00598 break;
00599 }
00600 }
00601 }
00602 return true;
00603 }
00604
00605
00606 #include "classifierlistpage.moc"
00607