| 924 | } |
| 925 | |
| 926 | std::vector<std::pair<Property*, std::unique_ptr<Property>>> |
| 927 | DocumentObject::onProposedLabelChange(std::string& newLabel) |
| 928 | { |
| 929 | // Note that this work can't be done in onBeforeChangeLabel because FeaturePython overrides this |
| 930 | // method and does not initially base-call it. |
| 931 | |
| 932 | // We re only called if the new label differs from the old one, and our code to check duplicates |
| 933 | // may not work if this is not the case. |
| 934 | std::string_view oldLabel = Label.getStrValue(); |
| 935 | assert(newLabel != oldLabel); |
| 936 | if (!isAttachedToDocument()) { |
| 937 | return {}; |
| 938 | } |
| 939 | App::Document* doc = getDocument(); |
| 940 | if (doc->isPerformingTransaction() |
| 941 | || (doc->testStatus(App::Document::Restoring) |
| 942 | && !doc->testStatus(App::Document::Importing))) { |
| 943 | return {}; |
| 944 | } |
| 945 | static ParameterGrp::handle _hPGrp; |
| 946 | if (!_hPGrp) { |
| 947 | _hPGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document"); |
| 948 | } |
| 949 | if (doc && !newLabel.empty() && !_hPGrp->GetBool("DuplicateLabels") && !allowDuplicateLabel() |
| 950 | && doc->containsLabel(newLabel)) { |
| 951 | // The label already exists but settings are such that duplicate labels should not be assigned. |
| 952 | std::string_view objName = getNameInDocument(); |
| 953 | if (!doc->containsLabel(objName) && doc->haveSameBaseName(objName, newLabel)) { |
| 954 | // The object name is not already a Label and the base name of the proposed label |
| 955 | // equals the base name of the object Name, so we use the object Name as the replacement Label. |
| 956 | newLabel = objName; |
| 957 | } |
| 958 | else { |
| 959 | // Otherwise we generate a unique Label using newLabel as a prototype name. In doing so, |
| 960 | // we must also act as if the current value of the property is not an existing Label |
| 961 | // entry. |
| 962 | // We deregister the old label so it does not interfere with making the new label, |
| 963 | // and re-register it after. This is probably a bit less efficient that having a special |
| 964 | // make-unique-label-as-if-this-one-did-not-exist method, but such a method would be a real |
| 965 | // ugly wart. |
| 966 | doc->unregisterLabel(oldLabel); |
| 967 | newLabel = doc->makeUniqueLabel(newLabel); |
| 968 | doc->registerLabel(oldLabel); |
| 969 | } |
| 970 | } |
| 971 | |
| 972 | // Despite our efforts to make a unique label, onBeforeLabelChange can change it. |
| 973 | onBeforeChangeLabel(newLabel); |
| 974 | |
| 975 | if (oldLabel == newLabel || getDocument()->testStatus(App::Document::Restoring)) { |
| 976 | // Don't update label reference if we are restoring or if the label is unchanged. |
| 977 | // When importing (which also counts as restoring), it is possible the |
| 978 | // new object changes its label. However, we cannot update label |
| 979 | // references here, because object being restored is not based on |
| 980 | // dependency order. It can only be done in afterRestore(). |
| 981 | // |
| 982 | // See PropertyLinkBase::restoreLabelReference() for more details. |
| 983 | return {}; |
no test coverage detected