]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Task 5.1.7: To be able to export a part to a file and import it into an existing...
authorazv <azv@opencascade.com>
Wed, 13 Nov 2019 11:59:24 +0000 (14:59 +0300)
committerazv <azv@opencascade.com>
Fri, 15 Nov 2019 11:56:32 +0000 (14:56 +0300)
* Verify the list of features before export for referring to external document
* Add translations for messages produced by ExportPart/ImportPart features

src/ExchangePlugin/ExchangePlugin_ExportPart.cpp
src/ExchangePlugin/ExchangePlugin_ImportPart.cpp
src/ExchangePlugin/ExchangePlugin_msg_en.ts
src/Model/Model_AttributeSelection.cpp

index 626f835e823da6abdf80df2da9ee313d1f868e77..cc4af14c6ac7e97874ce8c6a1a5d6c27fb28975b 100644 (file)
 #include <ConstructionPlugin_Plane.h>
 #include <ConstructionPlugin_Point.h>
 
+#include <Events_InfoMessage.h>
+
+#include <PartSetPlugin_Part.h>
+
+#include <sstream>
+
 // Obtain all features to be exported to get the list of selected results.
-static void collectFeatures(AttributeSelectionListPtr theSelected,
+static void collectFeatures(DocumentPtr theDocument,
+                            AttributeSelectionListPtr theSelected,
                             std::list<FeaturePtr>& theExport);
 // Obtain all constuction elements of the document.
 static void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExport);
+// Check features could be exported. The following features cannot be exported:
+// * non-construction result (Part) when exporting the PartSet;
+// * features, which refer to objects from another document.
+// Returns true if all features can be exported.
+static bool verifyExport(const std::list<FeaturePtr>& theFeatures,
+                         std::list<FeaturePtr>& theExternalReferences,
+                         std::list<FeaturePtr>& theExportedParts);
 
 
 ExchangePlugin_ExportPart::ExchangePlugin_ExportPart()
@@ -54,31 +68,73 @@ void ExchangePlugin_ExportPart::execute()
   AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
   std::string aFilename = aFilePathAttr->value();
   if (aFilename.empty()) {
-    setError("File path is empty.");
+    setError("File name is empty.");
     return;
   }
 
   std::list<FeaturePtr> aFeaturesToExport;
 
-  SessionPtr aSession = ModelAPI_Session::get();
+  DocumentPtr anExportDoc = document();
+  DocumentPtr aPartSetDoc = ModelAPI_Session::get()->moduleDocument();
   AttributeSelectionListPtr aSelected = selectionList(SELECTION_LIST_ID());
-  DocumentPtr anExportDoc;
-  if (aSelected && aSelected->size() == 0 &&
-      aSession->activeDocument() == aSession->moduleDocument()) {
+  if (aSelected && aSelected->size() == 0 && anExportDoc == aPartSetDoc) {
     // no result is selected, thus have to export all features of the current document,
     // but the document is a PartSet; and it is forbidden to copy results of Parts,
     // thus copy construction elements only
-    collectConstructions(aSession->moduleDocument(), aFeaturesToExport);
+    collectConstructions(anExportDoc, aFeaturesToExport);
   }
   else
-    collectFeatures(aSelected, aFeaturesToExport);
+    collectFeatures(anExportDoc, aSelected, aFeaturesToExport);
+
+  if (aFeaturesToExport.empty()) {
+    Events_InfoMessage(getKind(), "Selected features cannot be exported from the document.").send();
+    return;
+  }
+
+  // remove 'ExportPart' feature if any
+  if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
+    aFeaturesToExport.pop_back();
+
+  std::list<FeaturePtr> anExternalLinks, aReferredParts;
+  if (!verifyExport(aFeaturesToExport, anExternalLinks, aReferredParts)) {
+    if (!anExternalLinks.empty()) {
+      // collect names of features as a string
+      std::ostringstream aListOfFeatures;
+      for (std::list<FeaturePtr>::iterator anIt = anExternalLinks.begin();
+           anIt != anExternalLinks.end(); ++anIt) {
+        if (anIt != anExternalLinks.begin())
+          aListOfFeatures << ", ";
+        aListOfFeatures << "'" << (*anIt)->name() << "'";
+      }
+
+      std::string aMessage = "The selected results were created using external references "
+                             "outside of this Part from features %1. "
+                             "Please, remove these references or select another "
+                             "sub-set of results to be able to export.";
+      Events_InfoMessage(getKind(), aMessage).arg(aListOfFeatures.str()).send();
+    }
+    if (!aReferredParts.empty()) {
+      // collect names of parts as a string
+      std::ostringstream aListOfParts;
+      for (std::list<FeaturePtr>::iterator anIt = aReferredParts.begin();
+           anIt != aReferredParts.end(); ++anIt) {
+        if (anIt != aReferredParts.begin())
+          aListOfParts << ", ";
+        aListOfParts << "'" << (*anIt)->name() << "'";
+      }
+
+      std::string aMessage = "The selected results were created using references "
+                             "to results of Parts %1. Please, remove these references "
+                             "or select another sub-set of results to be able to export.";
+      Events_InfoMessage(getKind(), aMessage).arg(aListOfParts.str()).send();
+    }
+    // should not export anything
+    aFeaturesToExport.clear();
+  }
 
   if (!aFeaturesToExport.empty()) {
-    // remove 'ExportPart' feature is any
-    if (aFeaturesToExport.back()->getKind() == ExchangePlugin_ExportPart::ID())
-      aFeaturesToExport.pop_back();
     // save the document
-    if (!aSession->activeDocument()->save(aFilename.c_str(), aFeaturesToExport))
+    if (!anExportDoc->save(aFilename.c_str(), aFeaturesToExport))
       setError("Cannot save the document.");
   }
 }
