예제 #1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Create an annotation in response to an error returned by a check.
        /// The check calls this delegate whenever an error is found.
        /// </summary>
        /// <param name="args">Information about the potential inconsistency being reported</param>
        /// ------------------------------------------------------------------------------------
        public void RecordError(RecordErrorEventArgs args)
        {
            ScrCheckingToken firstToken = args.Tts.FirstToken as ScrCheckingToken;
            ScrCheckingToken lastToken  = args.Tts.LastToken as ScrCheckingToken;

            Debug.Assert(firstToken != null);
            Debug.Assert(lastToken != null);
            Debug.Assert(firstToken.Object == lastToken.Object);
            int    offset       = args.Tts.Offset;
            int    length       = args.Tts.Length;
            Guid   checkId      = args.CheckId;
            string formattedMsg = args.Tts.Message;

            // If the token is for a missing reference, then replace the token's
            // reference range with the missing reference range.
            if (args.Tts.MissingStartRef != null && !args.Tts.MissingStartRef.IsEmpty)
            {
                firstToken.m_startRef = new BCVRef(firstToken.MissingStartRef);
                firstToken.m_endRef   = new BCVRef(firstToken.MissingEndRef != null ?
                                                   firstToken.m_missingEndRef : firstToken.m_startRef);
            }

            int    bookNum   = firstToken.StartRef.Book;
            string citedText = args.Tts.Text;

            ScrBookAnnotations annotations =
                (ScrBookAnnotations)m_scr.BookAnnotationsOS[bookNum - 1];

            // key for the error with the same cited text and message at a particular reference.
            string errorLocKey = firstToken.StartRef.AsString + lastToken.EndRef.AsString +
                                 citedText + formattedMsg;
            // key for an error with the same cited text and message.
            string errorKey = checkId.ToString() + citedText + formattedMsg;

            if (CheckForPreviousInconsistency(firstToken, lastToken, citedText, offset, length, checkId, errorLocKey, errorKey))
            {
                return;
            }

            // NOTE: A maxIdenticalErrors value of -1 indicates that there is no maximum set.
            int maxIdenticalErrors = GetMaxIdenticalErrors(checkId);
            int errorCount         = m_errorCounts.GetValue(errorKey);

            // Check the number of times this same error has already been reported.
            // If the maximum allowed number of identical errors already has been reached then
            // we don't want to report the error as usual.
            if (errorCount == maxIdenticalErrors)
            {
                formattedMsg = GetExceededErrorMsg(checkId);
            }
            else if (errorCount > maxIdenticalErrors && maxIdenticalErrors > -1)
            {
                // We have exceeded the maximum allowed for this error, so don't write out an annotation.
                return;
            }

            m_errorCounts.IncrementError(errorKey);
            AddErrorAnnotation(citedText, offset, length, checkId, firstToken, lastToken, formattedMsg);
            m_bookChecksFailed[bookNum][checkId] = ScrCheckRunResult.Inconsistencies;
        }
예제 #2
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Initializes the scripture note import manager.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public static void Initialize(IScripture scr, int bookNum, string alternateRfcWsDir)
		{
			s_scr = scr;

			if (!string.IsNullOrEmpty(alternateRfcWsDir))
				s_alternateRfcWsDir = alternateRfcWsDir;

			CacheCheckIds();

			if (s_rfcWs == null)
				s_rfcWs = new RfcWritingSystem(s_scr.Cache, false);

			if (bookNum != s_prevBookNum)
			{
				s_prevBookNum = bookNum;
				s_annotationList = (ScrBookAnnotations)scr.BookAnnotationsOS[bookNum - 1];
				s_existingAnnotations = new Dictionary<ScrScriptureNote.ScrNoteKey, ScrScriptureNote>();

				foreach (ScrScriptureNote ann in s_annotationList.NotesOS)
					s_existingAnnotations[ann.Key] = ann;
			}
		}
