Skip to content

Commit

Permalink
Fixed crash by means of extra validation
Browse files Browse the repository at this point in the history
The program should no longer freeze as it is no longer possible to update
the 3D view or create the shape without entering in all the details for a
component shape.
If any fields don't contain a number that's convertable to double, the
program will show an error message.
The error doesn't show what's wrong specifically, it just tells the user
there is something to check.

Refs #3737
  • Loading branch information
keithnbrown committed Jul 16, 2013
1 parent 0742f16 commit 549e777
Show file tree
Hide file tree
Showing 4 changed files with 335 additions and 63 deletions.
Expand Up @@ -89,6 +89,8 @@ private slots:
void changeTreeData(BinaryTreeWidgetItem* item, int data);
/// Update the object within the 3D widget
void update3DView();
/// The ok button overridden to validate data for this custom dialog
void accept();

private:
/// Initialize the layout
Expand All @@ -101,6 +103,8 @@ private slots:
ShapeDetails* createDetailsWidget(const QString & shapename) const;
/// Construct the XML from the current tree
QString constructShapeXML() const;
/// validation for the shapes
bool validate() const;

private:
/// The form generated with Qt Designer
Expand Down
Expand Up @@ -43,6 +43,9 @@ class PointGroupBox : public QGroupBox
///Write the element tag for a 3D point
QString write3DElement(const QString & elem_name) const;

///make sure the point is valid
bool valid();

private slots:
// Switch to cartesian coordinates
void changeToCartesian();
Expand Down Expand Up @@ -152,6 +155,8 @@ class ShapeDetails : public QWidget
/// Get complement flag
bool getComplementFlag() const;

/// Validate this shape
virtual bool valid() {return true;}
protected:
/// ID string of this object
QString m_idvalue;
Expand Down Expand Up @@ -182,7 +187,9 @@ class SphereDetails : public ShapeDetails

//Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edit for radius value
QLineEdit *m_radius_box;
Expand Down Expand Up @@ -212,7 +219,9 @@ class CylinderDetails : public ShapeDetails

//Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edits to enter values
QLineEdit *m_radius_box, *m_height_box;
Expand Down Expand Up @@ -242,7 +251,9 @@ class InfiniteCylinderDetails : public ShapeDetails

//Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edits to enter values
QLineEdit *m_radius_box;
Expand Down Expand Up @@ -272,7 +283,9 @@ class SliceOfCylinderRingDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edits to enter values
QLineEdit *m_rinner_box, *m_router_box, *m_depth_box, *m_arc_box;
Expand Down Expand Up @@ -300,7 +313,9 @@ class ConeDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edits to enter values
QLineEdit *m_height_box, *m_angle_box;
Expand Down Expand Up @@ -330,7 +345,9 @@ class InfiniteConeDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Line edits to enter values
QLineEdit *m_angle_box;
Expand Down Expand Up @@ -358,7 +375,9 @@ class InfinitePlaneDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Centre and axis point boxes
PointGroupBox *m_plane, *m_normal;
Expand All @@ -384,7 +403,9 @@ class CuboidDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Corner points
PointGroupBox *m_left_frt_bot, *m_left_frt_top, *m_left_bck_bot, *m_right_frt_bot;
Expand All @@ -410,7 +431,9 @@ class HexahedronDetails : public ShapeDetails

/// Write the XML definition of a sphere
QString writeXML() const;


/// Validate this shape
bool valid();
private:
/// Corner points
PointGroupBox *m_left_bck_bot, *m_left_frt_bot, *m_right_frt_bot, *m_right_bck_bot,
Expand All @@ -437,7 +460,9 @@ class HexahedronDetails : public ShapeDetails

// /// Write the XML definition of a sphere
// QString writeXML() const;

//
// /// Validate this shape
// bool valid();
// private:
// /// Radius values
// QLineEdit *m_tube_rad, *m_inner_rad;
Expand Down
163 changes: 112 additions & 51 deletions Code/Mantid/MantidQt/CustomDialogs/src/CreateSampleShapeDialog.cpp
Expand Up @@ -156,67 +156,128 @@ void CreateSampleShapeDialog::parseInput()
storePropertyValue("InputWorkspace", m_uiForm.wksp_opt->currentText());
}

