public override void AddToDatabase(FdoCache cache) { CheckDisposed(); if (m_fInDatabase) return; // It's already in the database, so nothing more can be done. cache.BeginUndoTask(MGAStrings.ksUndoCreateInflectionFeature, MGAStrings.ksRedoCreateInflectionFeature); m_featDefn = FsFeatureSystem.AddFeatureAsXml(cache, m_node); cache.EndUndoTask(); }
public override void AddToDatabase(FdoCache cache) { CheckDisposed(); if (m_fInDatabase) return; // It's already in the database, so nothing more can be done. string sType = XmlUtils.GetManditoryAttributeValue(m_node, "type"); if (sType == "feature") { cache.BeginUndoTask(MGAStrings.ksUndoCreatePhonologicalFeature, MGAStrings.ksRedoCreatePhonologicalFeature); ILangProject lp = cache.LangProject; IFsFeatureSystem featsys = lp.PhFeatureSystemOA as IFsFeatureSystem; // Since phonological features in the chooser only have features and no values, // we need to create the positive and negative value nodes string sName = XmlUtils.GetManditoryAttributeValue(m_node, "id"); const string sTemplate = "<item id='v{0}Positive' type='value'><abbrev ws='en'>+</abbrev><term ws='en'>positive</term>" + "<fs id='v{0}PositiveFS' type='Phon'><f name='{0}'><sym value='+'/></f></fs></item>" + "<item id='v{0}Negative' type='value'><abbrev ws='en'>-</abbrev><term ws='en'>negative</term>" + "<fs id='v{0}NegativeFS' type='Phon'><f name='{0}'><sym value='-'/></f></fs></item>"; StringBuilder sb = new StringBuilder(); sb.AppendFormat(sTemplate, sName.Substring(1)); m_node.InnerXml += sb.ToString(); // have to use a ndw document or, for some odd reason, it keeps on using an old value and not the new one... XmlDocument doc = new XmlDocument(); doc.LoadXml(m_node.OuterXml); // add positive value; note that the FsFeatDefn will be the same for both XmlNode valueNode = doc.SelectSingleNode("//item[contains(@id,'Positive')]"); m_featDefn = FsFeatureSystem.AddFeatureAsXml(cache, featsys, valueNode); // add negative value valueNode = doc.SelectSingleNode("//item[contains(@id,'Negative')]"); m_featDefn = FsFeatureSystem.AddFeatureAsXml(cache, featsys, valueNode); cache.EndUndoTask(); } }
const int ktagMinVp = 0x7f000000; // copied from VwCacheDa.h, mimimum value for assigned virtual props. /// <summary> /// We implement this to record modify times. /// </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 (m_fModifyChangeInProgress) // ignore PropChanged on the DateModified property! { return; } // Typically an Undo will restore the modify time to what it was before the // main change. We don't want to reverse that by recording the time of the Undo! // Note that there is one pathological scenario: // t1: make a change. // t2: undo the change. // t3: export all changed records (since before t1). // t4: redo the change. Record appears to have been modified at time t2. // t5: export all changed records (since t3). // If this was the only change to the record, it is not part of either export, // and the change might be lost. // To prevent this, I think the 'export changed records' function should clear // the Undo stack. if (m_cache.ActionHandlerAccessor != null && m_cache.ActionHandlerAccessor.IsUndoOrRedoInProgress) { return; } if (tag < 0 || tag >= ktagMinVp) { return; // phony or virtual properties, not real changes (e.g., different filter applied, or selection moving in browse). } try { DateTime dtNow = DateTime.Now; int hvoMajor = 0; // hvo of the 'major' object that has the DateModified property. if (SameMinute(dtNow, m_currentMinute)) { // We can use our Dictionary if (m_recentMods.ContainsKey(hvo)) { hvoMajor = m_recentMods[hvo]; } } else { ResetDelay(); } int flidModify = 0; if (hvoMajor == 0) { for (int hvoCandidate = hvo; hvoCandidate != 0; hvoCandidate = m_cache.GetOwnerOfObject(hvoCandidate)) { // We assume that this is a dummy object at this point and GetClassOfObject // only accepts real objects. Since it's a dummy object, changes should never // affect the modify time of a real object. Maybe at some point we can get an // interface method to check for dummy objects. if (hvoCandidate < 0) { return; } int clid = m_cache.GetClassOfObject(hvoCandidate); if (clid == 0) { return; // maybe a deleted object, no good to us, we can't record modify time. } flidModify = (int)m_mdc.GetFieldId2((uint)clid, "DateModified", true); if (flidModify != 0) { hvoMajor = hvoCandidate; break; } } if (hvoMajor == 0) { return; // found no owner with DateCreated property. } m_recentMods[hvo] = hvoMajor; // lets us find it fast if modified again soon. } else { // We need to set flidModify! int clid = m_cache.GetClassOfObject(hvoMajor); if (clid != 0) { flidModify = (int)m_mdc.GetFieldId2((uint)clid, "DateModified", true); } } if (flidModify == 0) { return; // can't set the time prop without a field... } DateTime oldModifyTime = m_cache.GetTimeProperty(hvoMajor, flidModify); // If we already noted a modify time in the current minute, don't do it again. // This is intended to keep down the overhead of recording modify times for frequently // modified objects. if (SameMinute(oldModifyTime, dtNow)) { //Trace.TraceInformation("New Modify Time ({0}) for {1} is same minute as the old ({2}).\n", // dtNow, hvoMajor, oldModifyTime); return; } // if (m_currentMinute != null && // m_currentMinute.Date == dtNow.Date && m_currentMinute.Hour = dtNow.Hour && m_currentMinute.Minute == dtNow.Minute) // return; // Set the modify time. If possible tack this on to the last Undo task (or the current one, if a // transaction is open). if (m_cache.ActionHandlerAccessor != null && m_cache.VwOleDbDaAccessor != null && ((m_cache.DatabaseAccessor != null && m_cache.DatabaseAccessor.IsTransactionOpen()) || m_cache.CanUndo)) { m_cache.ContinueUndoTask(); m_cache.SetTimeProperty(hvoMajor, flidModify, dtNow); m_cache.EndUndoTask(); } else { // We don't have an Undo task to append to, so somehow a Save has occurred // in the midst of the operation that caused the time stamp modification. // If we make an empty undo task, the user will typically have no idea what // could be undone, and will be confused. Best to make it impossible to // undo the timestamp change also. using (new SuppressSubTasks(m_cache)) { m_cache.SetTimeProperty(hvoMajor, flidModify, dtNow); } } //Trace.TraceInformation("Setting new Modify Time ({0}) for {1}\n", // dtNow, hvoMajor); } finally { m_fModifyChangeInProgress = false; } }
internal static CmObjectUi DefaultCreateNewUiObject(uint classId, int hvoOwner, int flid, int insertionPosition, FdoCache cache) { CmObjectUi newUiObj; cache.BeginUndoTask(FdoUiStrings.ksUndoInsert, FdoUiStrings.ksRedoInsert); int newHvo = cache.CreateObject((int)classId, hvoOwner, flid, insertionPosition); newUiObj = CmObjectUi.MakeUi(cache, newHvo, classId); cache.EndUndoTask(); cache.MainCacheAccessor.PropChanged(null, (int)PropChangeType.kpctNotifyAll, hvoOwner, flid, insertionPosition, 1, 0); return newUiObj; }
public void AddToDatabase(FdoCache cache, ICmPossibilityList posList, MasterCategory parent, IPartOfSpeech subItemOwner) { CheckDisposed(); if (m_pos != null) return; // It's already in the database, so nothing more can be done. cache.BeginUndoTask(LexTextControls.ksUndoCreateCategory, LexTextControls.ksRedoCreateCategory); int newOwningFlid; int insertLocation; int newOwner = DeterminePOSLocationInfo(subItemOwner, parent, posList, out newOwningFlid, out insertLocation); ILgWritingSystemFactory wsf = cache.LanguageWritingSystemFactoryAccessor; Debug.Assert(m_pos != null); if (m_node == null) { // should not happen, but just in case... we still get something useful m_pos.Name.SetAlternative(m_term, wsf.GetWsFromStr(m_termWs)); m_pos.Abbreviation.SetAlternative(m_abbrev, wsf.GetWsFromStr(m_abbrevWs)); m_pos.Description.SetAlternative(m_def, wsf.GetWsFromStr(m_defWs)); } else { SetContentFromNode(cache, "abbrev", false, m_pos.Abbreviation); SetContentFromNode(cache, "term", true, m_pos.Name); SetContentFromNode(cache, "def", false, m_pos.Description); } m_pos.CatalogSourceId = m_id; // Need a PropChanged, since it isn't done in the 'Append' for some reason. cache.PropChanged(null, PropChangeType.kpctNotifyAll, newOwner, newOwningFlid, insertLocation, 1, 0); cache.EndUndoTask(); }