// ================================================================================================
//
// フォーム処理に関するユーティリティクラスソース。
//
//
// 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);
}
///
/// 文字列中のファイル名に使用できない文字を「_」に置換。
/// また、 由来の半角スペース (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
}
}