disable cutting of a certain shape

Started by perry59, December 21, 2021, 11:28:44 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

perry59

I need to disable cutting of a particular shape which is created and maintained by my addin which was created using Nikolay's awesome visual studio template.
So far it's been a lot harder than I thought it would be. I created an event handler for the enterScope event where I look for the cut event (1020), while that scope is current I check to see if a shape is selected, if so and it's the shape in question I want to bail on the cut command.
I have tried doing this via undo and simply deselecting the shape but neither works, the shape is still cut and invoking undo throws exceptions.
Here is the code I am currently struggling with:
Private Sub ChangeScope(app As Visio.Application, ScopeID As Integer, description As String)

        _lngScopeID = ScopeID
        _desScope = description
        Dim vsoshape As Visio.Shape

        'this goes into an endless loop if I set UndoScopeID
        'trying deselectAll does not work either, connector still gets cut
        'application undo fails here or in the noeventspending function if I call it there
        Try
            If Globals.ThisAddIn.Application.IsInScope(1020) = True Then
                'UndoScopeID1 = Globals.ThisAddIn.Application.BeginUndoScope("cut")
                If Globals.ThisAddIn.Application.ActiveWindow.Selection.Count > 0 Then
                    vsoshape = Globals.ThisAddIn.Application.ActiveWindow.Selection(1)
                    MsgBox("do not cut " & vsoshape.Name)
                    Globals.ThisAddIn.Application.ActiveWindow.Selection.DeselectAll()
                    'Globals.ThisAddIn.Application.Undo()
                    _cutFlag = True 'look for this in NoEventsPending
                End If
                'Globals.ThisAddIn.Application.EndUndoScope(UndoScopeID1, True) 'setting this in "NoEventsPending" still goes into an endless loop
            End If
        Catch err As System.Exception
            ' Handle generic ones here.
            'LogException(err)
            MsgBox(err.Message, MsgBoxStyle.OkOnly, "Error trapping cut")
        End Try
    End Sub


_lngScopeID and  _desScope are global vars declared at  the top of my events module, they don't do anything here, just for debugging info.
UndoScopeID1 is also global

maybe I am on a completely wrong track, any Ideas?
Thanks
what, me worry?

perry59

The solution was much simpler. I just installed a new handler:
AddHandler ThisAddIn.Application.QueryCancelSelectionDelete, AddressOf OnConnectorDelete

and put this code behind it.

'this seems to work for canceling the cutting of connectors!
Private Function OnConnectorDelete(sel As Visio.Selection) As Boolean
    If Globals.ThisAddIn.Application.IsInScope(Visio.VisUICmds.visCmdUFEditCut) = True Then '1020
        For Each shape In sel
            If UCase(Left(shape.Name, 9)) = "CONNECTOR" Then
                sel.DeselectAll() 'not deselecting
                MsgBox("Cutting/pasting connectors is prohibited. You may copy/paste or drag/paste or delete")
                Return True
            End If
        Next
    End If
    Return False
End Function

only hitch is, is that it does not deselect the selected items


what, me worry?

Visisthebest

Perry interested to know why you need to go to such length to prevent this, if you go to the ribbon Developer -> Protection -> Protect From deletion,

then cutting a shape is also blocked.

If a user turns off your addin, then they can still cut the shape. You can also check if the Developer ribbon is visible and turn it off, so users cannot access the Protection section and turn of deletion protection.

Visio 2021 Professional

perry59

Quote from: Visisthebest on December 25, 2021, 05:15:18 PM
Perry interested to know why you need to go to such length to prevent this, if you go to the ribbon Developer -> Protection -> Protect From deletion,

then cutting a shape is also blocked.

If a user turns off your addin, then they can still cut the shape. You can also check if the Developer ribbon is visible and turn it off, so users cannot access the Protection section and turn of deletion protection.
That is true, but I do not want to disable deletion, only cutting as that is usually a prelude to pasting and in this case I handle pasting in another routine which updates a database. If the shape is cut, it is deleted and its info is deleted from the database.
what, me worry?

Visisthebest

Ok yes different use case thank you for explaining why you want to do this Perry.
Visio 2021 Professional

wapperdude

Might you do a localized protect from deletion?

So, if a OneD shape is selected, protect it from deletion, deselect it, and then reset the protection.  See bit of code....
It doesn't have all of the screening inplace, but does cancel selection and prevents deletion.


Sub Macro1()
    Dim vsoShp As Visio.Shape

    Set vsoShp = ActivePage.Shapes.ItemFromID(10)  'This was connector shape in test case
       
    vsoShp.CellsSRC(visSectionObject, visRowLock, visLockDelete).FormulaU = "1"
    ActiveWindow.Select vsoShp, visDeselect      'Deselects the shape
   
    vsoShp.CellsU("LockDelete").FormulaU = "0"  'Alternate syntax form
End Sub

Visio 2019 Pro

perry59

Quote from: wapperdude on December 26, 2021, 03:36:39 AM
Might you do a localized protect from deletion?

So, if a OneD shape is selected, protect it from deletion, deselect it, and then reset the protection.  See bit of code....
It doesn't have all of the screening inplace, but does cancel selection and prevents deletion.


Sub Macro1()
    Dim vsoShp As Visio.Shape

    Set vsoShp = ActivePage.Shapes.ItemFromID(10)  'This was connector shape in test case
       
    vsoShp.CellsSRC(visSectionObject, visRowLock, visLockDelete).FormulaU = "1"
    ActiveWindow.Select vsoShp, visDeselect      'Deselects the shape
   
    vsoShp.CellsU("LockDelete").FormulaU = "0"  'Alternate syntax form
End Sub

That is true, however I  do not want to prevent the user from deleting, only cutting (assuming a paste is forthcoming). When the user deletes this particular shape I handle that and associated entities in my backend database are also deleted. This is by design. So if the user cuts, rather than deletes the original shape is still deleted but if they then paste the shape, the information in the database is no longer present to apply to the pasted shape.
what, me worry?