예제 #3
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Implement CreateTestData, called by InMemoryFdoTestBase set up.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected override void CreateTestData()
		{
			m_mockedChooserDlg = new DynamicMock(typeof(ICmPossibilitySupplier));
			m_mockedDataAccess = new DynamicMock(typeof(IVwCacheDa));

			m_scrInMemoryCache.InitializeAnnotationDefs();
			m_scrInMemoryCache.InitializeScrAnnotationCategories();
			CreateTestUserView();

			// Create some Scripture annotations
			m_annotationsGen = (ScrBookAnnotations)m_scr.BookAnnotationsOS[0];
			ScrReference ref1 = new ScrReference(1, 1, 1, Paratext.ScrVers.English);
			ScrReference ref2 = new ScrReference(1, 1, 2, Paratext.ScrVers.English);
			ScrReference ref3 = new ScrReference(1, 1, 3, Paratext.ScrVers.English);

			// Insert notes for Genesis 1:1, 1:2, and 1:3
			m_note1 = m_annotationsGen.InsertNote(ref1, ref1, null, null, LangProject.kguidAnnConsultantNote);
			m_note2a = m_annotationsGen.InsertNote(ref2, ref2, null, null, LangProject.kguidAnnConsultantNote);
			m_note2b = m_annotationsGen.InsertNote(ref2, ref2, null, null, LangProject.kguidAnnConsultantNote);
			m_note3 = m_annotationsGen.InsertNote(ref3, ref3, null, null, LangProject.kguidAnnConsultantNote);

			m_note1.AnnotationTypeRA = m_inMemoryCache.m_consultantNoteDefn;
			m_note2a.AnnotationTypeRA = m_inMemoryCache.m_consultantNoteDefn;
			m_note2b.AnnotationTypeRA = m_inMemoryCache.m_translatorNoteDefn;
			m_note3.AnnotationTypeRA = m_inMemoryCache.m_translatorNoteDefn;

			m_note1.ResolutionStatus = NoteStatus.Open;
			m_note2a.ResolutionStatus = NoteStatus.Closed;
			m_note2b.ResolutionStatus = NoteStatus.Open;
			m_note3.ResolutionStatus = NoteStatus.Closed;

			m_note1.CategoriesRS.Append(m_inMemoryCache.m_categoryDiscourse);
			m_note2a.CategoriesRS.Append(m_inMemoryCache.m_categoryGrammar);
			m_note2b.CategoriesRS.Append(m_inMemoryCache.m_categoryGrammar_PronominalRef);
			m_note3.CategoriesRS.Append(m_inMemoryCache.m_categoryGrammar_PronominalRef_ExtendedUse);
			m_note3.CategoriesRS.Append(m_inMemoryCache.m_categoryDiscourse); // This note has 2 categories
		}
예제 #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Adds the error annotation to the database.
        /// </summary>
        /// <param name="citedText">The cited text.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="length">The length.</param>
        /// <param name="checkId">The Scripture error checking id.</param>
        /// <param name="firstToken">The first token.</param>
        /// <param name="lastToken">The last token.</param>
        /// <param name="formattedMsg">The formatted error message.</param>
        /// ------------------------------------------------------------------------------------
        private void AddErrorAnnotation(string citedText, int offset, int length, Guid checkId,
                                        ScrCheckingToken firstToken, ScrCheckingToken lastToken, string formattedMsg)
        {
            ScrBookAnnotations annotations =
                (ScrBookAnnotations)m_scr.BookAnnotationsOS[firstToken.StartRef.Book - 1];

            StTxtParaBldr quote      = SetCitedText(citedText, firstToken.Ws);
            StTxtParaBldr discussion = SetErrorMessage(formattedMsg);

            bool        fNewTransaction = false;
            string      sSavePointName  = string.Empty;
            IOleDbEncap dbAccess        = m_cache.DatabaseAccessor;

            if (dbAccess != null)
            {
                // Open a transaction or set a save point in case there is a problem with the DB server.
                // If there is a problem adding the annotation or setting the type, this
                // transaction will be rolled back rather than not leaving the annotation
                // only partly initialized.
                if (!dbAccess.IsTransactionOpen())
                {
                    dbAccess.BeginTrans();
                    fNewTransaction = true;
                }
                else
                {
                    dbAccess.SetSavePoint(out sSavePointName);
                }
            }

            try
            {
                IScrScriptureNote note =
                    annotations.InsertErrorAnnotation(firstToken.StartRef, lastToken.EndRef,
                                                      firstToken.Object, lastToken.Object, checkId, quote, discussion);

                note.BeginOffset = firstToken.ParaOffset + offset;
                note.EndOffset   = note.BeginOffset + length;
                note.Flid        = firstToken.Flid;
                // REVIEW: Should we even be setting the WsSelector for anything except picture captions?
                note.WsSelector = m_cache.DefaultVernWs;
            }
            catch
            {
                // Rollback inserted note
                Debug.Assert(dbAccess != null);
                if (dbAccess != null)
                {
                    if (fNewTransaction)
                    {
                        dbAccess.RollbackTrans();
                    }
                    else
                    {
                        dbAccess.RollbackSavePoint(sSavePointName);
                    }
                }
                throw;
            }
            if (fNewTransaction)
            {
                dbAccess.CommitTrans();
            }
        }
