Perform the same name checks on renaming from TUI as they are during renaming from GUI.
ModelAPI_Object refactoring.
Add a macro, configuring whether or not perform name checks on renaming from TUI.
Add a macro, configuring whether or not perform a check if another ModelAPI_Result with the same name exists in a document on renaming both from TUI and GUI.
#include <TDF_ChildIDIterator.hxx>
#include <string>
+#include <QString>
#include <Python.h>
-#include <locale>
-#include <codecvt>
-
// myLab contains:
// TDataStd_Name - name of the object
// TDataStd_IntegerArray - state of the object execution, transaction ID of update
return L""; // not defined
}
-std::pair<bool, std::pair<const char*, std::list<std::wstring>>> Model_Data::setName(const std::wstring& theName)
+std::pair<bool, QString> Model_Data::setName(const std::wstring& theName, bool theCallFromTUI)
{
ModelDataDbg(L"Model_Data::setName(" + theName + L") ENTER");
+ auto res = std::pair<bool, QString>(true, "");
+
+ const auto canRenameAndMessage = myObject->canBeRenamed(theName);
+
+ if (!canRenameAndMessage.first || !canRenameAndMessage.second.isEmpty()) {
+ const QString& message = canRenameAndMessage.second;
+ ModelDataDbg(L"Model_Data::setName(" + theName + L"): " + message.toStdWString());
+#ifndef ALLOW_INVALID_RENAMING_FROM_TUI
+ if (canRenameAndMessage.first) {
+ res.first = true;
+ res.second = "Error-prone renaming. " + canRenameAndMessage.second + "\n";
+
+ // Just print warning about error-prone renaming.
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PySys_WriteStdout(res.second.toStdString().c_str());
+ PyGILState_Release(gstate);
+ }
+ else {
+ res.first = false;
+ res.second = canRenameAndMessage.second;
- { // Halt renaming, if document has another ModelAPI_Result with the same name.
- const auto result = std::dynamic_pointer_cast<ModelAPI_Result>(myObject);
- if (result && result->document()) {
- ResultPtr resultWithTheName = std::dynamic_pointer_cast<Model_Document>(result->document())->findResultByName(theName);
- if (resultWithTheName && resultWithTheName != result) {
- ModelDataDbg(L"Model_Data::setName(" + theName + L"). Another result with the same name exists.");
-
- const std::wstring message_wstr = L"Another result with the same name exists: \"" + theName + L"\"";
- using convert_type = std::codecvt_utf8<wchar_t>;
- std::wstring_convert<convert_type, wchar_t> converter;
+ // Stop TUI-script execution.
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PyErr_SetString(PyExc_RuntimeError, message.toStdString().c_str());
+ PyGILState_Release(gstate);
- const std::string message_str = converter.to_bytes(message_wstr);
+ ModelDataDbg(L"Model_Data::setName(" + theName + L") LEAVE");
+ return res;
+ }
+#else // ifdef ALLOW_INVALID_RENAMING_FROM_TUI
+ res.first = theCallFromTUI ? true : canRenameAndMessage.first;
+ res.second = "Error-prone or invalid renaming. " + canRenameAndMessage.second + "\n";
- // Stop TUI-script execution.
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyErr_SetString(PyExc_RuntimeError, message_str.c_str());
- PyGILState_Release(gstate);
+ // Just print warning about invalid renaming.
+ PyGILState_STATE gstate = PyGILState_Ensure();
+ PySys_WriteStdout(res.second.toStdString().c_str());
+ PyGILState_Release(gstate);
- const auto msgAndArgs = std::pair<const char*, std::list<std::wstring>>("Another result with the name \"%1\" exists.", {theName});
- return std::pair<bool, std::pair<const char*, std::list<std::wstring>>>(false, msgAndArgs);
- }
- }
+ if (!res.first)
+ return res;
+#endif // ALLOW_INVALID_RENAMING_FROM_TUI
}
bool isModified = false;
if (mySendAttributeUpdated && isModified)
ModelAPI_ObjectRenamedMessage::send(myObject, anOldName, theName, this);
if (isModified && myObject && myObject->document()) {
- std::dynamic_pointer_cast<Model_Document>(myObject->document())->
- changeNamingName(anOldName, theName, shapeLab());
+ std::dynamic_pointer_cast<Model_Document>(myObject->document())->changeNamingName(anOldName, theName, shapeLab());
}
#ifdef DEBUG_NAMES
myObject->myName = theName;
#endif
ModelDataDbg(L"Model_Data::setName(" + theName + L") LEAVE");
- return std::pair<bool, std::pair<const char*, std::list<std::wstring>>>(true, std::pair<const char*, std::list<std::wstring>>("", {}));
+ return res;
}
bool Model_Data::hasUserDefinedName() const
Model_Data();
/// Returns the name of the feature visible by the user in the object browser
MODEL_EXPORT virtual std::wstring name();
- /// Defines the name of the feature visible by the user in the object browser
- MODEL_EXPORT virtual std::pair<bool, std::pair<const char*, std::list<std::wstring>>> setName(const std::wstring& theName);
+ /// Defines the name of the feature visible by the user in the object browser.
+ /// Returns {false, _ } on failure. Returns { _ , message} anyway. Success with non-empty message means error-prone renaming.
+ MODEL_EXPORT virtual std::pair<bool, QString> setName(const std::wstring& theName, bool theCallFromTUI = false);
/// Return \c true if the object has been renamed by the user
MODEL_EXPORT virtual bool hasUserDefinedName() const;
/// Returns version of the feature (empty string if not applicable)
std::wstring& theSubShapeName,
bool& theUniqueContext);
- ResultPtr findResultByName(const std::wstring& theName) const;
+ virtual ResultPtr findResultByName(const std::wstring& theName) const;
///! Returns all features of the document including the hidden features which are not in
///! history. Not very fast method, for calling once, not in big cycles.
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDES})
INCLUDE(UnitTest)
SET(PROJECT_HEADERS
Locale
${PyInterp}
${PYTHON_LIBRARIES}
+ ${QT_LIBRARIES}
)
SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473)
-ADD_DEFINITIONS(-DMODELAPI_EXPORTS)
+ADD_DEFINITIONS(-DMODELAPI_EXPORTS ${QT_DEFINITIONS})
ADD_LIBRARY(ModelAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
SET_TARGET_PROPERTIES(ModelAPI PROPERTIES LINKER_LANGUAGE CXX)
if(${HAVE_SALOME})
enable_testing()
set(TEST_INSTALL_DIRECTORY "${SALOME_SHAPER_INSTALL_TESTS}/ModelAPI")
-
+
install(FILES CTestTestfileInstall.cmake
DESTINATION ${TEST_INSTALL_DIRECTORY}
RENAME CTestTestfile.cmake)
install(FILES tests.set DESTINATION ${TEST_INSTALL_DIRECTORY})
-
+
set(TMP_TESTS_NAMES)
foreach(tfile ${TEST_NAMES})
list(APPEND TMP_TESTS_NAMES "Test/${tfile}")
endforeach(tfile ${TEST_NAMES})
-
+
install(FILES ${TMP_TESTS_NAMES} DESTINATION ${TEST_INSTALL_DIRECTORY})
endif(${HAVE_SALOME})
const std::wstring MODEL_DATA_DBG_LOG_PREFIX = L"MODEL_DATA_DBG: ";
+bool ModelDataDbg(const QString& theString)
+{
+ if (ModelDataDbg()) {
+ std::wcout << MODEL_DATA_DBG_LOG_PREFIX << theString.toStdWString() << std::endl;
+ return true;
+ }
+ return false;
+}
+
bool ModelDataDbg(const std::wstring& theString)
{
if (ModelDataDbg()) {
#include <set>
#include <memory>
#include <utility>
+#include <QString>
-#define MODEL_DATA_DBG
+/** \brief Name validity check was and is performed, if ModelAPI_Object renaming was/is initiated from GUI.
+ * But the check had not been performed, if "Object.setName(theName)" was called from python script (until the release TODO).
+ * Also, It was/is possible to merge results of SHAPER script execution into SALOME document.
+ * It means, there are user-made SALOME documents and SHAPER scripts in existence with invalid object names.
+ *
+ * If the macro is defined, invalid renaming is still allowed from TUI, only warning message is shown.
+ * Otherwise, python exception is thrown, if invalid renaming occurs.*/
+#define ALLOW_INVALID_RENAMING_FROM_TUI
+
+/** \brief If the macro is defined, names of instances of ModelAPI_Result (and subclasses) must be unique within a document.
+ * Otherwise only names of instances of classes, returning the same groupName(), must be unique within a document. */
+// #define REQUIRE_UNIQUE_RESULT_NAMES
+
+
+// #define MODEL_DATA_DBG
extern inline bool ModelDataDbg() {
#ifdef MODEL_DATA_DBG
return true;
#endif
}
+extern bool ModelDataDbg(const QString& theString);
extern bool ModelDataDbg(const std::wstring& theString);
-
extern bool ModelDataDbg(const char* theString);
class ModelAPI_Attribute;
/// Returns the name of the feature visible by the user in the object browser
virtual std::wstring name() = 0;
/// Defines the name of the feature visible by the user in the object browser.
- /// Returns {false, errorMessage} on failure. The error message is composed of the message template and arguments.
- virtual std::pair<bool, std::pair<const char*, std::list<std::wstring>>> setName(const std::wstring& theName) = 0;
+ /// Returns {false, _ } on failure. Returns { _ , message} anyway. Success with non-empty message means error-prone renaming.
+ virtual std::pair<bool, QString> setName(const std::wstring& theName, bool theCallFromTUI = false) = 0;
/// Return \c true if the object has been renamed by the user
virtual bool hasUserDefinedName() const = 0;
const std::list<std::shared_ptr<ModelAPI_Feature> >& theFeatures,
const bool theBefore = true) = 0;
+ virtual std::shared_ptr<ModelAPI_Result> findResultByName(const std::wstring& theName) const = 0;
+
//! Informs the document that it becomes active and some actions must be performed
virtual void setActive(const bool theFlag) = 0;
//! Returns true if this document is currently active
}
/// Returns the group identifier of this result
- virtual std::string groupName()
+ virtual std::string groupName() const
{
return group();
}
}
/// Returns the group identifier of this result
- virtual std::string groupName()
+ virtual std::string groupName() const
{
return group();
}
#include "ModelAPI_Document.h"
#include "ModelAPI_Data.h"
#include "ModelAPI_Events.h"
-#include <Events_Loop.h>
+#include <QString>
+#include <QChar>
bool ModelAPI_Object::isInHistory()
{
return myDoc;
}
-void ModelAPI_Object::attributeChanged(const std::string& /*theID*/)
+std::pair<bool, QString> ModelAPI_Object::canBeRenamed(const std::wstring& theNewName) const
{
+ static const char* const INVALID_NAME_MSG = "Name \"%1\" is invalid.";
+ if (!isNameValid(theNewName))
+ return std::pair<bool, QString>(false, QString(INVALID_NAME_MSG).arg(QString::fromStdWString(theNewName)));
+
+ return canBeRenamedProtected(theNewName);
+}
+
+std::pair<bool, QString> ModelAPI_Object::canBeRenamedProtected(const std::wstring& theNewName) const
+{
+ static const char* const NAME_ALREADY_ASSIGNED_MSG = "Name \"%1\" is already assigned to another instance of \"%2\".";
+
+ const std::string typeName = groupName();
+ const ObjectPtr aObj = document()->objectByName(typeName, theNewName);
+ if (aObj && this != aObj.get())
+ return std::pair<bool, QString>(false, QString(NAME_ALREADY_ASSIGNED_MSG).arg(QString::fromStdWString(theNewName)).arg(QString::fromStdString(typeName)));
+
+ return std::pair<bool, QString>(true, "");
}
-ModelAPI_Object::ModelAPI_Object()
+/*static*/ bool ModelAPI_Object::IS_NAME_VALID(const std::wstring& theName)
{
+ const QString name = QString::fromStdWString(theName);
+ QChar aChar;
+ for (int i = 0; i < name.length(); i++) {
+ aChar = name[i];
+ if (!aChar.isLetterOrNumber()) {
+ if ((aChar != "_") && (!aChar.isSpace()))
+ return false;
+ }
+ }
+ return true;
}
-ModelAPI_Object::~ModelAPI_Object()
+bool ModelAPI_Object::isNameValid(const std::wstring& theName) const
{
+ return ModelAPI_Object::IS_NAME_VALID(theName);
}
void ModelAPI_Object::setData(std::shared_ptr<ModelAPI_Data> theData)
#include "ModelAPI_Entity.h"
#include <memory>
+#include <utility>
+#include <string>
+#include <QList>
class ModelAPI_Data;
class ModelAPI_Document;
*
* It may be feature or result of the feature. User just may set name for it
* or change this name later. Generic class for Feature, Body, Parameter and other
- * objects related to the features and their results. Contains attributes of this
+ * objects related to the features and their results. Contains attributes of this
* object in the "Data".
*/
class ModelAPI_Object: public ModelAPI_Entity
{
std::shared_ptr<ModelAPI_Data> myData; ///< manager of the data model of a feature
std::shared_ptr<ModelAPI_Document> myDoc; ///< document this object belongs to
- public:
+
+public:
#ifdef DEBUG_NAMES
- std::wstring myName; // name of this object
+ std::wstring myName; // name of this object // TODO Make names of type QString.
#endif
/// By default object is displayed in the object browser.
MODELAPI_EXPORT virtual bool isInHistory();
MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_Document> document() const;
/// Returns the group identifier of this object
- virtual std::string groupName() = 0;
+ virtual std::string groupName() const = 0;
/// Request for initialization of data model of the object: adding all attributes
virtual void initAttributes() = 0;
std::string& /*theName*/,
std::string& /*theDefault*/) {}
+ /// Returns { canBeRenamed, message }. canBeRenamed == true with non-empty message means error-prone renaming.
+ std::pair<bool, QString> canBeRenamed(const std::wstring& theNewName) const;
+
+protected:
+ /// Returns { canBeRenamed, message }. canBeRenamed == true with non-empty message means error-prone renaming.
+ /// Does not check name validity.
+ virtual std::pair<bool, QString> canBeRenamedProtected(const std::wstring& theNewName) const;
+
+public:
+ static bool IS_NAME_VALID(const std::wstring& theName);
+ virtual bool isNameValid(const std::wstring& theName) const;
+
/// Called on change of any argument-attribute of this object
/// \param theID identifier of changed attribute
- MODELAPI_EXPORT virtual void attributeChanged(const std::string& theID);
+ MODELAPI_EXPORT virtual void attributeChanged(const std::string& theID) { (void)theID; };
/// Initializes the default states of the object
- MODELAPI_EXPORT ModelAPI_Object();
+ MODELAPI_EXPORT ModelAPI_Object() = default;
/// To use virtuality for destructors
- MODELAPI_EXPORT virtual ~ModelAPI_Object();
+ MODELAPI_EXPORT virtual ~ModelAPI_Object() = default;
/// Returns true if object must be displayed in the viewer: flag is stored in the
/// data model, so on undo/redo, open/save or recreation of object by history-playing it keeps
friend class Model_Objects;
friend class ModelAPI_Feature;
friend class Model_Document;
-
};
typedef std::shared_ptr<ModelAPI_Object> ObjectPtr;
#include <PyInterp_Interp.h>
#include <Python.h>
+#include <QString>
ModelAPI_Result::~ModelAPI_Result()
{
myIsDisabled = true; // by default it is not initialized and false to be after created
myIsConcealed = false;
}
+
+std::pair<bool, QString> ModelAPI_Result::canBeRenamedProtected(const std::wstring& theNewName) const
+{
+ auto res = ModelAPI_Object::canBeRenamedProtected(theNewName);
+ if (!res.first)
+ return res;
+
+ {
+ const auto doc = document();
+ if (doc) {
+ ResultPtr resultWithTheName = doc->findResultByName(theNewName);
+ if (resultWithTheName && resultWithTheName.get() != this) {
+ ModelDataDbg(L"ModelAPI_Result::canBeRenamedProtected(" + theNewName + L"). Another result with the same name exists.");
+#ifdef REQUIRE_UNIQUE_RESULT_NAMES
+ res.first = false;
+#else
+ res.first = true;
+#endif //REQUIRE_UNIQUE_RESULT_NAMES
+ res.second = "Another result with the name \"" + QString::fromStdWString(theNewName) + "\" exists.";
+ return res;
+ }
+ }
+ }
+
+ return res;
+}
MODELAPI_EXPORT virtual ~ModelAPI_Result();
/// Returns the shape-result produced by this feature (or null if no shapes)
- MODELAPI_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
+ MODELAPI_EXPORT virtual std::shared_ptr<GeomAPI_Shape> shape();
/// Returns all the vertices of this result
MODELAPI_EXPORT virtual ListOfShape
/// all fields, normally initialized in the constructor
MODELAPI_EXPORT virtual void init();
+ /// Returns { canBeRenamed, message }. canBeRenamed == true with non-empty message means error-prone renaming.
+ /// Does not check name validity.
+ virtual std::pair<bool, QString> canBeRenamedProtected(const std::wstring& theNewName) const;
+
friend class Model_Objects;
};
{
}
-std::string ModelAPI_ResultBody::groupName()
+std::string ModelAPI_ResultBody::groupName() const
{
return group();
}
}
/// Returns the group identifier of this result
- MODELAPI_EXPORT virtual std::string groupName();
+ MODELAPI_EXPORT virtual std::string groupName() const;
/// Returns the group identifier of this result
inline static std::string group()
#include "ModelAPI_ResultConstruction.h"
#include <string>
-std::string ModelAPI_ResultConstruction::groupName()
+std::string ModelAPI_ResultConstruction::groupName() const
{
return group();
}
{
public:
/// Returns the group identifier of this result
- MODELAPI_EXPORT virtual std::string groupName();
+ MODELAPI_EXPORT virtual std::string groupName() const;
/// Returns the group identifier of this result
inline static std::string group()
}
-std::string ModelAPI_ResultField::groupName()
+std::string ModelAPI_ResultField::groupName() const
{
return group();
}
}
/// Returns the group identifier of this object
- virtual std::string groupName() { return group(); }
+ virtual std::string groupName() const { return group(); }
/// Request for initialization of data model of the object: adding all attributes
virtual void initAttributes() {}
MODELAPI_EXPORT virtual ~ModelAPI_ResultField();
/// Returns the group identifier of this result
- MODELAPI_EXPORT virtual std::string groupName();
+ MODELAPI_EXPORT virtual std::string groupName() const;
/// Returns the group identifier of this result
inline static std::string group()
}
-std::string ModelAPI_ResultGroup::groupName()
+std::string ModelAPI_ResultGroup::groupName() const
{
return group();
}
public:
MODELAPI_EXPORT virtual ~ModelAPI_ResultGroup();
/// Returns the group identifier of this result
- MODELAPI_EXPORT virtual std::string groupName();
+ MODELAPI_EXPORT virtual std::string groupName() const;
/// Returns the group identifier of this result
inline static std::string group()
//
#include "ModelAPI_ResultParameter.h"
+#include "ModelAPI_Tools.h"
-ModelAPI_ResultParameter::~ModelAPI_ResultParameter()
+std::pair<bool, QString> ModelAPI_ResultParameter::canBeRenamedProtected(const std::wstring& theNewName) const
{
+ static const char* const NAME_ALREADY_ASSIGNED_MSG = "The parameter can not be renamed to: \"%1\". "
+ "There is a parameter with the same name. Its value is: %2.";
+
+ double value;
+ ResultParameterPtr param;
+ if (ModelAPI_Tools::findVariable(document(), FeaturePtr(), theNewName, value, param))
+ return std::pair<bool, QString>(false, QString(NAME_ALREADY_ASSIGNED_MSG).arg(QString::fromStdWString(theNewName)).arg(value));
+
+ return std::pair<bool, QString>(true, "");
}
+
+/*static*/ bool ModelAPI_ResultParameter::IS_NAME_VALID(const std::wstring& theName)
+{
+ const QString name = QString::fromStdWString(theName);
+ char aCh;
+ for (int i = 0; i < name.length(); i++) {
+ aCh = name[i].toLatin1();
+ if (aCh == 0)
+ return false;
+ if ((aCh >= 0x30) && (aCh <= 0x39))
+ continue;
+ else if ((aCh >= 0x41) && (aCh <= 0x5A))
+ continue;
+ else if ((aCh >= 0x61) && (aCh <= 0x7A))
+ continue;
+ else if (aCh == 0x5f)
+ continue;
+ else
+ return false;
+ }
+ return true;
+}
+
+bool ModelAPI_ResultParameter::isNameValid(const std::wstring& theName) const
+{
+ return ModelAPI_ResultParameter::IS_NAME_VALID(theName);
+}
\ No newline at end of file
#include <ModelAPI.h>
#include <ModelAPI_Result.h>
+#include <QString>
/**\class ModelAPI_ResultParameter
* \ingroup DataModel
*/
class ModelAPI_ResultParameter : public ModelAPI_Result
{
- public:
+public:
/// Returns the group identifier of this result
- virtual std::string groupName()
+ virtual std::string groupName() const
{
return group();
}
/// The generic initialization of attributes
virtual void initAttributes() = 0;
- /// Destructor
- MODELAPI_EXPORT ~ModelAPI_ResultParameter();
+protected:
+ /// Returns { canBeRenamed, message }. canBeRenamed == true with non-empty message means error-prone renaming.
+ virtual std::pair<bool, QString> canBeRenamedProtected(const std::wstring& theNewName) const;
+public:
+ static bool IS_NAME_VALID(const std::wstring& theName);
+
+ /// Parameter name must be composed of ASCII-characters only.
+ virtual bool isNameValid(const std::wstring& theName) const;
+
+ MODELAPI_EXPORT ~ModelAPI_ResultParameter() = default;
};
//! Pointer on feature object
#include <string>
-std::string ModelAPI_ResultPart::groupName()
+std::string ModelAPI_ResultPart::groupName() const
{
return ModelAPI_ResultPart::group();
}
{
public:
/// Returns the group identifier of this result
- MODELAPI_EXPORT virtual std::string groupName();
+ MODELAPI_EXPORT virtual std::string groupName() const;
/// Returns the group identifier of this result
inline static std::string group()
if(!aResult.get()) {
return;
}
- aResult->data()->setName(theName);
+ aResult->data()->setName(theName, true /*theCallFromTUI*/);
}
}
#include <QMessageBox>
#include <QApplication>
+#include <string>
+
#ifdef DEBUG_INDXES
#include <QToolTip>
#endif
{
static int aEntrance = 0;
if (aEntrance == 0) {
- // We have to check number of enter and exit of this function because it can be called
- // recursively by Qt in order to avoid double modifying of a data
+ // Amount of enters and exits to the block must be counted to avoid repeated modification of a data,
+ // because it can be executed recursively.
aEntrance = 1;
QLineEdit* aEditor = dynamic_cast<QLineEdit*>(theEditor);
if (aEditor) {
if (XGUI_Tools::canRename(aObj, aName)) {
SessionPtr aMgr = ModelAPI_Session::get();
aMgr->startOperation("Rename");
- const auto renameRes = aObj->data()->setName(aName.toStdWString());
+ aObj->data()->setName(aName.toStdWString());
aMgr->finishOperation();
-
- if (!renameRes.first) {
- const auto& msgAndArgs = renameRes.second;
- QString msg = tr(msgAndArgs.first);
- for (const std::wstring& arg : msgAndArgs.second) {
- msg = msg.arg(QString::fromStdWString(arg));
- }
- Events_InfoMessage("XGUI_Tools", msg.toStdString()).send();
- }
}
}
}
#include <iostream>
#include <sstream>
#include <string>
+#include <QString>
#ifndef WIN32
# include <sys/stat.h>
return aResult;
}
-//******************************************************************
-bool isAscii(const QString& theStr)
-{
- char aCh;
- for (int i = 0; i < theStr.size(); i++) {
- aCh = theStr[i].toLatin1();
- if (aCh == 0)
- return false;
- if ((aCh >= 0x30) && (aCh <= 0x39))
- continue;
- else if ((aCh >= 0x41) && (aCh <= 0x5A))
- continue;
- else if ((aCh >= 0x61) && (aCh <= 0x7A))
- continue;
- else if (aCh == 0x5f)
- continue;
- else
- return false;
- }
- return true;
-}
-
-//******************************************************************
-bool isValidName(const QString& theName)
-{
- QChar aChar;
- for (int i = 0; i < theName.size(); i++) {
- aChar = theName[i];
- if (!aChar.isLetterOrNumber()) {
- if ((aChar != "_") && (!aChar.isSpace()))
- return false;
- }
- }
- return true;
-}
-
//******************************************************************
bool canRename(const ObjectPtr& theObject, const QString& theName)
{
- std::string aType = theObject->groupName();
- if (aType == ModelAPI_ResultParameter::group()) {
- // For parameters names only ASCII symbols have to be used
- if (!isAscii(theName))
- return false;
-
- double aValue;
- ResultParameterPtr aParam;
- if (ModelAPI_Tools::findVariable(theObject->document(),
- FeaturePtr(), theName.toStdWString(), aValue, aParam)) {
- const char* aKeyStr = "Selected parameter can not be renamed to: %1. "
- "There is a parameter with the same name. Its value is: %2.";
- QString aErrMsg(QObject::tr(aKeyStr).arg(theName).arg(aValue));
- // We can not use here a dialog box for message -
- // it will crash editing process in ObjectBrowser
- Events_InfoMessage("XGUI_Tools", aErrMsg.toStdString()).send();
- return false;
- }
- }
- else {
- if (!isValidName(theName))
- return false;
-
- DocumentPtr aDoc = theObject->document();
- ObjectPtr aObj =
- aDoc->objectByName(aType, theName.toStdWString());
-
- if (aObj.get() && theObject != aObj) {
- QString aErrMsg(QObject::tr("Name %2 already exists in %1.").
- arg(aType.c_str()).arg(theName));
- // We can not use here a dialog box for message -
- // it will crash editing process in ObjectBrowser
- Events_InfoMessage("XGUI_Tools", aErrMsg.toStdString()).send();
- return false;
- }
- }
+ ModelDataDbg("XGUI_Tools::canRename(const ObjectPtr& theObject, \"" + theName + "\")");
+
+ const auto canRenameAndMessage = theObject->canBeRenamed(theName.toStdWString());
+ if (!canRenameAndMessage.second.isEmpty())
+ Events_InfoMessage("XGUI_Tools", canRenameAndMessage.second.toStdString()).send();
- return true;
+ return canRenameAndMessage.first;
}
//**************************************************************
*/
bool XGUI_EXPORT canRemoveOrRename(QWidget* theParent, const std::set<FeaturePtr>& theFeatures);
-/*!
- Check possibility to rename object
- \param theObject an object to rename
- \param theName a name
- */
+/*! \brief Call theObject->canBeRenamed(theName) and sends event-message with description why renaming failed or why it is error-prone. */
bool canRename(const ObjectPtr& theObject, const QString& theName);
-/*!
- Checks that the given string contains only ASCII symbols
- \param theStr a string to check
- */
-bool isAscii(const QString& theStr);
-
/*!
Returns converted workshop
\param theWorkshop an interface workshop
<source>Warning</source>
<translation>Attention</translation>
</message>
- <message>
- <source>Name %2 already exists in %1.</source>
- <translation>Le nom %2 existe déjà dans %1.</translation>
- </message>
<message>
<source>Move to the end</source>
<translation>Aller à la fin</translation>