Example #1
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Check to make sure all of the file encodings are valid for importing.
		/// </summary>
		/// <returns><c>true</c> if all files have valid encodings<c>false</c> otherwise</returns>
		/// ------------------------------------------------------------------------------------
		public bool FileEncodingsAreValid()
		{
			CheckDisposed();

			if (ScrListView.Items.Count == 0)
				return false;

			// Verify that the files all have supported encodings
			List<Encoding> supportedEncodings = new List<Encoding>(4);
			supportedEncodings.Add(Encoding.ASCII);
			supportedEncodings.Add(Encoding.UTF8);
			supportedEncodings.Add(Encoding.BigEndianUnicode);
			supportedEncodings.Add(Encoding.Unicode);

			foreach (ListView lv in new ListView[] {ScrListView, BtListView, NotesListView})
			{
				foreach(ListViewItem lvi in lv.Items)
				{
					ScrImportFileInfo fileInfo = (ScrImportFileInfo)lvi.Tag;

					if (fileInfo.IsReadable && !supportedEncodings.Contains(fileInfo.FileEncoding))
					{
						string message = string.Format(TeResourceHelper.GetResourceString("kstidUnsupportedEncoding"),
							fileInfo.FileName, fileInfo.FileEncoding.EncodingName);

						DisplayMessageBox(message);
						return false;
					}
				}
			}
			return true;
		}
Example #2
0
		/// <summary>
		///
		/// </summary>
		/// <param name="argument">The xCore Command object.</param>
		/// <returns>true</returns>
		public bool OnAddApprovedAnalysis(object argument)
		{
			var mainWnd = (FwXWindow)m_dataEntryForm.FindForm();
			using (EditMorphBreaksDlg dlg = new EditMorphBreaksDlg(mainWnd.Mediator.HelpTopicProvider))
			{
				IWfiWordform wf = Wordform;
				if (wf == null)
					return true;
				ITsString tssWord = Wordform.Form.BestVernacularAlternative;
				string morphs = tssWord.Text;
				var cache = Cache;
				dlg.Initialize(tssWord, morphs, cache.MainCacheAccessor.WritingSystemFactory,
					cache, m_dataEntryForm.Mediator.StringTbl, m_dataEntryForm.StyleSheet);
				// Making the form active fixes problems like LT-2619.
				// I'm (RandyR) not sure what adverse impact might show up by doing this.
				mainWnd.Activate();
				if (dlg.ShowDialog(mainWnd) == DialogResult.OK)
				{
					morphs = dlg.GetMorphs().Trim();
					if (morphs.Length == 0)
						return true;

					string[] prefixMarkers = MorphServices.PrefixMarkers(cache);
					string[] postfixMarkers = MorphServices.PostfixMarkers(cache);

					List<string> allMarkers = new List<string>();
					foreach (string s in prefixMarkers)
					{
						allMarkers.Add(s);
					}

					foreach (string s in postfixMarkers)
					{
						if (!allMarkers.Contains(s))
							allMarkers.Add(s);
					}
					allMarkers.Add(" ");

					string[] breakMarkers = new string[allMarkers.Count];
					for (int i = 0; i < allMarkers.Count; ++i)
						breakMarkers[i] = allMarkers[i];

					string fullForm = SandboxBase.MorphemeBreaker.DoBasicFinding(morphs, breakMarkers, prefixMarkers, postfixMarkers);

					var command = (Command) argument;
					UndoableUnitOfWorkHelper.Do(command.UndoText, command.RedoText, cache.ActionHandlerAccessor,
						() =>
							{
								IWfiAnalysis newAnalysis = Cache.ServiceLocator.GetInstance<IWfiAnalysisFactory>().Create();
								Wordform.AnalysesOC.Add(newAnalysis);
								newAnalysis.ApprovalStatusIcon = 1; // Make it human approved.
								int vernWS = TsStringUtils.GetWsAtOffset(tssWord, 0);
								foreach (string morph in fullForm.Split(Unicode.SpaceChars))
								{
									if (morph != null && morph.Length != 0)
									{
										IWfiMorphBundle mb = cache.ServiceLocator.GetInstance<IWfiMorphBundleFactory>().Create();
										newAnalysis.MorphBundlesOS.Add(mb);
										mb.Form.set_String(vernWS, Cache.TsStrFactory.MakeString(morph, vernWS));
									}
								}
							});
				}
			}
			return true;
		}
Example #3
0
		private void m_btnDuplicate_Click(object sender, EventArgs e)
		{
			Debug.Assert(m_current.Level > 0);
			StoreNodeData();	// Ensure duplicate has current data.
			LayoutTreeNode ltnDup = (LayoutTreeNode)m_current.Clone();
			ltnDup.IsDuplicate = true;
			// Generate a unique label to identify this as the n'th duplicate in the list.
			List<string> rgsLabels = new List<string>();
			string sBaseLabel = null;
			for (int i = 0; i < m_current.Parent.Nodes.Count; ++i)
			{
				LayoutTreeNode ltn = (LayoutTreeNode)m_current.Parent.Nodes[i];
				if (ltn.Configuration == m_current.Configuration &&
					ltn.LayoutName == m_current.LayoutName &&
					ltn.PartName == m_current.PartName)
				{
					rgsLabels.Add(ltn.Label);
					if (!ltn.IsDuplicate)
						sBaseLabel = ltn.Label;
				}
			}
			if (sBaseLabel == null)
				sBaseLabel = m_current.Label;
			int cDup = 1;
			string sLabel = String.Format("{0} ({1})", sBaseLabel, cDup);
			while (rgsLabels.Contains(sLabel))
			{
				++cDup;
				sLabel = String.Format("{0} ({1})", sBaseLabel, cDup);
			}
			ltnDup.Label = sLabel;		// sets Text as well.
			string sDup = ltnDup.DupString;
			if (String.IsNullOrEmpty(sDup))
				sDup = cDup.ToString();
			else
				sDup = String.Format("{0}-{1}", sDup, cDup);
			ltnDup.DupString = sDup;
			int idx = m_current.Index;
			m_current.Parent.Nodes.Insert(idx + 1, ltnDup);
			m_tvParts.SelectedNode = ltnDup;
		}
		public override void AddItem(int hvoNew)
		{
			CheckDisposed();

			List<int> lexemes = new List<int>();
			ILexEntryRef ler = m_obj as ILexEntryRef;
			if (m_flid == (int)LexEntryRef.LexEntryRefTags.kflidComponentLexemes)
				lexemes.AddRange(ler.ComponentLexemesRS.HvoArray);
			else if (m_flid == (int)LexEntryRef.LexEntryRefTags.kflidPrimaryLexemes)
				lexemes.AddRange(ler.PrimaryLexemesRS.HvoArray);
			// don't add a duplicate items.
			if (!lexemes.Contains(hvoNew))
			{
				lexemes.Add(hvoNew);
				SetItems(lexemes);
			}
		}
