using System; using System.Collections.Generic; using System.Windows.Forms; using com.andoutomo.kybernetes.control; using com.andoutomo.kybernetes.data.DAO; using System.Drawing; using com.andoutomo.kybernetes.data.accessor; using System.Runtime.InteropServices; using com.andoutomo.kybernetes.data; namespace com.andoutomo.kybernetes.view { public partial class BaseForm : Form { public BaseForm() { InitializeComponent(); List initialText = new List(); initialText.Add("#####################################################"); initialText.Add("# " + AppInfoContainer.Title + " " + AppInfoContainer.Description); initialText.Add("# Version " + AppInfoContainer.VersionNo); initialText.Add("# " + AppInfoContainer.CopyRight); initialText.Add("# "); initialText.Add("#####################################################"); addMultiText(initialText); addPrompt(); history = new CmdHistory(); this.Text = AppInfoContainer.Title + " " + AppInfoContainer.Description; Echo = true; txtInput.Focus(); } private CmdHistory history; /// /// カテゴリ設定ダイアログを表示します。 /// /// public void invokeCategSettingDialog(List arg) { CategorySetting categSetting = new CategorySetting(); categSetting.StartPosition = FormStartPosition.CenterParent; categSetting.setCategoryList(arg); categSetting.ShowDialog(); } /// /// バージョン情報を表示します /// public void invokeCreditDialog() { Credit creditForm = new Credit(); creditForm.StartPosition = FormStartPosition.CenterParent; creditForm.ShowDialog(); } /// /// エクスポート用のファイルダイアログを開いて選択したファイルパスを返します。 /// /// public string invokeExpDialog() { DialogResult result = this.expData.ShowDialog(); if (result == DialogResult.OK) { return this.expData.FileName; } else { return string.Empty; } } /// /// ダンプ用のファイルダイアログを開いて選択したファイルパスを返します。 /// /// public string invokeDmpDialog() { DialogResult result = this.dmpData.ShowDialog(); if (result == DialogResult.OK) { return this.dmpData.FileName; } return string.Empty; } /// /// バッチ呼び出しダイアログを呼び出します。 /// /// public string invokeShellDialog() { DialogResult result = this.selSh.ShowDialog(); if (result == DialogResult.OK) { return this.selSh.FileName; } return string.Empty; } /// /// タイムエリア設定画面を表示します。 /// /// public void invokeTimeareaSettingDialog(List arg) { TimeAreaSetting setting = new TimeAreaSetting(); setting.StartPosition = FormStartPosition.CenterParent; setting.setTimeareaList(arg); setting.ShowDialog(); } /// /// コンソールに文字列を表示します。 /// /// 表示したい文字列 public void addText(string args) { rConsole.AppendText(args + System.Environment.NewLine); KybernetesLogger.Log.trace(args); } /// /// コンソールに複数文章を追加します。 /// /// 追加したい文章群 public void addMultiText(List messages) { foreach (string message in messages) { addText(message); } rConsole.AppendText(System.Environment.NewLine); } private void addPrompt() { rConsole.AppendText("> "); } public int getPanelSize() { return this.pnlTask.Width; } /// /// コンソールをクリアします。 /// public void clearText() { rConsole.Clear(); rTotalConsole.Clear(); rEstConsole.Clear(); } private bool exitSwitch = false; public bool ExitSwitch { set { exitSwitch = value; } } private int lastRow = 17; /// /// パネルを追加します。 /// /// public void addPanel(TaskData data) { Panel targetPanel = new PanelController(this).createRow(lastRow, data); pnlTask.Controls.Add(targetPanel); lastRow += targetPanel.Height - 1; } /// /// インデックスパネルを追加します /// /// public void addIndexPanel(string timeArea) { Panel targetPanel = new IndexPanelController().createRow(timeArea, this.pnlTask.Width, lastRow, frColor); pnlTask.Controls.Add(targetPanel); lastRow += targetPanel.Height - 1; } /// /// パネルがダブルクリックされた時に対応します。IDをテキストボックスに転記します。 /// /// public void AddIDToText(string data) { this.txtInput.Text += data + " "; txtInput.Focus(); this.txtInput.Select(this.txtInput.Text.Length, 0); } /// /// パネルをクリアします。 /// public void clearPanel() { this.pnlTask.AutoScrollPosition = new Point(0, 0); int dummy = pnlTask.Controls.Count; for (int h = dummy; h > 0; h--) { Control ctrl = pnlTask.Controls[h - 1]; for (int i = ctrl.Controls.Count; i > 0; i--) { ctrl.Controls[i - 1].Dispose(); } ctrl.Dispose(); } pnlTask.Controls.Clear(); //先頭行は足す pnlTask.Controls.Add(new CaptionPanelController().createRow(this.pnlTask.Width, frColor)); lastRow = 17; } /// /// コマンド内容を表示するかどうかを決定します。 /// public bool Echo { get; set; } /// /// コマンド入力を受け付けます。 /// /// /// private void txtInput_KeyDown(object sender, KeyEventArgs e) { int currentYPosition; int currentScrollHeight = this.pnlTask.Height - 25; switch (e.KeyCode) { case Keys.Enter: e.SuppressKeyPress = true; doCommand(); break; case Keys.Space: if (e.Control) { e.SuppressKeyPress = true; if (txtInput.ImeMode == ImeMode.Off) { txtInput.ImeMode = ImeMode.On; } else { txtInput.ImeMode = ImeMode.Off; } } break; case Keys.Escape: e.SuppressKeyPress = true; history.resetPosition(); txtInput.Clear(); break; case Keys.Up: e.SuppressKeyPress = true; txtInput.Text = history.prevCommand(); txtInput.Select(this.txtInput.Text.Length, 0); break; case Keys.Down: e.SuppressKeyPress = true; txtInput.Text = history.nextCommand(); txtInput.Select(this.txtInput.Text.Length, 0); break; case Keys.PageDown: currentYPosition = Math.Abs(this.pnlTask.AutoScrollPosition.Y); if (e.Control) { this.pnlTask.AutoScrollPosition = new Point(0, currentYPosition + 25); } else { this.pnlTask.AutoScrollPosition = new Point(0, currentYPosition + currentScrollHeight); } break; case Keys.PageUp: currentYPosition = Math.Abs(this.pnlTask.AutoScrollPosition.Y); if (e.Control) { this.pnlTask.AutoScrollPosition = new Point(0, currentYPosition - 25); } else { this.pnlTask.AutoScrollPosition = new Point(0, currentYPosition - currentScrollHeight); } break; case Keys.Tab: if (e.Control) { tabChange(); } break; } } /// /// コマンドを実行します /// private void doCommand() { rConsole.Focus(); if (Echo) { addText(txtInput.Text); } KybernetesLogger.Log.trace("[dispatch]" + txtInput.Text); string result = wkOnCmdDispatch(txtInput.Text.Trim()); if (!string.IsNullOrEmpty(result)) { addText(result); } addPrompt(); if (!string.IsNullOrEmpty(txtInput.Text)) { history.stackCmd(txtInput.Text); } txtInput.Clear(); txtInput.ImeMode = ImeMode.Off; //panelResize(); if (exitSwitch == true) { this.Close(); } txtInput.Focus(); } /// /// 文字入力ボックスを表示します。 /// /// /// public string showInputBox(string prompt) { return this.showInputBox(prompt, string.Empty); } /// /// 文字入力ボックスを表示します。 /// /// /// /// public string showInputBox(string prompt, string defaultData) { return showInputBox(prompt, defaultData, ImeMode.Off); } /// /// 文字入力ボックスを表示します。 /// /// /// /// /// public string showInputBox(string prompt, string defaultData, ImeMode imeMode) { InputBox inputBox = new InputBox(prompt, defaultData); inputBox.StartPosition = FormStartPosition.CenterParent; inputBox.ImeMode = imeMode; inputBox.Owner = this; DialogResult res = inputBox.ShowDialog(); if (res == DialogResult.OK) { return InputDialogData; } return null; } /// /// 文字入力ボックスを表示します。 /// /// /// /// public string showInputBox(string prompt, ImeMode imeMode) { return showInputBox(prompt, string.Empty, imeMode); } /// /// 文字入力ボックスを表示します。プロンプトなし版です。 /// /// public string showInputBox() { return showInputBox(""); } /// /// プロンプトで指定した値を(プロンプトがここに)格納します。 /// public string InputDialogData { private get; set; } /// /// ドロップダウン式リストを表示します。 /// /// /// public string showDropBoxInputBox(List list, string prompt,out bool isOK) { DropBoxInputBox inputBox = new DropBoxInputBox(prompt); inputBox.StartPosition = FormStartPosition.CenterParent; inputBox.setDropData(list); inputBox.Owner = this; DialogResult res = inputBox.ShowDialog(); if (res == DialogResult.OK) { isOK = true; return InputDialogData; } isOK = false; return null; } /// /// ドロップダウン式リストを表示します。デフォルト表示を追加しています。 /// /// /// /// /// public string showDropBoxInputBox(List list, string prompt, string defaultData ,out bool isOK) { DropBoxInputBox inputBox = new DropBoxInputBox(prompt, defaultData); inputBox.StartPosition = FormStartPosition.CenterParent; inputBox.setDropData(list); inputBox.Owner = this; DialogResult res = inputBox.ShowDialog(); if (res == DialogResult.OK) { isOK = true; return InputDialogData; } isOK = false; return null; } /// /// ファイル選択ダイアログつきインプットボックスを表示します。 /// /// /// public string showFileInputBox(string prompt) { FileInputBox inputBox = new FileInputBox(prompt); inputBox.StartPosition = FormStartPosition.CenterParent; inputBox.Owner = this; DialogResult res = inputBox.ShowDialog(); if (res == DialogResult.OK) { return InputDialogData; } return null; } /// /// マウスでコンソールをドラッグした時に、選択対象をクリップボードにコピーします。 /// /// /// private void rConsole_MouseUp(object sender, MouseEventArgs e) { Clipboard.SetDataObject(rConsole.SelectedText.Trim()); //txtInput.Text += rConsole.SelectedText.Trim(); txtInput.Focus(); //選択状態を解除する this.txtInput.Select(this.txtInput.Text.Length, 0); } /// /// 選択対象をクリップボードにコピーします。サブコンソール版です。 /// /// /// private void rSubConsole_MouseUp(object sender, MouseEventArgs e) { Clipboard.SetDataObject(rEstConsole.SelectedText.Trim()); txtInput.Focus(); this.txtInput.Select(this.txtInput.Text.Length, 0); } /// /// 背景色設定を呼び出します。コンテンツすべてが対象です。 /// public bool setPnlBackground() { DialogResult res = this.BGColorDlg.ShowDialog(); if (res == System.Windows.Forms.DialogResult.OK) { pnlTask.BackColor = BGColorDlg.Color; rEstConsole.BackColor = BGColorDlg.Color; rConsole.BackColor = BGColorDlg.Color; rTotalConsole.BackColor = BGColorDlg.Color; txtInput.BackColor = BGColorDlg.Color; return true; } else { return false; } } /// /// 前景色設定を呼び出します. /// /// public bool setPnlForeground() { DialogResult res = this.FRColorDlg.ShowDialog(); if (res == System.Windows.Forms.DialogResult.OK) { frColor = FRColorDlg.Color; rEstConsole.ForeColor = FRColorDlg.Color; rConsole.ForeColor = FRColorDlg.Color; rTotalConsole.ForeColor = FRColorDlg.Color; txtInput.ForeColor = FRColorDlg.Color; return true; } else { return false; } } private Color frColor = Color.White; /// /// スプリッターが動いた時に、入力ボックスにフォーカスを移します。 /// /// /// private void splBase_SplitterMoved(object sender, SplitterEventArgs e) { txtInput.Focus(); } /// /// タイマーを呼び出します。 /// タイマーはモードレスダイアログとして表示されます。 /// /// public void showTimer(int second) { ClockForm form; if (second > 0) { form = new ClockForm(second * 60); } else { form = new ClockForm(); } form.Owner = this; form.Show(); } /// /// タイマーを呼び出します。タイトルも付けます。 /// /// /// public void showTimer(int second, string title) { ClockForm form; if (second > 0) { form = new ClockForm(second * 60, title); } else { form = new ClockForm(title); } form.Owner = this; form.Show(); } #region 点滅ロジック [DllImport("user32.dll")] static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi); /// /// 画面点滅制御用Struct /// [StructLayout(LayoutKind.Sequential)] struct FLASHWINFO { public UInt32 cbSize; // FLASHWINFO構造体のサイズ public IntPtr hwnd; // 点滅対象のウィンドウ・ハンドル public UInt32 dwFlags; // 以下の「FLASHW_XXX」のいずれか public UInt32 uCount; // 点滅する回数 public UInt32 dwTimeout; // 点滅する間隔(ミリ秒単位) } //private const UInt32 FLASHW_STOP = 0; // 点滅を止める //private const UInt32 FLASHW_CAPTION = 1; // タイトルバーを点滅させる //private const UInt32 FLASHW_TRAY = 2; // タスクバー・ボタンを点滅させる private const UInt32 FLASHW_ALL = 3; // タスクバー・ボタンとタイトルバーを点滅させる //private const UInt32 FLASHW_TIMER = 4; // FLASHW_STOPが指定されるまでずっと点滅させる //private const UInt32 FLASHW_TIMERNOFG = 12; // ウィンドウが最前面に来るまでずっと点滅させる /// /// タスクバーを点滅させる /// public void showAlert() { FLASHWINFO fInfo = new FLASHWINFO(); fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo)); fInfo.hwnd = this.Handle; fInfo.dwFlags = FLASHW_ALL; fInfo.uCount = 5; // 点滅回数 fInfo.dwTimeout = 0; FlashWindowEx(ref fInfo); } #endregion /// /// バッチコマンド用です。ちょっと迂遠ですが、バッチで読み込んだコマンドを /// フォームで受け取り、さらにもう一回ディスパッチをフォームから依頼します。 /// /// public void cmdForBatch(string command) { this.addText(wkOnCmdDispatch(command)); } /// /// コマンド実行時のハンドラです。 /// /// /// public delegate void CmdDispatchEventHandler(object sender, CmdDispatchEventArg e); /// /// コマンドイベントです。コマンド実行時処理をここに設定してください。 /// public event CmdDispatchEventHandler onCmdDispatch; /// /// コマンドディスパッチを実施し、戻り値(CmdDispatchEventArg.Result)から /// 画面表示用のテキストを受領します。 /// /// /// string wkOnCmdDispatch(string command) { if (onCmdDispatch != null) { CmdDispatchEventArg args = new CmdDispatchEventArg(); args.Command = command; onCmdDispatch(this, args); return args.Result; } else { throw new KybernetesApplicationException(); } } /// /// 時間予測コンソールに文字を追加します。 /// /// public void showOnEstConsole(List estTimeStr) { this.rEstConsole.Text = string.Empty; foreach (EstTextSet str in estTimeStr) { this.rEstConsole.AppendText(str.Text); int currentSelectionStart = rEstConsole.SelectionStart - str.Text.Length; Color tmpColor = str.TxtColor; if (tmpColor == Color.Transparent) { //tmpColor = this.frColor; tmpColor =rEstConsole.ForeColor; } //色を変更する rEstConsole.Select(currentSelectionStart, str.Text.Length); rEstConsole.SelectionColor = tmpColor; rEstConsole.Select(rEstConsole.Text.Length, 0); } } /// /// 合計時間コンソールに文字を追加します。 /// /// public void showOnTotalConsole(List dataList) { this.rTotalConsole.Text = string.Empty; Font baseFont = rTotalConsole.SelectionFont; foreach (EstTextSet data in dataList) { this.rTotalConsole.AppendText(data.Text); int currentSelectionStart = rTotalConsole.SelectionStart - data.Text.Length; Color tmpColor = data.TxtColor; if (tmpColor == Color.Transparent) { tmpColor = rTotalConsole.ForeColor; } //色変更する rTotalConsole.Select(currentSelectionStart,data.Text.Length); rTotalConsole.SelectionColor = tmpColor; rTotalConsole.Select(rTotalConsole.Text.Length, 0); } baseFont.Dispose(); } /// /// 取得したデータを元にタスクパネルにタスクを表示します。 /// /// public void showOnPanel(List taskList) { clearPanel(); string wkAreaForIndex = ""; DateComponent wkIndexDate = new DateComponent("19000101"); bool wkIsComplete = false; foreach (TaskData data in taskList) { //data.Today = todayDate; if (!data.isComplete) { //日付が違う場合 if (wkIndexDate.calculateDateDiff(data.DoDate) != 0 || wkIsComplete) { string wkBranc = " "; addIndexPanel(wkBranc); } if (wkAreaForIndex != data.TimeArea || wkIndexDate.calculateDateDiff(data.DoDate) != 0 || wkIsComplete) { string wkIndex = "-- " + data.TimeArea + " -- on " + data.DoDate.getDateString("yyyy/MM/dd"); addIndexPanel(wkIndex); } wkAreaForIndex = data.TimeArea; wkIndexDate = data.DoDate; wkIsComplete = false; } else { //直前の日付が未来のときのみ if (wkIndexDate.calculateDateDiff(data.DoDate) > 0) { string wkBranc = " "; addIndexPanel(wkBranc); } wkAreaForIndex = data.TimeArea; wkIndexDate = data.DoDate; wkIsComplete = true; } addPanel(data); } } private void splConsole_SplitterMoved(object sender, SplitterEventArgs e) { txtInput.Focus(); } private void tabInfo_SelectedIndexChanged(object sender, EventArgs e) { txtInput.Focus(); } private void tabInfo_MouseUp(object sender, MouseEventArgs e) { txtInput.Focus(); } private void rForcastConsole_MouseUp(object sender, MouseEventArgs e) { Clipboard.SetDataObject(rTotalConsole.SelectedText.Trim()); txtInput.Focus(); this.txtInput.Select(this.txtInput.Text.Length, 0); } public TaskData taskFromTemplate { private get; set; } public TaskData showTemplateTaskBox(List dataList) { TemplateBox tempBox = new TemplateBox(); tempBox.setTemplateData(dataList); tempBox.Owner = this; DialogResult res = tempBox.ShowDialog(); if (res == DialogResult.OK) { return taskFromTemplate; } return null; } private void tabChange() { if (tabInfo.SelectedIndex == 0) { tabInfo.SelectedIndex = 1; } else { tabInfo.SelectedIndex = 0; } } } /// /// 見積もり用コンソールの文字列クラス /// public class EstTextSet { public string Text { get; private set; } public Color TxtColor { get; private set; } public EstTextSet(string text, Color prtxtColor) { this.Text = text; this.TxtColor = prtxtColor; } public EstTextSet(string text): this(text, Color.Transparent) { } public EstTextSet(): this(System.Environment.NewLine) { } } }