コード例 #1
0
        public void Dispose()
        {
            if (!m_IsDisposed)
            {
                m_Logger.Log("Disposing page", XCad.Base.Enums.LoggerMessageSeverity_e.Debug);

                foreach (var ctrl in m_Page.Binding.Bindings.Select(b => b.Control).OfType <IDisposable>())
                {
                    try
                    {
                        ctrl.Dispose();
                    }
                    catch (Exception ex)
                    {
                        m_Logger.Log(ex);
                    }
                }

                m_IconsConv.Dispose();

                m_IsDisposed = true;

                Disposed?.Invoke(this);
            }
        }
コード例 #2
0
ファイル: TriggersManager.cs プロジェクト: bangush/cad-plus
        private void InvokeTrigger(Triggers_e trigger)
        {
            CommandMacroInfo[] cmds;

            if (m_Triggers.TryGetValue(trigger, out cmds))
            {
                cmds = cmds.Where(c => c.Scope.IsInScope(m_App)).ToArray();

                if (cmds != null && cmds.Any())
                {
                    m_Logger.Log($"Invoking {cmds.Length} command(s) for the trigger {trigger}");

                    foreach (var cmd in cmds)
                    {
                        try
                        {
                            m_MacroRunner.RunMacro(cmd.MacroPath, cmd.EntryPoint, false, cmd.Arguments);
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex);
                            m_Msg.ShowError(ex, $"Failed to run a macro '{cmd.Title}' on trigger '{trigger}'");
                        }
                    }
                }
            }
        }
コード例 #3
0
        private void OnPopupNotClosed(Process prc, IntPtr hWnd)
        {
            using (var vbaErrPopup = new VbaErrorPopup(hWnd))
            {
                if (vbaErrPopup.IsVbaErrorPopup)
                {
                    var curMacro = m_CurrentContext.CurrentMacro;

                    if (curMacro != null)
                    {
                        curMacro.InternalMacroException = new VbaMacroException(vbaErrPopup.ErrorText);
                    }

                    m_Logger.Log($"Closing VBA Error popup window: {hWnd}", LoggerMessageSeverity_e.Debug);

                    vbaErrPopup.Close();
                }
                else
                {
                    m_Logger.Log($"Blocking popup window is not closed: {hWnd}", LoggerMessageSeverity_e.Debug);

                    m_JournalWriter.WriteLine("Failed to close the blocking popup window");
                }
            }
        }
コード例 #4
0
            public void Dispose()
            {
                if (m_CloseDrawing)
                {
                    if (CanClose(m_Drawing))
                    {
                        m_Logger.Log("Closing temp drawing document for QR code");
                        m_Drawing.Close();
                    }
                    else
                    {
                        Debug.Assert(false, "Drawing cannot be closed");
                    }
                }

                if (m_CloseDocument)
                {
                    if (CanClose(Document))
                    {
                        m_Logger.Log("Closing temp referenced document for QR code");
                        Document.Close();
                    }
                    else
                    {
                        Debug.Assert(false, "Document cannot be closed");
                    }
                }
            }
