コード例 #1
0
        private async Task GenerateJson(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

            try
            {
                await cmdExport.DoThreadSafeAsync(x => x.Enabled = false, token);

                await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token);

                try
                {
                    token.ThrowIfCancellationRequested();
                    string strText = JsonConvert.SerializeXmlNode(_objCharacterXml, Formatting.Indented);
                    token.ThrowIfCancellationRequested();
                    await SetTextToWorkerResult(strText, token);
                }
                finally
                {
                    await cmdExport.DoThreadSafeAsync(x => x.Enabled = true, token);

                    await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = true, token);
                }
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #2
0
        private async Task GenerateCharacterXml(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

            try
            {
                await Task.WhenAll(cmdExport.DoThreadSafeAsync(x => x.Enabled      = false, token),
                                   cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token),
                                   LanguageManager.GetStringAsync("String_Generating_Data")
                                   .ContinueWith(
                                       y => txtText.DoThreadSafeAsync(x => x.Text = y.Result, token),
                                       token).Unwrap());

                token.ThrowIfCancellationRequested();
                using (token.Register(() => _objCharacterXmlGeneratorCancellationTokenSource.Cancel(false)))
                    _objCharacterXml = await _objCharacter.GenerateExportXml(_objExportCulture, _strExportLanguage,
                                                                             _objCharacterXmlGeneratorCancellationTokenSource
                                                                             .Token);
                token.ThrowIfCancellationRequested();
                if (_objCharacterXml != null)
                {
                    await DoXsltUpdate(token);
                }
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #3
0
        private async ValueTask DoExport(CancellationToken token = default)
        {
            if (string.IsNullOrEmpty(_strXslt))
            {
                return;
            }

            CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

            try
            {
                if (_strXslt == "JSON")
                {
                    await ExportJson(token : token);
                }
                else
                {
                    await ExportNormal(token : token);
                }
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #4
0
        /// <summary>
        /// Update the internal XML of the Viewer window.
        /// </summary>
        private async Task RefreshCharacterXml(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            CursorWait objCursorWait = await CursorWait.NewAsync(this, true, token);

            try
            {
                await Task.WhenAll(this.DoThreadSafeAsync(() =>
                {
                    tsPrintPreview.Enabled = false;
                    tsSaveAsHtml.Enabled = false;
                }, token),
                                   cmdPrint.DoThreadSafeAsync(x => x.Enabled     = false, token),
                                   cmdSaveAsPdf.DoThreadSafeAsync(x => x.Enabled = false, token));

                token.ThrowIfCancellationRequested();
                Character[] aobjCharacters = await _lstCharacters.ToArrayAsync();

                token.ThrowIfCancellationRequested();
                _objCharacterXml = aobjCharacters.Length > 0
                    ? await CommonFunctions.GenerateCharactersExportXml(_objPrintCulture, _strPrintLanguage,
                                                                        _objRefresherCancellationTokenSource.Token,
                                                                        aobjCharacters)
                    : null;

                token.ThrowIfCancellationRequested();
                await this.DoThreadSafeAsync(() => tsSaveAsXml.Enabled = _objCharacterXml != null, token);

                token.ThrowIfCancellationRequested();
                await RefreshSheet(token);
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #5
0
ファイル: CursorWait.cs プロジェクト: Stexinator/chummer5a
        public static async Task <CursorWait> NewAsync(Control objControl = null, bool blnAppStarting = false, CancellationToken token = default)
        {
            CursorWait objReturn = new CursorWait(objControl, blnAppStarting);

            if (objReturn._objControl == null)
            {
                if (Interlocked.Increment(ref _intApplicationWaitCursors) == 1)
                {
                    Application.UseWaitCursor            = true;
                    objReturn._blnDoUnsetCursorOnDispose = true;
                }
                return(objReturn);
            }
            Form frmControl = objReturn._objControl as Form;

            try
            {
                if (frmControl == null || await frmControl.DoThreadSafeFuncAsync(x => x.IsMdiChild, token))
                {
                    if (frmControl != null)
                    {
                        objReturn._frmControlTopParent = await frmControl.DoThreadSafeFuncAsync(x => x.MdiParent, token);
                    }
                    else if (objReturn._objControl is UserControl objUserControl)
                    {
                        objReturn._frmControlTopParent = await objUserControl.DoThreadSafeFuncAsync(x => x.ParentForm, token);
                    }
                    else if (objReturn._objControl != null)
                    {
                        for (Control objLoop = await objReturn._objControl.DoThreadSafeFuncAsync(x => x.Parent, token); objLoop != null; objLoop = await objLoop.DoThreadSafeFuncAsync(x => x.Parent, token))
                        {
                            if (objLoop is Form objLoopForm)
                            {
                                objReturn._frmControlTopParent = objLoopForm;
                                break;
                            }
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                await objReturn.DisposeAsync();

                throw;
            }

            if (objReturn._objControl != null)
            {
                if (objReturn._blnAppStartingCursor)
                {
                    int intNewValue = s_DicCursorControls.AddOrUpdate(objReturn._objControl, 1, (x, y) => Interlocked.Increment(ref y));
                    try
                    {
                        await objReturn.SetControlCursorAsync(intNewValue < short.MaxValue?Cursors.AppStarting : Cursors.WaitCursor, token);
                    }
                    catch (OperationCanceledException)
                    {
                        await objReturn.DisposeAsync();

                        throw;
                    }
                    objReturn._blnDoUnsetCursorOnDispose = true;
                }
                else
                {
                    s_DicCursorControls.AddOrUpdate(objReturn._objControl, short.MaxValue, (x, y) => Interlocked.Add(ref y, short.MaxValue));
                    try
                    {
                        await objReturn.SetControlCursorAsync(Cursors.WaitCursor, token);
                    }
                    catch (OperationCanceledException)
                    {
                        await objReturn.DisposeAsync();

                        throw;
                    }
                    objReturn._blnDoUnsetCursorOnDispose = true;
                }
            }
            return(objReturn);
        }
コード例 #6
0
        /// <summary>
        /// Run the generated XML file through the XSL transformation engine to create the file output.
        /// </summary>
        private async Task AsyncGenerateOutput(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

            try
            {
                await Task.WhenAll(this.DoThreadSafeAsync(() =>
                {
                    tsPrintPreview.Enabled = false;
                    tsSaveAsHtml.Enabled = false;
                }, token),
                                   cmdPrint.DoThreadSafeAsync(x => x.Enabled     = false, token),
                                   cmdSaveAsPdf.DoThreadSafeAsync(x => x.Enabled = false, token));

                token.ThrowIfCancellationRequested();
                await SetDocumentText(await LanguageManager.GetStringAsync("String_Generating_Sheet"), token);

                token.ThrowIfCancellationRequested();
                string strXslPath = Path.Combine(Utils.GetStartupPath, "sheets", _strSelectedSheet + ".xsl");
                if (!File.Exists(strXslPath))
                {
                    string strReturn = "File not found when attempting to load " + _strSelectedSheet +
                                       Environment.NewLine;
                    Log.Debug(strReturn);
                    Program.ShowMessageBox(this, strReturn);
                    return;
                }

                token.ThrowIfCancellationRequested();
                XslCompiledTransform objXslTransform;
                try
                {
                    objXslTransform = await XslManager.GetTransformForFileAsync(strXslPath);
                }
                catch (ArgumentException)
                {
                    token.ThrowIfCancellationRequested();
                    string strReturn = "Last write time could not be fetched when attempting to load "
                                       + _strSelectedSheet +
                                       Environment.NewLine;
                    Log.Debug(strReturn);
                    Program.ShowMessageBox(this, strReturn);
                    return;
                }
                catch (PathTooLongException)
                {
                    token.ThrowIfCancellationRequested();
                    string strReturn = "Last write time could not be fetched when attempting to load "
                                       + _strSelectedSheet +
                                       Environment.NewLine;
                    Log.Debug(strReturn);
                    Program.ShowMessageBox(this, strReturn);
                    return;
                }
                catch (UnauthorizedAccessException)
                {
                    token.ThrowIfCancellationRequested();
                    string strReturn = "Last write time could not be fetched when attempting to load "
                                       + _strSelectedSheet +
                                       Environment.NewLine;
                    Log.Debug(strReturn);
                    Program.ShowMessageBox(this, strReturn);
                    return;
                }
                catch (XsltException ex)
                {
                    token.ThrowIfCancellationRequested();
                    string strReturn = "Error attempting to load " + _strSelectedSheet + Environment.NewLine;
                    Log.Debug(strReturn);
                    Log.Error("ERROR Message = " + ex.Message);
                    strReturn += ex.Message;
                    Program.ShowMessageBox(this, strReturn);
                    return;
                }

                token.ThrowIfCancellationRequested();

                XmlWriterSettings objSettings = objXslTransform.OutputSettings?.Clone();
                if (objSettings != null)
                {
                    objSettings.CheckCharacters  = false;
                    objSettings.ConformanceLevel = ConformanceLevel.Fragment;
                }

                using (MemoryStream objStream = new MemoryStream())
                {
                    using (XmlWriter objWriter = objSettings != null
                               ? XmlWriter.Create(objStream, objSettings)
                               : Utils.GetXslTransformXmlWriter(objStream))
                    {
                        token.ThrowIfCancellationRequested();
                        await Task.Run(() => objXslTransform.Transform(_objCharacterXml, objWriter), token);
                    }

                    token.ThrowIfCancellationRequested();

                    objStream.Position = 0;

                    // This reads from a static file, outputs to an HTML file, then has the browser read from that file. For debugging purposes.
                    //objXSLTransform.Transform("D:\\temp\\print.xml", "D:\\temp\\output.htm");
                    //webBrowser1.Navigate("D:\\temp\\output.htm");

                    if (GlobalSettings.PrintToFileFirst)
                    {
                        // The DocumentStream method fails when using Wine, so we'll instead dump everything out a temporary HTML file, have the WebBrowser load that, then delete the temporary file.

                        // Delete any old versions of the file
                        if (!await Utils.SafeDeleteFileAsync(_strTempSheetFilePath, true, token: token))
                        {
                            return;
                        }

                        // Read in the resulting code and pass it to the browser.
                        using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true))
                        {
                            string strOutput = await objReader.ReadToEndAsync();

                            File.WriteAllText(_strTempSheetFilePath, strOutput);
                        }

                        token.ThrowIfCancellationRequested();
                        await this.DoThreadSafeAsync(x => x.UseWaitCursor = true, token);

                        await webViewer.DoThreadSafeAsync(
                            x => x.Url = new Uri("file:///" + _strTempSheetFilePath), token);

                        token.ThrowIfCancellationRequested();
                    }
                    else
                    {
                        token.ThrowIfCancellationRequested();
                        // Populate the browser using DocumentText (DocumentStream would cause issues due to stream disposal).
                        using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true))
                        {
                            string strOutput = await objReader.ReadToEndAsync();

                            token.ThrowIfCancellationRequested();
                            await this.DoThreadSafeAsync(() => UseWaitCursor = true, token);

                            await webViewer.DoThreadSafeAsync(x => x.DocumentText = strOutput, token);

                            token.ThrowIfCancellationRequested();
                        }
                    }
                }
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #7
0
        private async void cmdSaveAsPdf_Click(object sender, EventArgs e)
        {
            try
            {
                CursorWait objCursorWait = await CursorWait.NewAsync(this, token : _objGenericToken);

                try
                {
                    try
                    {
                        // Check to see if we have any "Print to PDF" printers, as they will be a lot more reliable than wkhtmltopdf
                        string strPdfPrinter = string.Empty;
                        foreach (string strPrinter in PrinterSettings.InstalledPrinters)
                        {
                            if (strPrinter == "Microsoft Print to PDF" || strPrinter == "Foxit Reader PDF Printer" ||
                                strPrinter == "Adobe PDF")
                            {
                                strPdfPrinter = strPrinter;
                                break;
                            }
                        }

                        if (!string.IsNullOrEmpty(strPdfPrinter))
                        {
                            DialogResult ePdfPrinterDialogResult = Program.ShowMessageBox(this,
                                                                                          string.Format(GlobalSettings.CultureInfo,
                                                                                                        await LanguageManager.GetStringAsync("Message_Viewer_FoundPDFPrinter"),
                                                                                                        strPdfPrinter),
                                                                                          await LanguageManager.GetStringAsync("MessageTitle_Viewer_FoundPDFPrinter"),
                                                                                          MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
                            switch (ePdfPrinterDialogResult)
                            {
                            case DialogResult.Cancel:
                            case DialogResult.Yes when await DoPdfPrinterShortcut(strPdfPrinter):
                                return;

                            case DialogResult.Yes:
                                Program.ShowMessageBox(this,
                                                       await LanguageManager.GetStringAsync(
                                                           "Message_Viewer_PDFPrinterError"));
                                break;
                            }
                        }
                    }
                    // This exception type is returned if PrinterSettings.InstalledPrinters fails
                    catch (Win32Exception)
                    {
                        //swallow this
                    }

                    // Save the generated output as PDF.
                    SaveFileDialog1.Filter = await LanguageManager.GetStringAsync("DialogFilter_Pdf") + '|' +
                                             await LanguageManager.GetStringAsync("DialogFilter_All");

                    SaveFileDialog1.Title = await LanguageManager.GetStringAsync("Button_Viewer_SaveAsPdf");

                    SaveFileDialog1.ShowDialog();
                    string strSaveFile = SaveFileDialog1.FileName;

                    if (string.IsNullOrEmpty(strSaveFile))
                    {
                        return;
                    }

                    if (!strSaveFile.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
                    {
                        strSaveFile += ".pdf";
                    }

                    if (!Directory.Exists(Path.GetDirectoryName(strSaveFile)) || !Utils.CanWriteToPath(strSaveFile))
                    {
                        Program.ShowMessageBox(this,
                                               string.Format(GlobalSettings.CultureInfo,
                                                             await LanguageManager.GetStringAsync(
                                                                 "Message_File_Cannot_Be_Accessed"), strSaveFile));
                        return;
                    }

                    if (!await Utils.SafeDeleteFileAsync(strSaveFile, true, token: _objGenericToken))
                    {
                        Program.ShowMessageBox(this,
                                               string.Format(GlobalSettings.CultureInfo,
                                                             await LanguageManager.GetStringAsync(
                                                                 "Message_File_Cannot_Be_Accessed"), strSaveFile));
                        return;
                    }

                    // No PDF printer found, let's use wkhtmltopdf

                    try
                    {
                        PdfDocument objPdfDocument = new PdfDocument
                        {
                            Html        = webViewer.DocumentText,
                            ExtraParams = new Dictionary <string, string>(8)
                            {
                                { "encoding", "UTF-8" },
                                { "dpi", "300" },
                                { "margin-top", "13" },
                                { "margin-bottom", "19" },
                                { "margin-left", "13" },
                                { "margin-right", "13" },
                                { "image-quality", "100" },
                                { "print-media-type", string.Empty }
                            }
                        };
                        PdfConvertEnvironment objPdfConvertEnvironment = new PdfConvertEnvironment
                        {
                            WkHtmlToPdfPath = Path.Combine(Utils.GetStartupPath, "wkhtmltopdf.exe")
                        };
                        PdfOutput objPdfOutput = new PdfOutput {
                            OutputFilePath = strSaveFile
                        };
                        await PdfConvert.ConvertHtmlToPdfAsync(objPdfDocument, objPdfConvertEnvironment, objPdfOutput);

                        if (!string.IsNullOrWhiteSpace(GlobalSettings.PdfAppPath))
                        {
                            Uri    uriPath   = new Uri(strSaveFile);
                            string strParams = GlobalSettings.PdfParameters
                                               .Replace("{page}", "1")
                                               .Replace("{localpath}", uriPath.LocalPath)
                                               .Replace("{absolutepath}", uriPath.AbsolutePath);
                            ProcessStartInfo objPdfProgramProcess = new ProcessStartInfo
                            {
                                FileName    = GlobalSettings.PdfAppPath,
                                Arguments   = strParams,
                                WindowStyle = ProcessWindowStyle.Hidden
                            };
                            objPdfProgramProcess.Start();
                        }
                    }
                    catch (Exception ex)
                    {
                        Program.ShowMessageBox(this, ex.ToString());
                    }
                }
                finally
                {
                    await objCursorWait.DisposeAsync();
                }
            }
            catch (OperationCanceledException)
            {
                //swallow this
            }
        }
コード例 #8
0
        private async Task GenerateXml(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

            try
            {
                await cmdExport.DoThreadSafeAsync(x => x.Enabled = false, token);

                await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token);

                try
                {
                    token.ThrowIfCancellationRequested();
                    string exportSheetPath = Path.Combine(Utils.GetStartupPath, "export", _strXslt + ".xsl");

                    XslCompiledTransform objXslTransform;
                    try
                    {
                        objXslTransform
                            = await XslManager
                              .GetTransformForFileAsync(exportSheetPath);   // Use the path for the export sheet.
                    }
                    catch (ArgumentException)
                    {
                        token.ThrowIfCancellationRequested();
                        string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt +
                                           Environment.NewLine;
                        Log.Debug(strReturn);
                        await SetTextToWorkerResult(strReturn, token);

                        return;
                    }
                    catch (PathTooLongException)
                    {
                        token.ThrowIfCancellationRequested();
                        string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt +
                                           Environment.NewLine;
                        Log.Debug(strReturn);
                        await SetTextToWorkerResult(strReturn, token);

                        return;
                    }
                    catch (UnauthorizedAccessException)
                    {
                        token.ThrowIfCancellationRequested();
                        string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt +
                                           Environment.NewLine;
                        Log.Debug(strReturn);
                        await SetTextToWorkerResult(strReturn, token);

                        return;
                    }
                    catch (XsltException ex)
                    {
                        token.ThrowIfCancellationRequested();
                        string strReturn = "Error attempting to load " + _strXslt + Environment.NewLine;
                        Log.Debug(strReturn);
                        Log.Error("ERROR Message = " + ex.Message);
                        strReturn += ex.Message;
                        await SetTextToWorkerResult(strReturn, token);

                        return;
                    }

                    token.ThrowIfCancellationRequested();

                    XmlWriterSettings objSettings = objXslTransform.OutputSettings?.Clone();
                    if (objSettings != null)
                    {
                        objSettings.CheckCharacters  = false;
                        objSettings.ConformanceLevel = ConformanceLevel.Fragment;
                    }

                    string strText;
                    using (MemoryStream objStream = new MemoryStream())
                    {
                        using (XmlWriter objWriter = objSettings != null
                                   ? XmlWriter.Create(objStream, objSettings)
                                   : Utils.GetXslTransformXmlWriter(objStream))
                        {
                            token.ThrowIfCancellationRequested();
                            await Task.Run(() => objXslTransform.Transform(_objCharacterXml, objWriter), token);
                        }

                        token.ThrowIfCancellationRequested();
                        objStream.Position = 0;

                        // Read in the resulting code and pass it to the browser.
                        using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true))
                            strText = await objReader.ReadToEndAsync();
                    }

                    token.ThrowIfCancellationRequested();
                    await SetTextToWorkerResult(strText, token);
                }
                finally
                {
                    await cmdExport.DoThreadSafeAsync(x => x.Enabled = true, token);

                    await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = true, token);
                }
            }
            finally
            {
                await objCursorWait.DisposeAsync();
            }
        }
コード例 #9
0
        private async Task DoXsltUpdate(CancellationToken token = default)
        {
            token.ThrowIfCancellationRequested();
            if (!_blnLoading)
            {
                if (_objCharacterXml != null)
                {
                    _strXslt = await cboXSLT.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString(), token);

                    if (!string.IsNullOrEmpty(_strXslt))
                    {
                        CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token);

                        try
                        {
                            token.ThrowIfCancellationRequested();
                            string strText = await LanguageManager.GetStringAsync("String_Generating_Data");

                            await txtText.DoThreadSafeAsync(x => x.Text = strText, token);

                            (bool blnSuccess, Tuple <string, string> strBoxText)
                                = await _dicCache.TryGetValueAsync(
                                      new Tuple <string, string>(_strExportLanguage, _strXslt), token);

                            token.ThrowIfCancellationRequested();
                            if (blnSuccess)
                            {
                                await txtText.DoThreadSafeAsync(x => x.Text = strBoxText.Item2, token);
                            }
                            else
                            {
                                CancellationTokenSource objNewSource = new CancellationTokenSource();
                                CancellationTokenSource objTemp
                                    = Interlocked.Exchange(ref _objXmlGeneratorCancellationTokenSource, objNewSource);
                                if (objTemp?.IsCancellationRequested == false)
                                {
                                    objTemp.Cancel(false);
                                    objTemp.Dispose();
                                }

                                try
                                {
                                    token.ThrowIfCancellationRequested();
                                }
                                catch (OperationCanceledException)
                                {
                                    Interlocked.CompareExchange(ref _objXmlGeneratorCancellationTokenSource, null,
                                                                objNewSource);
                                    objNewSource.Dispose();
                                    throw;
                                }

                                try
                                {
                                    if (_tskXmlGenerator?.IsCompleted == false)
                                    {
                                        await _tskXmlGenerator;
                                    }
                                }
                                catch (OperationCanceledException)
                                {
                                    // Swallow this
                                }

                                CancellationToken objToken = objNewSource.Token;
                                _tskXmlGenerator = _strXslt == "JSON"
                                    ? Task.Run(() => GenerateJson(objToken), objToken)
                                    : Task.Run(() => GenerateXml(objToken), objToken);
                            }
                        }
                        finally
                        {
                            await objCursorWait.DisposeAsync();
                        }
                    }
                }
                else
                {
                    token.ThrowIfCancellationRequested();
                    CancellationTokenSource objNewSource = new CancellationTokenSource();
                    CancellationTokenSource objTemp
                        = Interlocked.Exchange(ref _objCharacterXmlGeneratorCancellationTokenSource, objNewSource);
                    if (objTemp?.IsCancellationRequested == false)
                    {
                        objTemp.Cancel(false);
                        objTemp.Dispose();
                    }

                    try
                    {
                        token.ThrowIfCancellationRequested();
                    }
                    catch (OperationCanceledException)
                    {
                        Interlocked.CompareExchange(ref _objCharacterXmlGeneratorCancellationTokenSource, null,
                                                    objNewSource);
                        objNewSource.Dispose();
                        throw;
                    }

                    try
                    {
                        if (_tskCharacterXmlGenerator?.IsCompleted == false)
                        {
                            await _tskCharacterXmlGenerator;
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        // Swallow this
                    }

                    CancellationToken objToken = objNewSource.Token;
                    _tskCharacterXmlGenerator = Task.Run(() => GenerateCharacterXml(objToken), objToken);
                }
            }
        }