예제 #5
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Runs the check.
        /// </summary>
        /// <param name="check">The check.</param>
        /// ------------------------------------------------------------------------------------
        public void RunCheck(IScriptureCheck check)
        {
            if (m_bookChecksFailed == null)
            {
                m_bookChecksFailed = new Dictionary <int, Dictionary <Guid, ScrCheckRunResult> >();
            }

            if (m_pendingCheckErrors == null)
            {
                m_pendingCheckErrors = new Dictionary <int, Dictionary <Guid, Dictionary <string, List <ScrScriptureNote> > > >();
            }

            Dictionary <Guid, Dictionary <string, List <ScrScriptureNote> > > pendingErrorsForBook;
            int bookNum = m_bookBeingChecked.CanonicalNum;

            if (!m_pendingCheckErrors.TryGetValue(bookNum, out pendingErrorsForBook))
            {
                pendingErrorsForBook          = new Dictionary <Guid, Dictionary <string, List <ScrScriptureNote> > >();
                m_pendingCheckErrors[bookNum] = pendingErrorsForBook;
            }
            Dictionary <string, List <ScrScriptureNote> > pendingErrorsForCheck =
                new Dictionary <string, List <ScrScriptureNote> >();

            pendingErrorsForBook[check.CheckId] = pendingErrorsForCheck;

            ScrBookAnnotations annotations =
                (ScrBookAnnotations)m_scr.BookAnnotationsOS[bookNum - 1];

            // Find previously created error annotions for the current book and check.
            foreach (ScrScriptureNote ann in annotations.NotesOS)
            {
                BCVRef beginRef = new BCVRef(ann.BeginRef);
                // ENHANCE, use a smarter algorithm to search for the start of the annotations for this book
                if (beginRef.Book == bookNum && ann.AnnotationTypeRA.Guid == check.CheckId)
                {
                    BCVRef    endRef         = new BCVRef(ann.EndRef);
                    StTxtPara quotePara      = (StTxtPara)ann.QuoteOA.ParagraphsOS[0];
                    StTxtPara discussionPara = (StTxtPara)ann.DiscussionOA.ParagraphsOS[0];
                    string    key            = beginRef.AsString + endRef.AsString + quotePara.Contents.Text +
                                               discussionPara.Contents.Text;

                    List <ScrScriptureNote> errors;
                    if (!pendingErrorsForCheck.TryGetValue(key, out errors))
                    {
                        errors = new List <ScrScriptureNote>();
                        pendingErrorsForCheck[key] = errors;
                    }
                    errors.Add(ann);
                }
            }

            if (!m_bookChecksFailed.ContainsKey(bookNum))
            {
                m_bookChecksFailed[bookNum] = new Dictionary <Guid, ScrCheckRunResult>();
            }

            // Before running the check, reset the check result for this book and check.
            // This is like initializing our check result to green bar in an NUnit test.
            // As the check is running, that status may get changed to "Inconsistencies"
            // (red bar) or "IgnoredInconsistencies" (yellow bar).
            m_bookChecksFailed[bookNum][check.CheckId] = ScrCheckRunResult.NoInconsistencies;

            // Create a hash table for this check to tally how many times each unique error is generated.
            if (m_errorCounts != null)
            {
                m_errorCounts.Clear();
                m_errorCounts = null;
            }
            m_errorCounts = new ErrorInventory();

            // Run the Scripture check.
            check.Check(TextTokens(), RecordError);

            // Find a check history record for the check just run.
            // If one cannot be found, then create a new one.
            ScrCheckRun checkRun = null;

            foreach (ScrCheckRun scrChkRun in annotations.ChkHistRecsOC)
            {
                if (scrChkRun.CheckId == check.CheckId)
                {
                    checkRun = scrChkRun;
                    break;
                }
            }

            if (checkRun == null)
            {
                checkRun = new ScrCheckRun();
                annotations.ChkHistRecsOC.Add(checkRun);
                checkRun.CheckId = check.CheckId;
            }

            checkRun.RunDate = DateTime.Now;
            checkRun.Result  = m_bookChecksFailed[bookNum][check.CheckId];

            // Should this be initialized to certain capacity?
            Set <int> obsoleteErrorIds = new Set <int>();

            foreach (List <ScrScriptureNote> obsoleteErrors in pendingErrorsForCheck.Values)
            {
                foreach (ScrScriptureNote obsoleteError in obsoleteErrors)
                {
                    //annotations.NotesOS.Remove(obsoleteError);
                    obsoleteErrorIds.Add(obsoleteError.Hvo);
                }
            }

            CmObject.DeleteObjects(obsoleteErrorIds, m_cache);
        }