コード例 #5
0
        private void OnPageClosed(PageCloseReasons_e reason)
        {
            if (reason == PageCloseReasons_e.Okay)
            {
                try
                {
                    IXDocument[] docs    = null;
                    var          rootDoc = m_Data.Input.Document;

                    switch (m_Data.Input.Scope)
                    {
                    case InputScope_e.AllReferences:
                        docs = m_Data.Input.AllDocuments.References
                               .Where(d => d.IsChecked).Select(d => d.Document).ToArray();
                        break;

                    case InputScope_e.Selection:
                        docs = m_Data.Input.Components
                               .Distinct(new ComponentDocumentSafeEqualityComparer())
                               .Select(c => c.ReferencedDocument).ToArray();
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    var input = docs.ToList();
                    ProcessInput?.Invoke(m_Host.Extension.Application, input);

                    var exec = new AssemblyBatchRunJobExecutor(m_Host.Extension.Application, m_MacroRunnerSvc,
                                                               input.ToArray(), m_Logger, m_Data.Macros.Macros.Macros.Select(x => x.Data).ToArray(),
                                                               m_Data.Options.ActivateDocuments, m_Data.Options.AllowReadOnly,
                                                               m_Data.Options.AllowRapid, m_Data.Options.AutoSave);

                    var vm = new JobResultVM(rootDoc.Title, exec, m_CadDesc, m_Logger);

                    using (var cancelHandler = new EscapeBatchExecutorCancelHandler(exec, m_Host.Extension.Application, m_Dispatcher))
                    {
                        vm.TryRunBatch();
                    }

                    var wnd = m_Host.Extension.CreatePopupWindow <ResultsWindow>();
                    wnd.Control.Title       = $"{rootDoc.Title} batch job result";
                    wnd.Control.DataContext = vm;
                    wnd.Show();
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    m_Msg.ShowError(ex);
                    m_Logger.Log(ex);
                }
            }
        }
コード例 #6
0
        public void Dispose()
        {
            m_Logger.Log("Disposing page");

            foreach (var ctrl in m_Page.Binding.Bindings.Select(b => b.Control).OfType <IDisposable>())
            {
                ctrl.Dispose();
            }

            m_IconsConv.Dispose();
        }
コード例 #7
0
        public void Dispose()
        {
            m_Logger.Log("Disposing page", XCad.Base.Enums.LoggerMessageSeverity_e.Debug);

            foreach (var ctrl in m_Page.Binding.Bindings.Select(b => b.Control).OfType <IDisposable>())
            {
                ctrl.Dispose();
            }

            m_IconsConv.Dispose();
        }
コード例 #8
0
ファイル: CommandsManager.cs プロジェクト: 15831944/cad-plus
 public void RunMacroCommand(CommandMacroInfo cmd)
 {
     try
     {
         m_MacroRunner.RunMacro(cmd.MacroPath, cmd.EntryPoint, cmd.UnloadAfterRun);
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex);
         m_Msg.ShowError(ex, $"Failed to run macro: '{cmd.Title}'");
     }
 }
コード例 #9
0
ファイル: ToolbarModule.cs プロジェクト: xarial/cad-plus
        private void OnCommandClick(Commands_e spec)
        {
            try
            {
                switch (spec)
                {
                case Commands_e.Configuration:

                    var vm = Resolve <CommandManagerVM>();

                    vm.Load(m_ToolbarConfMgr.Toolbar.Clone(), m_ToolbarConfMgr.FilePath);

                    var popup = m_Host.Extension.CreatePopupWindow <CommandManagerForm>();
                    popup.Control.DataContext           = vm;
                    popup.Control.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;

                    if (popup.ShowDialog() == true)
                    {
                        try
                        {
                            m_ToolbarConfMgr.Toolbar  = vm.ToolbarInfo;
                            m_ToolbarConfMgr.FilePath = vm.ToolbarSpecificationPath;

                            if (m_ToolbarConfMgr.SettingsChanged)
                            {
                                m_ToolbarConfMgr.SaveSettings();
                            }

                            if (m_ToolbarConfMgr.ToolbarChanged)
                            {
                                m_ToolbarConfMgr.SaveToolbar();

                                //TODO: make this message SOLIDWORKS specific only as other CAD systems might have different conditions for loading of toolbar
                                m_Msg.ShowInformation("Toolbar settings have been changed. Restart SOLIDWORKS to load the command manager and menu. If commands in the toolbar have been changed (added or removed) then it might be required to restart SOLIDWORKS twice for the changes to be applied");
                            }
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex);
                            m_Msg.ShowError(ex, "Failed to save toolbar specification");
                        }
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
                m_Msg.ShowError(ex, "Unknown error");
                m_Logger.Log(ex);
            }
        }
コード例 #10
0
 private void TryEnableAddIns(List <string> guids)
 {
     try
     {
         if (guids?.Any() == true)
         {
             SwApplicationFactory.EnableAddInsStartup(guids);
         }
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex);
     }
 }
コード例 #11
0
ファイル: SwAddInEx.cs プロジェクト: persadewh/xcad
        public bool ConnectToSW(object ThisSW, int cookie)
        {
            m_IsDisposed = false;

            try
            {
                var app = ThisSW as ISldWorks;
                AddInId = cookie;

                if (app.IsVersionNewerOrEqual(Enums.SwVersion_e.Sw2015))
                {
                    app.SetAddinCallbackInfo2(0, this, AddInId);
                }
                else
                {
                    app.SetAddinCallbackInfo(0, this, AddInId);
                }

                m_Application = new SwApplication(app);

                m_Application.FirstStartupCompleted += OnStartupCompleted;

                var svcCollection = GetServicesCollection();

                ConfigureServices?.Invoke(this, svcCollection);
                OnConfigureServices(svcCollection);

                m_SvcProvider = svcCollection.CreateProvider();

                Logger = m_SvcProvider.GetService <IXLogger>();

                m_Application.Init(svcCollection);

                Logger.Log("Loading add-in");

                SwMacroFeatureDefinition.Application = m_Application;

                m_CommandManager = new SwCommandManager(Application, AddInId, m_SvcProvider, this.GetType().GUID);

                Connect?.Invoke(this);
                OnConnect();

                return(true);
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
                return(false);
            }
        }