@@ -86,11 +142,14 @@ void ExchangePlugin_ExportPart::execute()
 
 // ================================     Auxiliary functions     ===================================
 
-static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
+static void allReferencedFeatures(const std::set<FeaturePtr>& theFeatures,
+                                  std::set<FeaturePtr>& theReferencedFeatures)
 {
   std::set<FeaturePtr> aReferences;
-  for (std::set<FeaturePtr>::iterator anIt = theFeatures.begin();
+  for (std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin();
        anIt != theFeatures.end(); ++anIt) {
+    theReferencedFeatures.insert(*anIt);
+
     std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
     (*anIt)->data()->referencesToObjects(aRefs);
 
@@ -99,21 +158,29 @@ static void allReferencedFeatures(std::set<FeaturePtr>& theFeatures)
       for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
            anObjIt != aRIt->second.end(); ++anObjIt) {
         FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
-        if (aFeature)
+        if (aFeature && theReferencedFeatures.find(aFeature) == theReferencedFeatures.end())
           aReferences.insert(aFeature);
       }
     }
   }
 
-  if (!aReferences.empty()) {
-    allReferencedFeatures(aReferences);
-    theFeatures.insert(aReferences.begin(), aReferences.end());
-  }
+  if (!aReferences.empty())
+    allReferencedFeatures(aReferences, theReferencedFeatures);
+}
+
+static bool isCoordinate(FeaturePtr theFeature)
+{
+  return !theFeature->isInHistory() &&
+          (theFeature->getKind() == ConstructionPlugin_Point::ID() ||
+           theFeature->getKind() == ConstructionPlugin_Axis::ID() ||
+           theFeature->getKind() == ConstructionPlugin_Plane::ID());
 }
 
-void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr>& theExport)
+void collectFeatures(DocumentPtr theDocument,
+                     AttributeSelectionListPtr theSelected,
+                     std::list<FeaturePtr>& theExport)
 {
-  theExport = ModelAPI_Session::get()->activeDocument()->allFeatures();
+  theExport = theDocument->allFeatures();
 
   if (!theSelected || theSelected->size() == 0) {
     // nothing is selected, return all features of the document
@@ -129,7 +196,7 @@ void collectFeatures(AttributeSelectionListPtr theSelected, std::list<FeaturePtr
       aFeaturesToExport.insert(aCurrentFeature);
   }
   // recursively collect all features used for the selected results
-  allReferencedFeatures(aFeaturesToExport);
+  allReferencedFeatures(aFeaturesToExport, aFeaturesToExport);
 
   // remove the features which are not affect the selected results
   std::list<FeaturePtr>::iterator anIt = theExport.begin();
@@ -153,13 +220,8 @@ void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExp
     ResultPtr aCurResult = aCurFeature->lastResult();
 
     bool isApplicable =
-        (!aCurResult || aCurResult->groupName() == ModelAPI_ResultConstruction::group());
-
-    if (isApplicable && !aCurFeature->isInHistory()) {
-      isApplicable = aCurFeature->getKind() != ConstructionPlugin_Point::ID() &&
-                     aCurFeature->getKind() != ConstructionPlugin_Axis::ID() &&
-                     aCurFeature->getKind() != ConstructionPlugin_Plane::ID();
-    }
+        (!aCurResult || aCurResult->groupName() == ModelAPI_ResultConstruction::group()) &&
+        !isCoordinate(aCurFeature);
 
     if (isApplicable)
       ++anIt;
@@ -169,3 +231,38 @@ void collectConstructions(DocumentPtr theDocument, std::list<FeaturePtr>& theExp
     }
   }
 }