예제 #6
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Writes the list of annotations to the specified cache.
		/// </summary>
		/// <param name="scr">The scripture.</param>
		/// <param name="styleSheet">The style sheet.</param>
		/// <returns>The created annotation</returns>
		/// ------------------------------------------------------------------------------------
		internal IScrScriptureNote WriteToCache(IScripture scr, FwStyleSheet styleSheet)
		{
			if (AnnotationTypeGuid == Guid.Empty.ToString())
				return null;

			Debug.Assert(scr.Cache == styleSheet.Cache, "This can't end well");
			int bookNum = BeginScrBCVRef.Book;
			IScrBookAnnotations sba = scr.BookAnnotationsOS[bookNum - 1];

			if (sba == null)
			{
				sba = new ScrBookAnnotations();
				scr.BookAnnotationsOS.InsertAt(sba.Hvo, bookNum - 1);
			}

			IScrScriptureNote scrNote = FindOrCreateAnnotation(styleSheet);

			scrNote.BeginOffset = BeginOffset;
			scrNote.EndOffset = EndOffset;
			scrNote.ResolutionStatus = ResolutionStatus;

			if (m_createdDate > DateTime.MinValue)
				scrNote.DateCreated = m_createdDate;

			if (m_modifiedDate > DateTime.MinValue)
				scrNote.DateModified = m_modifiedDate;

			if (m_resolvedDate > DateTime.MinValue)
				scrNote.DateResolved = m_resolvedDate;

			foreach (XmlNoteCategory category in Categories)
				category.WriteToCache(scrNote);

			foreach (XmlNoteResponse response in Responses)
				response.WriteToCache(scrNote, styleSheet);

			//((Scripture)scr).AttachAnnotatedObjects(bookNum, scrNote);
			if (scrNote.BeginObjectRA == null && scrNote.CitedTextTss != null)
				AttachAnnotatedObjects(scr, bookNum, scrNote);

			return scrNote;
		}
