View Issue Details

IDProjectCategoryView StatusLast Update
0004617NoesisGUIStudiopublic2025-12-08 16:31
Reportermaherne Assigned Tomaherne  
PrioritynormalSeveritycrash 
Status resolvedResolutionfixed 
Product VersionStudio_Beta 
Target VersionStudio_BetaFixed in VersionStudio_Beta 
Summary0004617: Context menu Edit commands can be used on the the style and template root elements, causing a crash
Description

When opening the context menu for a the root element in the Navigator tree, in a style or template scope, you can select the Cut and Import SVG paths, which will cause a crash.

This also affects the context menu when right clicking the element on the stage within a Style scope.

Attached is patch which disables these menu entries when the element is the root of a style or template.

Attached Files
CanEditCommands.patch (4,445 bytes)   
Index: Native/Src/Packages/Gui/Studio/Src/XamlDocument.cpp
===================================================================
--- Native/Src/Packages/Gui/Studio/Src/XamlDocument.cpp	(revision 16408)
+++ Native/Src/Packages/Gui/Studio/Src/XamlDocument.cpp	(working copy)
@@ -236,9 +236,12 @@
     mUndoCommand.SetExecuteFunc(MakeDelegate(this, &XamlDocument::Undo));
     mRedoCommand.SetExecuteFunc(MakeDelegate(this, &XamlDocument::Redo));
 
-    mCutCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::Cut));
-    mCopyCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::Copy));
-    mPasteCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::Paste));
+    mCutCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanEdit),
+        MakeDelegate(this, &XamlDocument::Cut));
+    mCopyCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanEdit),
+        MakeDelegate(this, &XamlDocument::Copy));
+    mPasteCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanEdit),
+        MakeDelegate(this, &XamlDocument::Paste));
     mPasteAsTextCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanPasteAsText),
         MakeDelegate(this, &XamlDocument::PasteAsText));
     mSelectAllCommand.SetExecuteFunc(MakeDelegate(this, &XamlDocument::SelectAll));
@@ -253,7 +256,8 @@
         MakeDelegate(this, &XamlDocument::Duplicate));
     mResetLayoutCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::ResetLayout));
     mResetSizeCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::ResetSize));
-    mDeleteElementCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::DeleteElement));
+    mDeleteElementCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanEdit),
+        MakeDelegate(this, &XamlDocument::DeleteElement));
 
     mGroupElementsCommand = MakePtr<DelegateCommand>(MakeDelegate(this, &XamlDocument::CanGroupElements),
         MakeDelegate(this, &XamlDocument::GroupElements));
@@ -3089,6 +3093,44 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
+bool XamlDocument::CanEdit(Noesis::BaseComponent*)
+{
+    if (!HasOneElementSelected(nullptr))
+    {
+        return false;
+    }
+    Scope* scope = GetCurrentScope();
+    if (scope == nullptr)
+    {
+        return false;
+    }
+    Vector<DocumentObjectTreeItem*, 1> selection;
+    scope->GatherSelectedNodesByType(DocumentObjectType_Element, selection);
+    NS_ASSERT(selection.Size() == 1);
+    if (selection.Empty())
+    {
+        return false;
+    }
+
+    // Don't allow pasting in non-element tree items
+    ElementTreeItem* selectedItem = DynamicCast<ElementTreeItem*>(selection.Back());
+    if (selectedItem == nullptr)
+    {
+        return false;
+    }
+
+    // Don't allow Edit commands on the Style or Template scope root
+    if (scope->GetRoot() == selectedItem && (
+        scope->GetType() == ScopeType_Style ||
+        scope->GetType() == ScopeType_Template))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
 bool XamlDocument::CanPasteAsText(Noesis::BaseComponent*)
 {
     String text = Clipboard::Get();
@@ -4157,7 +4199,7 @@
     NS_ASSERT(selection.Size() == 1);
 
     ElementTreeItem* treeItem = (ElementTreeItem*)selection.Back();
-    if (treeItem == nullptr)
+    if (treeItem == nullptr || !Helper::IsType<FrameworkElement>(treeItem->GetScopeElement()))
     {
         return false;
     }
Index: Native/Src/Packages/Gui/Studio/Src/XamlDocument.h
===================================================================
--- Native/Src/Packages/Gui/Studio/Src/XamlDocument.h	(revision 16408)
+++ Native/Src/Packages/Gui/Studio/Src/XamlDocument.h	(working copy)
@@ -484,6 +484,7 @@
     bool TryPasteKeyFrames(const char* text, Noesis::NodeObject* node);
     bool TryPasteXAML(const char* text, Noesis::NodeObject* node);
     Noesis::Ptr<Noesis::NodeObject> ValidateXAML(const char* text);
+    bool CanEdit(Noesis::BaseComponent*);
     bool CanPasteAsText(Noesis::BaseComponent*);
     void PasteAsText(Noesis::BaseComponent*);
     void DeleteElement(Noesis::BaseComponent*);
CanEditCommands.patch (4,445 bytes)   
PlatformAny

Activities

Issue History

Date Modified Username Field Change
2025-12-08 14:39 maherne New Issue
2025-12-08 14:39 maherne File Added: CanEditCommands.patch
2025-12-08 14:39 maherne Target Version => Studio_Beta
2025-12-08 14:42 jsantos Assigned To => dfranjic
2025-12-08 14:42 jsantos Status new => assigned
2025-12-08 16:30 maherne Assigned To dfranjic => maherne
2025-12-08 16:31 maherne Status assigned => resolved
2025-12-08 16:31 maherne Resolution open => fixed
2025-12-08 16:31 maherne Fixed in Version => Studio_Beta