コード例 #12
0
        /// <summary>
        /// Logs error
        /// </summary>
        /// <param name="logger">Logger</param>
        /// <param name="ex">Exception</param>
        /// <param name="stackTrace">True to log stack trace</param>
        /// <param name="severity">Severity of the message</param>
        public static void Log(this IXLogger logger, Exception ex, bool stackTrace = true, LoggerMessageSeverity_e severity = LoggerMessageSeverity_e.Error)
        {
            var msg           = new StringBuilder();
            var stackTraceMsg = new StringBuilder();

            ParseExceptionLog(ex, msg, stackTraceMsg, stackTrace);

            logger.Log(msg.ToString(), severity);

            if (stackTrace)
            {
                logger.Log(stackTraceMsg.ToString(), LoggerMessageSeverity_e.Debug);
            }
        }
コード例 #13
0
ファイル: MacroRunner.cs プロジェクト: xarial/cad-plus
        public bool TryRunMacroCommand(Triggers_e trigger, CommandMacroInfo macroInfo, IXDocument targetDoc, string workDir)
        {
            try
            {
                m_Logger.Log($"Invoking '{trigger}' trigger for '{macroInfo.Title}'", LoggerMessageSeverity_e.Debug);

                var eventType = GetEventType(trigger);

                var eventArgs = new MacroRunningArguments(macroInfo, targetDoc)
                {
                    Cancel = false
                };

                m_ToolbarModuleProxy.CallMacroRunning(eventType, eventArgs);

                if (!eventArgs.Cancel)
                {
                    var opts = eventArgs.MacroInfo.UnloadAfterRun ? MacroRunOptions_e.UnloadAfterRun : MacroRunOptions_e.Default;

                    var macroPath = m_FilePathResolver.Resolve(eventArgs.MacroInfo.MacroPath, workDir);

                    m_Logger.Log($"Running macro '{macroPath}' with arguments '{eventArgs.MacroInfo.Arguments}'", LoggerMessageSeverity_e.Debug);

                    var entryPoint = eventArgs.MacroInfo.EntryPoint;

                    if (entryPoint == null)
                    {
                        throw new UserException($"Entry point is not specified for macro '{macroInfo.Title}'");
                    }

                    m_Runner.RunMacro(m_App, macroPath,
                                      new MacroEntryPoint(entryPoint.ModuleName, entryPoint.SubName),
                                      opts, eventArgs.MacroInfo.Arguments, null);

                    return(true);
                }
                else
                {
                    m_Logger.Log($"Trigger '{trigger}' for '{macroInfo.Title}' invoking cancelled", LoggerMessageSeverity_e.Debug);
                    return(false);
                }
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
                m_MsgSvc.ShowError(ex, $"Failed to run a macro '{macroInfo.Title}' on trigger '{trigger}'");
                return(false);
            }
        }
コード例 #14
0
        public bool Execute()
        {
            var startTime = DateTime.Now;

            try
            {
                m_CurrentCancellationToken = new CancellationTokenSource();
                var cancellationToken = m_CurrentCancellationToken.Token;

                using (var prg = m_App.CreateProgress())
                {
                    LogMessage("Preparing job");

                    var jobItems = PrepareJob();

                    JobSet?.Invoke(jobItems, startTime);

                    for (int i = 0; i < jobItems.Length; i++)
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        var jobItem = jobItems[i];

                        prg.SetStatus($"Processing {jobItem.FilePath}");

                        var res = TryProcessFile(jobItem, cancellationToken);

                        ProgressChanged?.Invoke(jobItem, res);
                        prg.Report((double)(i + 1) / (double)jobItems.Length);
                    }
                }

                return(true);
            }
            catch (OperationCanceledException)
            {
                throw new JobCancelledException();
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
                return(false);
            }
            finally
            {
                JobCompleted?.Invoke(DateTime.Now - startTime);
            }
        }