Example #5
0
		protected virtual void ComputeValue(List<ICmObject> chosenObjs, int hvoItem, out List<ICmObject> oldVals, out List<ICmObject> newVal)
		{
			int hvoReal;
			// Check whether we can actually compute values for this item.  If not,
			// just return a pair of empty lists.  (See LT-11016 and LT-11357.)
			if (!CanActuallyComputeValuesFor(hvoItem, out hvoReal))
			{
				oldVals = new List<ICmObject>();
				newVal = oldVals;
				return;
			}

			oldVals = GetOldVals(hvoReal);
			newVal = chosenObjs;

			if (m_fRemove)
			{
				newVal = oldVals; // by default no change in remove mode.
				if (oldVals.Count > 0)
				{
					var newValues = new List<ICmObject>(oldVals);
					foreach (ICmObject obj in chosenObjs)
					{
						if (newValues.Contains(obj))
							newValues.Remove(obj);
					}
					newVal = newValues;
				}
			}
			else if (!m_fReplace && oldVals.Count != 0)
			{
				// Need to handle as append.
				if (Atomic)
					newVal = oldVals; // can't append to non-empty atomic value
				else
				{
					var newValues = new List<ICmObject>(oldVals);
					foreach (ICmObject obj in chosenObjs)
					{
						if (!newValues.Contains(obj))
							newValues.Add(obj);
					}
					newVal = newValues;
				}
			}
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Loads into the grid, the checking errors for the specified checks.
		/// </summary>
		/// <param name="selectedCheckIds">The list of checkIds for which to show results.
		/// When this is null, results for all the checks are shown.</param>
		/// ------------------------------------------------------------------------------------
		public void LoadCheckingErrors(List<Guid> selectedCheckIds)
		{
			m_list.Clear();

			// Unsubscribe so we don't get reference changed events (which happens in the
			// grid's RowEnter event delegate) while we are loading the grid.
			m_dataGridView.RowEnter -= m_dataGridView_RowEnter;
			m_dataGridView.RowCount = 0;
			m_dataGridView.ResetFonts();
			m_dataGridView.IsStale = false;

			if (m_BookFilter == null || m_BookFilter.BookIds == null)
				return;

			m_cache.LoadAllOfAnOwningVectorProp(
				(int)ScrBookAnnotations.ScrBookAnnotationsTags.kflidNotes, "ScrScriptureNote", true);

			m_cache.LoadAllOfAnOwningAtomicProp(
				(int)ScrScriptureNote.ScrScriptureNoteTags.kflidQuote, "StJournalText");

			m_cache.LoadAllOfAnOwningAtomicProp(
				(int)ScrScriptureNote.ScrScriptureNoteTags.kflidDiscussion, "StJournalText");

			m_cache.LoadAllOfAnIntProp(
				(int)ScrScriptureNote.ScrScriptureNoteTags.kflidResolutionStatus);

			m_cache.LoadAllOfAnIntProp(
				(int)ScrScriptureNote.CmBaseAnnotationTags.kflidBeginRef);

			// ENHANCE: get end ref. when we deal with it in the checking error class.
			//m_cache.LoadAllOfAnIntProp(
			//	(int)ScrScriptureNote.CmBaseAnnotationTags.kflidEndRef);

			m_cache.LoadAllOfAnIntProp(
				(int)ScrScriptureNote.CmAnnotationTags.kflidAnnotationType);

			m_cache.LoadAllOfAnOwningVectorProp(
				(int)StJournalText.StTextTags.kflidParagraphs, "StPara", true);

			FdoOwningSequence<IScrBookAnnotations> booksAnnotations =
				m_cache.LangProject.TranslatedScriptureOA.BookAnnotationsOS;

			foreach (int bookId in m_BookFilter.BookIds)
			{
				IScrBookAnnotations annotations = booksAnnotations[bookId - 1];
				for (int i = annotations.NotesOS.HvoArray.Length - 1; i >= 0; i--)
				{
					int hvoNote = annotations.NotesOS.HvoArray[i];
					CheckingError error = CheckingError.Create(m_cache, hvoNote, false, false);
					if (error != null && (selectedCheckIds == null || selectedCheckIds.Count == 0 ||
						selectedCheckIds.Contains(error.AnnotationTypeRA.Guid)))
					{
						if (error.Status == (int)CheckingStatus.StatusEnum.Irrelevant)
							error.DeleteUnderlyingObject();
						else
							m_list.Add(error);
					}
				}
			}

			m_dataGridView.RowCount = m_list.Count;
			m_dataGridView.CheckingErrors = m_list;
			m_dataGridView.StyleSheet = StyleSheet;
			m_dataGridView.TMAdapter = TMAdapter;
			Sort(m_sortedColumn, false, kRefCol);

			m_prevResultRow = -1;

			if (m_persistence != null)
				OnLoadSettings(m_persistence.SettingsKey);

			m_dataGridView.RowEnter += m_dataGridView_RowEnter;

			if (m_dataGridView.RowCount > 0)
			{
				m_dataGridView.CurrentCell = m_dataGridView[0, 0];

				// Do this in case the current row didn't change by setting the current cell.
				m_dataGridView_RowEnter(this, new DataGridViewCellEventArgs(0, 0));
			}
		}
		/// <summary>
		/// gets a list of ws hvos, starting with the current wss, followed by remaining (non-current) active ones
		/// </summary>
		/// <param name="currentWss"></param>
		/// <param name="activeWss"></param>
		/// <param name="fAddOnlyCurrent">if true, only add the current wss, ignoring remaining active wss.</param>
		/// <returns></returns>
		internal static List<int> GetCurrentThenRemainingActiveWss(FdoReferenceSequence<ILgWritingSystem> currentWss,
			FdoReferenceCollection<ILgWritingSystem> activeWss, bool fAddOnlyCurrent)
		{
			List<int> hvoWss = new List<int>();
			// Add ordered (checked) writing system names to the list.
			foreach (ILgWritingSystem ws in currentWss)
				hvoWss.Add(ws.Hvo);
			if (fAddOnlyCurrent)
				return hvoWss;	// finished adding current wss, so return;
			// Now add the unchecked (or not current) writing systems to the list.
			foreach (ILgWritingSystem ws in activeWss)
			{
				if (!hvoWss.Contains(ws.Hvo))
					hvoWss.Add(ws.Hvo);
			}
			return hvoWss;
		}
Example #8
0
		/// <summary>
		///
		/// </summary>
		/// <param name="argument">The xCore Command object.</param>
		/// <returns>true</returns>
		public bool OnAddApprovedAnalysis(object argument)
		{
			using (EditMorphBreaksDlg dlg = new EditMorphBreaksDlg())
			{
				IWfiWordform wf = Wordform;
				if (wf == null)
					return true;
				ITsString tssWord = Wordform.Form.BestVernacularAlternative;
				string morphs = tssWord.Text;
				FdoCache cache = Cache;
				dlg.Initialize(tssWord, morphs, cache.MainCacheAccessor.WritingSystemFactory,
					cache, m_dataEntryForm.Mediator.StringTbl, m_dataEntryForm.StyleSheet);
				Form mainWnd = m_dataEntryForm.FindForm();
				// Making the form active fixes problems like LT-2619.
				// I'm (RandyR) not sure what adverse impact might show up by doing this.
				mainWnd.Activate();
				if (dlg.ShowDialog(mainWnd) == DialogResult.OK)
				{
					morphs = dlg.GetMorphs().Trim();
					if (morphs.Length == 0)
						return true;

					string[] prefixMarkers = MoMorphType.PrefixMarkers(cache);
					string[] postfixMarkers = MoMorphType.PostfixMarkers(cache);

					List<string> allMarkers = new List<string>();
					foreach (string s in prefixMarkers)
					{
						allMarkers.Add(s);
					}

					foreach (string s in postfixMarkers)
					{
						if (!allMarkers.Contains(s))
							allMarkers.Add(s);
					}
					allMarkers.Add(" ");

					string[] breakMarkers = new string[allMarkers.Count];
					for (int i = 0; i < allMarkers.Count; ++i)
						breakMarkers[i] = allMarkers[i];

					string fullForm = SandboxBase.MorphemeBreaker.DoBasicFinding(morphs, breakMarkers, prefixMarkers, postfixMarkers);

					using (UndoRedoCommandHelper undoRedoTask = new UndoRedoCommandHelper(Cache,
						argument as Command))
					{
						IWfiAnalysis newAnalysis = Wordform.AnalysesOC.Add(new WfiAnalysis());
						newAnalysis.ApprovalStatusIcon = 1; // Make it human approved.
						int vernWS = StringUtils.GetWsAtOffset(tssWord, 0);
						foreach (string morph in fullForm.Split(Unicode.SpaceChars))
						{
							if (morph != null && morph.Length != 0)
							{
								IWfiMorphBundle mb = newAnalysis.MorphBundlesOS.Append(new WfiMorphBundle());
								mb.Form.SetAlternative(morph, vernWS);
							}
						}
						int outlineFlid = BaseVirtualHandler.GetInstalledHandlerTag(cache, "WfiAnalysis", "HumanApprovedNumber");
						foreach (int haaHvo in Wordform.HumanApprovedAnalyses)
						{
							// Do PropChanged for the outline number for all of them.
							// This fixes LT-5007, as the older ones kept their old number,
							// which could have been a duplicate number.
							cache.PropChanged(
								null,
								PropChangeType.kpctNotifyAll,
								haaHvo,
								outlineFlid,
								0, 0, 0);
						}
						cache.PropChanged(
							null,
							PropChangeType.kpctNotifyAll,
							Wordform.Hvo,
							BaseVirtualHandler.GetInstalledHandlerTag(cache, "WfiWordform", "HumanApprovedAnalyses"),
							0, 1, 0);
					}
				}
			}

			return true;
		}
Example #9
0
		private void ComputeValue(int[] chosenHvos, int hvoItem, out int[] oldVals, out int[] newVal)
		{
			oldVals = m_cache.GetVectorProperty(hvoItem, m_flid, true);
			newVal = chosenHvos;
			if (m_fRemove)
			{
				newVal = oldVals; // by default no change in remove mode.
				if (oldVals.Length > 0)
				{
					List<int> newValues = new List<int>(oldVals);
					foreach (int hvo in chosenHvos)
					{
						if (newValues.Contains(hvo))
							newValues.Remove(hvo);
					}
					newVal = newValues.ToArray();
				}
			}
			else if (!m_fReplace && oldVals.Length != 0)
			{
				// Need to handle as append.
				List<int> newValues = new List<int>(oldVals);
				foreach (int hvo in chosenHvos)
				{
					if (!newValues.Contains(hvo))
						newValues.Add(hvo);
				}
				newVal = newValues.ToArray();
			}
		}
		/// <summary>
		/// Handle interaction between POS and Slot ptoeprties for a inflectional affix MSA.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		/// <remarks>
		/// If the new value is zero, then set the Slot prop to zero.
		/// If the new value is not zero, then make sure the Slot prop is valid.
		///		If the current slot is not legal for the new POS value, then set it to zero.
		///		Otherwise leave the slot value alone.
		/// </remarks>
		protected void OnReferenceChanged(object sender, SIL.FieldWorks.Common.Utils.FwObjectSelectionEventArgs e)
		{
			Debug.Assert(sender is AtomicReferenceLauncher);
			AtomicReferenceLauncher source = (AtomicReferenceLauncher)sender;
			Debug.Assert(Control == source);
			Debug.Assert(Object is MoInflAffMsa);

			int idxSender = Parent.Controls.IndexOf(this);

			int otherFlid = (int)MoInflAffMsa.MoInflAffMsaTags.kflidSlots;
			Slice otherSlice = null;
			int idxOther;

			// Try to get the Slots slice.
			// Check for slices before this one.
			if (idxSender > 0)
			{
				idxOther = idxSender - 1;
				while (idxOther >= 0
					&& (otherSlice == null
						|| (otherSlice.Indent == Indent && idxOther > 0 && otherSlice.Object == Object)))
				{
					otherSlice = (Slice)Parent.Controls[idxOther--];
					if (otherSlice is ReferenceVectorSlice && (otherSlice as ReferenceVectorSlice).Flid == otherFlid)
						break;
					otherSlice = null;
				}
			}

			// Check for following slices, if we didn't get one earlier.
			if (otherSlice == null && idxSender < Parent.Controls.Count)
			{
				idxOther = idxSender + 1;
				while (idxOther < Parent.Controls.Count
					&& (otherSlice == null
						|| (otherSlice.Indent == Indent && idxOther > 0 && otherSlice.Object == Object)))
				{
					otherSlice = (Slice)Parent.Controls[idxOther++];
					if (otherSlice is ReferenceVectorSlice && (otherSlice as ReferenceVectorSlice).Flid == otherFlid)
						break;
					otherSlice = null;
				}
			}

			VectorReferenceLauncher otherControl = null;
			if (otherSlice != null)
			{
				Debug.Assert((otherSlice as ReferenceVectorSlice).Flid == otherFlid);
				Debug.Assert(otherSlice.Object == Object);
				otherControl = otherSlice.Control as VectorReferenceLauncher;
				Debug.Assert(otherControl != null);
			}

			MoInflAffMsa msa = Object as MoInflAffMsa;
			int slotHvo = 0;
			if (msa.SlotsRC.Count > 0)
			{
				int[] hvos = msa.SlotsRC.HvoArray;
				slotHvo = hvos[0];
			}
			if (e.Hvo == 0 || slotHvo > 0)
			{
				IPartOfSpeech pos = msa.PartOfSpeechRA;
				List<int> slotIDs = new List<int>();
				if (pos != null)
					slotIDs = pos.AllAffixSlotIDs;
				bool clearSlot = (   (e.Hvo == 0)
								  || (!slotIDs.Contains(slotHvo)));
				if (clearSlot)
				{
					if (otherControl == null)
						msa.ClearAllSlots(); // The slot slice is not showing, so directly set the object's Slot property.
					else
						otherControl.AddItem(0); // Reset it using the other slice, so it gets refreshed.
				}
			}
		}
Example #11
0
		/// <summary>
		/// This method assumes all of the Find and UsedBy items are included in the fcfList.
		/// </summary>
		/// <param name="mediator"></param>
		/// <param name="fcfList"></param>
		/// <param name="startingItem"></param>
		internal void SetupDlg(Mediator mediator, List<FindComboFillerBase> fcfList, FindComboFillerBase startingItem)
		{
			if (mediator == null)
				throw new ArgumentException("No Mediator.");
			if (fcfList == null)
				throw new ArgumentException("No items found.");
			if (fcfList.Count < 1)
				throw new ArgumentException("There has to be at least one item.");
			foreach (FindComboFillerBase fcf in fcfList)
			{
				if (fcf.List_UBF.Count == 0)
					throw new ArgumentException("No sub-items found.");
			}
			if (startingItem != null && !fcfList.Contains(startingItem))
				throw new ArgumentException("'startingItem' is not in the 'fcfList' list.");

			m_mediator = mediator;
			m_cbFind.BeginUpdate();
			m_cbFind.Items.Clear();
			m_cbFind.Items.AddRange(fcfList.ToArray());
			m_cbFind.EndUpdate();
			m_cbFind.SelectedItem = startingItem;
			m_mediator.BroadcastPendingItems();
		}
Example #12
0
		protected override DummyCmObject GetMergeinfo(WindowParams wp, List<DummyCmObject> mergeCandidates, out string guiControl, out string helpTopic)
		{
			wp.m_title = FdoUiStrings.ksMergeSense;
			wp.m_label = FdoUiStrings.ksSenses;

			ILexEntry le = (Object as LexSense).Entry;
			// Exclude subsenses of the chosen sense.  See LT-6107.
			List<int> rghvoExclude = new List<int>();
			foreach (ILexSense ls in (Object as ILexSense).AllSenses)
				rghvoExclude.Add(ls.Hvo);
			foreach (ILexSense sense in le.AllSenses)
			{
				if (sense.Hvo != Object.Hvo && !rghvoExclude.Contains(sense.Hvo))
				{
					mergeCandidates.Add(
						new DummyCmObject(
						sense.Hvo,
						sense.ShortName,
						m_cache.LangProject.DefaultAnalysisWritingSystem));
				}
			}
			guiControl = "MergeSenseList";
			helpTopic = "khtpMergeSense";
			return new DummyCmObject(m_hvo, Object.ShortName, m_cache.LangProject.DefaultAnalysisWritingSystem);
		}
Example #13
0
			internal bool GetModifiedLayouts(List<XmlNode> rgxn, List<LayoutTreeNode> topNodes)
			{
				List<XmlNode> rgxnDirtyLayouts = new List<XmlNode>();
				for (int i = 0; i < Nodes.Count; ++i)
				{
					LayoutTreeNode ltn = (LayoutTreeNode)Nodes[i];
					if (ltn.GetModifiedLayouts(rgxn, topNodes))
					{
						XmlNode xn = ltn.ParentLayout;
						if (xn != null && !rgxnDirtyLayouts.Contains(xn))
							rgxnDirtyLayouts.Add(xn);
						xn = ltn.HiddenChildLayout;
						if (xn != null && ltn.HiddenChildDirty && !rgxnDirtyLayouts.Contains(xn))
							rgxnDirtyLayouts.Add(xn);
						xn = ltn.m_xnHiddenParentLayout;
						if (xn != null && ltn.HasMoved && !rgxnDirtyLayouts.Contains(xn))
							rgxnDirtyLayouts.Add(xn);
						foreach (LayoutTreeNode ltnMerged in ltn.MergedNodes)
						{
							xn = ltnMerged.ParentLayout;
							if (xn != null && !rgxnDirtyLayouts.Contains(xn))
								rgxnDirtyLayouts.Add(xn);
						}
					}
				}
				var fDirty = IsDirty();
				if (Level == 0 && !rgxnDirtyLayouts.Contains(m_xnParentLayout))
				{
					if (OverallLayoutVisibilityChanged())
					{
						rgxnDirtyLayouts.Add(m_xnParentLayout);
					}
					else if (!IsTopLevel && fDirty)
					{
						rgxnDirtyLayouts.Add(m_xnParentLayout);
					}
				}
				foreach (XmlNode xnDirtyLayout in rgxnDirtyLayouts)
				{
					// Create a new layout node with all its parts in order.  This is needed
					// to handle arbitrary reordering and possible addition or deletion of
					// duplicate nodes.  This is complicated by the presence (or rather absence)
					// of "hidden" nodes, and by "merged" nodes.
					XmlNode xnLayout = xnDirtyLayout.Clone();
					if (xnDirtyLayout == m_xnParentLayout && IsTopLevel && OverallLayoutVisibilityChanged())
						UpdateAttribute(xnLayout, "visibility", Checked ? "always" : "never");
					if (xnLayout.Attributes != null)
					{
						XmlAttribute[] rgxa = new XmlAttribute[xnLayout.Attributes.Count];
						xnLayout.Attributes.CopyTo(rgxa, 0);
						List<XmlNode> rgxnGen = new List<XmlNode>();
						List<int> rgixn = new List<int>();
						for (int i = 0; i < xnLayout.ChildNodes.Count; ++i)
						{
							XmlNode xn = xnLayout.ChildNodes[i];
							if (xn.Name != "part")
							{
								rgxnGen.Add(xn);
								rgixn.Add(i);
							}
						}
						xnLayout.RemoveAll();
						for (int i = 0; i < rgxa.Length; ++i)
						{
							if (xnLayout.Attributes != null)
								xnLayout.Attributes.SetNamedItem(rgxa[i]);
						}
						if (Level == 0 && !IsTopLevel && xnDirtyLayout == m_xnParentLayout)
						{
							foreach (var ltn in topNodes)
							{
								if (ltn.IsTopLevel || ltn.ParentLayout != xnDirtyLayout)
									continue;
								if (fDirty && ltn == this)
									ltn.StoreUpdatedValuesInConfiguration();
								xnLayout.AppendChild(ltn.Configuration.CloneNode(true));
							}
						}
						else
						{
							for (int i = 0; i < Nodes.Count; ++i)
							{
								LayoutTreeNode ltn = (LayoutTreeNode) Nodes[i];
								if (ltn.ParentLayout == xnDirtyLayout)
								{
									xnLayout.AppendChild(ltn.Configuration.CloneNode(true));
								}
								else if (ltn.HiddenNodeLayout == xnDirtyLayout)
								{
									var xpathString = "/" + ltn.HiddenNode.Name + "[" +
													  BuildXPathFromAttributes(ltn.HiddenNode.Attributes) + "]";
									if (xnLayout.SelectSingleNode(xpathString) == null)
										xnLayout.AppendChild(ltn.HiddenNode.CloneNode(true));
								}
								else if (ltn.HiddenChildLayout == xnDirtyLayout)
								{
									var xpathString = "/" + ltn.HiddenNode.Name + "[" +
													  BuildXPathFromAttributes(ltn.HiddenChild.Attributes) + "]";
									if (xnLayout.SelectSingleNode(xpathString) == null)
										xnLayout.AppendChild(ltn.HiddenChild.CloneNode(true));
								}
								else
								{
									for (int itn = 0; itn < ltn.MergedNodes.Count; itn++)
									{
										LayoutTreeNode ltnMerged = ltn.MergedNodes[itn];
										if (ltnMerged.ParentLayout == xnDirtyLayout)
										{
											xnLayout.AppendChild(ltnMerged.Configuration.CloneNode(true));
											break;
										}
									}
								}
							}
						}
						XmlNode xnRef;
						for (int i = 0; i < rgxnGen.Count; ++i)
						{
							if (rgixn[i] <= xnLayout.ChildNodes.Count/2)
							{
								xnRef = xnLayout.ChildNodes[rgixn[i]];
								xnLayout.InsertBefore(rgxnGen[i], xnRef);
							}
							else
							{
								if (rgixn[i] < xnLayout.ChildNodes.Count)
									xnRef = xnLayout.ChildNodes[rgixn[i]];
								else
									xnRef = xnLayout.LastChild;
								xnLayout.InsertAfter(rgxnGen[i], xnRef);
							}
						}
					}
					if (!rgxn.Contains(xnLayout))
						rgxn.Add(xnLayout);
				}
				if (IsTopLevel)
					return UpdateLayoutVisibilityIfChanged();
				if (Level > 0 && fDirty)
					StoreUpdatedValuesInConfiguration();
				return fDirty || HasMoved || IsNew;
			}
Example #14
0
		private void OnDuplicateClick(object sender, EventArgs e)
		{
			Debug.Assert(!m_current.IsTopLevel);
			StoreNodeData(m_current);	// Ensure duplicate has current data.
			LayoutTreeNode ltnDup;

			// Generate a unique label to identify this as the n'th duplicate in the list.
			var rgsLabels = new List<string>();
			string sBaseLabel = null;
			if (m_current.Level == 0)
			{
				var nodes = ((LayoutTypeComboItem)m_cbDictType.SelectedItem).TreeNodes;
				sBaseLabel = GetBaseLabel(nodes, rgsLabels);
			}
			else
			{
				sBaseLabel = GetBaseLabel(m_current.Parent.Nodes, rgsLabels);
			}
			if (sBaseLabel == null)
				sBaseLabel = m_current.Label;
			var cDup = 1;
			var sLabel = String.Format("{0} ({1})", sBaseLabel, cDup);
			while (rgsLabels.Contains(sLabel))
			{
				++cDup;
				sLabel = String.Format("{0} ({1})", sBaseLabel, cDup);
			}
			if (String.IsNullOrEmpty(m_current.Param))
			{
				Debug.Assert(m_current.Nodes.Count == 0);
				ltnDup = m_current.CreateCopy();
			}
			else
			{
				ltnDup = DuplicateLayoutSubtree(cDup);
				if (ltnDup == null)
					return;
			}
			ltnDup.Label = sLabel;		// sets Text as well.
			var sDup = ltnDup.DupString;
			sDup = String.IsNullOrEmpty(sDup) ? cDup.ToString() : String.Format("{0}-{1}", sDup, cDup);
			ltnDup.DupString = sDup;
			if (m_current.Level == 0)
			{
				var nodes = ((LayoutTypeComboItem)m_cbDictType.SelectedItem).TreeNodes;
				var idx = nodes.IndexOf(m_current);
				nodes.Insert(idx + 1, ltnDup);
				m_tvParts.Nodes.Insert(idx + 1, ltnDup);
			}
			else
			{
				var idx = m_current.Index;
				m_current.Parent.Nodes.Insert(idx + 1, ltnDup);
			}
			ltnDup.Checked = m_current.Checked; // remember this before m_current changes
			m_tvParts.SelectedNode = ltnDup;
		}
Example #15
0
		/// <summary>
		/// Move focus to next/previous pane.
		/// 'Pane' here means:
		/// 1. the Sidebar (m_sidebar),
		/// 2. the record list, (if showing at all, m_recordBar),
		/// 3. the first or second control of a MultiPane, or a parent MultiPane.
		/// 4. the main content control, if is not a MultiPane, or 'focusedControl'
		/// is not contained in a MultiPane.
		/// </summary>
		/// <param name="fForward"></param>
		/// <returns>control in pane that got the focus.</returns>
		private Control MoveToNextPane(bool fForward)
		{
			Control focusedControl = FocusedControl();

			if (focusedControl == this)
				return null;

			Control indexControl = null;
			// We can make a complete collection of candidates here.
			// In all cases, we add m_sidebar, since it is always showing.
			// We may want to include m_recordBar, if it is also showing.
			// We then want one or more controls from the m_mainContentControl.
			// (Note: m_mainContentPlaceholderPanel will be replaced by m_mainContentControl in normal operations,
			// but is is theoretically possible it is a current option.)
			List<Control> targetCandidates = new List<Control>();
			// The m_sidebar is currently always showing (as of Jan 11, 2007),
			// but it may not be in the future, so add it is it is showing.
			if (m_mainSplitContainer.Panel1.Controls[0] == m_sidebar)
			{
				if (m_sidebar.ContainsFocus)
				{
					targetCandidates.Add(focusedControl);
					indexControl = focusedControl;
				}
				else
				{
					Control target = m_sidebar;
					foreach (Control child in m_sidebar.Controls)
					{
						if (child.Controls.Count > 0)
						{
							Control innerChild = child.Controls[0];
							if (innerChild is ListView)
							{
								if ((innerChild as ListView).SelectedItems.Count > 0)
								{
									target = innerChild;
									break;
								}
							}
						}
					}
					targetCandidates.Add(target);
				}
			}
			if (!m_secondarySplitContainer.Panel1Collapsed
				&& m_secondarySplitContainer.Panel1.Controls[0] == m_recordBar)
			{
				if (m_recordBar.ContainsFocus)
				{
					targetCandidates.Add(focusedControl);
					indexControl = focusedControl;
				}
				else
				{
					// It looks like the record list can deal with waht is selected,
					// so just toss in the whole thing.
					targetCandidates.Add(m_recordBar);
				}
			}

			if (!m_secondarySplitContainer.Panel2Collapsed
				&& m_secondarySplitContainer.Panel2.Controls[0] == m_mainContentControl)
			{
				// Now deal with the m_mainContentControl side of things.
				Control otherControl = (m_mainContentControl as IxCoreCtrlTabProvider).PopulateCtrlTabTargetCandidateList(targetCandidates);
				if (otherControl != null)
				{
					Debug.Assert(indexControl == null, "indexCntrol should have been null.");
					indexControl = otherControl;
				}
			}
			Debug.Assert(indexControl != null, "Couldn't find the focused control anywhere.");
			Debug.Assert(targetCandidates.Contains(indexControl));
			int srcIndex = targetCandidates.IndexOf(indexControl);
			int targetIndex = 0;
			if (fForward)
			{
				targetIndex = srcIndex + 1 < targetCandidates.Count ? srcIndex + 1 : 0;
			}
			else
			{
				targetIndex = srcIndex > 0 ? srcIndex - 1 : targetCandidates.Count - 1;
			}

			Control newFocusedControl = targetCandidates[targetIndex];
			newFocusedControl.Focus(); // Note: may result in Focusing in a subcontrol.
			return newFocusedControl;
		}
Example #16
0
		private static void FindChosenHvos(ObjectLabelCollection labels, List<string> chosenLabels, ref List<int> chosenHvos)
		{
			foreach (ObjectLabel label in labels)
			{
				// go through the labels, and build of list of matching labels.
				if (chosenLabels.Contains(label.DisplayName))
					chosenHvos.Add(label.Hvo);
				// do the same for subitems
				if (label.SubItems.Count != 0)
					FindChosenHvos(label.SubItems, chosenLabels, ref chosenHvos);
			}
		}
Example #17
0
 private void ResetLangFilesToMasterValues()
 {
     XmlDocument masterDoc = new XmlDocument();
     masterDoc.Load(m_sMasterAnswerFile);
     XmlNodeList languageElements = masterDoc.SelectNodes("//language/*");
     List<string> asElementsToSkip = new List<string>(4);
     asElementsToSkip.Add("langName");
     asElementsToSkip.Add("langAbbr");
     asElementsToSkip.Add("font");
     asElementsToSkip.Add("answerFile");
     foreach (XmlNode node in languageElements)
     {
         if (!asElementsToSkip.Contains(node.Name))
         {
             string sXPath = "//" + node.Name;
             SetAnswerValue(sXPath, node.InnerText);
         }
     }
 }
Example #18
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Executes the requested action with all FW applications temporarily shut down and
		/// then (re)starts the applications in a sensible order. At the end, we're guaranteed
		/// to have at least one app started or FieldWorks will be shut down.
		/// </summary>
		/// <param name="abbrevOfDefaultAppToStart">The abbreviation of the default application
		/// to start.</param>
		/// <param name="action">The action to execute.</param>
		/// ------------------------------------------------------------------------------------
		private static void ExecuteWithAppsShutDown(string abbrevOfDefaultAppToStart, Func<ProjectId> action)
		{
			bool allowFinalShutdownOrigValue = s_allowFinalShutdown;
			s_allowFinalShutdown = false; // don't shutdown when we close all windows!

			// Remember which apps were running (and the order in which to restore them)
			List<string> appsToRestore = new List<string>();
			// If the requested default application is running, then add it as the first app to restore
			if (GetAppFromAppNameOrAbbrev(abbrevOfDefaultAppToStart) != null)
				appsToRestore.Add(abbrevOfDefaultAppToStart);
			if (s_flexApp != null && !appsToRestore.Contains(FwUtils.ksFlexAbbrev))
				appsToRestore.Add(FwUtils.ksFlexAbbrev);
			if (s_teApp != null && !appsToRestore.Contains(FwUtils.ksTeAbbrev))
				appsToRestore.Add(FwUtils.ksTeAbbrev);
			if (appsToRestore.Count == 0)
			{
				if (abbrevOfDefaultAppToStart.Equals(FwUtils.ksTeAbbrev, StringComparison.InvariantCultureIgnoreCase) &&
					FwUtils.IsTEInstalled)
				{
					appsToRestore.Add(FwUtils.ksTeAbbrev);
				}
				else
					appsToRestore.Add(FwUtils.ksFlexAbbrev);
			}
			// Now shut down everything (windows, apps, cache, etc.)
			GracefullyShutDown();

			if (s_applicationExiting)
			{
				// Something bad must have happened because we are shutting down. There is no point in
				// executing the action or in restarting the applications since we have no idea what
				// state the applications/data are in. (FWR-3179)
				Debug.Assert(s_allowFinalShutdown, "If something bad happened, we should be allowing application shutdown");
				return;
			}

			try
			{
				// Run the action
				ProjectId projId = action();

				if (projId == null)
					return;

				s_projectId = null; // Needs to be null in InitializeFirstApp

				// Restart the default app from which the action was kicked off
				FwApp app = GetOrCreateApplication(new FwAppArgs(appsToRestore[0],
					projId.Handle, projId.ServerName, string.Empty, Guid.Empty));
				if (!InitializeFirstApp(app, projId))
					return;

				s_projectId = projId; // Process needs to know its project

				// Reopen other apps if necessary (shouldn't ever be more then one) :P
				for (int i = 1; i < appsToRestore.Count; i++)
				{
					app = GetOrCreateApplication(new FwAppArgs(appsToRestore[i], projId.Handle,
						projId.ServerName, string.Empty, Guid.Empty));
					InitializeApp(app, null);
				}
			}
			finally
			{
				s_allowFinalShutdown = allowFinalShutdownOrigValue; // mustn't suppress any longer (unless we already were).
				ExitIfNoAppsRunning();
			}
		}
			/// <summary>
			/// Count how many non-blank alternatives tss has that are not listed in wsIds.
			/// </summary>
			/// <param name="tss"></param>
			/// <param name="wsIds"></param>
			/// <returns></returns>
			static int AdditionalAlternatives(IWfiGloss wg, List<int> wsIds)
			{
				int result = 0;
				foreach (var ws in wg.Form.AvailableWritingSystemIds)
				{
					if (wsIds.Contains(ws))
						continue;
					if (wg.Form.get_String(ws).Length > 0)
						result++;
				}
				return result;
			}
Example #20
0
		protected override DummyCmObject GetMergeinfo(WindowParams wp, List<DummyCmObject> mergeCandidates, out string guiControl, out string helpTopic)
		{
			wp.m_title = FdoUiStrings.ksMergeSense;
			wp.m_label = FdoUiStrings.ksSenses;
			int defAnalWs = m_cache.ServiceLocator.WritingSystems.DefaultAnalysisWritingSystem.Handle;

			var sense = (ILexSense) Object;
			var le = sense.Entry;
			// Exclude subsenses of the chosen sense.  See LT-6107.
			var rghvoExclude = new List<int>();
			foreach (var ls in sense.AllSenses)
				rghvoExclude.Add(ls.Hvo);
			foreach (var senseInner in le.AllSenses)
			{
				if (senseInner != Object && !rghvoExclude.Contains(senseInner.Hvo))
				{
					// Make sure we get the actual WS used (best analysis would be the
					// descriptive term) for the ShortName.  See FWR-2812.
					ITsString tssName = senseInner.ShortNameTSS;
					mergeCandidates.Add(
						new DummyCmObject(
						senseInner.Hvo,
						tssName.Text,
						TsStringUtils.GetWsAtOffset(tssName, 0)));
				}
			}
			guiControl = "MergeSenseList";
			helpTopic = "khtpMergeSense";
			ITsString tss = Object.ShortNameTSS;
			return new DummyCmObject(m_hvo, tss.Text, TsStringUtils.GetWsAtOffset(tss, 0));
		}
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Loads into the grid, the checking errors for the specified checks.
		/// </summary>
		/// <param name="selectedCheckIds">The list of checkIds for which to show results.
		/// When this is null, results for all the checks are shown.</param>
		/// ------------------------------------------------------------------------------------
		public void LoadCheckingErrors(List<Guid> selectedCheckIds)
		{
			m_list.Clear();

			// Unsubscribe so we don't get reference changed events (which happens in the
			// grid's RowEnter event delegate) while we are loading the grid.
			m_dataGridView.RowEnter -= m_dataGridView_RowEnter;
			m_dataGridView.RowCount = 0;
			m_dataGridView.ResetFonts();
			m_dataGridView.IsStale = false;

			if (m_BookFilter == null || m_BookFilter.BookIds == null)
				return;

			IFdoOwningSequence<IScrBookAnnotations> booksAnnotations =
				m_cache.LangProject.TranslatedScriptureOA.BookAnnotationsOS;

			foreach (int bookId in m_BookFilter.BookIds)
			{
				IScrBookAnnotations annotations = booksAnnotations[bookId - 1];
				foreach (IScrScriptureNote note in annotations.NotesOS)
				{
					CheckingError error = CheckingError.Create(note);
					if (error != null && (selectedCheckIds == null || selectedCheckIds.Count == 0 ||
						selectedCheckIds.Contains(error.MyNote.AnnotationTypeRA.Guid)))
					{
						// ignore errors in process of being deleted - will be removed next time checks are run.
						if (error.Status != (int)CheckingStatus.StatusEnum.Irrelevant)
							m_list.Add(error);
					}
				}
			}

			m_dataGridView.RowCount = m_list.Count;
			m_dataGridView.CheckingErrors = m_list;
			m_dataGridView.StyleSheet = StyleSheet;
			m_dataGridView.TMAdapter = TMAdapter;
			Sort(m_sortedColumn, false, kRefCol);

			m_prevResultRow = -1;

			if (m_persistence != null)
				OnLoadSettings(m_persistence.SettingsKey);

			m_dataGridView.RowEnter += m_dataGridView_RowEnter;

			if (m_dataGridView.RowCount > 0)
			{
				m_dataGridView.CurrentCell = m_dataGridView[0, 0];

				// Do this in case the current row didn't change by setting the current cell.
				m_dataGridView_RowEnter(this, new DataGridViewCellEventArgs(0, 0));
			}
		}
Example #22
0
		/// <summary>
		/// Add to excludedSenses any sense of the entry (directly or indirectly owned)
		/// which is not a member of includedSenses.
		/// </summary>
		void AddExcludedSenses(ILexEntry entry, List<ILexSense> excludedSenses, List<ILexSense> includedSenses)
		{
			foreach (var sense in entry.SensesOS)
			{
				if (!includedSenses.Contains(sense))
					excludedSenses.Add(sense);
				AddExcludedSenses(sense, excludedSenses, includedSenses);
			}
		}
		/// <summary>
		/// Overridden to set the new values selected from the chooser dialog.
		/// </summary>
		/// <param name="rghvosChosen"></param>
		public override void SetItems(List<int> rghvosChosen)
		{
			CheckDisposed();
			m_phoneEnvRefView.Commit();
			// null indicates that we cancelled out of the chooser dialog -- we shouldn't get
			// here with that value, but just in case...
			if (rghvosChosen == null)
				return;
			int h1 = m_phoneEnvRefView.RootBox.Height;
			// First, we need a list of hvos added and a list of hvos deleted.
			int citemsOld = m_cache.GetVectorSize(m_obj.Hvo, m_flid);
			List<int> rghvosNew = new List<int>(rghvosChosen);
			List<int> rghvosDel = new List<int>(citemsOld);
			if (citemsOld > 0)
			{
				int[] hvosOld = m_cache.GetVectorProperty(m_obj.Hvo, m_flid, false);
				Debug.Assert(citemsOld == hvosOld.Length);
				for (int i = 0; i < citemsOld; ++i)
				{
					if (rghvosNew.Contains(hvosOld[i]))
						rghvosNew.Remove(hvosOld[i]);
					else
						rghvosDel.Add(hvosOld[i]);
				}
			}
			// Add all the new environments.
			using (new UndoRedoTaskHelper(m_cache,
				String.Format(DetailControlsStrings.ksUndoSet, m_fieldName),
				String.Format(DetailControlsStrings.ksRedoSet, m_fieldName)))
			{
				for (int i = 0; i < rghvosNew.Count; ++i)
				{
					int hvo = (int)rghvosNew[i];
					m_phoneEnvRefView.AddNewItem(hvo);
					if (m_flid == (int)MoAffixAllomorph.MoAffixAllomorphTags.kflidPosition)
					{
						((MoAffixAllomorph)m_obj).PositionRS.Append(hvo);
					}
					else
					{
						if (m_obj is MoAffixAllomorph)
							((MoAffixAllomorph)m_obj).PhoneEnvRC.Add(hvo);
						else
							((MoStemAllomorph)m_obj).PhoneEnvRC.Add(hvo);
					}
				}
				for (int i = 0; i < rghvosDel.Count; ++i)
				{
					int hvo = (int)rghvosDel[i];
					m_phoneEnvRefView.RemoveItem(hvo);
					if (m_flid == (int)MoAffixAllomorph.MoAffixAllomorphTags.kflidPosition)
					{
						((MoAffixAllomorph)m_obj).PositionRS.Remove(hvo);
					}
					else
					{
						if (m_obj is MoAffixAllomorph)
							((MoAffixAllomorph)m_obj).PhoneEnvRC.Remove(hvo);
						else
							((MoStemAllomorph)m_obj).PhoneEnvRC.Remove(hvo);
					}
				}
			}
			int h2 = m_phoneEnvRefView.RootBox.Height;
			if (h1 != h2 && ViewSizeChanged != null)
			{
				ViewSizeChanged(this,
					new FwViewSizeEventArgs(h2, m_phoneEnvRefView.RootBox.Width));
			}
		}
Example #24
0
		/// <summary>
		/// Add to excludedSenses any sense of the entry (directly or indirectly owned)
		/// which is not a member of includedSenses.
		/// </summary>
		void AddExcludedSenses(ILexSense owningSense, List<ILexSense> excludedSenses, List<ILexSense> includedSenses)
		{
			foreach (var sense in owningSense.SensesOS)
			{
				if (!includedSenses.Contains(sense))
					excludedSenses.Add(sense);
				AddExcludedSenses(sense, excludedSenses, includedSenses);
			}
		}
Example #25
0
		protected override void ComputeValue(List<ICmObject> chosenObjs, int hvoItem, out List<ICmObject> oldVals,
			out List<ICmObject> newVal)
		{
			if (!m_doingSuggest)
			{
				base.ComputeValue(chosenObjs, hvoItem, out oldVals, out newVal);
				return;
			}

			oldVals = GetOldVals(hvoItem);

			// ComputeValue() is used by FakeDoIt to put values in the suggestion cache,
			// and by DoIt to get values from the cache (and thereby not repeat the search).

			if (m_suggestionCache.TryGetValue(hvoItem, out newVal))
			{
				return; // This must be the DoIt pass; MakeSuggestions clears out the cache each time.
			}

			// resist the temptation to do "newVal = oldVals"
			// if we change newVal we don't want oldVals to change
			newVal = new List<ICmObject>();
			newVal.AddRange(oldVals);

			var curObject = m_cache.ServiceLocator.GetObject(hvoItem) as ILexSense;
			if (curObject == null)
				return;

			var matches = m_semDomRepo.FindCachedDomainsThatMatchWordsInSense(m_searchCache, curObject);

			foreach (var domain in matches)
			{
				if (!newVal.Contains(domain))
					newVal.Add(domain);
			}

			m_suggestionCache[hvoItem] = newVal; // This must be the FakeDoIt pass; cache semantic domains.
		}
Example #26
0
		/// ------------------------------------------------------------------------------------
		/// <summary>
		/// Handle changes to the LinkedFiles root directory for a language project.
		/// </summary>
		/// <param name="sOldLinkedFilesRootDir">The old LinkedFiles root directory.</param>
		/// <returns></returns>
		/// <remarks>This may not be the best place for this method, but I'm not sure there is a
		/// "best place".</remarks>
		/// ------------------------------------------------------------------------------------
		public bool UpdateExternalLinks(string sOldLinkedFilesRootDir)
		{
			ILangProject lp = Cache.LanguageProject;
			string sNewLinkedFilesRootDir = lp.LinkedFilesRootDir;
			if (!FileUtils.PathsAreEqual(sNewLinkedFilesRootDir, sOldLinkedFilesRootDir))
			{
				List<string> rgFilesToMove = new List<string>();
				// TODO: offer to move or copy existing files.
				foreach (ICmFolder cf in lp.MediaOC)
					CollectMovableFilesFromFolder(cf, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
				foreach (ICmFolder cf in lp.PicturesOC)
					CollectMovableFilesFromFolder(cf, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
				//Get the files which are pointed to by links in TsStrings
				CollectMovableFilesFromFolder(lp.FilePathsInTsStringsOA, rgFilesToMove, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);

				var hyperlinks = StringServices.GetHyperlinksInFolder(Cache, sOldLinkedFilesRootDir);
				foreach (var linkInfo in hyperlinks)
				{
					if (!rgFilesToMove.Contains(linkInfo.RelativePath) &&
						FileUtils.SimilarFileExists(Path.Combine(sOldLinkedFilesRootDir, linkInfo.RelativePath)) &&
						!FileUtils.SimilarFileExists(Path.Combine(sNewLinkedFilesRootDir, linkInfo.RelativePath)))
					{
						rgFilesToMove.Add(linkInfo.RelativePath);
					}
				}
				if (rgFilesToMove.Count > 0)
				{
					FileLocationChoice action;
					using (MoveOrCopyFilesDlg dlg = new MoveOrCopyFilesDlg()) // REVIEW (Hasso) 2015.08: should this go in MoveOrCopyFilesController?
					{
						dlg.Initialize(rgFilesToMove.Count, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir, this);
						DialogResult res = dlg.ShowDialog();
						Debug.Assert(res == DialogResult.OK);
						if (res != DialogResult.OK)
							return false;	// should never happen!
						action = dlg.Choice;
					}
					if (action == FileLocationChoice.Leave) // Expand path
					{
						NonUndoableUnitOfWorkHelper.Do(Cache.ActionHandlerAccessor,
							() =>
								{
									foreach (ICmFolder cf in lp.MediaOC)
										ExpandToFullPath(cf, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
									foreach (ICmFolder cf in lp.PicturesOC)
										ExpandToFullPath(cf, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir);
								});
						// Hyperlinks are always already full paths.
						return false;
					}
					List<string> rgLockedFiles = new List<string>();
					foreach (string sFile in rgFilesToMove)
					{
						string sOldPathname = Path.Combine(sOldLinkedFilesRootDir, sFile);
						string sNewPathname = Path.Combine(sNewLinkedFilesRootDir, sFile);
						string sNewDir = Path.GetDirectoryName(sNewPathname);
						if (!Directory.Exists(sNewDir))
							Directory.CreateDirectory(sNewDir);
						Debug.Assert(FileUtils.TrySimilarFileExists(sOldPathname, out sOldPathname));
						if (FileUtils.TrySimilarFileExists(sNewPathname, out sNewPathname))
							File.Delete(sNewPathname);
						try
						{
							if (action == FileLocationChoice.Move)
							{
								//LT-13343 do copy followed by delete to ensure the file gets put in the new location.
								//If the current FLEX record has a picture displayed the File.Delete will fail.
								File.Copy(sOldPathname, sNewPathname);
								File.Delete(sOldPathname);
							}

							else
								File.Copy(sOldPathname, sNewPathname);
						}
						catch (Exception ex)
						{
							Debug.WriteLine(String.Format("{0}: {1}", ex.Message, sOldPathname));
							rgLockedFiles.Add(sFile);
						}
					}
					NonUndoableUnitOfWorkHelper.DoUsingNewOrCurrentUOW(Cache.ActionHandlerAccessor,
						() => StringServices.FixHyperlinkFolder(hyperlinks, sOldLinkedFilesRootDir, sNewLinkedFilesRootDir));

					// If any files failed to be moved or copied above, try again now that we've
					// opened a new window and had more time elapse (and more demand to reuse
					// memory) since the failure.
					if (rgLockedFiles.Count > 0)
					{
						GC.Collect();	// make sure the window is disposed!
						Thread.Sleep(1000);
						foreach (string sFile in rgLockedFiles)
						{
							string sOldPathname = Path.Combine(sOldLinkedFilesRootDir, sFile);
							string sNewPathname = Path.Combine(sNewLinkedFilesRootDir, sFile);
							try
							{
								if (action == FileLocationChoice.Move)
									FileUtils.Move(sOldPathname, sNewPathname);
								else
									File.Copy(sOldPathname, sNewPathname);
							}
							catch (Exception ex)
							{
								Debug.WriteLine(String.Format("{0}: {1} (SECOND ATTEMPT)", ex.Message, sOldPathname));
							}
						}
					}
					return true;
				}
			}
			return false;
		}
Example #27
0
			internal bool GetModifiedLayouts(List<XmlNode> rgxn)
			{
				List<XmlNode> rgxnDirtyLayouts = new List<XmlNode>();
				for (int i = 0; i < Nodes.Count; ++i)
				{
					LayoutTreeNode ltn = (LayoutTreeNode)Nodes[i];
					if (ltn.GetModifiedLayouts(rgxn))
					{
						XmlNode xn = ltn.ParentLayout;
						if (xn != null && !rgxnDirtyLayouts.Contains(xn))
							rgxnDirtyLayouts.Add(xn);
						foreach (LayoutTreeNode ltnMerged in ltn.MergedNodes)
						{
							xn = ltnMerged.ParentLayout;
							if (xn != null && !rgxnDirtyLayouts.Contains(xn))
								rgxnDirtyLayouts.Add(xn);
						}
					}
				}
				if (Level == 0 && OverallLayoutVisibilityChanged())
				{
					if (!rgxnDirtyLayouts.Contains(m_xnParentLayout))
						rgxnDirtyLayouts.Add(m_xnParentLayout);
				}
				foreach (XmlNode xnDirtyLayout in rgxnDirtyLayouts)
				{
					// Create a new layout node with all its parts in order.  This is needed
					// to handle arbitrary reordering and possible addition or deletion of
					// duplicate nodes.  This is complicated by the presence (or rather absence)
					// of "hidden" nodes, and by "merged" nodes.
					XmlNode xnLayout = xnDirtyLayout.Clone();
					if (xnDirtyLayout == m_xnParentLayout && Level == 0 && OverallLayoutVisibilityChanged())
						UpdateAttribute(xnLayout, "visibility", this.Checked ? "always" : "never");
					XmlAttribute[] rgxa = new XmlAttribute[xnLayout.Attributes.Count];
					xnLayout.Attributes.CopyTo(rgxa, 0);
					List<XmlNode> rgxnGen = new List<XmlNode>();
					List<int> rgixn = new List<int>();
					int cChildren = xnLayout.ChildNodes.Count;
					for (int i = 0; i < xnLayout.ChildNodes.Count; ++i)
					{
						XmlNode xn = xnLayout.ChildNodes[i];
						if (xn.Name != "part")
						{
							rgxnGen.Add(xn);
							rgixn.Add(i);
						}
					}
					xnLayout.RemoveAll();
					for (int i = 0; i < rgxa.Length; ++i)
						xnLayout.Attributes.SetNamedItem(rgxa[i]);
					for (int i = 0; i < Nodes.Count; ++i)
					{
						LayoutTreeNode ltn = (LayoutTreeNode)Nodes[i];
						if (ltn.ParentLayout == xnDirtyLayout)
						{
							xnLayout.AppendChild(ltn.Configuration.CloneNode(true));
						}
						else if (ltn.HiddenParent == xnDirtyLayout)
						{
							xnLayout.AppendChild(ltn.HiddenNode.CloneNode(true));
						}
						else
						{
							for (int itn = 0; itn < ltn.MergedNodes.Count; itn++)
							{
								LayoutTreeNode ltnMerged = ltn.MergedNodes[itn];
								if (ltnMerged.ParentLayout == xnDirtyLayout)
								{
									xnLayout.AppendChild(ltnMerged.Configuration.CloneNode(true));
									break;
								}
							}
						}
					}
					XmlNode xnRef;
					for (int i = 0; i < rgxnGen.Count; ++i)
					{
						if (rgixn[i] <= xnLayout.ChildNodes.Count / 2)
						{
							xnRef = xnLayout.ChildNodes[rgixn[i]];
							xnLayout.InsertBefore(rgxnGen[i], xnRef);
						}
						else
						{
							if (rgixn[i] < xnLayout.ChildNodes.Count)
								xnRef = xnLayout.ChildNodes[rgixn[i]];
							else
								xnRef = xnLayout.LastChild;
							xnLayout.InsertAfter(rgxnGen[i], xnRef);
						}
					}
					if (!rgxn.Contains(xnLayout))
						rgxn.Add(xnLayout);
				}
				if (Level == 0)
					return UpdateLayoutVisibilityIfChanged();
				bool fDirty = Level > 0 && IsNodeDirty();
				if (fDirty)
					StoreUpdatedValuesInConfiguration();
				return fDirty;
			}
Example #28
0
		/// <summary>
		/// Build a list of files that can be moved (or copied) to the new LinkedFiles root
		/// directory.
		/// </summary>
		/// <param name="folder"></param>
		/// <param name="rgFilesToMove"></param>
		/// <param name="sOldRootDir"></param>
		/// <param name="sNewRootDir"></param>
		private static void CollectMovableFilesFromFolder(ICmFolder folder,
			List<string> rgFilesToMove, string sOldRootDir, string sNewRootDir)
		{
			foreach (var file in folder.FilesOC)
			{
				string sFilepath = file.InternalPath;
				//only select files which have relative paths so they are in the LinkedFilesRootDir
				if (!Path.IsPathRooted(sFilepath))
				{
					// Don't put the same file in more than once!
					if (rgFilesToMove.Contains(sFilepath))
						continue;
					var sOldFilePath = Path.Combine(sOldRootDir, sFilepath);
					if (FileUtils.TrySimilarFileExists(sOldFilePath, out sOldFilePath))
					{
						var sNewFilePath= Path.Combine(sNewRootDir, sFilepath);
						if (FileUtils.TrySimilarFileExists(sNewFilePath, out sNewFilePath))
						{
							//if the file exists in the destination LinkedFiles location, then only copy/move it if
							//file in the source location is newer.
							var dateTimeOfFileSourceFile = File.GetLastWriteTime(sOldFilePath);
							var dateTimeOfFileDestinationFile = File.GetLastWriteTime(sNewFilePath);
							if (dateTimeOfFileSourceFile > dateTimeOfFileDestinationFile)
								rgFilesToMove.Add(sFilepath);
						}
						else
						{
							//if the file does not exist in the destination LinkeFiles location then copy/move it.
							rgFilesToMove.Add(sFilepath);
						}
					}
				}
			}
			foreach (var sub in folder.SubFoldersOC)
				CollectMovableFilesFromFolder(sub, rgFilesToMove, sOldRootDir, sNewRootDir);
		}
Example #29
0
		/// <summary>
		/// Add to excludedSenses (an array of HVOs) any value in property flid of object
		/// hvoBase (which might be entry or sense) which is not a member of includedSenses.
		/// Also any nested senses.
		/// </summary>
		/// <param name="hvoBase"></param>
		/// <param name="flid"></param>
		/// <param name="excludedSenses"></param>
		/// <param name="includedSenses"></param>
		void AddExcludedSenses(ISilDataAccess sda, int hvoBase, int flid, List<int> excludedSenses, List<int> includedSenses)
		{
			int chvo = sda.get_VecSize(hvoBase, flid);
			for (int ihvo = 0; ihvo < chvo; ihvo++)
			{
				int hvoSense = sda.get_VecItem(hvoBase, flid, ihvo);
				if (!includedSenses.Contains(hvoSense))
					excludedSenses.Add(hvoSense);
				AddExcludedSenses(sda, hvoSense, (int)LexSense.LexSenseTags.kflidSenses, excludedSenses, includedSenses);
			}
		}
		/// <summary>
		/// Overridden to set the new values selected from the chooser dialog.
		/// </summary>
		/// <param name="rghvosChosen"></param>
		public override void SetItems(List<int> rghvosChosen)
		{
			CheckDisposed();
			// null indicates that we cancelled out of the chooser dialog -- we shouldn't get
			// here with that value, but just in case...
			if (rghvosChosen == null)
				return;
			int h1 = m_vectorRefView.RootBox.Height;
			int citemsOld = m_cache.GetVectorSize(m_obj.Hvo, m_flid);
			// Find out whether we're adding or deleting items.
			bool fChange = false;
			if (citemsOld != rghvosChosen.Count)
			{
				fChange = true;
			}
			else if (citemsOld > 0)
			{
				int[] hvosOld = m_cache.GetVectorProperty(m_obj.Hvo, m_flid, false);
				Debug.Assert(citemsOld == hvosOld.Length);
				// First check whether we're deleting any items (that data is already in place).
				for (int i = 0; i < hvosOld.Length; ++i)
				{
					if (!rghvosChosen.Contains(hvosOld[i]))
					{
						fChange = true;
						break;
					}
				}
				if (!fChange)
				{
					// Nothing was deleted, now check whether anything was added.
					List<int> rghvosOld = new List<int>();
					for (int i = 0; i < citemsOld; ++i)
						rghvosOld.Add(hvosOld[i]);
					for (int i = 0; i < rghvosChosen.Count; ++i)
					{
						if (!rghvosOld.Contains(rghvosChosen[i]))
						{
							fChange = true;
							break;
						}
					}
				}
			}
			if (fChange)
			{
				ResetProperty(DetailControlsStrings.ksSetItem, rghvosChosen.ToArray());
				m_vectorRefView.ReloadVector();
				int h2 = m_vectorRefView.RootBox.Height;
				CheckViewSizeChanged(h1, h2);
			}
		}