private static void RegisterQueryDeleteEventHandlers()
        {
            QueryDeleteEventHandlerRegistry.Register("forceConcern", new QDForceComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("forceDescription", new QDForceComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("forceValue", new QDForceComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("forceContainer", new QDForceContainerEventHandler());
            QueryDeleteEventHandlerRegistry.Register("forces", new QDForcesContainerEventHandler());

            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeAlternativeState, new QDAlternativeComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeAlternativeIdentifier, new QDAlternativeComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeAlternativeTitle, new QDAlternativeComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeAlternativeDescription, new QDAlternativeComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeAlternative, new QDAlternativeContainerEventHander());

            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeRelatedUrlUrl, new QDRelatedDocumentComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeRelatedUrl, new QDRelatedDocumentComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeRelatedFile, new QDRelatedDocumentComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeRelatedDocumentTitle, new QDRelatedDocumentComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register(ShapeNames.TypeRelatedDocumentContainer, new QDRelatedDocumentContainerEventHandler());

            QueryDeleteEventHandlerRegistry.Register("stakeholderRole", new QDStakeholderComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("stakeholderName", new QDStakeholderComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("stakeholder", new QDStakeholderContainerEventHandler());

            QueryDeleteEventHandlerRegistry.Register("checkBoxComponent", new QDPlanningItemComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("checkBoxStateComponent", new QDPlanningItemComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("planningItemTextComponent", new QDPlanningItemComponentEventHandler());
            QueryDeleteEventHandlerRegistry.Register("planningItem", new QDPlanningContainerEventHandler());
        }
        private bool Application_QueryCancelSelectionDelete(Selection e) //Fired before a shape is deleted. Shape still exists here
        {
            List <Shape> toBeDeleted = e.Cast <Shape>().ToList();

            if (!e.Document.Template.Contains(Information.TemplateName))
            {
                return(false);
            }
            try
            {
                Log.Debug("before shape deleted event for " + e.Count + " shapes.");
                if (toBeDeleted.Any(s => ((s.CellExistsU[VisioFormulas.Cell_RationallyType, (short)VisExistsFlags.visExistsAnywhere] == Constants.CellExists) &&
                                          (s.CellsU[VisioFormulas.Cell_RationallyType].ResultStr[VisioFormulas.Value] == "forceHeaderRow")) || (s.CellsU[VisioFormulas.Cell_RationallyType].ResultStr[VisioFormulas.Value] == "forceTotalsRow")))
                {
                    if (toBeDeleted.All(s => s.CellsU[VisioFormulas.Cell_RationallyType].ResultStr[VisioFormulas.Value] != "forces"))
                    {
                        MessageBox.Show(Messages.CannotDeleteForceHeaderFooter, Messages.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(true);
                    }
                }

                //store the rationally type of the last shape, which is responsible for ending the undo scope
                if (string.IsNullOrEmpty(LastDelete) && (StartedUndoState == 0))
                {
                    LastDelete = toBeDeleted.Last().Name;
                    Globals.RationallyAddIn.StartedUndoState = Globals.RationallyAddIn.Application.BeginUndoScope("Delete shape");
                }

                //all shapes in the selection are already bound to be deleted. Mark them, so other pieces of code don't also try to delete them, if they are in the tree.
                toBeDeleted.Where(s => View.ExistsInTree(s)).ToList().ForEach(tbd => View.GetComponentByShape(tbd).Deleted = true);
                foreach (Shape s in e)
                {
                    Log.Debug("deleted shape name: " + s.Name);
                    if (s.CellExistsU[VisioFormulas.Cell_RationallyType, (short)VisExistsFlags.visExistsAnywhere] == Constants.CellExists)
                    {
                        string rationallyType = s.CellsU[VisioFormulas.Cell_RationallyType].ResultStr[VisioFormulas.Value];

                        QueryDeleteEventHandlerRegistry.HandleEvent(rationallyType, View, s);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, ex);
#if DEBUG
                throw;
#endif
            }
            return(false);
        }