コード例 #15
0
ファイル: ToolbarModule.cs プロジェクト: xarial/cad-plus
        private void OnConnect()
        {
            CreateContainer();

            m_Msg    = Resolve <IMessageService>();
            m_Logger = Resolve <IXLogger>();

            m_ToolbarProxy = Resolve <IToolbarModuleProxy>();
            m_ToolbarProxy.RequestMacroRunning += OnRequestMacroRunning;

            m_ToolbarConfMgr = Resolve <IToolbarConfigurationManager>();

            m_Host.RegisterCommands <Commands_e>(OnCommandClick);

            try
            {
                m_ToolbarConfMgr.Load();
                var workDir = Path.GetDirectoryName(m_ToolbarConfMgr.FilePath);
                LoadCommands(m_ToolbarConfMgr.Toolbar, workDir);
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
                m_Msg.ShowError(ex, "Failed to load Toolbar+ commands");
            }
        }
コード例 #16
0
ファイル: ExportModule.cs プロジェクト: xarial/cad-plus
        private void OnCommandClick(Commands_e spec)
        {
            switch (spec)
            {
            case Commands_e.RunStandAlone:
                try
                {
                    var exportPath = Path.GetFullPath(Path.Combine(
                                                          Path.GetDirectoryName(this.GetType().Assembly.Location), @"..\..\exportplus.exe"));

                    if (File.Exists(exportPath))
                    {
                        System.Diagnostics.Process.Start(exportPath);
                    }
                    else
                    {
                        throw new FileNotFoundException("Failed to find the path to executable");
                    }
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex);
                    m_Msg.ShowError("Failed to run Batch+");
                }
                break;
            }
        }
コード例 #17
0
 public object DeserializeValue(string val)
 {
     try
     {
         if (!string.IsNullOrEmpty(val))
         {
             var feat = (IFeature)((ISwDrawing)m_Draw).Drawing.FeatureByName(val);
             if (feat != null)
             {
                 var skPict = (ISketchPicture)feat.GetSpecificFeature2();
                 return(((ISwDrawing)m_Draw).CreateObjectFromDispatch <ISwObject>(skPict));
             }
             else
             {
                 throw new Exception("Failed to find the picture");
             }
         }
         else
         {
             throw new Exception("Value is empty");
         }
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex);
         return(null);
     }
 }
コード例 #18
0
        /// <summary>
        /// Logs error
        /// </summary>
        /// <param name="ex">Exception</param>
        public static void Log(this IXLogger logger, Exception ex, bool stackTrace = true)
        {
            var msg = new StringBuilder();

            ParseExceptionLog(ex, msg, stackTrace);

            logger.Log(msg.ToString());
        }
