private void OnNewTextKey() { var win = new TextKeyWindow(); win.Owner = MainWindow.Instance; win.Title = Tx.T("window.text key.create.title"); win.CaptionLabel.Text = Tx.T("window.text key.create.caption"); win.OKButton.Content = Tx.T("window.text key.create.accept button"); var selKey = MainWindow.Instance.TextKeysTreeView.LastSelectedItem as TextKeyViewModel; if (selKey != null) { win.TextKey = selKey.TextKey + (selKey.IsNamespace ? ":" : "."); } if (win.ShowDialog() == true) { string newKey = win.TextKey; TextKeyViewModel tk; try { tk = FindOrCreateTextKey(newKey); } catch (NonNamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create namespace key", "key", Tx.Q(newKey))); return; } catch (NamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create non-namespace key", "key", Tx.Q(newKey))); return; } bool alreadyExists = !tk.IsEmpty(); // Ensure that all loaded cultures exist in every text key so that they can be entered foreach (string cn in LoadedCultureNames) { EnsureCultureInTextKey(tk, cn); } tk.UpdateCultureTextSeparators(); ValidateTextKeysDelayed(); FileModified = true; bool wasExpanded = tk.IsExpanded; tk.IsExpanded = true; // Expands all parents if (!wasExpanded) tk.IsExpanded = false; // Collapses this item again ViewCommandManager.InvokeLoaded("SelectTextKey", tk); if (alreadyExists) { StatusText = Tx.T("statusbar.text key already exists"); } else { StatusText = Tx.T("statusbar.text key created"); } if (tk.CultureTextVMs.Count > 0) tk.CultureTextVMs[0].ViewCommandManager.InvokeLoaded("FocusText"); } }
private void OnRenameTextKey() { var selKey = MainWindow.Instance.TextKeysTreeView.LastSelectedItem as TextKeyViewModel; if (selKey == null) return; // No key selected, something is wrong var win = new TextKeyWindow(); win.Owner = MainWindow.Instance; win.Title = Tx.T("window.text key.rename.title"); win.CaptionLabel.Text = Tx.T("window.text key.rename.caption"); win.TextKey = selKey.TextKey; win.OKButton.Content = Tx.T("window.text key.rename.accept button"); win.RenameSelectMode = true; if (selKey.Children.Count > 0) { // There are other keys below the selected key // Initially indicate that all subkeys will also be renamed win.IncludeSubitemsCheckbox.Visibility = Visibility.Visible; win.IncludeSubitemsCheckbox.IsChecked = true; win.IncludeSubitemsCheckbox.IsEnabled = false; if (selKey.IsFullKey) { // The selected key is a full key // Allow it to be renamed independently of the subkeys win.IncludeSubitemsCheckbox.IsEnabled = true; } } if (win.ShowDialog() == true) { // The dialog was confirmed string newKey = win.TextKey; // Was the name changed at all? if (newKey == selKey.TextKey) return; // Don't allow namespace nodes to be moved elsewhere if (selKey.IsNamespace && (newKey.Contains('.') || newKey.Contains(':'))) { App.WarningMessage(Tx.T("msg.cannot move namespace")); return; } bool needDuplicateForChildren = win.IncludeSubitemsCheckbox.IsChecked == false && selKey.Children.Count > 0; // Test whether the entered text key already exists with content or subkeys TextKeyViewModel tryDestKey; try { tryDestKey = FindOrCreateTextKey(newKey, false, false); } catch (NonNamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create namespace key", "key", Tx.Q(newKey))); return; } catch (NamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create non-namespace key", "key", Tx.Q(newKey))); return; } bool destExists = tryDestKey != null && (!tryDestKey.IsEmpty() || tryDestKey.Children.Count > 0); bool destWasFullKey = false; if (destExists) { // FindOrCreateTextKey below will make it a full key, no matter whether it // should be one. Remember this state to reset it afterwards. destWasFullKey = tryDestKey.IsFullKey; TaskDialogResult result = TaskDialog.Show( owner: MainWindow.Instance, allowDialogCancellation: true, title: "TxEditor", mainInstruction: Tx.T("msg.rename text key.exists", "key", Tx.Q(newKey)), content: Tx.T("msg.rename text key.exists.content"), customButtons: new string[] { Tx.T("task dialog.button.merge"), Tx.T("task dialog.button.cancel") }); if (result.CustomButtonResult != 0) { return; } } var oldParent = selKey.Parent; int affectedKeyCount = selKey.IsFullKey ? 1 : 0; if (!needDuplicateForChildren) { // Remove the selected key from its original tree position oldParent.Children.Remove(selKey); } // Create the new text key if needed TextKeyViewModel destKey = FindOrCreateTextKey(newKey, false); if (!destExists) { // Key was entirely empty or is newly created. if (needDuplicateForChildren) { // Keep new key but copy all data from the source key destKey.MergeFrom(selKey); // The source key is now no longer a full key selKey.IsFullKey = false; } else { // Replace it with the source key affectedKeyCount = selKey.SetKeyRecursive(newKey, TextKeys); if (selKey.IsNamespace) { // We're renaming a namespace item. But we've created a temporary // normal key (destKey) which is now at the wrong position. // Namespace entries are sorted differently, which was not known when // creating the key because it was no namespace at that time. Remove the // newly created key entry (all of its possibly created parent keys are // still useful though!) and insert the selected key at the correct // position in that tree level. destKey.Parent.Children.Remove(destKey); destKey.Parent.Children.InsertSorted(selKey, TextKeyViewModel.Compare); } else { // The sort order is already good for normal keys so we can simply replace // the created item with the selected key at the same position. destKey.Parent.Children.Replace(destKey, selKey); } // Update the key's parent reference to represent the (possible) new tree location. selKey.Parent = destKey.Parent; } } else { // Key already has some text or child keys. // Restore original full key state first destKey.IsFullKey = destWasFullKey; // Merge data into destKey, overwriting conflicts destKey.MergeFrom(selKey); if (win.IncludeSubitemsCheckbox.IsChecked == true) { // Add/merge all subkeys as well destKey.MergeChildrenRecursive(selKey); // Delete the source key after it has been merged into destKey DeleteTextKey(selKey); } else { // The source key will be kept but is now no longer a full key selKey.IsFullKey = false; TextKeys.Remove(selKey.TextKey); } } if (!needDuplicateForChildren && oldParent != selKey.Parent) { // The key has moved to another subtree. // Clean up possible unused partial keys at the old position. DeletePartialParentKeys(oldParent as TextKeyViewModel); } FileModified = true; StatusText = Tx.T("statusbar.text keys renamed", affectedKeyCount); // Fix an issue with MultiSelectTreeView: It can only know that an item is selected // when its TreeViewItem property IsSelected is set through a binding defined in // this application. The already-selected item was removed from the SelectedItems // list when it was removed from the tree (to be re-inserted later). Not sure how // to fix this right. selKey.IsSelected = true; if (needDuplicateForChildren || destExists) { bool wasExpanded = selKey.IsExpanded; destKey.IsExpanded = true; // Expands all parents if (!wasExpanded) destKey.IsExpanded = false; // Collapses the item again like it was before ViewCommandManager.InvokeLoaded("SelectTextKey", destKey); } else { bool wasExpanded = selKey.IsExpanded; selKey.IsExpanded = true; // Expands all parents if (!wasExpanded) selKey.IsExpanded = false; // Collapses the item again like it was before ViewCommandManager.InvokeLoaded("SelectTextKey", selKey); } ValidateTextKeysDelayed(); } }
private void OnDuplicateTextKey() { var selKey = MainWindow.Instance.TextKeysTreeView.LastSelectedItem as TextKeyViewModel; if (selKey == null) return; // No key selected, something is wrong var win = new TextKeyWindow(); win.Owner = MainWindow.Instance; win.Title = Tx.T("window.text key.duplicate.title"); win.CaptionLabel.Text = Tx.T("window.text key.duplicate.caption"); win.TextKey = selKey.TextKey; win.OKButton.Content = Tx.T("window.text key.duplicate.accept button"); win.RenameSelectMode = true; if (selKey.Children.Count > 0) { // There are other keys below the selected key // Initially indicate that all subkeys will also be duplicated win.IncludeSubitemsCheckbox.Visibility = Visibility.Visible; win.IncludeSubitemsCheckbox.IsChecked = true; win.IncludeSubitemsCheckbox.IsEnabled = false; if (selKey.IsFullKey) { // The selected key is a full key // Allow it to be duplicated independently of the subkeys win.IncludeSubitemsCheckbox.IsEnabled = true; } } if (win.ShowDialog() == true) { // The dialog was confirmed string newKey = win.TextKey; bool includeChildren = win.IncludeSubitemsCheckbox.IsChecked == true; // Don't allow namespace nodes to be copied elsewhere if (selKey.IsNamespace && (newKey.Contains('.') || newKey.Contains(':'))) { App.WarningMessage(Tx.T("msg.cannot copy namespace")); return; } // Test whether the entered text key already exists with content or subkeys TextKeyViewModel tryDestKey; try { tryDestKey = FindOrCreateTextKey(newKey, false, false, selKey.IsNamespace); } catch (NonNamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create namespace key", "key", Tx.Q(newKey))); return; } catch (NamespaceExistsException) { App.WarningMessage(Tx.T("msg.cannot create non-namespace key", "key", Tx.Q(newKey))); return; } bool destExists = tryDestKey != null && (!tryDestKey.IsEmpty() || tryDestKey.Children.Count > 0); bool destWasFullKey = false; if (destExists) { // FindOrCreateTextKey below will make it a full key, no matter whether it // should be one. Remember this state to reset it afterwards. destWasFullKey = tryDestKey.IsFullKey; TaskDialogResult result = TaskDialog.Show( owner: MainWindow.Instance, allowDialogCancellation: true, title: "TxEditor", mainInstruction: Tx.T("msg.rename text key.exists", "key", Tx.Q(newKey)), content: Tx.T("msg.rename text key.exists.content"), customButtons: new string[] { Tx.T("task dialog.button.merge"), Tx.T("task dialog.button.cancel") }); if (result.CustomButtonResult != 0) { return; } } int affectedKeys = selKey.IsFullKey ? 1 : 0; // Create the new text key if needed TextKeyViewModel destKey = FindOrCreateTextKey(newKey, true, true, selKey.IsNamespace); // Restore original full key state first destKey.IsFullKey = destWasFullKey; if (!destWasFullKey && !selKey.IsFullKey) { TextKeys.Remove(destKey.TextKey); } // Merge data into destKey, overwriting conflicts destKey.MergeFrom(selKey); if (includeChildren) { if (!destExists) { // Key was entirely empty or is newly created. foreach (TextKeyViewModel child in selKey.Children) { affectedKeys += DuplicateTextKeyRecursive(child, destKey); } } else { // Key already has some text or child keys. // Add/merge all subkeys as well destKey.MergeChildrenRecursive(selKey); } } FileModified = true; StatusText = Tx.T("statusbar.text keys duplicated", affectedKeys); destKey.IsSelected = true; bool wasExpanded = selKey.IsExpanded; destKey.IsExpanded = true; // Expands all parents if (!wasExpanded) destKey.IsExpanded = false; // Collapses the item again like it was before ViewCommandManager.InvokeLoaded("SelectTextKey", destKey); ValidateTextKeysDelayed(); } }