예제 #7
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Cleanups the scripture note import manager.
		/// </summary>
		/// ------------------------------------------------------------------------------------
		public static void Cleanup()
		{
			s_existingAnnotations = null;
			s_checkNamesToGuids = null;
			s_annotationList = null;
			s_rfcWs = null;
			s_prevBookNum = 0;
			s_scr = null;
		}
예제 #8
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Add a collection of annotations for Genesis (in a real DB, this would be done for
		/// all 66 books in TeScrInitializer).
		/// </summary>
		/// ------------------------------------------------------------------------------------
		protected override void CreateTestData()
		{
			ScrBookAnnotations notes = new ScrBookAnnotations();
			m_scr.BookAnnotationsOS.Append(notes);
			m_notesEditingHelper = new DummyNotesEditingHelper(Cache, null);
			m_scrInMemoryCache.InitializeAnnotationDefs();
		}
예제 #9
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Delete the current annotation.
		/// </summary>
		/// <returns>true if we delete an annotation, otherwise false</returns>
		/// ------------------------------------------------------------------------------------
		public bool OnEditDeleteNote(object args)
		{
			CheckDisposed();

			if (FwEditingHelper == null || FwEditingHelper.CurrentSelection == null)
				return false;

			SelectionHelper helper = FwEditingHelper.CurrentSelection;
			int iAnn = -1;
			int hvoAnn = 0;
			ScrBookAnnotations sba = null;
			foreach (SelLevInfo info in helper.LevelInfo)
			{
				if (info.tag == ((FwRootSite)ActiveView).GetVirtualTagForFlid(Scripture.ScriptureTags.kflidBookAnnotations))
					sba = new ScrBookAnnotations(m_cache, info.hvo);
				else if (info.tag == ((FwRootSite)ActiveView).GetVirtualTagForFlid(ScrBookAnnotations.ScrBookAnnotationsTags.kflidNotes))
				{
					hvoAnn = info.hvo;
					iAnn = info.ihvo;
				}
			}
			if (sba == null || hvoAnn == 0) // Didn't find a deletable note... weird!
				return false;

			string sUndo, sRedo;
			TeResourceHelper.MakeUndoRedoLabels("kstidDeleteAnnotation", out sUndo, out sRedo);

			using (UndoTaskHelper undoTaskHelper = new UndoTaskHelper(Cache.MainCacheAccessor,
					   null, sUndo, sRedo, false))
			{
				m_dataEntryView.ResetPrevNoteHvo();
				sba.NotesOS.Remove(hvoAnn);
			}

			return true;
		}
예제 #10
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Sets the current book, particularly picking the right set of annotations
		/// to add new ones to. Also (and more conspicuously) ends the current Undo task
		/// and makes a new one for importing the new book. Should therefore be called
		/// BEFORE setting up the Undo action for the creation of the book.
		/// </summary>
		/// <param name="nCanonicalBookNumber">The canonical book number.</param>
		/// <returns>The action handler</returns>
		/// ------------------------------------------------------------------------------------
		private IActionHandler SetCurrentBookInternal(int nCanonicalBookNumber)
		{
			// We temporarily un-suppress our action handler long enough to get it so we can
			// grab a local copy.
			m_suppressor.Dispose();
			m_suppressor = null;
			IActionHandler actionHandler = m_cache.ActionHandlerAccessor;
			m_suppressor = new SuppressSubTasks(m_cache);

			if ((m_importedSavedVersion != null && m_importedSavedVersion.BooksOS.Count > 0) ||
				(m_savedVersion != null && m_savedVersion.BooksOS.Count > 0))
			{
				// We want a new undo task for each new book, except the first one
				actionHandler.EndOuterUndoTask();
			}

			// No need to use localizable string from resources because the user will never
			// see these labels because we collapse to a single undo task when the import
			// completes.
			actionHandler.BeginUndoTask("Undo Import Book " + nCanonicalBookNumber,
				"Redo Import Book " + nCanonicalBookNumber);

			m_annotations = (ScrBookAnnotations)m_scr.BookAnnotationsOS[nCanonicalBookNumber - 1];

			return actionHandler;
		}