コード例 #19
0
        public void Init()
        {
            try
            {
                if (!m_IsInit)
                {
                    m_JobHandle = CreateJobObject(IntPtr.Zero, null);

                    if (m_JobHandle == IntPtr.Zero)
                    {
                        throw new Exception("Failed to create job handle");
                    }

                    var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION()
                    {
                        BasicLimitInformation = new JOBOBJECT_BASIC_LIMIT_INFORMATION()
                        {
                            LimitFlags = 0x2000
                        }
                    };

                    var length          = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
                    var extendedInfoPtr = Marshal.AllocHGlobal(length);

                    Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

                    if (!SetInformationJobObject(m_JobHandle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
                    {
                        throw new Exception(string.Format("Unable to set information.  Error: {0}", Marshal.GetLastWin32Error()));
                    }

                    m_Logger.Log($"Job initiated: {m_JobHandle}", LoggerMessageSeverity_e.Debug);
                    m_IsInit = true;
                }
                else
                {
                    throw new Exception("Job is already initialized");
                }
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
                throw;
            }
        }
コード例 #20
0
        private string[] TryLoadRecentFiles()
        {
            string[] recentFiles = null;

            try
            {
                if (File.Exists(m_RecentFilesPath))
                {
                    recentFiles = File.ReadAllLines(m_RecentFilesPath);
                }
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
            }

            return(recentFiles ?? new string[0]);
        }
コード例 #21
0
ファイル: DocumentsHandler.cs プロジェクト: EddyAlleman/xcad
        public void TryInitHandlers(IXDocument doc)
        {
            var handlers = new List <IDocumentHandler>();

            foreach (var handlerInfo in m_Handlers)
            {
                try
                {
                    CreateHandler(doc, handlerInfo, handlers);
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex);
                }
            }

            m_DocsMap.Add(doc, handlers);
        }
コード例 #22
0
 private void OnInsertQrCodePageClosing(PageCloseReasons_e reason, PageClosingArg arg)
 {
     if (reason == PageCloseReasons_e.Okay)
     {
         try
         {
             if (string.IsNullOrEmpty(m_QrDataProvider.GetData(m_CurDrawing, m_CurInsertQrCodePageData.Source)))
             {
                 throw new UserException("Data for QR code is empty");
             }
         }
         catch (Exception ex)
         {
             m_Logger.Log(ex);
             arg.Cancel       = true;
             arg.ErrorMessage = ex.ParseUserError();
         }
     }
 }
コード例 #23
0
        public void TryInitHandlers(IXDocument doc)
        {
            var handlers = new List <IDocumentHandler>();

            foreach (var type in m_Handlers.Keys)
            {
                try
                {
                    var handler = CreateHandler(doc, type);
                    handlers.Add(handler);
                }
                catch (Exception ex)
                {
                    m_Logger.Log(ex);
                }
            }

            m_DocsMap.Add(doc, handlers);
        }
コード例 #24
0
ファイル: CommandsManager.cs プロジェクト: xarial/cad-plus
        public void CreateCommandGroups(CustomToolbarInfo toolbarInfo, string workDir)
        {
            const string COMMAND_GROUP_TITLE_TEMPLATE = "Toolbar+ Command Group";
            const string COMMAND_TITLE_TEMPLATE       = "Toolbar+ Command";

            m_WorkDir = workDir;

            var usedCommandGroupNames = new List <string>();
            var usedCommandNames      = new List <string>();

            if (toolbarInfo?.Groups != null)
            {
                foreach (var grp in toolbarInfo.Groups
                         .Where(g => g.Commands?.Any(c => c.Triggers.HasFlag(Triggers_e.Button)) == true))
                {
                    var cmdGrp = new CommandGroupInfoSpec(grp, m_IconsProviders, m_PathResolver, m_WorkDir);

                    ResolveEmptyName(cmdGrp.Info, COMMAND_GROUP_TITLE_TEMPLATE, usedCommandGroupNames, out string grpTitle, out string grpTooltip);
                    cmdGrp.Title   = grpTitle;
                    cmdGrp.Tooltip = grpTooltip;

                    foreach (var cmd in cmdGrp.Commands)
                    {
                        ResolveEmptyName(((CommandItemInfoSpec)cmd).Info, COMMAND_TITLE_TEMPLATE, usedCommandNames, out string cmdTitle, out string cmdTooltip);
                        cmd.Title   = cmdTitle;
                        cmd.Tooltip = cmdTooltip;
                    }

                    m_Logger.Log($"Adding command group: {cmdGrp.Title} [{cmdGrp.Id}]. Commands: {string.Join(", ", cmdGrp.Commands.Select(c => $"{c.Title} [{c.UserId}]").ToArray())}", XCad.Base.Enums.LoggerMessageSeverity_e.Debug);

                    var cmdGrpCad = m_AddIn.CommandManager.AddCommandGroup(cmdGrp);

                    cmdGrpCad.CommandClick        += OnCommandClick;
                    cmdGrpCad.CommandStateResolve += OnCommandStateResolve;
                }

                LoadToggleStateResolvers(
                    toolbarInfo.Groups.SelectMany(
                        g => g.Commands ?? Enumerable.Empty <CommandMacroInfo>())
                    .Where(m => m.Triggers.HasFlag(Triggers_e.ToggleButton) && m.ToggleButtonStateCodeType != ToggleButtonStateCode_e.None));
            }
        }
コード例 #25
0
 private void TryAddProcessToJob(IXApplication app)
 {
     try
     {
         m_JobMgr.AddProcess(app.Process);
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex);
     }
 }
コード例 #26
0
ファイル: MacroRunnerBase.cs プロジェクト: xarial/cad-plus
        public IMacroResult Run(object appDisp, string macroPath, string moduleName,
                                string subName, int opts, IMacroParameter param, bool cacheReg = false)
        {
            var app = CastApplication(appDisp);

            var macro = app.OpenMacro(macroPath);

            GetMacroParametersManager(true, out RotRegister newReg, out IMacroParameterManager macroParamsMgr);

            if (newReg != null)
            {
                if (cacheReg)
                {
                    if (m_Register != null)
                    {
                        try
                        {
                            m_Register.Dispose();
                        }
                        catch (Exception ex)
                        {
                            m_Logger.Log(ex);
                        }
                    }

                    m_Register = newReg;
                }
            }

            try
            {
                var sessionId = CreateMacroSessionId(app, macro);
                macroParamsMgr.PushParameter(sessionId, param);

                try
                {
                    macro.Run(new MacroEntryPoint(moduleName, subName), (MacroRunOptions_e)opts);
                }
                finally
                {
                    macroParamsMgr.TryRemoveParameter(sessionId, param);
                }
            }
            finally
            {
                if (newReg != null && !cacheReg)
                {
                    newReg.Dispose();
                }
            }

            return(param.Result);
        }
