FileListView.cpp

#include "StdAfx.h"
#include "FileListView.h"


using namespace Core;

using namespace System;
using namespace System::Diagnostics;


/// [ Constructor ]
FileListView::FileListView()
{
    this->View = System::Windows::Forms::View::Details; // 項目を表示する方法


    // 列を作成する
    this->Columns->Add( "名前", 100, Windows::Forms::HorizontalAlignment::Left );
    this->Columns->Add( "更新日時", 128, Windows::Forms::HorizontalAlignment::Left );
}


/// ファイルを表示する
void FileListView::ShowFiles()
{
    Debug::Assert( m_directoryName != String::Empty, "ディレクトリ名は設定されている" );


    // ディレクトリのアクセスするためのインスタンスを構築する
    IO::DirectoryInfo^ dirInfo = gcnew IO::DirectoryInfo( m_directoryName );

    Array^ fileCatalogue;  // ファイル一覧

    try
    {
        String^ searchPattern = "*." + m_extension;  // 検索文字列

        // ... 現在のディレクトリから、ファイルの一覧を取得する
        fileCatalogue = dirInfo->GetFiles( searchPattern );
    }
    catch( System::IO::DirectoryNotFoundException^ e )
    {
        Debug::WriteLine( "ファイルが見つからない " + e->Message );

        // 処理を抜ける
        return;
    }

    // 全ての項目を削除する
    this->Items->Clear();

    // ... ファイル一覧を追加する
    AddFileCatalogue( fileCatalogue );
}

/// ファイル一覧を追加する
void FileListView::AddFileCatalogue( System::Array^ fileCatalogue )
{
    for each( IO::FileInfo^ fileInfo in fileCatalogue )
    {
        // ファイル情報から 拡張子を付けずにファイル名を取得する
        String^ fileName = IO::Path::GetFileNameWithoutExtension( fileInfo->Name );

        // ... その名称で リストビュー アイテムを構築する
        Windows::Forms::ListViewItem^ listViewItem = gcnew Windows::Forms::ListViewItem( fileName );

        listViewItem->ImageIndex = 0;   // イメージ


        // 更新日時を取得する
        DateTime lastWriteTime = fileInfo->LastWriteTime;

        // ... それを書式指定して追加する
        listViewItem->SubItems->Add( lastWriteTime.ToString( "g" ) );


        // リストビュー アイテムをリストビューに追加する
        Items->Add( listViewItem );
    }
}

/// 絶対パスを取得する
String^ FileListView::GetAbsolutePath( System::String^ fileName )
{
    Debug::Assert( m_directoryName != String::Empty, "ディレクトリ名は設定されている" );
    Debug::Assert( m_extension != String::Empty, "拡張子は設定されている" );


    // ファイル名に拡張子を付ける
    String^ fileNameWithExtension = IO::Path::ChangeExtension( fileName, m_extension );

    // ... ディレクトリ名と連結する
    String^ result = IO::Path::Combine( m_directoryName, fileNameWithExtension );

    return result;
}


/// 項目のドラッグが開始された
void FileListView::OnItemDrag( System::Windows::Forms::ItemDragEventArgs^ e )
{
    // 基本クラスの同一関数を呼び出す
    Windows::Forms::ListView::OnItemDrag( e );


    Collections::Generic::List< String^ >^ selectedFiles
        = gcnew Collections::Generic::List< String^ >();

    for each( Windows::Forms::ListViewItem^ item in this->SelectedItems )
    {
        // 選択されている項目の 絶対パスを取得する
        String^ absolutePath = GetAbsolutePath( item->Text );

        // ... それをリストに追加する
        selectedFiles->Add( absolutePath );
    }


    /// @todo 編集中のファイルが含まれるならば、それの保存を促す。


    // データ転送機構のインスタンスを構築する
    Windows::Forms::DataObject^ data = gcnew Windows::Forms::DataObject(
        Windows::Forms::DataFormats::FileDrop,  // ファイル ドロップ形式
        selectedFiles->ToArray()                // 転送するデータ
    );

    // ... ドラッグ&ドロップの効果を指定する
    Windows::Forms::DragDropEffects effect =
        Windows::Forms::DragDropEffects::Copy |
        Windows::Forms::DragDropEffects::Move;

    // ... ドラッグ&ドロップを開始する
    Windows::Forms::DragDropEffects resultOfDragDrop = DoDragDrop( data, effect );


    if( resultOfDragDrop == Windows::Forms::DragDropEffects::Move )
    {
        // 移動されたならば、表示を更新する
        ShowFiles();
    }
    else if( resultOfDragDrop == Windows::Forms::DragDropEffects::None )
    {
        // 何もされなかった場合でも、対象とされた項目について調べる(エクスプローラーは結果を返さないため)
        for each( String^ fileName in selectedFiles )
        {
            // ファイルが存在するかを調べる
            if( !IO::File::Exists( fileName ) )
            {
                // 削除されたならば、表示を更新する
                ShowFiles();

                break;
            }
        }
    }
}