From: azv Date: Thu, 28 Nov 2019 12:23:23 +0000 (+0300) Subject: Issue #3095: Import Part: provide list of parts if any X-Git-Tag: V9_5_0a1~151 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=9862e7da8e2c6bef746be6fbb5ea50541956c550;p=modules%2Fshaper.git Issue #3095: Import Part: provide list of parts if any --- diff --git a/src/ExchangeAPI/ExchangeAPI_Import.cpp b/src/ExchangeAPI/ExchangeAPI_Import.cpp index e585f971e..621ebcab5 100644 --- a/src/ExchangeAPI/ExchangeAPI_Import.cpp +++ b/src/ExchangeAPI/ExchangeAPI_Import.cpp @@ -25,6 +25,10 @@ #include #include //-------------------------------------------------------------------------------------- +#include +#include +#include +//-------------------------------------------------------------------------------------- #include ExchangeAPI_Import::ExchangeAPI_Import( @@ -111,6 +115,24 @@ void importPart(const std::shared_ptr & thePart, FeaturePtr aFeature = thePart->addFeature(ExchangePlugin_ImportPart::ID()); aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(theFilePath); + + // specify the ID of selected document + int aTargetPartIndex = 0; + SessionPtr aSession = ModelAPI_Session::get(); + if (aSession->moduleDocument() == thePart) { + // Importing to PartSet has 2 choices: import directly to PartSet (if possible) + // or create a new part. Because then importing to existing part the document + // has to be specified explicitly. + // As a result, parse the list of possible target documents and generate new part + // if the import document is not applicable on PartSet level + // (there is no 'PartSet' in the list of applicable documents). + AttributeStringArrayPtr aDocsList = + aFeature->stringArray(ExchangePlugin_ImportPart::TARGET_PARTS_LIST_ID()); + if (aDocsList->size() > 1 && aDocsList->value(1) == "PartSet") + aTargetPartIndex = 1; + } + aFeature->integer(ExchangePlugin_ImportPart::TARGET_PART_ID())->setValue(aTargetPartIndex); + // restart transaction to execute and delete the macro-feature apply(); diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp index 14f2c1951..3b9ec7e06 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ImportPart.cpp @@ -19,17 +19,25 @@ #include +#include #include +#include #include #include +#include #include #include #include +static const std::string THE_NEW_PART_STR("New Part"); +static const std::string THE_PART_SET_STR("PartSet"); + // Update names of imported features/results concurent with existing objects. static void correntNonUniqueNames(DocumentPtr theDocument, std::list& theImported); +// Find the document according to its name or create the new one. +static DocumentPtr findDocument(DocumentPtr thePartSetDoc, const std::string& thePartName); ExchangePlugin_ImportPart::ExchangePlugin_ImportPart() { @@ -38,8 +46,11 @@ ExchangePlugin_ImportPart::ExchangePlugin_ImportPart() void ExchangePlugin_ImportPart::initAttributes() { data()->addAttribute(FILE_PATH_ID(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(TARGET_PART_ID(), ModelAPI_AttributeInteger::typeId()); + data()->addAttribute(TARGET_PARTS_LIST_ID(), ModelAPI_AttributeStringArray::typeId()); } + void ExchangePlugin_ImportPart::execute() { AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID()); @@ -49,35 +60,110 @@ void ExchangePlugin_ImportPart::execute() return; } - // load the file into the active document + // get the document where to import + AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aDoc = document(); - bool isPartSet = aDoc == aSession->moduleDocument(); + DocumentPtr aDoc = + findDocument(aSession->moduleDocument(), aPartsAttr->value(aTargetAttr->value())); + + // load the file into the document std::list anImportedFeatures; - bool isOk = aDoc->import(aFilename.c_str(), anImportedFeatures, isPartSet); - if (!isOk && isPartSet) { - // there are features not appropriate for PartSet, - // create new part and load there - FeaturePtr aPartFeature = aDoc->addFeature(PartSetPlugin_Part::ID()); - ResultPartPtr aPartResult; - if (aPartFeature) { - aPartFeature->execute(); - aPartResult = std::dynamic_pointer_cast(aPartFeature->lastResult()); - } - if (aPartResult) { - aDoc = aPartResult->partDoc(); - isOk = aDoc->import(aFilename.c_str(), anImportedFeatures); - } - } - if (isOk) + if (aDoc && aDoc->importPart(aFilename.c_str(), anImportedFeatures)) correntNonUniqueNames(aDoc, anImportedFeatures); else setError("Cannot import the document."); } +void ExchangePlugin_ImportPart::attributeChanged(const std::string& theID) +{ + if (theID == FILE_PATH_ID()) { + AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID()); + if (aFilePathAttr->value().empty()) + return; + + AttributeStringArrayPtr aPartsAttr = stringArray(TARGET_PARTS_LIST_ID()); + AttributeIntegerPtr aTargetAttr = integer(TARGET_PART_ID()); + + // update the list of target parts + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aDoc = document(); + bool isPartSet = aDoc == aSession->moduleDocument(); + if (isPartSet) { + std::list anAcceptedValues; + anAcceptedValues.push_back(THE_NEW_PART_STR); + + std::list anImportedFeatures; + if (aDoc->importPart(aFilePathAttr->value().c_str(), anImportedFeatures, isPartSet)) + anAcceptedValues.push_back(THE_PART_SET_STR); + + // append names of all parts + std::list aSubFeatures = aDoc->allFeatures(); + for (std::list::iterator aFIt = aSubFeatures.begin(); + aFIt != aSubFeatures.end(); ++aFIt) { + if ((*aFIt)->getKind() == PartSetPlugin_Part::ID()) + anAcceptedValues.push_back((*aFIt)->name()); + } + + if (aPartsAttr->size() != anAcceptedValues.size()) + aTargetAttr->setValue(0); + + aPartsAttr->setSize((int)anAcceptedValues.size()); + std::list::iterator anIt = anAcceptedValues.begin(); + for (int anInd = 0; anIt != anAcceptedValues.end(); ++anIt, ++anInd) + aPartsAttr->setValue(anInd, *anIt); + } + else { + // keep only the name of the current part + if (aPartsAttr->size() == 0) { + FeaturePtr aPartFeature = ModelAPI_Tools::findPartFeature(aSession->moduleDocument(), aDoc); + + aPartsAttr->setSize(1); + aPartsAttr->setValue(0, aPartFeature->name()); + aTargetAttr->setValue(0); + } + } + } +} + // ================================ Auxiliary functions =================================== +DocumentPtr findDocument(DocumentPtr thePartSetDoc, const std::string& thePartName) +{ + DocumentPtr aDoc; + if (thePartName == THE_PART_SET_STR) + aDoc = thePartSetDoc; + else { + FeaturePtr aPartFeature; + if (thePartName == THE_NEW_PART_STR) { + // create new part + aPartFeature = thePartSetDoc->addFeature(PartSetPlugin_Part::ID()); + if (aPartFeature) + aPartFeature->execute(); + } + else { + // find existing part by its name + std::list aSubFeatures = thePartSetDoc->allFeatures(); + for (std::list::iterator aFIt = aSubFeatures.begin(); + aFIt != aSubFeatures.end(); ++aFIt) { + if ((*aFIt)->getKind() == PartSetPlugin_Part::ID() && (*aFIt)->name() == thePartName) { + aPartFeature = *aFIt; + break; + } + } + } + + if (aPartFeature) { + ResultPartPtr aPartResult = + std::dynamic_pointer_cast(aPartFeature->lastResult()); + if (aPartResult) + aDoc = aPartResult->partDoc(); + } + } + return aDoc; +} + typedef std::map > > ObjectNameMap; bool splitName(std::string& theName, int& theIndex) diff --git a/src/ExchangePlugin/ExchangePlugin_ImportPart.h b/src/ExchangePlugin/ExchangePlugin_ImportPart.h index b10ba54d7..25d4461c7 100644 --- a/src/ExchangePlugin/ExchangePlugin_ImportPart.h +++ b/src/ExchangePlugin/ExchangePlugin_ImportPart.h @@ -43,6 +43,18 @@ public: static const std::string MY_FILE_PATH_ID("file_path"); return MY_FILE_PATH_ID; } + /// attribute name of target part + inline static const std::string& TARGET_PART_ID() + { + static const std::string MY_TARGET_PART_ID("target_part"); + return MY_TARGET_PART_ID; + } + /// attribute name of list of target parts + inline static const std::string& TARGET_PARTS_LIST_ID() + { + static const std::string MY_TARGET_PARTS_LIST_ID("target_parts_list"); + return MY_TARGET_PARTS_LIST_ID; + } /// Default constructor ExchangePlugin_ImportPart(); @@ -55,6 +67,10 @@ public: /// Request for initialization of data model of the feature: adding all attributes EXCHANGEPLUGIN_EXPORT virtual void initAttributes(); + /// Called on change of any argument-attribute of this object + /// \param theID identifier of changed attribute + EXCHANGEPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID); + /// Computes or recomputes the results EXCHANGEPLUGIN_EXPORT virtual void execute(); diff --git a/src/ExchangePlugin/plugin-Exchange.xml b/src/ExchangePlugin/plugin-Exchange.xml index ecb36cf17..ac0ad0711 100644 --- a/src/ExchangePlugin/plugin-Exchange.xml +++ b/src/ExchangePlugin/plugin-Exchange.xml @@ -40,6 +40,10 @@ + >& theImported, - bool theCheckBefore) +bool Model_Document::importPart(const char* theFileName, + std::list >& theImported, + bool theCheckOnly) { Handle(Model_Application) anApp = Model_Application::getApplication(); TCollection_ExtendedString aFormat; @@ -361,7 +361,7 @@ bool Model_Document::import(const char* theFileName, Handle(TDocStd_Document) aTempDoc; bool isOk = loadDocument(anApp, aTempDoc, theFileName); - if (isOk && theCheckBefore) { + if (isOk && theCheckOnly) { // verify all features are applicable for the current document type (e.g. PartSet) std::shared_ptr aSession = std::dynamic_pointer_cast(ModelAPI_Session::get()); @@ -380,7 +380,7 @@ bool Model_Document::import(const char* theFileName, } } - if (isOk) { + if (isOk && !theCheckOnly) { // copy features from the temporary document to the current Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); TDF_LabelList anAllNewFeatures; diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index 023770a4d..1615ffce4 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -60,12 +60,12 @@ class Model_Document : public ModelAPI_Document //! All the features are added after the active feature. //! \param theFileName name of the file to import //! \param theImported list of features imported from the file - //! \param theCheckBefore verify the document does not contain unappropriate features - //! (useful for import to PartSet) + //! \param theCheckOnly verify the document does not contain unappropriate features + //! (useful for import to PartSet), but do not import it //! \returns true if file was loaded successfully - MODEL_EXPORT virtual bool import(const char* theFileName, + MODEL_EXPORT virtual bool importPart(const char* theFileName, std::list >& theImported, - bool theCheckBefore = false); + bool theCheckOnly = false); //! Saves the OCAF document to the file. //! \param theDirName directory where the document will be saved diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 6900965d5..5f51a3376 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -263,12 +263,12 @@ public: /// All the features are added after the active feature. /// \param theFileName name of the file to import /// \param theImported list of features imported from the file - /// \param theCheckBefore verify the document does not contain unappropriate features - /// (useful for import to PartSet) + /// \param theCheckOnly verify the document does not contain unappropriate features + /// (useful for import to PartSet), but do not import it /// \returns true if file was loaded successfully - MODELAPI_EXPORT virtual bool import(const char* theFileName, + MODELAPI_EXPORT virtual bool importPart(const char* theFileName, std::list >& theImported, - bool theCheckBefore = false) = 0; + bool theCheckOnly = false) = 0; /// Export the list of features to the file /// \param theFilename path to save the file diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 8c4e9a1b7..6a1766792 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1273,27 +1273,10 @@ void XGUI_Workshop::onWidgetObjectUpdated() //****************************************************** void XGUI_Workshop::onImportPart() { - if (!abortAllOperations()) - return; - - //show file dialog, check if readable and open - qreal aRatio = ModuleBase_Tools::currentPixelRatio(); - // If the ratio is > 1 (HD screen) then QT has a bug in - // displaying of system open file dialog (too small) - QString aFile = QFileDialog::getOpenFileName(desktop(), tr("Import part"), QString(), - MyImportPartFilter, Q_NULLPTR, - ((aRatio > 1) ? QFileDialog::DontUseNativeDialog : QFileDialog::Options())); - if (!aFile.isNull()) { + if (abortAllOperations()) { ModuleBase_OperationFeature* anImportPartOp = dynamic_cast( module()->createOperation(ExchangePlugin_ImportPart::ID())); - if (operationMgr()->startOperation(anImportPartOp)) { - // initialize the filename to be imported - FeaturePtr aFeature = anImportPartOp->feature(); - aFeature->string(ExchangePlugin_ImportPart::FILE_PATH_ID())->setValue(aFile.toStdString()); - ModuleBase_Tools::flushUpdated(aFeature); - operationMgr()->commitOperation(); - setStatusBarMessage(""); - } + operationMgr()->startOperation(anImportPartOp); } }