コード例 #27
0
ファイル: MacroExecutor.cs プロジェクト: xarial/cad-plus
 private IMacroRunner TryCreateMacroRunner()
 {
     try
     {
         return((IMacroRunner)Activator.CreateInstance(Type.GetTypeFromProgID(MacroRunnerProgId)));
     }
     catch (Exception ex)
     {
         m_Logger.Log(ex);
         return(null);
     }
 }
コード例 #28
0
        //NOTE: it is not safe to dispatch the pointer to IModelDoc2 as for assembly documents it can cause RPC_E_WRONG_THREAD when retrieved on EndDispatch
        internal void Dispatch(string title, string path)
        {
            lock (m_Lock)
            {
                m_Logger.Log($"Adding '{title}' to the dispatch queue", LoggerMessageSeverity_e.Debug);

                m_ModelsDispatchQueue.Add(new ModelInfo()
                {
                    Title = title,
                    Path  = path
                });

                if (!m_DocsDispatchQueue.Any())
                {
                    DispatchAllModels();
                }
            }
        }
コード例 #29
0
        private ObservableCollection <QrCodeInfo> ReadQrCodeData()
        {
            ObservableCollection <QrCodeInfo> data = null;

            try
            {
                using (var stream = m_Drawing.TryOpenStream(STREAM_NAME, AccessType_e.Read))
                {
                    if (stream != null)
                    {
                        m_Logger.Log("Reading QR code data", LoggerMessageSeverity_e.Debug);

                        using (var reader = new StreamReader(stream))
                        {
                            data = m_Serializer.ReadSettings <ObservableCollection <QrCodeInfo> >(
                                reader, new PictureValueSerializer(m_Logger, m_Drawing));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                m_Logger.Log(ex);
            }

            if (data != null)
            {
                var usedPictures = new List <IXObject>();

                for (int i = data.Count - 1; i >= 0; i--)
                {
                    if (data[i].Picture == null)
                    {
                        data.RemoveAt(i);
                        m_Logger.Log($"Removed dangling QR code data at index {i}", LoggerMessageSeverity_e.Debug);
                    }
                    //As we serialize names of the features (removing and readding QR code may cause duplication in the data which is not recognized as dangling)
                    else if (usedPictures.Find(p => p.Equals(data[i].Picture)) != null)
                    {
                        data.RemoveAt(i);
                        m_Logger.Log($"Removed duplicate QR code data at index {i}", LoggerMessageSeverity_e.Debug);
                    }
                    else
                    {
                        usedPictures.Add(data[i].Picture);
                    }
                }
            }
            else
            {
                data = new ObservableCollection <QrCodeInfo>();
            }

            data.CollectionChanged += OnDataCollectionChanged;

            Init(data);

            return(data);
        }
        public override void PostProcessControls(IEnumerable <IPropertyManagerPageControlEx> ctrls)
        {
            var selBoxes = ctrls.OfType <PropertyManagerPageSelectionBoxControl>().ToArray();

            var autoAssignSelMarksCtrls = selBoxes
                                          .Where(s => s.SelectionBox.Mark == -1).ToList();

            var assignedMarks = ctrls.OfType <PropertyManagerPageSelectionBoxControl>()
                                .Except(autoAssignSelMarksCtrls).Select(c => c.SelectionBox.Mark).ToList();

            ValidateMarks(assignedMarks);

            if (selBoxes.Length == 1)
            {
                if (autoAssignSelMarksCtrls.Any())
                {
                    autoAssignSelMarksCtrls[0].SelectionBox.Mark = 0;
                }
            }
            else
            {
                int index = 0;

                autoAssignSelMarksCtrls.ForEach(c =>
                {
                    int mark;
                    do
                    {
                        mark = (int)Math.Pow(2, index);
                        index++;
                    } while (assignedMarks.Contains(mark));

                    c.SelectionBox.Mark = mark;
                });
            }

            m_Logger.Log($"Assigned selection box marks: {string.Join(", ", selBoxes.Select(s => s.SelectionBox.Mark).ToArray())}", LoggerMessageSeverity_e.Debug);
        }