Functionality for cropping images with a cuboid. More...
#include <QmitkImageCropper.h>
Classes | |
class | opExchangeNodes |
Public Slots | |
virtual void | CropImage () |
virtual void | SurroundingCheck (bool value) |
virtual void | CreateNewBoundingObject () |
virtual void | ChkInformationToggled (bool on) |
virtual void | OnImageSelectionChanged (const mitk::DataNode *) |
Public Member Functions | |
QmitkImageCropper (QObject *parent=0) | |
Constructor. Called by SampleApp (or other apps that use functionalities) | |
virtual | ~QmitkImageCropper () |
Destructor. | |
virtual void | CreateQtPartControl (QWidget *parent) |
Creates the Qt widget containing the functionality controls, like sliders, buttons etc. | |
virtual void | CreateConnections () |
Creates the Qt connections needed. | |
virtual void | Activated () |
Invoked when this functionality is selected by the application. | |
virtual void | Deactivated () |
Invoked when the user leaves this functionality. | |
virtual void | StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) |
virtual void | StdMultiWidgetNotAvailable () |
virtual void | ExecuteOperation (mitk::Operation *) |
QWidget * | GetControls () |
const mitk::DataNode::Pointer | selectedImage () |
Protected Member Functions | |
virtual void | CreateBoundingObject () |
Creates the cuboid and its data tree node. | |
virtual void | AddBoundingObjectToNode (mitk::DataNode *node) |
Finds the given node in the data tree and fits the cuboid to it. | |
virtual void | RemoveBoundingObjectFromNode () |
Removes the cuboid from any node and hides it from the user. | |
template<typename TPixel , unsigned int VImageDimension> | |
void | AddSurrounding (itk::Image< TPixel, VImageDimension > *itkImage, mitk::Image::Pointer image) |
virtual void | NodeRemoved (const mitk::DataNode *node) |
Protected Attributes | |
QmitkStdMultiWidget * | m_MultiWidget |
Ui::QmitkImageCropperControls * | m_Controls |
mitk::WeakPointer< mitk::DataNode > | m_ImageNode |
A pointer to the node of the image to be croped. | |
mitk::WeakPointer< mitk::Image > | m_ImageToCrop |
A pointer to the image to be cropped. | |
mitk::BoundingObject::Pointer | m_CroppingObject |
The cuboid used for cropping. | |
mitk::DataNode::Pointer | m_CroppingObjectNode |
Tree node of the cuboid used for cropping. | |
mitk::AffineInteractor::Pointer | m_AffineInteractor |
Interactor for moving and scaling the cuboid. |
Functionality for cropping images with a cuboid.
This functionality lets the user select an image from the data tree, select an area of interest by placing a cuboid object, and then crop the image, so that pixels from outside the cuboid will remove.
The image size is automatically reduced, if the cuboid is not rotated but parallel to the image axes.
Implementation
The functionality owns a cuboid (m_CroppingObject) and the associated interactor (m_AffineInteractor), which implements moving and scaling the cuboid.
Definition at line 52 of file QmitkImageCropper.h.
QmitkImageCropper::QmitkImageCropper | ( | QObject * | parent = 0 ) |
Constructor. Called by SampleApp (or other apps that use functionalities)
Definition at line 91 of file QmitkImageCropper.cpp.
: QObject(parent), m_Controls(NULL) { }
QmitkImageCropper::~QmitkImageCropper | ( | ) | [virtual] |
Destructor.
Definition at line 98 of file QmitkImageCropper.cpp.
References m_CroppingObject, and m_CroppingObjectNode.
{ //delete smart pointer objects m_CroppingObjectNode = NULL; m_CroppingObject = NULL; }
void QmitkImageCropper::Activated | ( | ) | [virtual] |
Invoked when this functionality is selected by the application.
Reimplemented from QmitkFunctionality.
Definition at line 141 of file QmitkImageCropper.cpp.
{ QmitkFunctionality::Activated(); // just call the inherited function }
void QmitkImageCropper::AddBoundingObjectToNode | ( | mitk::DataNode * | node ) | [protected, virtual] |
Finds the given node in the data tree and fits the cuboid to it.
Definition at line 424 of file QmitkImageCropper.cpp.
References mitk::DataNode::GetData(), QmitkFunctionality::GetDefaultDataStorage(), mitk::GlobalInteraction::GetInstance(), m_AffineInteractor, m_CroppingObject, m_CroppingObjectNode, and m_ImageToCrop.
Referenced by CreateNewBoundingObject().
{ m_ImageToCrop = dynamic_cast<mitk::Image*>(node->GetData()); if(!this->GetDefaultDataStorage()->Exists(m_CroppingObjectNode)) { this->GetDefaultDataStorage()->Add(m_CroppingObjectNode, node); m_CroppingObject->FitGeometry(m_ImageToCrop->GetTimeSlicedGeometry()); mitk::GlobalInteraction::GetInstance()->AddInteractor( m_AffineInteractor ); } m_CroppingObjectNode->SetVisibility(true); }
void QmitkImageCropper::AddSurrounding | ( | itk::Image< TPixel, VImageDimension > * | itkImage, |
mitk::Image::Pointer | image | ||
) | [protected] |
Definition at line 327 of file QmitkImageCropper.cpp.
References mitk::ImportItkImage(), m_Controls, QmitkFunctionality::m_Parent, Ui_QmitkImageCropperControls::m_SurroundingSpin, and mitk::Image::New().
Referenced by CropImage().
{ typedef itk::Image< TPixel, VImageDimension > InputImageType; typename InputImageType::Pointer extended = InputImageType::New(); typename InputImageType::IndexType start; start[0]=0; start[1]=0; start[2]=0; unsigned int *dims = image->GetDimensions(); typename InputImageType::SizeType size; size[0]=dims[0]; size[1]=dims[1]; size[2]=dims[2]; typename InputImageType::RegionType region; region.SetSize(size); region.SetIndex(start); extended->SetRegions(region); extended->SetDirection(itkImage->GetDirection()); extended->SetOrigin(itkImage->GetOrigin()); extended->Allocate(); extended->SetSpacing(itkImage->GetSpacing()); typename InputImageType::IndexType idx; progress = new QProgressDialog( "Adding surrounding...", "Abort", 0, (size[0]-1), m_Parent); progress->setLabelText("Image cropper"); progress->show(); for (unsigned int i=0;i<size[0];i++) { for (unsigned int j=0;j<size[1];j++) { for (unsigned int k=0;k<size[2];k++) { idx[0]=i; idx[1]=j; idx[2]=k; if(i==0 || j==0 || k==0 || i==size[0]-1 || j==size[1]-1 || k==size[2]-1) { extended->SetPixel(idx, m_Controls->m_SurroundingSpin->value()); } else { extended->SetPixel(idx, itkImage->GetPixel(idx)); } } } progress->setValue(i); if ( progress->wasCanceled() ) break; } m_surrImage = mitk::Image::New(); m_surrImage = mitk::ImportItkImage(extended); }
void QmitkImageCropper::ChkInformationToggled | ( | bool | on ) | [virtual, slot] |
Definition at line 456 of file QmitkImageCropper.cpp.
References Ui_QmitkImageCropperControls::groupInfo, and m_Controls.
Referenced by CreateConnections().
{ if (on) m_Controls->groupInfo->show(); else m_Controls->groupInfo->hide(); }
void QmitkImageCropper::CreateBoundingObject | ( | ) | [protected, virtual] |
Creates the cuboid and its data tree node.
Definition at line 390 of file QmitkImageCropper.cpp.
References m_AffineInteractor, m_CroppingObject, m_CroppingObjectNode, QmitkFunctionality::m_Parent, mitk::AffineInteractor::New(), mitk::BoolProperty::New(), mitk::IntProperty::New(), mitk::FloatProperty::New(), mitk::ColorProperty::New(), mitk::StringProperty::New(), mitk::DataNode::New(), mitk::Cuboid::New(), mitk::Cone::New(), mitk::Cylinder::New(), and mitk::Ellipsoid::New().
Referenced by CreateNewBoundingObject().
{ QStringList items; items << tr("Cuboid") << tr("Ellipsoid") << tr("Cylinder") << tr("Cone"); bool ok; QString item = QInputDialog::getItem(m_Parent, tr("Select Bounding Object"), tr("Type of Bounding Object:"), items, 0, false, &ok); if (!ok) return; if (item == "Ellipsoid") m_CroppingObject = mitk::Ellipsoid::New(); else if(item == "Cylinder") m_CroppingObject = mitk::Cylinder::New(); else if (item == "Cone") m_CroppingObject = mitk::Cone::New(); else if (item == "Cuboid") m_CroppingObject = mitk::Cuboid::New(); else return; m_CroppingObjectNode = mitk::DataNode::New(); m_CroppingObjectNode->SetData( m_CroppingObject ); m_CroppingObjectNode->SetProperty( "name", mitk::StringProperty::New( "CroppingObject" ) ); m_CroppingObjectNode->SetProperty( "color", mitk::ColorProperty::New(1.0, 1.0, 0.0) ); m_CroppingObjectNode->SetProperty( "opacity", mitk::FloatProperty::New(0.4) ); m_CroppingObjectNode->SetProperty( "layer", mitk::IntProperty::New(99) ); // arbitrary, copied from segmentation functionality m_CroppingObjectNode->SetProperty( "helper object", mitk::BoolProperty::New(true) ); m_AffineInteractor = mitk::AffineInteractor::New("AffineInteractions ctrl-drag", m_CroppingObjectNode); }
void QmitkImageCropper::CreateConnections | ( | ) | [virtual] |
Creates the Qt connections needed.
Definition at line 129 of file QmitkImageCropper.cpp.
References Ui_QmitkImageCropperControls::btnCrop, Ui_QmitkImageCropperControls::chkInformation, ChkInformationToggled(), Ui_QmitkImageCropperControls::cmbImage, CreateNewBoundingObject(), CropImage(), m_Controls, Ui_QmitkImageCropperControls::m_EnableSurroundingCheckBox, Ui_QmitkImageCropperControls::m_NewBoxButton, OnImageSelectionChanged(), QmitkFunctionality::OnSelectionChanged(), and SurroundingCheck().
Referenced by CreateQtPartControl().
{ if ( m_Controls ) { connect( m_Controls->btnCrop, SIGNAL(clicked()), this, SLOT(CropImage())); // click on the crop button connect( m_Controls->m_NewBoxButton, SIGNAL(clicked()), this, SLOT(CreateNewBoundingObject()) ); connect( m_Controls->m_EnableSurroundingCheckBox, SIGNAL(toggled(bool)), this, SLOT(SurroundingCheck(bool)) ); connect( m_Controls->chkInformation, SIGNAL(toggled(bool)), this, SLOT(ChkInformationToggled(bool)) ); connect( m_Controls->cmbImage, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnImageSelectionChanged(const mitk::DataNode*)) ); } }
void QmitkImageCropper::CreateNewBoundingObject | ( | ) | [virtual, slot] |
Definition at line 183 of file QmitkImageCropper.cpp.
References AddBoundingObjectToNode(), Ui_QmitkImageCropperControls::btnCrop, CreateBoundingObject(), mitk::RenderingManager::GetInstance(), mitk::WeakPointer< TObjectType >::IsNotNull(), QmitkFunctionality::IsVisible(), m_Controls, m_CroppingObject, m_ImageNode, m_ImageToCrop, Ui_QmitkImageCropperControls::m_NewBoxButton, and selectedImage().
Referenced by CreateConnections().
{ // 1. Get the selected image // 2. If any image is selected, // attach the cuboid to it, and update the views if (this->IsVisible()) { m_ImageNode = this->selectedImage(); if (m_ImageNode.IsNotNull()) { m_ImageToCrop = dynamic_cast<mitk::Image*>(m_ImageNode->GetData()); if(m_ImageToCrop.IsNotNull()) { if(m_CroppingObject.IsNull()) CreateBoundingObject(); if (m_CroppingObject.IsNull()) return; AddBoundingObjectToNode( m_ImageNode ); m_ImageNode->SetVisibility(true); mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_Controls->m_NewBoxButton->setEnabled(false); m_Controls->btnCrop->setEnabled(true); } } else QMessageBox::information(NULL, "Image cropping functionality", "Load an image first!"); } }
void QmitkImageCropper::CreateQtPartControl | ( | QWidget * | parent ) | [virtual] |
Creates the Qt widget containing the functionality controls, like sliders, buttons etc.
Implements berry::QtViewPart.
Definition at line 105 of file QmitkImageCropper.cpp.
References Ui_QmitkImageCropperControls::cmbImage, CreateConnections(), QmitkFunctionality::GetDefaultDataStorage(), Ui_QmitkImageCropperControls::groupInfo, m_Controls, Ui_QmitkImageCropperControls::m_NewBoxButton, Ui_QmitkImageCropperControls::m_SurroundingSlider, Ui_QmitkImageCropperControls::m_SurroundingSpin, Ui_QmitkImageCropperControls::m_TLGrayvalue, mitk::NodePredicateDataType::New(), QmitkDataStorageComboBox::SetDataStorage(), QmitkDataStorageComboBox::SetPredicate(), and Ui_QmitkImageCropperControls::setupUi().
{ if (!m_Controls) { // build ui elements m_Controls = new Ui::QmitkImageCropperControls; m_Controls->setupUi(parent); // setup ui elements m_Controls->groupInfo->hide(); m_Controls->m_SurroundingSlider->hide(); m_Controls->m_SurroundingSpin->hide(); m_Controls->m_TLGrayvalue->hide(); m_Controls->m_NewBoxButton->setEnabled(true); // create ui element connections this->CreateConnections(); m_Controls->cmbImage->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->cmbImage->SetPredicate(mitk::NodePredicateDataType::New("Image")); } }
void QmitkImageCropper::CropImage | ( | ) | [virtual, slot] |
Definition at line 259 of file QmitkImageCropper.cpp.
References AccessByItk_1, AddSurrounding(), Ui_QmitkImageCropperControls::btnCrop, ExecuteOperation(), mitk::UndoController::GetCurrentUndoModel(), mitk::WeakPointer< TObjectType >::GetPointer(), mitk::WeakPointer< TObjectType >::IsNull(), m_Controls, m_CroppingObject, m_CroppingObjectNode, Ui_QmitkImageCropperControls::m_EnableSurroundingCheckBox, m_ImageNode, m_ImageToCrop, Ui_QmitkImageCropperControls::m_NewBoxButton, mitk::BoundingObjectCutter::New(), and RemoveBoundingObjectFromNode().
Referenced by CreateConnections().
{ // test, if image is selected if (m_ImageToCrop.IsNull()) return; // test, if bounding box is visible if (m_CroppingObjectNode.IsNull()) { QMessageBox::information(NULL, "Image cropping functionality", "Generate a new bounding object first!"); return; } // image and bounding object ok mitk::BoundingObjectCutter::Pointer cutter = mitk::BoundingObjectCutter::New(); cutter->SetBoundingObject( m_CroppingObject ); cutter->SetInput( m_ImageToCrop ); cutter->AutoOutsideValueOff(); // do the actual cutting try { cutter->Update(); //cutter->UpdateLargestPossibleRegion(); } catch(itk::ExceptionObject&) { QMessageBox::warning ( NULL, tr("Cropping not possible"), tr("Sorry, the bounding box has to be completely inside the image.\n\n" "The possibility to drag it larger than the image a bug and has to be fixed."), QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton ); return; } // cutting successful mitk::Image::Pointer resultImage = cutter->GetOutput(); resultImage->DisconnectPipeline(); if(m_Controls->m_EnableSurroundingCheckBox->isChecked()) { AccessByItk_1( resultImage, AddSurrounding, resultImage); resultImage = m_surrImage; } RemoveBoundingObjectFromNode(); { opExchangeNodes* doOp = new opExchangeNodes(OP_EXCHANGE, m_ImageNode.GetPointer(), m_ImageNode->GetData(), resultImage); opExchangeNodes* undoOp = new opExchangeNodes(OP_EXCHANGE, m_ImageNode.GetPointer(), resultImage, m_ImageNode->GetData()); // TODO: MITK doesn't recognize that a new event happens in the next line, // because nothing happens in the render window. // As a result the undo action will happen together with the last action // recognized by MITK. mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent( new mitk::OperationEvent(this, doOp, undoOp, "Crop image") ); // tell the undo controller about the action ExecuteOperation(doOp); // execute action } m_Controls->m_NewBoxButton->setEnabled(true); m_Controls->btnCrop->setEnabled(false); }
void QmitkImageCropper::Deactivated | ( | ) | [virtual] |
Invoked when the user leaves this functionality.
Reimplemented from QmitkFunctionality.
Definition at line 147 of file QmitkImageCropper.cpp.
References mitk::RenderingManager::GetInstance(), and RemoveBoundingObjectFromNode().
{ RemoveBoundingObjectFromNode(); QmitkFunctionality::Deactivated(); // just call the inherited function mitk::RenderingManager::GetInstance()->RequestUpdateAll(); }
void QmitkImageCropper::ExecuteOperation | ( | mitk::Operation * | operation ) | [virtual] |
When called with an opExchangeNodes, it changes the content of a node from one data set to another
Implements mitk::OperationActor.
Definition at line 158 of file QmitkImageCropper.cpp.
References mitk::RenderingManager::GetInstance(), and mitk::Operation::GetOperationType().
Referenced by CropImage().
{ if (!operation) return; switch (operation->GetOperationType()) { case OP_EXCHANGE: { //RemoveBoundingObjectFromNode(); opExchangeNodes* op = static_cast<opExchangeNodes*>(operation); op->GetNode()->SetData(op->GetNewData()); mitk::RenderingManager::GetInstance()->InitializeViews(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); break; } default:; } }
QWidget* QmitkImageCropper::GetControls | ( | ) |
void QmitkImageCropper::NodeRemoved | ( | const mitk::DataNode * | node ) | [protected, virtual] |
Called when a DataStorage Remove event was thrown. May be reimplemented by deriving classes.
Reimplemented from QmitkFunctionality.
Definition at line 474 of file QmitkImageCropper.cpp.
References Ui_QmitkImageCropperControls::btnCrop, mitk::DataNode::GetName(), m_Controls, m_CroppingObject, m_CroppingObjectNode, and Ui_QmitkImageCropperControls::m_NewBoxButton.
{ std::string name = node->GetName(); if (strcmp(name.c_str(), "CroppingObject")==0) { m_CroppingObjectNode=NULL; m_CroppingObject = NULL; m_Controls->btnCrop->setEnabled(false); m_Controls->m_NewBoxButton->setEnabled(true); } }
void QmitkImageCropper::OnImageSelectionChanged | ( | const mitk::DataNode * | ) | [virtual, slot] |
Definition at line 178 of file QmitkImageCropper.cpp.
References RemoveBoundingObjectFromNode().
Referenced by CreateConnections().
{ this->RemoveBoundingObjectFromNode(); }
void QmitkImageCropper::RemoveBoundingObjectFromNode | ( | ) | [protected, virtual] |
Removes the cuboid from any node and hides it from the user.
Definition at line 438 of file QmitkImageCropper.cpp.
References QmitkFunctionality::GetDefaultDataStorage(), mitk::GlobalInteraction::GetInstance(), m_AffineInteractor, and m_CroppingObjectNode.
Referenced by CropImage(), Deactivated(), and OnImageSelectionChanged().
{ if (m_CroppingObjectNode.IsNotNull()) { if(this->GetDefaultDataStorage()->Exists(m_CroppingObjectNode)) { this->GetDefaultDataStorage()->Remove(m_CroppingObjectNode); mitk::GlobalInteraction::GetInstance()->RemoveInteractor(m_AffineInteractor); } } }
const mitk::DataNode::Pointer QmitkImageCropper::selectedImage | ( | ) |
Definition at line 450 of file QmitkImageCropper.cpp.
References Ui_QmitkImageCropperControls::cmbImage, QmitkDataStorageComboBox::GetSelectedNode(), and m_Controls.
Referenced by CreateNewBoundingObject(), and SurroundingCheck().
{ return m_Controls->cmbImage->GetSelectedNode(); }
void QmitkImageCropper::StdMultiWidgetAvailable | ( | QmitkStdMultiWidget & | stdMultiWidget ) | [virtual] |
Called when a StdMultiWidget is available.
Reimplemented from QmitkFunctionality.
Definition at line 464 of file QmitkImageCropper.cpp.
References m_MultiWidget.
{ m_MultiWidget = &stdMultiWidget; }
void QmitkImageCropper::StdMultiWidgetNotAvailable | ( | ) | [virtual] |
Called when no StdMultiWidget is available.
Reimplemented from QmitkFunctionality.
Definition at line 469 of file QmitkImageCropper.cpp.
References m_MultiWidget.
{ m_MultiWidget = NULL; }
void QmitkImageCropper::SurroundingCheck | ( | bool | value ) | [virtual, slot] |
Definition at line 216 of file QmitkImageCropper.cpp.
References mitk::DataNode::GetData(), mitk::WeakPointer< TObjectType >::GetPointer(), mitk::Image::GetScalarValueMax(), mitk::Image::GetScalarValueMin(), mitk::WeakPointer< TObjectType >::IsNotNull(), m_Controls, Ui_QmitkImageCropperControls::m_EnableSurroundingCheckBox, m_ImageNode, Ui_QmitkImageCropperControls::m_SurroundingSlider, Ui_QmitkImageCropperControls::m_SurroundingSpin, Ui_QmitkImageCropperControls::m_TLGrayvalue, QuadProgPP::max(), min, and selectedImage().
Referenced by CreateConnections().
{ if(value) { m_ImageNode = this->selectedImage(); if(m_ImageNode.IsNotNull()) { mitk::DataNode *imageNode = m_ImageNode.GetPointer(); if (imageNode) { mitk::BaseData* data = imageNode->GetData(); if (data) { // test if this data item is an image or not (could also be a surface or something totally different) mitk::Image* image = dynamic_cast<mitk::Image*>( data ); if (image) { float min = 10000.0; float max = -10000.0; min = image->GetScalarValueMin(); max = image->GetScalarValueMax(); m_Controls->m_SurroundingSlider->setRange((int)min,(int)max); m_Controls->m_SurroundingSpin->setRange((int)min,(int)max); } } } m_Controls->m_SurroundingSlider->show(); m_Controls->m_SurroundingSpin->show(); m_Controls->m_TLGrayvalue->show(); } else m_Controls->m_EnableSurroundingCheckBox->setChecked(false); } else { m_Controls->m_SurroundingSlider->hide(); m_Controls->m_SurroundingSpin->hide(); m_Controls->m_TLGrayvalue->hide(); } }
Interactor for moving and scaling the cuboid.
Definition at line 175 of file QmitkImageCropper.h.
Referenced by AddBoundingObjectToNode(), CreateBoundingObject(), and RemoveBoundingObjectFromNode().
Controls containing an image selection drop down, some usage information and a "crop" button
Definition at line 150 of file QmitkImageCropper.h.
Referenced by AddSurrounding(), ChkInformationToggled(), CreateConnections(), CreateNewBoundingObject(), CreateQtPartControl(), CropImage(), NodeRemoved(), selectedImage(), and SurroundingCheck().
The cuboid used for cropping.
Definition at line 165 of file QmitkImageCropper.h.
Referenced by AddBoundingObjectToNode(), CreateBoundingObject(), CreateNewBoundingObject(), CropImage(), NodeRemoved(), and ~QmitkImageCropper().
Tree node of the cuboid used for cropping.
Definition at line 170 of file QmitkImageCropper.h.
Referenced by AddBoundingObjectToNode(), CreateBoundingObject(), CropImage(), NodeRemoved(), RemoveBoundingObjectFromNode(), and ~QmitkImageCropper().
A pointer to the node of the image to be croped.
Definition at line 155 of file QmitkImageCropper.h.
Referenced by CreateNewBoundingObject(), CropImage(), and SurroundingCheck().
mitk::WeakPointer<mitk::Image> QmitkImageCropper::m_ImageToCrop [protected] |
A pointer to the image to be cropped.
Definition at line 160 of file QmitkImageCropper.h.
Referenced by AddBoundingObjectToNode(), CreateNewBoundingObject(), and CropImage().
QmitkStdMultiWidget* QmitkImageCropper::m_MultiWidget [protected] |
Default main widget containing 4 windows showing 3 orthogonal slices of the volume and a 3d render window
Definition at line 145 of file QmitkImageCropper.h.
Referenced by StdMultiWidgetAvailable(), and StdMultiWidgetNotAvailable().