Example #1
0
        /// <summary>
        /// Handle a change by adding a record to the database (only if the
        /// change does not arise directly out of processing a sync record from elsewhere).
        /// </summary>
        /// <param name="hvo"></param>
        /// <param name="tag"></param>
        /// <param name="ivMin"></param>
        /// <param name="cvIns"></param>
        /// <param name="cvDel"></param>
        public void PropChanged(int hvo, int tag, int ivMin, int cvIns, int cvDel)
        {
            CheckDisposed();
            if (hvo == m_hvoIgnore && tag == m_flidIgnore)
            {
                return;
            }
            if (tag < 0)
            {
                return;                 // common for fake properties
            }
            // If it's a virtual property we don't want to make a sync record.
            IVwCacheDa        cda = m_cache.MainCacheAccessor as IVwCacheDa;
            IVwVirtualHandler vh  = cda.GetVirtualHandlerId(tag);

            if (vh != null)
            {
                return;
            }
            // (CLE-76) Topics List Editor needs to be sync'd with the database when
            // we make certain changes to possibility lists, especially structural ones
            // like adding/removing/moving/promoting possibilities. The simplest thing
            // to do for now, is to indicate a full refresh is needed when any of these
            // properties are being altered (even if it turns out to be minor).
            SyncMsg msg = SyncMsg.ksyncSimpleEdit;

            if (tag == (int)CmPossibility.CmPossibilityTags.kflidName ||
                tag == (int)CmPossibility.CmPossibilityTags.kflidAbbreviation ||
                tag == (int)CmPossibilityList.CmPossibilityListTags.kflidPossibilities ||
                tag == (int)CmPossibility.CmPossibilityTags.kflidSubPossibilities)
            {
                // NOTE: assume that apps that watch for ksyncFullRefresh will only
                // refresh once, and not multiple times if multiple refreshes get posted.
                // This is how Topic List Editor currently behaves.
                msg = SyncMsg.ksyncFullRefresh;
            }
            m_cache.StoreSync(m_appGuid, new SyncInfo(msg, hvo, tag));
        }
Example #2
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Cycle through the applications main windows and synchronize them with database
		/// changes.
		/// </summary>
		/// <param name="sync">synchronization information record</param>
		/// <param name="cache">database cache</param>
		/// <returns>false if a refreshall was performed or presync failed; this suppresses
		/// subsequent sync messages. True to continue processing.</returns>
		/// ------------------------------------------------------------------------------------
		public virtual bool Synchronize(SyncInfo sync, FdoCache cache)
		{
			CheckDisposed();

			if (m_suppressedCaches.ContainsKey(cache))
			{
				Queue<SyncInfo> messages = m_suppressedCaches[cache].Queue;
				if (!messages.Contains(sync))
					messages.Enqueue(sync);
				return true;
			}

			cache.StoreSync(SyncGuid, sync);

			if (sync.msg == SyncMsg.ksyncFullRefresh || sync.msg == SyncMsg.ksyncCustomField)
			{
				RefreshAllViews(cache);
				return false;
			}

			foreach (IFwMainWnd wnd in MainWindows)
			{
				if (wnd.Cache == cache && !wnd.PreSynchronize(sync))
					return false;
			}

			if (sync.msg == SyncMsg.ksyncWs)
			{
				// REVIEW TeTeam: AfLpInfo::Synchronize calls AfLpInfo::FullRefresh, which
				// clears the cache, loads the styles, loads ws and updates wsf, load project
				// basics, updates external link root, load overlays and refreshes possibility
				// lists. I don't think we need to do any of these here.
				RefreshAllViews(cache);
				return false;
			}
			else if (sync.msg == SyncMsg.ksyncPromoteEntry)
			{
				// Review: Write code here to deal with this case. Look at
				// AfLpInfo::Syncronize to see what's necessary.
				// This would be relevant to an application that uses subentries (like Data Notebook--
				// if it used FwApp).
			}
			else if (sync.msg == SyncMsg.ksyncSimpleEdit)
			{
				// Use the UpdatePropIfCached method to update anything that changed that we care about.
				// Todo: need to get Synchronize called for each new syncinfo in DB on window activate.
				IVwOleDbDa odd = cache.VwOleDbDaAccessor;
				int hvo = sync.hvo;
				int flid = sync.flid;
				FieldType iType = cache.GetFieldType(flid);

				switch(iType)
				{
					case FieldType.kcptMultiString:
					case FieldType.kcptMultiUnicode:
					case FieldType.kcptMultiBigString:
					case FieldType.kcptMultiBigUnicode:
						// Try all active WS to see if cached. (Pathologically, if some wss are used for both,
						// they will be updated twice.)
						foreach (int ws in cache.LangProject.VernWssRC.HvoArray)
							odd.UpdatePropIfCached(hvo, flid, (int)iType, ws);
						foreach (int ws in cache.LangProject.AnalysisWssRC.HvoArray)
							odd.UpdatePropIfCached(hvo, flid, (int)iType, ws);
						// This will usually prevent a double-update; pathologically, one might still happen
						// if the user ws is in the analysis or vernacular lists but is not the first analysis one.
						if (cache.DefaultUserWs != cache.DefaultAnalWs)
							odd.UpdatePropIfCached(hvo, flid, (int)iType, cache.DefaultUserWs);
						break;
					case 0:
						// This is very rare but possible.  Do nothing since kcptNull is not a real data
						// type, hence cannot have any data.
						break;
					default:
						odd.UpdatePropIfCached(hvo, flid, (int)iType, 0);
						break;
				}
				return true;
			}

			foreach (IFwMainWnd wnd in MainWindows)
			{
				if (wnd.Cache == cache && !wnd.Synchronize(sync))
				{
					// The window itself was not able to process the message successfully;
					// play safe and refresh everything
					RefreshAllViews(cache);
					return false;
				}
			}

			return true;
		}