1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0029674: Improvements in Inspector tool

- preferences for dock windows geometry, tree view columns and current view projection;
- ViewControl package for common functionality between plugins;
- processing Location and Orientation for external TopoDS_Shape object
- 'F5' key to update content of each plugin
- visibility column in tree view (used now only in ShapeView)
- properties child item for context (presents tree of current Filters of context)
This commit is contained in:
nds
2018-03-23 16:08:11 +03:00
committed by bugmaster
parent 6dfdbb7ab8
commit 6822a3bef1
135 changed files with 4187 additions and 1603 deletions

View File

@@ -17,16 +17,23 @@
#include <inspector/ShapeView_ItemRoot.hxx>
#include <inspector/ShapeView_ItemShape.hxx>
#include <inspector/ShapeView_TreeModel.hxx>
#include <inspector/ShapeView_VisibilityState.hxx>
#include <inspector/TreeModel_Tools.hxx>
#include <inspector/TreeModel_ContextMenu.hxx>
#include <inspector/ViewControl_Tools.hxx>
#include <inspector/ViewControl_TreeView.hxx>
#include <inspector/View_Displayer.hxx>
#include <inspector/View_PresentationType.hxx>
#include <inspector/View_Tools.hxx>
#include <inspector/View_ToolBar.hxx>
#include <inspector/View_Widget.hxx>
#include <inspector/View_Window.hxx>
#include <inspector/View_Viewer.hxx>
#include <inspector/ShapeView_Window.hxx>
#include <inspector/ShapeView_ItemRoot.hxx>
#include <inspector/ShapeView_ItemShape.hxx>
#include <inspector/ShapeView_TreeModel.hxx>
#include <inspector/ShapeView_OpenFileDialog.hxx>
#include <inspector/ShapeView_Tools.hxx>
@@ -54,13 +61,6 @@
#include <QVBoxLayout>
#include <Standard_WarningsRestore.hxx>
const int FIRST_COLUMN_WIDTH = 190;
const int SIZE_COLUMN_WIDTH = 30;
const int POINTER_COLUMN_WIDTH = 70;
const int ORIENTATION_COLUMN_WIDTH = 70;
const int LOCATION_COLUMN_WIDTH = 120;
const int FLAGS_COLUMN_WIDTH = 70;
const int DEFAULT_TEXT_VIEW_WIDTH = 800;
const int DEFAULT_TEXT_VIEW_HEIGHT = 700;
const int DEFAULT_TEXT_VIEW_POSITION_X = 430;
@@ -75,95 +75,44 @@ const int DEFAULT_SHAPE_VIEW_POSITION_Y = 60;
const int SHAPEVIEW_DEFAULT_TREE_VIEW_WIDTH = 600;
const int SHAPEVIEW_DEFAULT_TREE_VIEW_HEIGHT = 500;
const int SHAPEVIEW_DEFAULT_VIEW_WIDTH = 200;//400;
const int SHAPEVIEW_DEFAULT_VIEW_WIDTH = 300;
const int SHAPEVIEW_DEFAULT_VIEW_HEIGHT = 1000;
//! \class ShapeView_TreeView
//! Extended tree view control with possibility to set predefined size.
class ShapeView_TreeView : public QTreeView
{
public:
//! Constructor
ShapeView_TreeView (QWidget* theParent) : QTreeView (theParent), myDefaultWidth (-1), myDefaultHeight (-1) {}
//! Destructor
virtual ~ShapeView_TreeView() {}
//! Sets default size of control, that is used by the first control show
//! \param theDefaultWidth the width value
//! \param theDefaultHeight the height value
void SetPredefinedSize (int theDefaultWidth, int theDefaultHeight);
//! Returns predefined size if both values are positive, otherwise parent size hint
virtual QSize sizeHint() const Standard_OVERRIDE;
private:
int myDefaultWidth; //!< default width, -1 if it should not be used
int myDefaultHeight; //!< default height, -1 if it should not be used
};
// =======================================================================
// function : SetPredefinedSize
// purpose :
// =======================================================================
void ShapeView_TreeView::SetPredefinedSize (int theDefaultWidth, int theDefaultHeight)
{
myDefaultWidth = theDefaultWidth;
myDefaultHeight = theDefaultHeight;
}
// =======================================================================
// function : sizeHint
// purpose :
// =======================================================================
QSize ShapeView_TreeView::sizeHint() const
{
if (myDefaultWidth > 0 && myDefaultHeight > 0)
return QSize (myDefaultWidth, myDefaultHeight);
return QTreeView::sizeHint();
}
// =======================================================================
// function : Constructor
// purpose :
// =======================================================================
ShapeView_Window::ShapeView_Window (QWidget* theParent, const TCollection_AsciiString& theTemporaryDirectory)
: QObject (theParent), myTemporaryDirectory (theTemporaryDirectory), myNextPosition (0)
ShapeView_Window::ShapeView_Window (QWidget* theParent)
: QObject (theParent), myNextPosition (0)
{
myMainWindow = new QMainWindow (theParent);
myTreeView = new ShapeView_TreeView (myMainWindow);
((ShapeView_TreeView*)myTreeView)->SetPredefinedSize (SHAPEVIEW_DEFAULT_TREE_VIEW_WIDTH,
SHAPEVIEW_DEFAULT_TREE_VIEW_HEIGHT);
myTreeView = new ViewControl_TreeView (myMainWindow);
((ViewControl_TreeView*)myTreeView)->SetPredefinedSize (QSize (SHAPEVIEW_DEFAULT_TREE_VIEW_WIDTH,
SHAPEVIEW_DEFAULT_TREE_VIEW_HEIGHT));
myTreeView->setContextMenuPolicy (Qt::CustomContextMenu);
connect (myTreeView, SIGNAL (customContextMenuRequested (const QPoint&)),
this, SLOT (onTreeViewContextMenuRequested (const QPoint&)));
new TreeModel_ContextMenu (myTreeView);
ShapeView_TreeModel* aModel = new ShapeView_TreeModel (myTreeView);
myTreeView->setModel (aModel);
QItemSelectionModel* aSelectionModel = new QItemSelectionModel (aModel);
myTreeView->setSelectionMode (QAbstractItemView::ExtendedSelection);
myTreeView->setSelectionModel (aSelectionModel);
connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
this, SLOT (onTreeViewSelectionChanged (const QItemSelection&, const QItemSelection&)));
ShapeView_VisibilityState* aVisibilityState = new ShapeView_VisibilityState (aModel);
aModel->SetVisibilityState (aVisibilityState);
TreeModel_Tools::UseVisibilityColumn (myTreeView);
QModelIndex aParentIndex = myTreeView->model()->index (0, 0);
myTreeView->setExpanded (aParentIndex, true);
myTreeView->setColumnWidth (0, FIRST_COLUMN_WIDTH);
myTreeView->setColumnWidth (1, SIZE_COLUMN_WIDTH);
myTreeView->setColumnWidth (2, POINTER_COLUMN_WIDTH);
myTreeView->setColumnWidth (3, ORIENTATION_COLUMN_WIDTH);
myTreeView->setColumnWidth (4, LOCATION_COLUMN_WIDTH);
myTreeView->setColumnWidth (5, FLAGS_COLUMN_WIDTH);
myMainWindow->setCentralWidget (myTreeView);
// view
myViewWindow = new View_Window (myMainWindow);
myViewWindow = new View_Window (myMainWindow, false);
connect (myViewWindow, SIGNAL(eraseAllPerformed()), this, SLOT(onEraseAllPerformed()));
aVisibilityState->SetDisplayer (myViewWindow->GetDisplayer());
aVisibilityState->SetPresentationType (View_PresentationType_Main);
myViewWindow->GetView()->SetPredefinedSize (SHAPEVIEW_DEFAULT_VIEW_WIDTH, SHAPEVIEW_DEFAULT_VIEW_HEIGHT);
QDockWidget* aViewDockWidget = new QDockWidget (tr ("View"), myMainWindow);
aViewDockWidget->setObjectName (aViewDockWidget->windowTitle());
aViewDockWidget->setWidget (myViewWindow);
aViewDockWidget->setTitleBarWidget (myViewWindow->GetViewToolBar()->GetControl());
myMainWindow->addDockWidget (Qt::RightDockWidgetArea, aViewDockWidget);
@@ -196,6 +145,61 @@ void ShapeView_Window::SetParent (void* theParent)
}
}
// =======================================================================
// function : FillActionsMenu
// purpose :
// =======================================================================
void ShapeView_Window::FillActionsMenu (void* theMenu)
{
QMenu* aMenu = (QMenu*)theMenu;
QList<QDockWidget*> aDockwidgets = myMainWindow->findChildren<QDockWidget*>();
for (QList<QDockWidget*>::iterator it = aDockwidgets.begin(); it != aDockwidgets.end(); ++it)
{
QDockWidget* aDockWidget = *it;
if (aDockWidget->parentWidget() == myMainWindow)
aMenu->addAction (aDockWidget->toggleViewAction());
}
}
// =======================================================================
// function : GetPreferences
// purpose :
// =======================================================================
void ShapeView_Window::GetPreferences (TInspectorAPI_PreferencesDataMap& theItem)
{
theItem.Clear();
theItem.Bind ("geometry", TreeModel_Tools::ToString (myMainWindow->saveState()).toStdString().c_str());
QMap<QString, QString> anItems;
TreeModel_Tools::SaveState (myTreeView, anItems);
View_Tools::SaveState(myViewWindow, anItems);
for (QMap<QString, QString>::const_iterator anItemsIt = anItems.begin(); anItemsIt != anItems.end(); anItemsIt++)
theItem.Bind (anItemsIt.key().toStdString().c_str(), anItemsIt.value().toStdString().c_str());
}
// =======================================================================
// function : SetPreferences
// purpose :
// =======================================================================
void ShapeView_Window::SetPreferences (const TInspectorAPI_PreferencesDataMap& theItem)
{
if (theItem.IsEmpty())
{
TreeModel_Tools::SetDefaultHeaderSections (myTreeView);
return;
}
for (TInspectorAPI_IteratorOfPreferencesDataMap anItemIt (theItem); anItemIt.More(); anItemIt.Next())
{
if (anItemIt.Key().IsEqual ("geometry"))
myMainWindow->restoreState (TreeModel_Tools::ToByteArray (anItemIt.Value().ToCString()));
else if (TreeModel_Tools::RestoreState (myTreeView, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
continue;
else if (View_Tools::RestoreState(myViewWindow, anItemIt.Key().ToCString(), anItemIt.Value().ToCString()))
continue;
}
}
// =======================================================================
// function : UpdateContent
// purpose :
@@ -255,15 +259,28 @@ void ShapeView_Window::Init (NCollection_List<Handle(Standard_Transient)>& thePa
{
Handle(AIS_InteractiveContext) aContext;
NCollection_List<Handle(Standard_Transient)> aParameters;
for (NCollection_List<Handle(Standard_Transient)>::Iterator aParamsIt (theParameters);
aParamsIt.More(); aParamsIt.Next())
TCollection_AsciiString aPluginName ("TKShapeView");
NCollection_List<TCollection_AsciiString> aSelectedParameters;
if (myParameters->FindSelectedNames (aPluginName)) // selected names have TShape parameters
aSelectedParameters = myParameters->GetSelectedNames (aPluginName);
NCollection_List<TCollection_AsciiString>::Iterator aParamsIt (aSelectedParameters);
for (NCollection_List<Handle(Standard_Transient)>::Iterator anObjectsIt (theParameters);
anObjectsIt.More(); anObjectsIt.Next())
{
Handle(Standard_Transient) anObject = aParamsIt.Value();
Handle(Standard_Transient) anObject = anObjectsIt.Value();
Handle(TopoDS_TShape) aShapePointer = Handle(TopoDS_TShape)::DownCast (anObject);
if (!aShapePointer.IsNull())
{
TopoDS_Shape aShape;
aShape.TShape (aShapePointer);
if (aParamsIt.More())
{
// each Transient object has own location/orientation description
TInspectorAPI_PluginParameters::ParametersToShape (aParamsIt.Value(), aShape);
aParamsIt.Next();
}
addShape (aShape);
}
else
@@ -277,6 +294,7 @@ void ShapeView_Window::Init (NCollection_List<Handle(Standard_Transient)>& thePa
myViewWindow->SetContext (View_ContextType_External, aContext);
theParameters = aParameters;
myParameters->SetSelectedNames (aPluginName, NCollection_List<TCollection_AsciiString>());
}
// =======================================================================
@@ -322,7 +340,7 @@ void ShapeView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition
if (!aModel)
return;
QModelIndex anIndex = ShapeView_TreeModel::SingleSelected (aModel->selectedIndexes(), 0);
QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (aModel->selectedIndexes(), 0);
TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
if (!anItemBase)
return;
@@ -330,19 +348,34 @@ void ShapeView_Window::onTreeViewContextMenuRequested (const QPoint& thePosition
QMenu* aMenu = new QMenu(myMainWindow);
ShapeView_ItemRootPtr aRootItem = itemDynamicCast<ShapeView_ItemRoot> (anItemBase);
if (aRootItem) {
aMenu->addAction (createAction("Load BREP file", SLOT (onLoadFile())));
aMenu->addAction (createAction ("Remove all shape items", SLOT (onClearView())));
aMenu->addAction (ViewControl_Tools::CreateAction ("Load BREP file", SLOT (onLoadFile()), myMainWindow, this));
aMenu->addAction (ViewControl_Tools::CreateAction ("Remove all shape items", SLOT (onClearView()), myMainWindow, this));
}
else {
if (!myTemporaryDirectory.IsEmpty())
aMenu->addAction (createAction ("BREP view", SLOT (onBREPView())));
aMenu->addAction (createAction ("Close All BREP views", SLOT (onCloseAllBREPViews())));
aMenu->addAction (createAction ("BREP directory", SLOT (onBREPDirectory())));
if (!GetTemporaryDirectory().IsEmpty())
aMenu->addAction (ViewControl_Tools::CreateAction ("BREP view", SLOT (onBREPView()), myMainWindow, this));
aMenu->addAction (ViewControl_Tools::CreateAction ("Close All BREP views", SLOT (onCloseAllBREPViews()), myMainWindow, this));
aMenu->addAction (ViewControl_Tools::CreateAction ("BREP directory", SLOT (onBREPDirectory()), myMainWindow, this));
}
QPoint aPoint = myTreeView->mapToGlobal (thePosition);
aMenu->exec (aPoint);
}
// =======================================================================
// function : onEraseAllPerformed
// purpose :
// =======================================================================
void ShapeView_Window::onEraseAllPerformed()
{
ShapeView_TreeModel* aTreeModel = dynamic_cast<ShapeView_TreeModel*> (myTreeView->model());
// TODO: provide update for only visibility state for better performance TopoDS_Shape myCustomShape;
aTreeModel->Reset();
aTreeModel->EmitLayoutChanged();
}
// =======================================================================
// function : onBREPDirectory
// purpose :
@@ -352,7 +385,7 @@ void ShapeView_Window::onBREPDirectory()
QString aFilter (tr ("BREP file (*.brep*)"));
QString aSelectedFilter;
QString aFileName = QFileDialog::getOpenFileName (0, tr ("Export shape to BREP file"),
myTemporaryDirectory.ToCString(), aSelectedFilter);
GetTemporaryDirectory().ToCString(), aSelectedFilter);
if (!aFileName.isEmpty())
viewFile (aFileName);
}
@@ -377,7 +410,7 @@ void ShapeView_Window::onLoadFile()
// =======================================================================
void ShapeView_Window::onBREPView()
{
if (myTemporaryDirectory.IsEmpty())
if (GetTemporaryDirectory().IsEmpty())
return;
QItemSelectionModel* aModel = myTreeView->selectionModel();
@@ -401,7 +434,7 @@ void ShapeView_Window::onBREPView()
QDir aDir;
if (aFileName.isEmpty() || !aDir.exists (aFileName))
{
TCollection_AsciiString aFileNameIndiced = myTemporaryDirectory + TCollection_AsciiString ("\\") +
TCollection_AsciiString aFileNameIndiced = GetTemporaryDirectory() + TCollection_AsciiString ("\\") +
getNextTmpName (anItem->TShapePointer());
const TopoDS_Shape& aShape = anItem->GetItemShape();
BRepTools::Write (aShape, aFileNameIndiced.ToCString());
@@ -440,32 +473,6 @@ void ShapeView_Window::onEditorDestroyed(QObject* theObject)
}
}
// =======================================================================
// function : displaySelectedShapes
// purpose :
// =======================================================================
void ShapeView_Window::displaySelectedShapes (const QModelIndexList& theSelected)
{
for (QModelIndexList::const_iterator aSelIt = theSelected.begin(); aSelIt != theSelected.end(); aSelIt++)
{
QModelIndex anIndex = *aSelIt;
if (anIndex.column() != 0)
continue;
TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
if (!anItemBase)
continue;
ShapeView_ItemShapePtr aShapeItem = itemDynamicCast<ShapeView_ItemShape>(anItemBase);
if (!aShapeItem)
continue;
TopoDS_Shape aShape = aShapeItem->GetItemShape();
myViewWindow->GetDisplayer()->DisplayPresentation (ShapeView_Tools::CreatePresentation(aShape),
View_PresentationType_Main, true);
}
myViewWindow->GetDisplayer()->UpdateViewer();
}
// =======================================================================
// function : viewFile
// purpose :
@@ -506,7 +513,7 @@ void ShapeView_Window::viewFile (const QString& theFileName)
// =======================================================================
void ShapeView_Window::removeBREPFiles()
{
QDir aDir (myTemporaryDirectory.ToCString());
QDir aDir (GetTemporaryDirectory().ToCString());
QStringList anEntries = aDir.entryList();
QString aPrefix(viewBREPPrefix().ToCString());
@@ -517,17 +524,6 @@ void ShapeView_Window::removeBREPFiles()
}
}
// =======================================================================
// function : createAction
// purpose :
// =======================================================================
QAction* ShapeView_Window::createAction (const QString& theText, const char* theSlot)
{
QAction* anAction = new QAction (theText, myMainWindow);
connect (anAction, SIGNAL (triggered(bool)), this, theSlot);
return anAction;
}
// =======================================================================
// function : getNextTmpName
// purpose :