#include <ModelHighAPI_Services.h>
#include <ModelHighAPI_Tools.h>
//--------------------------------------------------------------------------------------
+#include <ModelAPI_AttributeStringArray.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
+//--------------------------------------------------------------------------------------
#include <algorithm>
ExchangeAPI_Import::ExchangeAPI_Import(
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();
#include <ExchangePlugin_ImportPart.h>
+#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeStringArray.h>
#include <ModelAPI_ResultPart.h>
#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
#include <PartSetPlugin_Part.h>
#include <map>
#include <sstream>
+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<FeaturePtr>& 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()
{
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());
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<FeaturePtr> 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<ModelAPI_ResultPart>(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<std::string> anAcceptedValues;
+ anAcceptedValues.push_back(THE_NEW_PART_STR);
+
+ std::list<FeaturePtr> anImportedFeatures;
+ if (aDoc->importPart(aFilePathAttr->value().c_str(), anImportedFeatures, isPartSet))
+ anAcceptedValues.push_back(THE_PART_SET_STR);
+
+ // append names of all parts
+ std::list<FeaturePtr> aSubFeatures = aDoc->allFeatures();
+ for (std::list<FeaturePtr>::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<std::string>::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<FeaturePtr> aSubFeatures = thePartSetDoc->allFeatures();
+ for (std::list<FeaturePtr>::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<ModelAPI_ResultPart>(aPartFeature->lastResult());
+ if (aPartResult)
+ aDoc = aPartResult->partDoc();
+ }
+ }
+ return aDoc;
+}
+
typedef std::map<std::string, std::map<std::string, std::set<int> > > ObjectNameMap;
bool splitName(std::string& theName, int& theIndex)
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();
/// 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();
<file_selector id="file_path" title="Import file" path="">
<validator id="ExchangePlugin_ImportFormat" parameters="shaperpart:Part" />
</file_selector>
+ <choice id="target_part"
+ string_list_attribute="target_parts_list"
+ label="Import to"
+ tooltip="Select the part to import the document" />
</feature>
<feature id="ExportPart" title="Export part" tooltip="Export structure of the Part to file" icon="icons/Exchange/export_part.png"
helpfile="exportPart.html"
return isOk;
}
-bool Model_Document::import(const char* theFileName,
- std::list<std::shared_ptr<ModelAPI_Feature> >& theImported,
- bool theCheckBefore)
+bool Model_Document::importPart(const char* theFileName,
+ std::list<std::shared_ptr<ModelAPI_Feature> >& theImported,
+ bool theCheckOnly)
{
Handle(Model_Application) anApp = Model_Application::getApplication();
TCollection_ExtendedString aFormat;
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<Model_Session> aSession =
std::dynamic_pointer_cast<Model_Session>(ModelAPI_Session::get());
}
}
- if (isOk) {
+ if (isOk && !theCheckOnly) {
// copy features from the temporary document to the current
Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable();
TDF_LabelList anAllNewFeatures;
//! 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<std::shared_ptr<ModelAPI_Feature> >& theImported,
- bool theCheckBefore = false);
+ bool theCheckOnly = false);
//! Saves the OCAF document to the file.
//! \param theDirName directory where the document will be saved
/// 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<std::shared_ptr<ModelAPI_Feature> >& theImported,
- bool theCheckBefore = false) = 0;
+ bool theCheckOnly = false) = 0;
/// Export the list of features to the file
/// \param theFilename path to save the file
//******************************************************
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<ModuleBase_OperationFeature*>(
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);
}
}