/**
* Validates all the shapes in the 3d space to see if thay have enough information to render
* @return boolean : true if sucessful, false if one or more shapes failed to validate.
*/
bool CreateSampleShapeDialog::validate() const
{
//Look through all the shapes to check if they all have details
QMapIterator<BinaryTreeWidgetItem*, ShapeDetails*> itr(m_details_map);
while (itr.hasNext())
{
itr.next();
if (!itr.value()->valid())
{
return false;
}
}
return true;
}
/**
* A slot that can be used to connect a button that accepts the dialog if
* all of the properties are valid
*/
void CreateSampleShapeDialog::accept()
{
//Specific validation for the shapes
if (validate())
{
// Get property values
parse();

//Try and set and validate the properties and
if( setPropertyValues() )
{
//Store input for next time
saveInput();
QDialog::accept();
}
else
{
QMessageBox::critical(this, "",
"One or more properties are invalid. The invalid properties are\n"
"marked with a *, hold your mouse over the * for more information." );
}
}
else
{
QMessageBox::critical(this, "",
"One or more shapes are invalid so the model cannot be rendered.\n"
"Please check all shapes in the model for any missing or invalid data." );
}
}
/**
* Update the 3D widget with a new object
*/
void CreateSampleShapeDialog::update3DView()
{
std::string shapexml = constructShapeXML().toStdString();
if( m_shapeTree->topLevelItemCount() > 0 && shapexml.empty() )
//Specific validation for the shapes
if (validate())
{
QMessageBox::information(this, "CreateSampleShapeDialog",
"An error occurred while parsing the shape tree.\n"
"Please check that each node has two children and the lowest elements are primitive shapes.");
return;
std::string shapexml = constructShapeXML().toStdString();
if( m_shapeTree->topLevelItemCount() > 0 && shapexml.empty() )
{
QMessageBox::information(this, "CreateSampleShapeDialog",
"An error occurred while parsing the shape tree.\n"
"Please check that each node has two children and the lowest elements are primitive shapes.");
return;

}
}

// Testing a predefined complex shape PLEASE LEAVE FOR THE MOMENT
// std::string shapexml = "<cuboid id=\"cuboid_1\" >\n"
// "<left-front-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.0\" />\n"
// "<left-front-top-point x=\"-0.02\" y=\"0.05\" z= \"0.0\" />\n"
// "<left-back-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.07\" />\n"
// "<right-front-bottom-point x=\"0.05\" y=\"-0.02\" z= \"0.0\" />\n"
// "</cuboid>\n"
// "<infinite-cylinder id=\"infcyl_1\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"0.015\" y=\"0.015\" z= \"0.07\" />"
// "<axis x=\"0.0\" y=\"0.0\" z= \"-0.001\" />"
// "</infinite-cylinder>\n"
// "<sphere id=\"sphere_1\">"
// "<centre x=\"0.015\" y=\"0.015\" z= \"0.035\" />"
// "<radius val=\"0.04\" />"
// "</sphere>\n"
// "<infinite-cylinder id=\"infcyl_3\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"0.015\" y=\"-0.02\" z= \"0.035\" />"
// "<axis x=\"0.0\" y=\"0.001\" z= \"0.0\" />"
// "</infinite-cylinder>\n"
// "<infinite-cylinder id=\"infcyl_2\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"-0.02\" y=\"0.015\" z= \"0.035\" />"
// "<axis x=\"0.001\" y=\"0.0\" z= \"0.0\" />"
// "</infinite-cylinder>\n"
// "<algebra val=\"((cuboid_1 sphere_1) (# (infcyl_1:(infcyl_2:infcyl_3))))\" />\n";


Mantid::Geometry::ShapeFactory sFactory;
boost::shared_ptr<Mantid::Geometry::Object> shape_sptr = sFactory.createShape(shapexml);
// std::cerr << "\n--------- XML String -----------\n" << shapexml << "\n---------------------\n";
if( shape_sptr == boost::shared_ptr<Mantid::Geometry::Object>() ) return;
try
{
shape_sptr->initDraw();
// Testing a predefined complex shape PLEASE LEAVE FOR THE MOMENT
// std::string shapexml = "<cuboid id=\"cuboid_1\" >\n"
// "<left-front-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.0\" />\n"
// "<left-front-top-point x=\"-0.02\" y=\"0.05\" z= \"0.0\" />\n"
// "<left-back-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.07\" />\n"
// "<right-front-bottom-point x=\"0.05\" y=\"-0.02\" z= \"0.0\" />\n"
// "</cuboid>\n"
// "<infinite-cylinder id=\"infcyl_1\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"0.015\" y=\"0.015\" z= \"0.07\" />"
// "<axis x=\"0.0\" y=\"0.0\" z= \"-0.001\" />"
// "</infinite-cylinder>\n"
// "<sphere id=\"sphere_1\">"
// "<centre x=\"0.015\" y=\"0.015\" z= \"0.035\" />"
// "<radius val=\"0.04\" />"
// "</sphere>\n"
// "<infinite-cylinder id=\"infcyl_3\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"0.015\" y=\"-0.02\" z= \"0.035\" />"
// "<axis x=\"0.0\" y=\"0.001\" z= \"0.0\" />"
// "</infinite-cylinder>\n"
// "<infinite-cylinder id=\"infcyl_2\" >"
// "<radius val=\"0.025\" />"
// "<centre x=\"-0.02\" y=\"0.015\" z= \"0.035\" />"
// "<axis x=\"0.001\" y=\"0.0\" z= \"0.0\" />"
// "</infinite-cylinder>\n"
// "<algebra val=\"((cuboid_1 sphere_1) (# (infcyl_1:(infcyl_2:infcyl_3))))\" />\n";


Mantid::Geometry::ShapeFactory sFactory;
boost::shared_ptr<Mantid::Geometry::Object> shape_sptr = sFactory.createShape(shapexml);
// std::cerr << "\n--------- XML String -----------\n" << shapexml << "\n---------------------\n";
if( shape_sptr == boost::shared_ptr<Mantid::Geometry::Object>() ) return;
try
{
shape_sptr->initDraw();
}
catch( ... )
{
QMessageBox::information(this,"Create sample shape",
QString("An error occurred while attempting to initialize the shape.\n") +
"Please check that all objects intersect each other.");
return;
}

m_object_viewer->setDisplayObject(shape_sptr);
}
catch( ... )
else
{
QMessageBox::information(this,"Create sample shape",
QString("An error occurred while attempting to initialize the shape.\n") +
"Please check that all objects intersect each other.");
return;
QMessageBox::critical(this, "",
"One or more shapes are invalid so the model cannot be rendered.\n"
"Please check all shapes in the model for any missing or invalid data." );
}

m_object_viewer->setDisplayObject(shape_sptr);
}

/**
Expand Down Expand Up @@ -532,7 +593,7 @@ QString CreateSampleShapeDialog::constructShapeXML() const
QString shapeID = shape->getShapeID();
if( shape->getComplementFlag() )
{
shapeID = QString("#(") + shapeID + QString(")");
shapeID = QString("#(") + shapeID + QString(")");
}
inter_results.append(shapeID);
}
Expand Down

0 comments on commit 549e777

Please sign in to comment.