private void LoadCategories()
        {
            ModelErrorDisplayFilter filter = myModel.ModelErrorDisplayFilter;

            DomainDataDirectory dataDirectory = myModel.Store.DomainDataDirectory;
            DomainClassInfo     baseType      = dataDirectory.GetDomainClass(typeof(ModelErrorCategory));
            ReadOnlyCollection <DomainClassInfo> categoryDescendants = baseType.AllDescendants;

            int numCategories = categoryDescendants.Count;

            Category[] categories = new Category[numCategories + 1];
            categories[numCategories] = new Category(null, false);
            for (int i = 0; i < numCategories; ++i)
            {
                DomainClassInfo info         = categoryDescendants[i];
                Type            categoryType = info.ImplementationClass;
                categories[i] = new Category(info, filter != null && filter.IsCategoryExcluded(categoryType));
            }

            // Presort the categories list
            Category.Sort(categories);

            baseType = dataDirectory.GetDomainClass(typeof(ModelError));
            ReadOnlyCollection <DomainClassInfo> errorDescendants = baseType.AllDescendants;
            int errorDescendantCount = errorDescendants.Count;
            int includedErrorCount   = 0;

            for (int i = 0; i < errorDescendantCount; ++i)
            {
                if (!errorDescendants[i].ImplementationClass.IsAbstract)
                {
                    ++includedErrorCount;
                }
            }

            Error[] errors             = new Error[includedErrorCount];
            int     includedErrorIndex = -1;

            for (int i = 0; i < errorDescendantCount; ++i)
            {
                DomainClassInfo info  = errorDescendants[i];
                Type            error = info.ImplementationClass;
                if (!error.IsAbstract)
                {
                    ++includedErrorIndex;
                    errors[includedErrorIndex] = new Error(
                        info,
                        Category.IndexOf(categories, ResolveErrorCategory(error)),
                        filter != null && filter.IsErrorExcluded(error));
                }
            }

            // Sort the errors with a primary sort on the presorted category index
            Array.Sort(errors,
                       delegate(Error error1, Error error2)
            {
                int retVal         = 0;
                int categoryIndex1 = error1.CategoryIndex;
                int categoryIndex2 = error2.CategoryIndex;
                if (categoryIndex1 < categoryIndex2)
                {
                    retVal = -1;
                }
                else if (categoryIndex1 > categoryIndex2)
                {
                    retVal = 1;
                }
                else
                {
                    retVal = string.Compare(error1.DisplayName, error2.DisplayName, StringComparison.CurrentCultureIgnoreCase);
                }
                return(retVal);
            });

            // Walk the errors and bind the categories to the errors
            int currentCategoryStartErrorIndex = -1;
            int lastCategoryIndex = -1;

            for (int i = 0; i < includedErrorCount; ++i)
            {
                int currentIndex = errors[i].CategoryIndex;
                if (currentIndex != lastCategoryIndex)
                {
                    if (lastCategoryIndex == -1)
                    {
                        lastCategoryIndex = currentIndex;
                        currentCategoryStartErrorIndex = i;
                    }
                    else
                    {
                        categories[lastCategoryIndex].BindErrorRange(currentCategoryStartErrorIndex, i - 1);
                        currentCategoryStartErrorIndex = i;
                        lastCategoryIndex = currentIndex;
                    }
                }
            }
            if (lastCategoryIndex != -1)
            {
                categories[lastCategoryIndex].BindErrorRange(currentCategoryStartErrorIndex, includedErrorCount - 1);
            }
            myCategories = categories;
            myErrors     = errors;
        }
        private void SaveChanges()
        {
            ORMModel model = myModel;
            ModelErrorDisplayFilter filter = model.ModelErrorDisplayFilter;
            Store store = model.Store;

            using (Transaction t = store.TransactionManager.BeginTransaction(ResourceStrings.ModelErrorDisplayFilterChangeTransactionName))
            {
                bool       deleteFilter = true, anyChanges = false;
                Error[]    errors     = myErrors;
                Category[] categories = myCategories;
                foreach (Category category in categories)
                {
                    bool allExcluded = true, allIncluded = true;

                    if (category.FirstError == -1)
                    {
                        allExcluded = false;
                        allIncluded = true;
                    }
                    else
                    {
                        for (int i = category.FirstError; i <= category.LastError; ++i)
                        {
                            Error error = errors[i];
                            if (error.IsExcluded != error.WasExcluded)
                            {
                                anyChanges = true;
                            }
                            if (error.IsExcluded)
                            {
                                deleteFilter = false;

                                allIncluded = false;
                            }
                            else
                            {
                                allExcluded = false;
                            }

                            if (anyChanges && !deleteFilter && !allExcluded && !allIncluded)
                            {
                                break;
                            }
                        }
                    }

                    if (allIncluded)
                    {
                        category.IsExcluded = false;
                    }
                    else if (allExcluded)
                    {
                        category.IsExcluded = true;
                    }
                }

                if (deleteFilter)
                {
                    //if all errors are included, we can delete the filter
                    anyChanges = true;
                    if (filter != null)
                    {
                        filter.Delete();
                    }
                }
                else if (anyChanges)
                {
                    if (filter == null)
                    {
                        filter       = new ModelErrorDisplayFilter(store);
                        filter.Model = model;
                    }

                    foreach (Category category in categories)
                    {
                        if (category.Type != null)
                        {
                            filter.ToggleCategory(category.Type, category.IsExcluded);
                        }
                    }

                    foreach (Error error in errors)
                    {
                        filter.ToggleError(error.Type, error.IsExcluded);
                    }

                    filter.CommitChanges();
                }
                if (anyChanges && t.HasPendingChanges)
                {
                    t.Commit();
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Attempt to activate an activatable error.
        /// </summary>
        /// <param name="e">DiagramPointEventArgs. Indicates the element to activate.</param>
        /// <returns>true if an error was activated</returns>
        public static bool AttemptErrorActivation(DiagramPointEventArgs e)
        {
            bool retVal = false;

            if (!e.Handled)
            {
                DiagramClientView clientView = e.DiagramClientView;
                MouseAction       action     = clientView.ActiveMouseAction;
                if ((action == null || !(action is ConnectAction || action is ToolboxAction)) &&
                    clientView.Selection.Count == 1)
                {
                    DiagramItem           diagramItem = e.DiagramHitTestInfo.HitDiagramItem;
                    IModelErrorActivation activator   = diagramItem.Shape as IModelErrorActivation;
                    if (activator != null)
                    {
                        IModelErrorOwner errorOwner = null;
                        foreach (ModelElement mel in diagramItem.RepresentedElements)
                        {
                            errorOwner = EditorUtility.ResolveContextInstance(mel, false) as IModelErrorOwner;
                            break;
                        }
                        if (errorOwner != null)
                        {
                            ModelErrorDisplayFilter displayFilter = null;
                            ORMDiagram diagram;
                            ORMModel   model;
                            if (null != (diagram = diagramItem.Diagram as ORMDiagram) &&
                                null != (model = diagram.ModelElement as ORMModel))
                            {
                                displayFilter = model.ModelErrorDisplayFilter;
                            }
                            MouseAction startingMouseAction = clientView.ActiveMouseAction;
                            foreach (ModelError error in errorOwner.GetErrorCollection(ModelErrorUses.DisplayPrimary))
                            {
                                if (ModelError.IsDisplayed(error, displayFilter))
                                {
                                    if (activator.ActivateModelError(error))
                                    {
                                        // UNDONE: MSBUG Report Microsoft bug DiagramClientView.OnDoubleClick is checking
                                        // for an active mouse action after the double click and clearing it if it is set.
                                        // This may be appropriate if the mouse action was set before the subfield double
                                        // click and did not change during the callback, but is definitely not appropriate
                                        // if the double click activated the mouse action.
                                        // Note that this bug makes it impossible to override OnDoubleClick and OnSubFieldDoubleClick
                                        // because e.Handled cannot be reliably checked, so there is no way to call base.OnDoubleClick
                                        // of base.OnSubFieldDoubleClick from a more derived class without attempting error activation
                                        // twice. If this is fixed, then any OnDoubleClick/OnSubFieldDoubleClick implementation
                                        // that simply defers to this method then calls the base can be eliminated in favor
                                        // of the same methods here.
                                        if (clientView.ActiveMouseAction == startingMouseAction)
                                        {
                                            e.Handled = true;
                                        }
                                        retVal = true;
                                        break;
                                    }
                                    else
                                    {
                                        if (!retVal)
                                        {
                                            IORMToolTaskItem     task;
                                            IORMToolServices     services;
                                            IORMToolTaskProvider provider;
                                            if (null != (task = error.TaskData as IORMToolTaskItem) &&
                                                null != (services = error.Store as IORMToolServices) &&
                                                null != (provider = services.TaskProvider))
                                            {
                                                if (provider.NavigateTo(task))
                                                {
                                                    retVal = true;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(retVal);
        }