#region License
// Copyright 2005-2019 Paul Kohler (https://github.com/paulkohler/minisqlquery). All rights reserved.
// This source code is made available under the terms of the GNU Lesser General Public License v3.0
// https://github.com/paulkohler/minisqlquery/blob/master/LICENSE
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Gui.CompletionWindow;
using MiniSqlQuery.Commands;
using MiniSqlQuery.Core;
using MiniSqlQuery.Core.Commands;
using MiniSqlQuery.Properties;
using WeifenLuo.WinFormsUI.Docking;
namespace MiniSqlQuery
{
/// <summary>The query form.</summary>
public partial class QueryForm : DockContent, IQueryEditor, IPrintableContent
{
/// <summary>The _host window.</summary>
private readonly IHostWindow _hostWindow;
/// <summary>The _services.</summary>
private readonly IApplicationServices _services;
/// <summary>The _settings.</summary>
private readonly IApplicationSettings _settings;
/// <summary>The _sync lock.</summary>
private static object _syncLock = new object();
/// <summary>Stores the widths of the columns for this window.</summary>
private Dictionary<string, int> _columnSizes = new Dictionary<string, int>();
/// <summary>When tru the grid is being resized on fill, used to avoid overriting column width values.</summary>
private bool _resizingGrid;
/// <summary>The _highlighting provider loaded.</summary>
private bool _highlightingProviderLoaded;
/// <summary>The _is dirty.</summary>
private bool _isDirty;
/// <summary>The _runner.</summary>
private QueryRunner _runner;
/// <summary>The status message for this window.</summary>
private string _status = string.Empty;
/// <summary>The row count for this window (tab dependent).</summary>
private int? _rowCount;
/// <summary>The _text find service.</summary>
private ITextFindService _textFindService;
private bool _cleaningTabs;
TextArea _textArea;
CodeCompletionWindow _completionWindow;
/// <summary>Initializes a new instance of the <see cref="QueryForm"/> class.</summary>
public QueryForm()
{
InitializeComponent();
txtQuery.ContextMenuStrip = contextMenuStripQuery;
LoadHighlightingProvider();
txtQuery.Document.DocumentChanged += DocumentDocumentChanged;
_textArea = txtQuery.ActiveTextAreaControl.TextArea;
contextMenuStripQuery.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<ExecuteTaskCommand>());
contextMenuStripQuery.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<CancelTaskCommand>());
editorContextMenuStrip.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<SaveFileCommand>());
editorContextMenuStrip.Items.Add(CommandControlBuilder.CreateToolStripMenuItemSeparator());
editorContextMenuStrip.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<CloseActiveWindowCommand>());
editorContextMenuStrip.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<CloseAllWindowsCommand>());
editorContextMenuStrip.Items.Add(CommandControlBuilder.CreateToolStripMenuItem<CopyQueryEditorFileNameCommand>());
CommandControlBuilder.MonitorMenuItemsOpeningForEnabling(editorContextMenuStrip);
}
/// <summary>Initializes a new instance of the <see cref="QueryForm"/> class.</summary>
/// <param name="services">The services.</param>
/// <param name="settings">The settings.</param>
/// <param name="hostWindow">The host window.</param>
public QueryForm(IApplicationServices services, IApplicationSettings settings, IHostWindow hostWindow)
: this()
{
_services = services;
_settings = settings;
_hostWindow = hostWindow;
var completionProvider = _services.Resolve<ICompletionProvider>();
if (completionProvider.Enabled)
{
_textArea.KeyEventHandler += completionProvider.KeyEventHandlerFired;
}
}
public CodeCompletionWindow CodeCompletionWindow
{
get { return _completionWindow; }
set
{
_completionWindow = value;
if (_completionWindow != null)
{
_completionWindow.Closed += CompletionWindowClosed;
}
}
}
private void CompletionWindowClosed(object sender, EventArgs e)
{
if (_completionWindow != null)
{
_completionWindow.Closed -= CompletionWindowClosed;
_completionWindow.Dispose();
_completionWindow = null;
}
}
/// <summary>Gets or sets AllText.</summary>
public string AllText
{
get { return txtQuery.Text; }
set { txtQuery.Text = value; }
}
/// <summary>
/// Gets a reference to the batch of queries.
/// </summary>
/// <value>The query batch.</value>
public QueryBatch Batch
{
get { return _runner == null ? null : _runner.Batch; }
}
/// <summary>Gets a value indicating whether CanReplaceText.</summary>
public bool CanReplaceText
{
get { return true; }
}
/// <summary>Gets or sets CursorColumn.</summary>
public int CursorColumn
{
get { return txtQuery.ActiveTextAreaControl.Caret.Column; }
set { txtQuery.ActiveTextAreaControl.Caret.Column = value; }
}
/// <summary>Gets or sets CursorLine.</summary>
public int CursorLine
{
get { return txtQuery.ActiveTextAreaControl.Caret.Line; }
set { txtQuery.ActiveTextAreaControl.Caret.Line = value; }
}
/// <summary>Gets CursorOffset.</summary>
public int CursorOffset
{
get { return txtQuery.ActiveTextAreaControl.Caret.Offset; }
}
/// <summary>Gets EditorControl.</summary>
public Control EditorControl
{
get { return txtQuery; }
}
/// <summary>Gets FileFilter.</summary>
public string FileFilter
{
get { return "SQL�ļ�(*.sql)|*.sql|�����ļ� (*.*)|*.*"; }
}
/// <summary>Gets or sets FileName.</summary>
public string FileName
{
get { return txtQuery.FileName; }
set
{
txtQuery.FileName = value;
SetTabTextByFilename();
}
}
/// <summary>Gets a value indicating whether IsBusy.</summary>
public bool IsBusy { get; private set; }
/// <summary>Gets or sets a value indicating whether IsDirty.</summary>
public bool IsDirty
{
get { return _isDirty; }
set
{
if (_isDirty != value)
{
_isDirty = value;
SetTabTextByFilename();
}
}
}
/// <summary>Gets PrintDocument.</summary>
public PrintDocument PrintDocument
{
get { return txtQuery.PrintDocument; }
}
/// <summary>Gets SelectedText.</summary>
public string SelectedText
{
get { return txtQuery.ActiveTextAreaControl.SelectionManager.SelectedText; }
}
/// <summary>Gets TextFindService.</summary>
public ITextFindService TextFindService
{
get
{
if (_textFindService == null)
{
_textFindService = _services.Resolve<ITextFindService>();
}
return _textFindService;
}
}
/// <summary>Gets TotalLines.</summary>
public int TotalLines
{
get { return txtQuery.Document.TotalNumberOfLines; }
}
/// <summary>The execute query.</summary>
/// <param name="sql">The sql.</param>
public void ExecuteQuery(string sql)
{
if (IsBusy)
{
_hostWindow.DisplaySimpleMessageBox(this, "��ȴ���ǰ�������.", "��æ");
return;
}
if (_settings.ConnectionDefinition == null)
{
_hostWindow.DisplaySimpleMessageBox(this, "��ѡ��һ������.", "ѡ��һ������");
return;
}
lock (_syncLock)
{
IsBusy = true;
}
_runner = QueryRunner.Create(_settings.ProviderFactory, _settings.ConnectionDefinition.ConnectionString, _settings.EnableQueryBatching, _settings.CommandTimeout);
UseWaitCursor = true;
queryBackgroundWorker.RunWorkerAsync(sql);
}
/// <summary>The load highlighting provider.</summary>
public void LoadHighlightingProvider()
{
if (_highlightingProviderLoaded)
{
return;
}
// see: http://wiki.sharpdevelop.net/Syntax%20highlighting.ashx
string dir = Path.GetDirectoryName(GetType().Assembly.Location);
FileSyntaxModeProvider fsmProvider = new FileSyntaxModeProvider(dir);
HighlightingManager.Manager.AddSyntaxModeFileProvider(fsmProvider); // Attach to the text editor.
txtQuery.SetHighlighting("SQL");
_highlightingProviderLoaded = true;
}
/// <summary>The clear selection.</summary>
public void ClearSelection()
{
txtQuery.ActiveTextAreaControl.SelectionManager.ClearSelection();
}
/// <summary>The highlight string.</summary>
/// <param name="offset">The offset.</param>
/// <param name="length">The length.</param>
public void HighlightString(int offset, int length)
{
if (offset < 0 || length < 1)
{
return;
}
int endPos = offset + length;
txtQuery.ActiveTextAreaControl.SelectionManager.SetSelection(
txtQuery.Document.OffsetToPosition(offset),
txtQuery.Document.OffsetToPosition(endPos));
SetCursorByOffset(endPos);
}
/// <summary>The insert text.</summary>
/// <param name="text">The text.</param>
public void InsertText(string text)
{
if (string.IsNullOrEmpty(text))
{
return;
}
int offset = txtQuery.ActiveTextAreaControl.Caret.Offset;
// if some text is selected we want to replace it
if (txtQuery.ActiveTextAreaControl.SelectionManager.IsSelected(offset))
{
offset = txtQuery.ActiveTextAreaControl.SelectionManager.SelectionCollection[0].Offset;
txtQuery.ActiveTextAreaControl.SelectionManager.RemoveSelectedText();
}
txtQuery.Document.Insert(offset, text);
int newOffset = offset + text.Length; // new offset at end of inserted text
// now reposition the caret if required to be after the inserted text
if (CursorOffset != newOffset)
{
SetCursorByOffset(newOffset);
}
txtQuery.Focus();
}
/// <summary>The load file.</summary>
public void LoadFile()
{
txtQuery.LoadFile(FileName);
IsDirty = false;
}
/// <summary>The save file.</summary>
/// <exception cref="InvalidOperationException"></exception>
public void SaveFile()
{
if (FileName == null)
{
throw new InvalidOperationException("'�ļ���'����Ϊ��");
}
txtQuery.SaveFile(FileName);
IsDirty = false;
}
/// <summary>The set syntax.</summary>
/// <param name="name">The name.</param>
public void SetSyntax(string name)
{
LoadHighlightingProvider();
txtQuery.SetHighlighting(name);
}
/// <summary>The find string.</summary>
/// <param name="value">The value.</param>
/// <param name="startIndex">The start index.</param>
/// <param name="comparisonType">The comparison type.</param>
/// <returns>The find string.</returns>
public int FindString(string value, int startIndex, StringComparison comparisonType)
{
if (string.IsNullOrEmpty(value) || startIndex < 0)
{
return -1;
}
string text = AllText;
int pos = text.IndexOf(value, startIndex, comparisonType);
if (pos > -1)
{
ClearSelection();
HighlightString(pos, value.Length);
}
return pos;
}
/// <summary>The replace string.</summary>
/// <param name="value">The value.</param>
/// <param name="startIndex">The start index.</param>
/// <param name="length">The length.</param>
/// <returns>The replace string.</returns>
public bool ReplaceString(string value, int startIndex, int length)
{
if (value == null || startIndex < 0 || length < 0)
{
return false;
}
if ((startIndex + length) > AllText.Length)
{
return false;
}
txtQuery.Document.Replace(startIndex, length, value);
return true;
}
/// <summary>The set text find service.</summary>
/// <param name="textFindService">The text find service.</param>
public void SetTextFindService(ITextFindService textFindService)
{
// accept nulls infering a reset
_textFindService = textFindService;
}
/// <summary>The set cursor by location.</summary>
/// <param name="line">The line.</param>
/// <param name="column">The column.</param>
/// <returns>The set cursor by location.</returns>
public bool SetCursorByLocation(int line, int column)
{
if (line > TotalLines)
{
return false;
}
txtQuery.ActiveTextAreaControl.Caret.Line = line;
txtQuery.ActiveTextAreaControl.Caret.Column = column;
return true;
}
/// <summary>The set cursor by offset.</summary>
/// <param name="offset">The offset.</param>
/// <returns>The set cursor by offset.</returns>
public bool SetCursorByOffset(int offset)
{
if (offset >= 0)
{
txtQuery.ActiveTextAreaControl.Caret.Position = txtQuery.Document.OffsetToPosition(offset);
return true;
}
return false;
}
/// <summary>The cancel task.</summary>
public void CancelTask()
{
if (queryBackgroundWorker.IsBusy && _runner != null)
{
_runner.Cancel();
}
}
/// <summary>The execute task.</summary>
public void ExecuteTask()
{
if (!string.IsNullOrEmpty(SelectedText))
{
ExecuteQuery(SelectedText);
}
else
{
ExecuteQuery(AllText);
}
}
/// <summary>The set status.</summary>
/// <param name="text">The text.</param>
public void SetStatus(string text)
{
_status = text;
UpdateHostStatus();
}
public void SetRowCount(int? rows)
{
_rowCount = rows;
UpdateHostStatus();
}
/// <summary>The create default font.</summary>
/// <returns></returns>
protected Font CreateDefaultFont()
{
return new Font("Courier New", 8.25F, FontStyle.Regular, GraphicsUnit.Point);
}
/// <summary>The update host status.</summary>
protected void UpdateHostStatus()
{
_hostWindow.SetStatus(this, _status);
_hostWindow.SetResultCount(this, _rowCount);
}
/// <summary>The create query complete message.</summary>
/// <param name="start">The start.</param>
/// <param name="end">The end.</param>
/// <returns>The create query complete message.</returns>
private static string CreateQueryCompleteMessage(DateTime start, DateTime end)
{
TimeSpan ts = end.Subtract(start);
string msg = string.Format(
"��ѯ���, {0:00}:{1:00}.{2:000}",
ts.Minutes,
ts.Seconds,
ts.Milliseconds);
return msg;
}
/// <summary>The add tables.</summary>
private void AddTables()
{
ClearGridsAndTabs();
SetRowCount(null);
if (Batch != null)
{
string nullText = _settings.NullText;
int counter = 1;
_resizingGrid = true;
foreach (Query query in Batch.Queries)
{
DataSet ds = query.Result;
if (ds != null)
{
foreach (DataTable dt in ds.Tables)
{
DataGridView grid = new DataGridView();
DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
grid.AllowUserToAddRows = false;
grid.AllowUserToDeleteRows = false;
grid.Dock = DockStyle.Fill;
grid.Name = "gridResults_" + counter;
grid.ReadOnly = true;
grid.DataSource = dt;
grid.DataError += GridDataError;
grid.DefaultCellStyle = cellStyle;
cellStyle.NullValue = nullText;
cellStyle.Font = CreateDefaultFont();
grid.DataBindingComplete += GridDataBindingComplete;
grid.Disposed += GridDisposed;
grid.ColumnWidthChanged += OnColumnWidthChanged;
TabPage tabPage = new TabPage();
tabPage.Controls.Add(grid);
tabPage.Name = "tabPageResults_" + counter;
tabPage.Padding = new Padding(3);
tabPage.Text = string.Format("{0}/�� {1}", ds.DataSetName, counter);
tabPage.UseVisualStyleBackColor = false;
_resultsTabControl.TabPages.Add(tabPage);
// create a reasonable default max width for columns
int maxColWidth = Math.Max(grid.ClientSize.Width / 2, 100);
// Autosize the columns then change the widths, gleaned from SO - http://stackoverflow.com/a/1031871/276563
grid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
for (int i = 0; i < grid.Columns.Count; i++)
{
int columnWidth = grid.Columns[i].Width;
grid.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
string headerText = grid.Columns[i].HeaderText;
if (!string.IsNullOrEmpty(headerText) && _columnSizes.ContainsKey(headerText))
{
// use the previous column size in case its been adjusted etc
grid.Columns[i].Width = _columnSizes[headerText];
}
else
{
// reset to a the smaller of the 2 sizes, this is mainly for the bigger text columns that throw the size out
grid.Columns[i].Width = Math.Min(columnWidth, maxColWidth);
if (!string.IsNullOrEmpty(headerText))
{
_columnSizes[headerText] = grid.Columns[i].Width;
}
}
}
// set the row count for the first tab for now.
if (counter == 1)
{
SetRowCount(dt.Rows.Count);
}
counter++;
}
}
}
if (!string.IsNullOrEmpty(Batch.Messages))
{
RichTextBox rtf = new RichTextBox();
rtf.Font = CreateDefaultFont();
rtf.Dock = DockStyle.Fill;
rtf.ScrollBars = RichTextBoxScrollBars.ForcedBoth;
rtf.Text = Batch.Messages;
TabPage tabPage = new TabPage();
tabPage.Controls.Add(rtf);
tabPage.Name = "tabPageResults_Messages";
tabPage.Padding = new Padding(3);
tabPage.Dock = DockStyle.Fill;
tabPage.Text = Resources.Messages;
tabPage.UseVisualStyleBackColor = false;
_resultsTabControl.TabPages.Add(tabPage);
}
_resizingGrid = false;
}
}
public void OnColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
if (_resizingGrid)
{
return;
}
string headerText = e.Column.HeaderText;
if (!string.IsNullOrEmpty(headerText))
{
_columnSizes[headerText] = e.Column.Width;
}
}
/// <summary>Iterate backweards through list of tabs disposing grid and removing the tab page.</summary>
private void ClearGridsAndTabs()
{
try
{
_cleaningTabs = true;
for (int i = _resultsTabControl.TabPages.Count - 1; i >= 0; i--)
{
TabPage tabPage = _resultsTabControl.TabPages[i];
if (tabPage.Controls.Count > 0)
{
tabPage.Controls[0].Dispose(); // dispose grid
}
_resultsTabControl.TabPages.Remove(tabPage);
tabPage.Dispose();
}
}
finally
{
_cleaningTabs = false;
}
}
private void SetResultCountOnTabSelectedIndexChanged(object sender, EventArgs e)
{
if (_cleaningTabs)
{
return;
}
// get the tab
var tabPage = _resultsTabControl.TabPages[_resultsTabControl.SelectedIndex];
// get the grid control, should be first
var dataGridView = tabPage.Controls[0] as DataGridView;
// default to blank row count
int? rows = null;
if (dataGridView != null)
{
var data = dataGridView.DataSource as DataTable;
if (data != null)
{
rows = data.Rows.Count;
}
}
_rowCount = rows;
UpdateHostStatus();
}
/// <summary>The document document changed.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void DocumentDocumentChanged(object sender, DocumentEventArgs e)
{
IsDirty = true;
}
/// <summary>Change the format style of date time columns. This has to be done post-bind.</summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GridDataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
DataGridView grid = sender as DataGridView;
if (grid == null)
{
return;
}
DataTable dt = grid.DataSource as DataTable;
if (dt == null)
{
return;
}
string nullText = _settings.NullText;
string dateTimeFormat = _settings.DateTimeFormat;
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Columns[i].DataType == typeof(DateTime))
{
DataGridViewCellStyle dateCellStyle = new DataGridViewCellStyle();
dateCellStyle.NullValue = nullText;
dateCellStyle.Format = dateTimeFormat;
grid.Columns[i].DefaultCellStyle = dateCellStyle;
}
}
}
/// <summary>The grid data error.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void GridDataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.ThrowException = false;
}
/// <summary>Clean up event subscriptions.</summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GridDisposed(object sender, EventArgs e)
{
DataGridView grid = sender as DataGridView;
if (grid == null)
{
return;
}
grid.DataBindingComplete -= GridDataBindingComplete;
grid.Disposed -= GridDisposed;
grid.ColumnWidthChanged -= OnColumnWidthChanged;
}
/// <summary>The query form_ activated.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void QueryForm_Activated(object sender, EventArgs e)
{
UpdateHostStatus();
}
/// <summary>The query form_ deactivate.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void QueryForm_Deactivate(object sender, EventArgs e)
{
_hostWindow.SetStatus(this, string.Empty);
}
/// <summary>The query form_ form closing.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void QueryForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (_isDirty)
{
DialogResult saveFile = _hostWindow.DisplayMessageBox(
this,
"�����Ѹ��ģ��Ƿ��ļ�?\r\n" + TabText, "����ı�?",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1,
0,
null,
null);
if (saveFile == DialogResult.Cancel)
{
e.Cancel = true;
}
else if (saveFile == DialogResult.Yes)
{
CommandManager.GetCommandInstance<SaveFileCommand>().Execute();
}
}
}
/// <summary>The query form_ load.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void QueryForm_Load(object sender, EventArgs e)
{
}
/// <summary>The runner batch progress.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void RunnerBatchProgress(object sender, BatchProgressEventArgs e)
{
// push the progress % through to the background worker
decimal i = Math.Max(1, e.Index);
decimal count = Math.Max(1, e.Count);
queryBackgroundWorker.ReportProgress(Convert.ToInt32(i / count * 100m));
}
/// <summary>The set tab text by filename.</summary>
private void SetTabTextByFilename()
{
string dirty = string.Empty;
string text = "���";
string tabtext;
if (_isDirty)
{
dirty = " *";
}
if (txtQuery.FileName != null)
{
text = FileName;
tabtext = Path.GetFileName(FileName);
}
else
{
text += _settings.GetUntitledDocumentCounter();
tabtext = text;
}
TabText = tabtext + dirty;
ToolTipText = text + dirty;
}
/// <summary>The copy tool strip menu item_ click.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
CopyForm win = null;
try
{
DataGridView grid = (DataGridView)_resultsTabControl.SelectedTab.Controls[0];
if (grid.SelectedCells.Count == 0)
{
return;
}
win = new CopyForm();
if (win.ShowDialog() == DialogResult.Cancel)
{
return;
}
SortedList headers = new SortedList();
SortedList rows = new SortedList();
string delimiter = win.Delimiter;
string line = string.Empty;
for (int i = 0; i < grid.SelectedCells.Count; i++)
{
DataGridViewCell cell = grid.SelectedCells[i];
DataGridViewColumn col = cell.OwningColumn;
if (!headers.ContainsKey(col.Index))
{
headers.Add(col.Index, col.Name);
}
if (!rows.ContainsKey(cell.RowIndex))
{
rows.Add(cell.RowIndex, cell.RowIndex);
}
}
if (win.IncludeHeaders)
{
for (int i = 0; i < headers.Count; i++)
{
line += (string)headers.GetByIndex(i);
if (i != headers.Count)
{
line += delimiter;
}
}
line += "\r\n";
}
for (int i = 0; i < rows.Count; i++)
{
DataGridViewRow row = grid.Rows[(int)rows.GetKey(i)];
DataGridViewCellCollection cells = row.Cells;
for (int j = 0; j < headers.Count; j++)
{
DataGridViewCell cell = cells[(int)headers.GetKey(j)];
if (cell.Selected)
{
line += cell.Value;
}
if (j != (headers.Count - 1))
{
line += delimiter;
}
}
line += "\r\n";
}
if (!string.IsNullOrEmpty(line))
{
Clipboard.Clear();
Clipboard.SetText(line);
_hostWindow.SetStatus(this, "��ѡ�����Ѹ��Ƶ�������");
}
}
finally
{
if (win != null)
{
win.Dispose();
}
}
}
/// <summary>The query background worker_ do work.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void queryBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
string sql = (string)e.Argument;
_runner.BatchProgress += RunnerBatchProgress;
_runner.ExecuteQuery(sql);
}
/// <summary>The query background worker_ progress changed.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void queryBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
SetStatus(string.Format("������{0}%...", e.ProgressPercentage));
}
/// <summary>The query background worker_ run worker completed.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void queryBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
_runner.BatchProgress -= RunnerBatchProgress;
if (e.Error != null)
{
// todo: improve!
_hostWindow.DisplaySimpleMessageBox(this, e.Error.Message, "����");
SetStatus(e.Error.Message);
}
else
{
_hostWindow.SetPointerState(Cursors.Default);
string message = CreateQueryCompleteMessage(_runner.Batch.StartTime, _runner.Batch.EndTime);
if (_runner.Exception != null)
{
message = "���� - " + message;
}
AddTables();
SetStatus(message);
txtQuery.Focus();
}
}
finally
{
UseWaitCursor = false;
lock (_syncLock)
{
IsBusy = false;
}
}
}
/// <summary>The select all tool strip menu item_ click.</summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
DataGridView grid = (DataGridView)_resultsTabControl.SelectedTab.Controls[0];
grid.SelectAll();
}
}
}
|