00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "QmitkToolSelectionBox.h"
00021 #include "QmitkToolGUI.h"
00022
00023 #include <qtoolbutton.h>
00024 #include <QList>
00025 #include <qtooltip.h>
00026 #include <qmessagebox.h>
00027 #include <qlayout.h>
00028 #include <qapplication.h>
00029
00030 #include <queue>
00031
00032 QmitkToolSelectionBox::QmitkToolSelectionBox(QWidget* parent, mitk::DataStorage* storage)
00033 :QWidget(parent),
00034 m_SelfCall(false),
00035 m_DisplayedGroups("default"),
00036 m_LayoutColumns(2),
00037 m_ShowNames(true),
00038 m_GenerateAccelerators(false),
00039 m_ToolGUIWidget(NULL),
00040 m_LastToolGUI(NULL),
00041 m_ToolButtonGroup(NULL),
00042 m_ButtonLayout(NULL),
00043 m_EnabledMode(EnabledWithReferenceAndWorkingData)
00044 {
00045 QFont currentFont = QWidget::font();
00046 currentFont.setBold(true);
00047 QWidget::setFont( currentFont );
00048
00049 m_ToolManager = mitk::ToolManager::New( storage );
00050
00051
00052
00053 m_ToolButtonGroup = new QButtonGroup(this);
00054
00055 m_ToolButtonGroup->setExclusive( false );
00056
00057 RecreateButtons();
00058
00059 QWidget::setContentsMargins(0, 0, 0, 0);
00060 if ( layout() != NULL )
00061 {
00062 layout()->setContentsMargins(0, 0, 0, 0);
00063 }
00064
00065
00066 connect( m_ToolButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(toolButtonClicked(int)) );
00067
00068
00069
00070 m_ToolManager->ActiveToolChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerToolModified );
00071 m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified );
00072 m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified );
00073
00074
00075 SetOrUnsetButtonForActiveTool();
00076
00077 QWidget::setEnabled( false );
00078 }
00079
00080 QmitkToolSelectionBox::~QmitkToolSelectionBox()
00081 {
00082 m_ToolManager->ActiveToolChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerToolModified );
00083 m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified );
00084 m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified );
00085
00086 }
00087
00088 void QmitkToolSelectionBox::SetEnabledMode(EnabledMode mode)
00089 {
00090 m_EnabledMode = mode;
00091 SetGUIEnabledAccordingToToolManagerState();
00092 }
00093
00094 mitk::ToolManager* QmitkToolSelectionBox::GetToolManager()
00095 {
00096 return m_ToolManager;
00097 }
00098
00099 void QmitkToolSelectionBox::SetToolManager(mitk::ToolManager& newManager)
00100 {
00101
00102 m_ToolManager->ActiveToolChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerToolModified );
00103 m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified );
00104 m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified );
00105
00106 if ( QWidget::isEnabled() )
00107 {
00108 m_ToolManager->UnregisterClient();
00109 }
00110
00111 m_ToolManager = &newManager;
00112 RecreateButtons();
00113
00114
00115 m_ToolManager->ActiveToolChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerToolModified );
00116 m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerReferenceDataModified );
00117 m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolManagerWorkingDataModified );
00118
00119 if ( QWidget::isEnabled() )
00120 {
00121 m_ToolManager->RegisterClient();
00122 }
00123
00124
00125 SetOrUnsetButtonForActiveTool();
00126 }
00127
00128 void QmitkToolSelectionBox::toolButtonClicked(int id)
00129 {
00130 if ( !QWidget::isEnabled() ) return;
00131
00132 MITK_DEBUG << "toolButtonClicked(" << id << "): id translates to tool ID " << m_ToolIDForButtonID[id];
00133
00134
00135 QToolButton* toolButton = dynamic_cast<QToolButton*>( m_ToolButtonGroup->buttons().at(id) );
00136 if (toolButton)
00137 {
00138 if ( (m_ButtonIDForToolID.find( m_ToolManager->GetActiveToolID() ) != m_ButtonIDForToolID.end())
00139 && (m_ButtonIDForToolID[ m_ToolManager->GetActiveToolID() ] == id) )
00140 {
00141
00142
00143 toolButton->setChecked(false);
00144 m_ToolManager->ActivateTool(-1);
00145 }
00146 else
00147 {
00148
00149 m_SelfCall = true;
00150
00151 m_ToolManager->ActivateTool( m_ToolIDForButtonID[id] );
00152
00153 m_SelfCall = false;
00154 }
00155 }
00156
00157 }
00158
00159 void QmitkToolSelectionBox::OnToolManagerToolModified()
00160 {
00161 SetOrUnsetButtonForActiveTool();
00162 }
00163
00164 void QmitkToolSelectionBox::SetOrUnsetButtonForActiveTool()
00165 {
00166
00167 int id = m_ToolManager->GetActiveToolID();
00168
00169
00170 bool emitSignal = true;
00171 mitk::Tool* tool = m_ToolManager->GetActiveTool();
00172 if(tool && std::string(tool->GetGroup()) == "organ_segmentation")
00173 emitSignal = false;
00174
00175 if(emitSignal)
00176 emit ToolSelected(id);
00177
00178
00179 if ( m_LastToolGUI && m_ToolGUIWidget )
00180 {
00181 if (m_ToolGUIWidget->layout())
00182 {
00183 m_ToolGUIWidget->layout()->removeWidget(m_LastToolGUI);
00184 }
00185
00186
00187
00188
00189 m_LastToolGUI->setParent(0);
00190 delete m_LastToolGUI;
00191 m_LastToolGUI = NULL;
00192
00193 QLayout* layout = m_ToolGUIWidget->layout();
00194 if (layout)
00195 {
00196 layout->activate();
00197 }
00198 }
00199
00200 QToolButton* toolButton(NULL);
00201
00202
00203 if (m_ButtonIDForToolID.find(id) != m_ButtonIDForToolID.end())
00204 {
00205
00206 toolButton = dynamic_cast<QToolButton*>( m_ToolButtonGroup->buttons().at( m_ButtonIDForToolID[id] ) );
00207 }
00208
00209 if ( toolButton )
00210 {
00211
00212
00213 QAbstractButton* tmpBtn = 0;
00214 QList<QAbstractButton*>::iterator it;
00215 for(int i=0; i < m_ToolButtonGroup->buttons().size(); ++i)
00216 {
00217 tmpBtn = m_ToolButtonGroup->buttons().at(i);
00218 if(tmpBtn != toolButton)
00219 dynamic_cast<QToolButton*>( tmpBtn )->setChecked(false);
00220 }
00221
00222 toolButton->setChecked(true);
00223
00224 if (m_ToolGUIWidget && tool)
00225 {
00226
00227 itk::Object::Pointer possibleGUI = tool->GetGUI("Qmitk", "GUI").GetPointer();
00228 QmitkToolGUI* gui = dynamic_cast<QmitkToolGUI*>( possibleGUI.GetPointer() );
00229
00231 m_LastToolGUI = gui;
00232 if (gui)
00233 {
00234 gui->SetTool( tool );
00235
00236
00237
00238 gui->setParent(m_ToolGUIWidget);
00239 gui->move(gui->geometry().topLeft());
00240 gui->show();
00241
00242 QLayout* layout = m_ToolGUIWidget->layout();
00243 if (!layout)
00244 {
00245 layout = new QVBoxLayout( m_ToolGUIWidget );
00246 }
00247 if (layout)
00248 {
00249
00250 layout->addWidget( gui );
00251
00252 layout->activate();
00253 }
00254 }
00255 }
00256 }
00257 else
00258 {
00259
00260 QToolButton* selectedToolButton = dynamic_cast<QToolButton*>( m_ToolButtonGroup->checkedButton() );
00261
00262 if (selectedToolButton)
00263 {
00264
00265 selectedToolButton->setChecked(false);
00266
00267 }
00268 }
00269 }
00270
00271 void QmitkToolSelectionBox::OnToolManagerReferenceDataModified()
00272 {
00273 if (m_SelfCall) return;
00274
00275 MITK_DEBUG << "OnToolManagerReferenceDataModified()";
00276
00277 SetGUIEnabledAccordingToToolManagerState();
00278 }
00279
00280 void QmitkToolSelectionBox::OnToolManagerWorkingDataModified()
00281 {
00282 if (m_SelfCall) return;
00283
00284 MITK_DEBUG << "OnToolManagerWorkingDataModified()";
00285
00286 SetGUIEnabledAccordingToToolManagerState();
00287 }
00288
00292 void QmitkToolSelectionBox::SetGUIEnabledAccordingToToolManagerState()
00293 {
00294 mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0);
00295 mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
00296
00297
00298
00299 bool enabled = true;
00300
00301 switch ( m_EnabledMode )
00302 {
00303 default:
00304 case EnabledWithReferenceAndWorkingData:
00305 enabled = referenceNode && workingNode && isVisible();
00306 break;
00307 case EnabledWithReferenceData:
00308 enabled = referenceNode && isVisible();
00309 break;
00310 case EnabledWithWorkingData:
00311 enabled = workingNode && isVisible();
00312 break;
00313 case AlwaysEnabled:
00314 enabled = isVisible();
00315 break;
00316 }
00317
00318 if ( QWidget::isEnabled() == enabled ) return;
00319
00320 QWidget::setEnabled( enabled );
00321 if (enabled)
00322 {
00323 m_ToolManager->RegisterClient();
00324
00325 int id = m_ToolManager->GetActiveToolID();
00326 emit ToolSelected(id);
00327 }
00328 else
00329 {
00330 m_ToolManager->ActivateTool(-1);
00331 m_ToolManager->UnregisterClient();
00332
00333 emit ToolSelected(-1);
00334 }
00335
00336 }
00337
00341 void QmitkToolSelectionBox::setEnabled( bool enable )
00342 {
00343 QWidget::setEnabled(enable);
00344 SetGUIEnabledAccordingToToolManagerState();
00345 }
00346
00347
00348 void QmitkToolSelectionBox::RecreateButtons()
00349 {
00350 if (m_ToolManager.IsNull()) return;
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 QList<QAbstractButton *> l = m_ToolButtonGroup->buttons();
00373
00374 QList<QAbstractButton *>::iterator it;
00375 QAbstractButton * btn;
00376
00377 for(it=l.begin(); it!=l.end();++it)
00378 {
00379 btn = *it;
00380 m_ToolButtonGroup->removeButton(btn);
00381
00382 delete btn;
00383 }
00384
00385
00386 mitk::ToolManager::ToolVectorTypeConst allPossibleTools = m_ToolManager->GetTools();
00387 mitk::ToolManager::ToolVectorTypeConst allTools;
00388
00389 typedef std::pair< std::string::size_type, const mitk::Tool* > SortPairType;
00390 typedef std::priority_queue< SortPairType > SortedToolQueueType;
00391 SortedToolQueueType toolPositions;
00392
00393
00394
00395 for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allPossibleTools.begin();
00396 iter != allPossibleTools.end();
00397 ++iter)
00398 {
00399 const mitk::Tool* tool = *iter;
00400
00401 std::string::size_type namePos = m_DisplayedGroups.find( std::string("'") + tool->GetName() + "'" );
00402 std::string::size_type groupPos = m_DisplayedGroups.find( std::string("'") + tool->GetGroup() + "'" );
00403
00404 if ( !m_DisplayedGroups.empty() && namePos == std::string::npos && groupPos == std::string::npos ) continue;
00405
00406 if ( m_DisplayedGroups.empty() && std::string(tool->GetName()).length() > 0 )
00407 {
00408 namePos = static_cast<std::string::size_type> (tool->GetName()[0]);
00409 }
00410
00411 SortPairType thisPair = std::make_pair( namePos < groupPos ? namePos : groupPos, *iter );
00412 toolPositions.push( thisPair );
00413 }
00414
00415
00416 MITK_DEBUG << "Sorting order of tools (lower number --> earlier in button group)";
00417 while ( !toolPositions.empty() )
00418 {
00419 SortPairType thisPair = toolPositions.top();
00420 MITK_DEBUG << "Position " << thisPair.first << " : " << thisPair.second->GetName();
00421
00422 allTools.push_back( thisPair.second );
00423 toolPositions.pop();
00424 }
00425 std::reverse( allTools.begin(), allTools.end() );
00426
00427 MITK_DEBUG << "Sorted tools:";
00428 for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin();
00429 iter != allTools.end();
00430 ++iter)
00431 {
00432 MITK_DEBUG << (*iter)->GetName();
00433 }
00434
00435
00436
00437
00438
00439 if(m_ButtonLayout == NULL)
00440 m_ButtonLayout = new QGridLayout;
00441
00442
00443
00444 int row(0);
00445 int column(-1);
00446
00447 int currentButtonID(0);
00448 m_ButtonIDForToolID.clear();
00449 m_ToolIDForButtonID.clear();
00450 QToolButton* button = 0;
00451
00452 MITK_DEBUG << "Creating buttons for tools";
00453
00454 for ( mitk::ToolManager::ToolVectorTypeConst::const_iterator iter = allTools.begin();
00455 iter != allTools.end();
00456 ++iter)
00457 {
00458 const mitk::Tool* tool = *iter;
00459 int currentToolID( m_ToolManager->GetToolID( tool ) );
00460
00461 ++column;
00462
00463 if(column == m_LayoutColumns)
00464 {
00465 ++row;
00466 column = 0;
00467 }
00468
00469 button = new QToolButton;
00470 button->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
00471
00472 MITK_DEBUG << "Adding button with ID " << currentToolID;
00473 m_ToolButtonGroup->addButton(button, currentButtonID);
00474
00475 MITK_DEBUG << "Adding button in row/column " << row << "/" << column;
00476 m_ButtonLayout->addWidget(button, row, column);
00477
00478 if (m_LayoutColumns == 1)
00479 {
00480
00481
00482 button->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
00483 }
00484 else
00485 {
00486
00487
00488 button->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );
00489 }
00490
00491
00492
00493 button->setCheckable ( true );
00494
00495 QString label;
00496 if (m_GenerateAccelerators)
00497 {
00498 label += "&";
00499 }
00500 label += tool->GetName();
00501 QString tooltip = tool->GetName();
00502 MITK_DEBUG << tool->GetName() << ", " << label.toLocal8Bit().constData() << ", '" << tooltip.toLocal8Bit().constData();
00503
00504 if ( m_ShowNames )
00505 {
00506
00507
00508
00509
00510
00511
00512 button->setText( label );
00513 button->setToolTip( tooltip );
00514
00515
00516 QFont currentFont = button->font();
00517 currentFont.setBold(false);
00518 button->setFont( currentFont );
00519 }
00520
00521
00522
00523 button->setIcon( QIcon( QPixmap( tool->GetXPM() ) ) );
00524
00525 if (m_GenerateAccelerators)
00526 {
00527 QString firstLetter = QString( tool->GetName() );
00528 firstLetter.truncate( 1 );
00529 button->setShortcut( firstLetter );
00530 }
00531
00532 m_ButtonIDForToolID[currentToolID] = currentButtonID;
00533 m_ToolIDForButtonID[currentButtonID] = currentToolID;
00534
00535 MITK_DEBUG << "m_ButtonIDForToolID[" << currentToolID << "] == " << currentButtonID;
00536 MITK_DEBUG << "m_ToolIDForButtonID[" << currentButtonID << "] == " << currentToolID;
00537
00538 tool->GUIProcessEventsMessage += mitk::MessageDelegate<QmitkToolSelectionBox>( this, &QmitkToolSelectionBox::OnToolGUIProcessEventsMessage );
00539 tool->ErrorMessage += mitk::MessageDelegate1<QmitkToolSelectionBox, std::string>( this, &QmitkToolSelectionBox::OnToolErrorMessage );
00540 tool->GeneralMessage += mitk::MessageDelegate1<QmitkToolSelectionBox, std::string>( this, &QmitkToolSelectionBox::OnGeneralToolMessage );
00541
00542 ++currentButtonID;
00543 }
00544
00545 this->setLayout(m_ButtonLayout);
00546
00547
00548 }
00549
00550 void QmitkToolSelectionBox::OnToolGUIProcessEventsMessage()
00551 {
00552 qApp->processEvents();
00553 }
00554
00555 void QmitkToolSelectionBox::OnToolErrorMessage(std::string s)
00556 {
00557 QMessageBox::critical(NULL, "MITK", QString( s.c_str() ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
00558 }
00559
00560 void QmitkToolSelectionBox::OnGeneralToolMessage(std::string s)
00561 {
00562 QMessageBox::information(NULL, "MITK", QString( s.c_str() ), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
00563 }
00564
00565
00566 void QmitkToolSelectionBox::SetDisplayedToolGroups(const std::string& toolGroups)
00567 {
00568 if (m_DisplayedGroups != toolGroups)
00569 {
00570 QString q_DisplayedGroups = toolGroups.c_str();
00571
00572 q_DisplayedGroups = q_DisplayedGroups.replace( QRegExp("\\b(\\w+)\\b|'([^']+)'"), "'\\1\\2'" );
00573 MITK_DEBUG << "m_DisplayedGroups was \"" << toolGroups << "\"";
00574
00575 m_DisplayedGroups = q_DisplayedGroups.toLocal8Bit().constData();
00576 MITK_DEBUG << "m_DisplayedGroups is \"" << m_DisplayedGroups << "\"";
00577
00578 RecreateButtons();
00579 SetOrUnsetButtonForActiveTool();
00580 }
00581 }
00582
00583 void QmitkToolSelectionBox::SetLayoutColumns(int columns)
00584 {
00585 if (columns > 0 && columns != m_LayoutColumns)
00586 {
00587 m_LayoutColumns = columns;
00588 RecreateButtons();
00589 }
00590 }
00591
00592 void QmitkToolSelectionBox::SetShowNames(bool show)
00593 {
00594 if (show != m_ShowNames)
00595 {
00596 m_ShowNames = show;
00597 RecreateButtons();
00598 }
00599 }
00600
00601
00602 void QmitkToolSelectionBox::SetGenerateAccelerators(bool accel)
00603 {
00604 if (accel != m_GenerateAccelerators)
00605 {
00606 m_GenerateAccelerators = accel;
00607 RecreateButtons();
00608 }
00609 }
00610
00611
00612 void QmitkToolSelectionBox::SetToolGUIArea( QWidget* parentWidget )
00613 {
00614 m_ToolGUIWidget = parentWidget;
00615 }
00616
00617 void QmitkToolSelectionBox::setTitle( const QString& )
00618 {
00619 }
00620
00621 void QmitkToolSelectionBox::showEvent( QShowEvent* e )
00622 {
00623 QWidget::showEvent(e);
00624 SetGUIEnabledAccordingToToolManagerState();
00625 }
00626
00627
00628 void QmitkToolSelectionBox::hideEvent( QHideEvent* e )
00629 {
00630 QWidget::hideEvent(e);
00631 SetGUIEnabledAccordingToToolManagerState();
00632 }
00633