FormSearch.cs
上传用户:hbhltzc
上传日期:2022-06-04
资源大小:1925k
文件大小:19k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Xml;
  9. using System.Xml.XPath;
  10. using Microsoft.Xml;
  11. using System.Reflection;
  12. using System.Diagnostics;
  13. namespace XmlNotepad {
  14.     public partial class FormSearch : Form {
  15.         IFindTarget target;
  16.         Settings settings;
  17.         bool findOnly;
  18.         TabNavigator tnav;
  19.         FindFlags lastFlags = FindFlags.Normal;
  20.         string lastExpression;
  21.         const int MaxRecentlyUsed = 15;
  22.         SearchFilter filter;
  23.         public FormSearch() {            
  24.             this.SetStyle(ControlStyles.Selectable, true);
  25.             this.KeyPreview = true;
  26.             InitializeComponent();
  27.             this.buttonFindNext.Click += new EventHandler(buttonFindNext_Click);
  28.             this.buttonReplace.Click += new EventHandler(buttonReplace_Click);
  29.             this.buttonReplaceAll.Click += new EventHandler(buttonReplaceAll_Click);
  30.             this.comboBoxFind.KeyDown += new KeyEventHandler(comboBoxFind_KeyDown);
  31.             this.comboBoxFind.LostFocus += new EventHandler(comboBoxFind_LostFocus);
  32.             this.comboBoxFilter.Items.AddRange(new object[] { SearchFilter.Everything, SearchFilter.Names, SearchFilter.Text, SearchFilter.Comments });
  33.             this.comboBoxFilter.SelectedItem = this.filter;
  34.             this.comboBoxFilter.SelectedValueChanged += new EventHandler(comboBoxFilter_SelectedValueChanged);
  35.             this.tnav = new TabNavigator(this);
  36.         }
  37.         void comboBoxFind_LostFocus(object sender, EventArgs e) {
  38.             return;
  39.         }
  40.         void comboBoxFilter_SelectedValueChanged(object sender, EventArgs e) {
  41.             this.filter = (SearchFilter)this.comboBoxFilter.SelectedItem;
  42.         }
  43.         public FormSearch(FormSearch old, ISite site) : this() {
  44.             if (old != null){
  45.                 foreach (string s in old.comboBoxFind.Items){
  46.                     this.comboBoxFind.Items.Add(s);
  47.                 }
  48.                 this.comboBoxFilter.SelectedItem = old.comboBoxFilter.SelectedItem;
  49.             }
  50.             this.Site = site;
  51.         }
  52.         public override ISite Site {
  53.             get {
  54.                 return base.Site;
  55.             }
  56.             set {
  57.                 base.Site = value;
  58.                 OnSiteChanged();
  59.             }
  60.         }
  61.         public SearchFilter Filter {
  62.             get { return filter; }
  63.             set { filter = value; }
  64.         }
  65.         void buttonFindNext_Click(object sender, EventArgs e) {
  66.             DoFind();
  67.         }
  68.         
  69.         void buttonReplace_Click(object sender, EventArgs e) {
  70.             DoReplace();
  71.         }
  72.         Control Window {
  73.             get { return this.IsDisposed ? null : this; }
  74.         }
  75.         void OnNotFound() {
  76.             MessageBox.Show(this.Window, SR.TextNotFoundPrompt, SR.FindErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Information);
  77.             this.comboBoxFind.Focus();
  78.         }
  79.         void OnFindDone() {
  80.             MessageBox.Show(this.Window, SR.FindNextDonePrompt, SR.ReplaceCompleteCaption, MessageBoxButtons.OK, MessageBoxIcon.Information);
  81.             this.comboBoxFind.Focus();
  82.         }
  83.         void OnError(Exception e, string caption) {
  84.             MessageBox.Show(this.Window, e.Message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
  85.             this.comboBoxFind.Focus();
  86.         }
  87.         void DoFind() {
  88.             try {
  89.                 FindNext(false);                
  90.             } catch (Exception ex) {
  91.                 OnError(ex, SR.FindErrorCaption);
  92.             }
  93.         }
  94.         void DoReplace() {
  95.             try {                
  96.                 string replacement = this.comboBoxReplace.Text;
  97.                 target.ReplaceCurrent(replacement);
  98.                 FindNext(false);
  99.             } catch (Exception ex) {
  100.                 OnError(ex, SR.ReplaceErrorCaption);
  101.             }
  102.         }
  103.         void buttonReplaceAll_Click(object sender, EventArgs e) {
  104.             UndoManager mgr = (UndoManager)this.Site.GetService(typeof(UndoManager));
  105.             mgr.OpenCompoundAction("Replace All");
  106.             try {
  107.                 string replacement = this.comboBoxReplace.Text;
  108.                 target.ReplaceCurrent(replacement);
  109.                 bool rc = FindNext(false);
  110.                 while (rc) {
  111.                     Application.DoEvents();
  112.                     target.ReplaceCurrent(replacement);
  113.                     rc = FindNext(true);
  114.                 }
  115.             } catch (Exception ex) {
  116.                 OnError(ex, SR.ReplaceErrorCaption);
  117.             } finally {
  118.                 mgr.CloseCompoundAction();
  119.             }
  120.         }
  121.         bool FindNext(bool quiet) {
  122.             FindFlags flags = FindFlags.Normal;
  123.             if (this.checkBoxRegex.Checked) flags |= FindFlags.Regex;
  124.             else if (this.checkBoxXPath.Checked) flags |= FindFlags.XPath;
  125.             if (this.checkBoxMatchCase.Checked) flags |= FindFlags.MatchCase;
  126.             if (this.checkBoxWholeWord.Checked) flags |= FindFlags.WholeWord;
  127.             if (this.radioButtonUp.Checked) flags |= FindFlags.Backwards;
  128.             string expr = this.Expression;
  129.             if (!this.comboBoxFind.Items.Contains(expr)) {
  130.                 this.comboBoxFind.Items.Add(expr);
  131.                 if (this.comboBoxFind.Items.Count > MaxRecentlyUsed) {
  132.                     this.comboBoxFind.Items.RemoveAt(0);
  133.                 }
  134.             }
  135.             lastFlags = flags;
  136.             lastExpression = expr;
  137.             FindResult rc = target.FindNext(expr, flags, filter);
  138.             if (rc == FindResult.Found && !this.IsDisposed) {
  139.                 this.MoveFindDialog(target.MatchRect);
  140.             }
  141.             if (!quiet) {
  142.                 if (rc == FindResult.None) {
  143.                     OnNotFound();
  144.                 } else if (rc == FindResult.NoMore) {
  145.                     OnFindDone();
  146.                 }
  147.             }
  148.             return rc == FindResult.Found;
  149.         }
  150.         public void FindAgain(bool reverse) {
  151.             // The find dialog might have been disposed, so we can only find using previous 
  152.             // find state information.
  153.             if (string.IsNullOrEmpty(lastExpression)) {
  154.                 return;
  155.             }
  156.             try {
  157.                 if (reverse) {
  158.                     lastFlags |= FindFlags.Backwards;
  159.                 } else {
  160.                     lastFlags &= ~FindFlags.Backwards;
  161.                 }
  162.                 FindResult rc = target.FindNext(lastExpression, lastFlags, filter);
  163.                 if (rc == FindResult.Found && !this.IsDisposed) {
  164.                     this.MoveFindDialog(target.MatchRect);
  165.                 }
  166.                 if (rc == FindResult.None) {
  167.                     OnNotFound();
  168.                 } else if (rc == FindResult.NoMore) {
  169.                     OnFindDone();
  170.                 }
  171.             } catch (Exception ex) {
  172.                 OnError(ex, SR.FindErrorCaption);
  173.             }
  174.         }
  175.         void MoveFindDialog(Rectangle selection) {
  176.             Rectangle r = this.Bounds;
  177.             if (r.IntersectsWith(selection)) {
  178.                 // find smallest adjustment (left,right,up,down) that still fits on screen.
  179.                 List<Adjustment> list = new List<Adjustment>();
  180.                 list.Add(new Adjustment(Direction.Up, this, selection));
  181.                 list.Add(new Adjustment(Direction.Down, this, selection));
  182.                 list.Add(new Adjustment(Direction.Left, this, selection));
  183.                 list.Add(new Adjustment(Direction.Right, this, selection));
  184.                 list.Sort();
  185.                 Adjustment smallest = list[0];
  186.                 smallest.AdjustDialog();
  187.                 return;
  188.             }
  189.         }
  190.  
  191.         enum Direction { Up, Down, Left, Right };
  192.         class Adjustment : IComparable {
  193.             Direction dir;
  194.             Form dialog;
  195.             Rectangle selection;
  196.             Rectangle formBounds;
  197.             public Adjustment(Direction dir, Form dialog, Rectangle selection) {
  198.                 this.dir = dir;
  199.                 this.dialog = dialog;
  200.                 this.selection = selection;
  201.                 this.formBounds = this.dialog.Bounds;
  202.             }
  203.             public int Delta {
  204.                 get {
  205.                     int delta = 0;
  206.                     Rectangle screen = Screen.FromControl(dialog).Bounds;
  207.                     switch (this.dir) {
  208.                         case Direction.Up:
  209.                             delta = formBounds.Bottom - selection.Top;
  210.                             if (formBounds.Top - delta < screen.Top) {
  211.                                 delta = Int32.MaxValue; // don't choose this one then.
  212.                             }
  213.                             break;
  214.                         case Direction.Down:
  215.                             delta = selection.Bottom - formBounds.Top;
  216.                             if (formBounds.Bottom + delta > screen.Bottom) {
  217.                                 delta = Int32.MaxValue; // don't choose this one then.
  218.                             }
  219.                             break;
  220.                         case Direction.Left:
  221.                             delta = formBounds.Right - selection.Left;
  222.                             if (formBounds.Right - delta < screen.Left) {
  223.                                 delta = Int32.MaxValue; // don't choose this one then.
  224.                             }
  225.                             break;
  226.                         case Direction.Right:
  227.                             delta = selection.Right - formBounds.Left;
  228.                             if (formBounds.Right + delta > screen.Right) {
  229.                                 delta = Int32.MaxValue; // don't choose this one then.
  230.                             }
  231.                             break;
  232.                     }
  233.                     return delta ;
  234.                 }
  235.             }
  236.             public void AdjustDialog() {
  237.                 if (this.Delta == Int32.MaxValue)
  238.                     return; // none of the choices were ideal
  239.                 switch (this.dir) {
  240.                     case Direction.Up:
  241.                         this.dialog.Top -= this.Delta;
  242.                         break;
  243.                     case Direction.Down:
  244.                         this.dialog.Top += this.Delta;
  245.                         break;
  246.                     case Direction.Left:
  247.                         this.dialog.Left -= this.Delta;
  248.                         break;
  249.                     case Direction.Right:
  250.                         this.dialog.Left += this.Delta;
  251.                         break;
  252.                 }
  253.             }
  254.             public int CompareTo(object obj) {
  255.                 Adjustment a = obj as Adjustment;
  256.                 if (a != null) {
  257.                     return this.Delta - a.Delta;
  258.                 }
  259.                 return 0;
  260.             }
  261.         }
  262.         void SetCheckBoxValue(CheckBox box, string name) {
  263.             object value = this.settings[name];
  264.             if (value != null) {
  265.                 box.Checked = (bool)value;
  266.             }
  267.         }
  268.         public virtual void OnSiteChanged() {
  269.             HelpProvider hp = this.Site.GetService(typeof(HelpProvider)) as HelpProvider;
  270.             if (hp != null) {
  271.                 hp.SetHelpKeyword(this, "Find");
  272.                 hp.SetHelpNavigator(this, HelpNavigator.KeywordIndex);
  273.             }
  274.             this.SuspendLayout();
  275.             settings = (Settings)this.Site.GetService(typeof(Settings));
  276.             SetCheckBoxValue(this.checkBoxXPath, "SearchXPath");
  277.             SetCheckBoxValue(this.checkBoxWholeWord, "SearchWholeWord");
  278.             SetCheckBoxValue(this.checkBoxRegex, "SearchRegex");
  279.             SetCheckBoxValue(this.checkBoxMatchCase, "SearchMatchCase");
  280.             Size s = this.ClientSize;
  281.             object o = this.settings["FindMode"];
  282.             if (o != null) {
  283.                 this.findOnly = (bool)o;
  284.                 SetFindModeControls(!this.findOnly);
  285.             }
  286.             object size = this.settings["SearchSize"];
  287.             if (size != null && (Size)size != Size.Empty) {
  288.                 Size cs = (Size)size;
  289.                 s = new Size(cs.Width, cs.Height);
  290.             }
  291.             this.ClientSize = s;
  292.             
  293.             object location = this.settings["SearchLocation"];
  294.             if (location != null && (Point)location != Point.Empty) {
  295.                 Control ctrl = this.Site as Control;
  296.                 if (ctrl != null) {
  297.                     Rectangle ownerBounds = ctrl.TopLevelControl.Bounds;
  298.                     if (IsSameScreen((Point)location, ownerBounds)) {
  299.                         this.Location = (Point)location;
  300.                     } else {
  301.                         this.Location = CenterPosition(ownerBounds);
  302.                     }
  303.                     this.StartPosition = FormStartPosition.Manual;
  304.                 }
  305.             }
  306.             this.ResumeLayout();
  307.         }
  308.         Point CenterPosition(Rectangle bounds) {
  309.             Size s = this.ClientSize;
  310.             Point center = new Point(bounds.Left + (bounds.Width / 2) - (s.Width / 2),
  311.                 bounds.Top + (bounds.Height / 2) - (s.Height / 2));
  312.             if (center.X < 0) center.X = 0;
  313.             if (center.Y < 0) center.Y = 0;
  314.             return center;
  315.         }
  316.         bool IsSameScreen(Point location, Rectangle ownerBounds) {
  317.             Point center = new Point(ownerBounds.Left + ownerBounds.Width/2, 
  318.                 ownerBounds.Top + ownerBounds.Height/2);
  319.             foreach (Screen s in Screen.AllScreens) {
  320.                 Rectangle sb = s.WorkingArea;
  321.                 if (sb.Contains(location)) {
  322.                     return sb.Contains(center);
  323.                 }
  324.             }
  325.             // Who knows where that location is (perhaps secondary monitor was removed!)
  326.             return false;
  327.         }
  328.         protected override void OnClosing(CancelEventArgs e) {
  329.             this.settings["SearchLocation"] = this.Location;
  330.             // save replace mode size, since we will shink the size next time findOnly is set.
  331.             this.settings["SearchSize"] = this.ClientSize;
  332.             this.settings["FindMode"] = this.findOnly;
  333.             this.settings["SearchXPath"] = this.checkBoxXPath.Checked;
  334.             this.settings["SearchWholeWord"] = this.checkBoxWholeWord.Checked;
  335.             this.settings["SearchRegex"] = this.checkBoxRegex.Checked;
  336.             this.settings["SearchMatchCase"] = this.checkBoxMatchCase.Checked;
  337.             base.OnClosing(e);
  338.         }
  339.         public IFindTarget Target {
  340.             get { return this.target; }
  341.             set { this.target = value; OnTargetChanged(); }
  342.         }
  343.         public bool ReplaceMode {
  344.             get { return !findOnly; }
  345.             set {
  346.                 if (findOnly != !value) {
  347.                     findOnly = !value;
  348.                     SetFindModeControls(!findOnly);                    
  349.                 }
  350.             }
  351.         }
  352.         void SetFindModeControls(bool visible) {
  353.             this.comboBoxReplace.Visible = visible;
  354.             this.label2.Visible = visible;
  355.             this.buttonReplace.Visible = visible;
  356.             this.buttonReplaceAll.Visible = visible;
  357.             this.Text = visible ? SR.FindWindowReplaceTitle : SR.FindWindowFindTitle;
  358.         }
  359.         public string Expression {
  360.             get { return this.comboBoxFind.Text; }
  361.             set { this.comboBoxFind.Text = value; }
  362.         }
  363.         protected override void OnKeyDown(KeyEventArgs e) {
  364.             HandleKeyDown(e);
  365.             if (!e.Handled) {
  366.                 base.OnKeyDown(e);
  367.             }
  368.         }
  369.         void comboBoxFind_KeyDown(object sender, KeyEventArgs e) {
  370.             HandleKeyDown(e);
  371.         }
  372.         protected override bool ProcessDialogKey(Keys keyData) {
  373.             if (keyData == Keys.Tab || (keyData == (Keys.Tab | Keys.Shift))) {
  374.                 tnav.HandleTab(new KeyEventArgs(keyData));
  375.                 return true;
  376.             } else {
  377.                 return base.ProcessDialogKey(keyData);
  378.             }
  379.         }
  380.         void HandleKeyDown(KeyEventArgs e) {
  381.             if (e.KeyCode == Keys.Escape) {
  382.                 this.Close();
  383.                 e.Handled = true;
  384.             } else if (e.KeyCode == Keys.Enter) {
  385.                 if (this.buttonReplace.Focused) {
  386.                     DoReplace();
  387.                 } else {
  388.                     DoFind();
  389.                 }
  390.                 e.Handled = true;
  391.             } else if ((e.Modifiers & Keys.Control) != 0) {
  392.                 if (e.KeyCode == Keys.H) {
  393.                     ReplaceMode = true;
  394.                     e.Handled = true;
  395.                 } else if (e.KeyCode == Keys.F) {
  396.                     ReplaceMode = false;
  397.                     e.Handled = true;
  398.                 }
  399.             }
  400.         }
  401.         void OnTargetChanged() {
  402.             this.dataTableNamespaces.Clear();
  403.             if (target != null && ShowNamespaces) {
  404.                 this.Expression = target.Location;
  405.                 XmlNamespaceManager nsmgr = target.Namespaces;
  406.                 foreach (string prefix in nsmgr) {
  407.                     if (!string.IsNullOrEmpty(prefix) && prefix != "xmlns") {
  408.                         string uri = nsmgr.LookupNamespace(prefix);
  409.                         this.dataTableNamespaces.Rows.Add(new object[] { prefix, uri });
  410.                     }
  411.                 }
  412.             } else {
  413.                 this.Expression = null;
  414.             }
  415.         }
  416.         private void checkBoxXPath_CheckedChanged(object sender, EventArgs e) {
  417.             bool namespaces = this.ShowNamespaces;
  418.             if (namespaces && string.IsNullOrEmpty(this.comboBoxFind.Text)) {
  419.                 OnTargetChanged();
  420.             }            
  421.             dataGridViewNamespaces.Visible = namespaces;
  422.             if (checkBoxRegex.Checked) {
  423.                 ManualToggle(checkBoxRegex, false);
  424.             }
  425.         }
  426.         bool ShowNamespaces {
  427.             get { return checkBoxXPath.Checked; }
  428.         }
  429.         
  430.         bool checkBoxLatch;
  431.         void ManualToggle(CheckBox box, bool value) {
  432.             if (!checkBoxLatch) {
  433.                 checkBoxLatch = true;
  434.                 box.Checked = value;
  435.                 checkBoxLatch = false;
  436.             }
  437.         }
  438.         private void checkBoxRegex_CheckedChanged(object sender, EventArgs e) {
  439.             if (checkBoxRegex.Checked) {
  440.                 ManualToggle(checkBoxXPath, false);
  441.             }
  442.         }
  443.     }
  444. }