// ================================================================================================ // // フォーム処理に関するユーティリティクラスソース。 // // // Copyright (C) 2012 Honeplus. All rights reserved. // // Honeplus // ================================================================================================ namespace Honememo.Wptscs.Utilities { using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Windows.Forms; using Honememo.Models; // ※ プロパティを含むので、そのまま他のプロジェクトに流用することはできない using Honememo.Wptscs.Properties; /// /// フォーム処理に関するユーティリティクラスです。 /// public static class FormUtils { #region リソース関連 /// /// バージョン情報を含んだアプリケーション名を返す。 /// /// アプリケーション名 public static string ApplicationName() { // アセンブリからバージョン情報を取得し、書式化して返す // ビルド番号・リビジョンは無視 // ※例外なし。もし万が一発生する場合はそのまま投げる Version ver = Assembly.GetExecutingAssembly().GetName().Version; return string.Format(Resources.ApplicationName, ver.Major, ver.Minor); } /// /// 指定されたファイルを UserAppDataPath /// → 旧バージョンのUserAppDataPath /// → StartupPath の順に探索し、その際のパスを返す。 /// /// ファイル名。 /// 探索する旧バージョンの最大。 /// ファイルが存在したパス、どこにも存在しない場合はnull /// アセンブリ名が変わっている場合、旧バージョンは探索不可。 public static string SearchUserAppData(string fileName, string compatible) { // ※ 以下GetFilesAtUserAppDataと共通化してもよいが、性能に影響あるかと考え自前で処理 // 現在の UserAppDataPath を探索 string path = Path.Combine(Application.UserAppDataPath, fileName); if (File.Exists(path)) { return path; } // 可能であれば、旧バージョンの UserAppDataPath を探索 if (!string.IsNullOrEmpty(compatible)) { // ファイルが見つかるまで探索 foreach (string dir in FormUtils.GetCompatibleUserAppDataPaths(compatible)) { path = Path.Combine(dir, fileName); if (File.Exists(path)) { return path; } } } // どこにも無い場合は、exeと同じフォルダを探索 path = Path.Combine(Application.StartupPath, fileName); if (File.Exists(path)) { return path; } return null; } /// /// 指定されたファイルを UserAppDataPath /// → StartupPath の順に探索し、その際のパスを返す。 /// /// ファイル名。 /// ファイルが存在したパス、どこにも存在しない場合はnull public static string SearchUserAppData(string fileName) { // オーバーロードメソッドをコール return FormUtils.SearchUserAppData(fileName, null); } /// /// UserAppDataPath /// → 旧バージョンのUserAppDataPath /// → StartupPath から、指定した検索パターンに一致するファイル名を返す。 /// /// ファイル名と対応させる検索文字列。 /// 探索する旧バージョンの最大。 /// /// 指定した検索パターンに一致するファイル名を格納するString配列。ファイル名には完全パスを含む。 /// 同名のファイルが複数のパスに存在する場合、最初に発見したもののみを返す。 /// /// に有効なパターンが含まれていない場合。 /// nullの場合。 /// 呼び出し元に、必要なアクセス許可がない場合。 /// アセンブリ名が変わっている場合、旧バージョンは探索不可。 public static string[] GetFilesAtUserAppData(string searchPattern, string compatible) { // 現在の UserAppDataPath を探索 List files = new List(); IgnoreCaseSet names = new IgnoreCaseSet(); if (Directory.Exists(Application.UserAppDataPath)) { FormUtils.MergeFiles(files, names, Directory.GetFiles(Application.UserAppDataPath, searchPattern)); } // 可能であれば、旧バージョンの UserAppDataPath を探索 if (!string.IsNullOrEmpty(compatible)) { // 各ディレクトリのファイル名を取得 foreach (string dir in FormUtils.GetCompatibleUserAppDataPaths(compatible)) { FormUtils.MergeFiles(files, names, Directory.GetFiles(dir, searchPattern)); } } // 最後に、exeと同じフォルダを探索 FormUtils.MergeFiles(files, names, Directory.GetFiles(Application.StartupPath, searchPattern)); return files.ToArray(); } /// /// UserAppDataPath /// → StartupPath から、指定した検索パターンに一致するファイル名を返す。 /// /// ファイル名と対応させる検索文字列。 /// /// 指定した検索パターンに一致するファイル名を格納するString配列。ファイル名には完全パスを含む。 /// 同名のファイルが複数のパスに存在する場合、最初に発見したもののみを返す。 /// /// に有効なパターンが含まれていない場合。 /// nullの場合。 /// 呼び出し元に、必要なアクセス許可がない場合。 public static string[] GetFilesAtUserAppData(string searchPattern) { // オーバーロードメソッドをコール return FormUtils.GetFilesAtUserAppData(searchPattern, null); } /// /// UserAppDataPath → StartupPath から、全ファイル名を返す。 /// /// /// フォルダ内の全ファイル名を格納するString配列。ファイル名には完全パスを含む。 /// 同名のファイルが複数のパスに存在する場合、最初に発見したもののみを返す。 /// /// 呼び出し元に、必要なアクセス許可がない場合。 public static string[] GetFilesAtUserAppData() { // オーバーロードメソッドをコール return FormUtils.GetFilesAtUserAppData("*", null); } /// /// 文字列中のファイル名に使用できない文字を「_」に置換。 /// また、&nbsp;由来の半角スペース (u00a0) も普通の半角スペース (u0020) に置換する。 /// /// ファイル名。 /// 置換後のファイル名。 public static string ReplaceInvalidFileNameChars(string fileName) { // 渡された文字列にファイル名に使えない文字が含まれている場合、_ に置き換える string result = fileName; foreach (char c in Path.GetInvalidFileNameChars()) { result = result.Replace(c, '_'); } //  由来の半角スペース (u00a0) も普通の半角スペース (u0020) に置き換える result = result.Replace(' ', ' '); return result; } #endregion #region null値許容メソッド /// /// nullの場合に空の文字列を返す。 /// /// 値をするセル。nullも可。 /// 渡されたセルのした結果。nullの場合には空の文字列。 public static string ToString(DataGridViewCell obj) { return FormUtils.ToString(obj, string.Empty); } /// /// nullの場合に指定された文字列を返す。 /// /// 値をするセル。nullも可。 /// 渡されたセルがnullの場合に返される文字列。nullも可。 /// 渡されたセルのした結果。nullの場合には指定された文字列。 public static string ToString(DataGridViewCell obj, string nullStr) { if (obj == null) { return nullStr; } else if (obj.Value == null) { return nullStr; } return obj.Value.ToString(); } #endregion #region ダイアログ /// /// 単純デザインの通知ダイアログ(入力された文字列を表示)。 /// /// メッセージ。 public static void InformationDialog(string msg) { // 渡された文字列で通知ダイアログを表示 MessageBox.Show( msg, Resources.InformationTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// 単純デザインの通知ダイアログ(入力された文字列を書式化して表示)。 /// /// 書式項目を含んだメッセージ。 /// 書式設定対象オブジェクト配列。 public static void InformationDialog(string format, params object[] args) { // オーバーロードメソッドをコール FormUtils.InformationDialog(string.Format(format, args)); } /// /// 単純デザインの警告ダイアログ(入力された文字列を表示)。 /// /// メッセージ。 public static void WarningDialog(string msg) { // 渡された文字列で警告ダイアログを表示 MessageBox.Show( msg, Resources.WarningTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); } /// /// 単純デザインの警告ダイアログ(入力された文字列を書式化して表示)。 /// /// 書式項目を含んだメッセージ。 /// 書式設定対象オブジェクト配列。 public static void WarningDialog(string format, params object[] args) { // オーバーロードメソッドをコール FormUtils.WarningDialog(string.Format(format, args)); } /// /// 単純デザインのエラーダイアログ(入力された文字列を表示)。 /// /// メッセージ。 public static void ErrorDialog(string msg) { // 渡された文字列でエラーダイアログを表示 MessageBox.Show( msg, Resources.ErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } /// /// 単純デザインのエラーダイアログ(入力された文字列を書式化して表示)。 /// /// 書式項目を含んだメッセージ。 /// 書式設定対象オブジェクト配列。 public static void ErrorDialog(string format, params object[] args) { // オーバーロードメソッドをコール FormUtils.ErrorDialog(string.Format(format, args)); } #endregion #region テーブル処理 /// /// が空行かを判定する。 /// /// 1行。 /// 空行の場合true public static bool IsEmptyRow(DataGridViewRow row) { foreach (DataGridViewCell cell in row.Cells) { if (!string.IsNullOrEmpty(FormUtils.ToString(cell))) { return false; } } return true; } #endregion #region 内部メソッド /// /// 指定されたバージョン以上の旧バージョンのUserAppDataPathを取得する。 /// /// 探索する旧バージョンの最大。 /// 旧バージョンと自バージョンの間のフォルダ名を格納するString配列。フォルダ名には完全パスを含む。 /// /// フォルダが異なる同じファイル名のパスが存在する場合、登録しない。 /// アセンブリ名が変わっている場合、旧バージョンは探索不可。 /// private static string[] GetCompatibleUserAppDataPaths(string compatible) { // UserAppDataPath は // <ベースパス>\\\ // という構成のはずなので、一つ上のフォルダから自分より前のフォルダを探索 List paths = new List(); string parent = Path.GetDirectoryName(Application.UserAppDataPath); if (!string.IsNullOrEmpty(parent)) { // 現在のバージョンのフォルダ名 string now = Path.GetFileName(Application.UserAppDataPath); // 同じ階層のフォルダをすべて取得し、降順にソート string[] directories = Directory.GetDirectories(parent); Array.Sort(directories); Array.Reverse(directories); // 指定された互換バージョンと自バージョンの間のパスのみを取得 foreach (string dir in directories) { string ver = Path.GetFileName(dir); if (compatible.CompareTo(ver) <= 0 && ver.CompareTo(now) < 0) { paths.Add(dir); } } } return paths.ToArray(); } /// /// 用のファイル名リストのマージを行う。 /// /// マージ先ファイル名リスト。 /// 比較高速化用のパスを含まないファイル名セット。 /// マージ元ファイル名リスト。 /// フォルダが異なる同じファイル名のパスが存在する場合、登録しない。 private static void MergeFiles(IList mergeto, IgnoreCaseSet names, IList mergefrom) { foreach (string file in mergefrom) { string name = Path.GetFileName(file); if (!names.Contains(name)) { mergeto.Add(file); names.Add(name); } } } #endregion } }