+
+bool verifyExport(const std::list<FeaturePtr>& theFeatures,
+                  std::list<FeaturePtr>& theExternalReferences,
+                  std::list<FeaturePtr>& theExportedParts)
+{
+  for (std::list<FeaturePtr>::const_iterator anIt = theFeatures.begin();
+       anIt != theFeatures.end(); ++anIt) {
+    // full part should not be exported
+    if ((*anIt)->getKind() == PartSetPlugin_Part::ID())
+      theExportedParts.push_back(*anIt);
+
+    DocumentPtr aDoc = (*anIt)->document();
+
+    std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
+    (*anIt)->data()->referencesToObjects(aRefs);
+    std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRIt = aRefs.begin();
+    for (;  aRIt != aRefs.end(); ++aRIt) {
+      for (std::list<ObjectPtr>::iterator anObjIt = aRIt->second.begin();
+           anObjIt != aRIt->second.end(); ++anObjIt) {
+        FeaturePtr aFeature = ModelAPI_Feature::feature(*anObjIt);
+        if (aFeature) {
+          // feature refers to external entity,
+          // which is neither the Origin nor coordinate axis or plane
+          if (aFeature->document() != aDoc && !isCoordinate(aFeature))
+            theExternalReferences.push_back(*anIt);
+          // feature refers to result of a part
+          if (aFeature->getKind() == PartSetPlugin_Part::ID())
+            theExportedParts.push_back(*anIt);
+        }
+      }
+    }
+  }
+
+  return theExternalReferences.empty() && theExportedParts.empty();
+}
index 11eae6c0d742c8420780de2e9bf1297a797bf0c2..9522e20bc53d88a457bc2a38bc86ab3fa8904a5f 100644 (file)
@@ -39,13 +39,13 @@ void ExchangePlugin_ImportPart::execute()
   AttributeStringPtr aFilePathAttr = string(FILE_PATH_ID());
   std::string aFilename = aFilePathAttr->value();
   if (aFilename.empty()) {
-    setError("File path is empty.");
+    setError("File name is empty.");
     return;
   }
 
   // load the file into the active document
   SessionPtr aSession = ModelAPI_Session::get();
-  DocumentPtr aDoc = aSession->activeDocument();
+  DocumentPtr aDoc = document();
   bool isPartSet = aDoc == aSession->moduleDocument();
   bool isOk = aDoc->import(aFilename.c_str(), isPartSet);
   if (!isOk && isPartSet) {
index 774af05d1efa1fd054a79aa5699b995bb3c6d5af..992e2357b8bce6ab31b7e56b96adf3e75b1578a2 100644 (file)
       <translation>Attribute %1 is not a string.</translation>
     </message>
   </context>
+
+  <context>
+    <name>Export:ExchangePlugin_ExportPart</name>
+    <message>
+      <source>Cannot save the document.</source>
+      <translation>Cannot save the document.</translation>
+    </message>
+    <message>
+      <source>Selected features cannot be exported from the document.</source>
+      <translation>Selected features cannot be exported from the document.</translation>
+    </message>
+    <message>
+      <source>The selected results were created using external references outside of this Part from features %1. Please, remove these references or select another sub-set of results to be able to export.</source>
+      <translation>The selected results were created using external references outside of this Part from features %1. Please, remove these references or select another sub-set of results to be able to export.</translation>
+    </message>
+    <message>
+      <source>The selected results were created using references to results of Parts %1. Please, remove these references or select another sub-set of results to be able to export.</source>
+      <translation>The selected results were created using references to results of Parts %1. Please, remove these references or select another sub-set of results to be able to export.</translation>
+    </message>
+  </context>
+
+  <context>
+    <name>Import:ExchangePlugin_ImportPart</name>
+    <message>
+      <source>Cannot import the document.</source>
+      <translation>Cannot import the document.</translation>
+    </message>
+  </context>
 </TS>
index c37149ede2ad5603bf6b3e4b8746adc28b4d759c..edec79b6c489955baeaa44437fa16b03dea95e25 100644 (file)
@@ -302,7 +302,7 @@ GeomShapePtr centerByEdge(GeomShapePtr theEdge, ModelAPI_AttributeSelection::Cen
 
 std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
 {
-  if (!ModelAPI_AttributeSelection::isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
+  if (!myRef.isInitialized() && !myTmpContext.get() && !myTmpSubShape.get())
     return std::shared_ptr<GeomAPI_Shape>();
   CenterType aType = NOT_CENTER;
   std::shared_ptr<GeomAPI_Shape> aResult = internalValue(aType);