view src/myframe.cpp @ 10:24e0775af32e

Add Name-View.
author pyon@macmini
date Wed, 22 Jun 2011 20:43:50 +0900
parents db7bd315e52c
children 07adad93df84
line wrap: on
line source

// Filename   : mainframe.cpp
// Last Change: 22-Jun-2011.
//

#include "symbol.h"
#include "common.h"
#include "myframe.h"
#include "hhsdb.h"
#include "htmlhelp.h"
#include "main.h"
#include "wx/wxsqlite3.h"

// resources
// the application icon (under Windows and OS/2 it is in resources and even
// though we could still include the XPM here it would be unused)
#if !defined(__WXMSW__) && !defined(__WXPM__)
    #include "sample.xpm"
    #include "print.xpm"
    #include "index.xpm"
#endif

//////////////////////////////////////////////////////////////////////////
// control constructor
MyCmdBox::MyCmdBox( wxWindow *parent, wxWindowID id, const wxString value, const wxPoint pos, const wxSize size, long style )
    : wxTextCtrl( parent, id, value, pos, size, style )
{
    // for search history
    hist = wxGetApp().searchhist;
    histpos = 5;

    // for autocomplete hhs
    wxString gszFile = wxGetCwd() + wxT("/db/ccn.db");
    wxSQLite3Database ccndb;
    ccndb.Open( gszFile );
    wxSQLite3Statement stmt = ccndb.PrepareStatement("SELECT hhsno FROM path ORDER BY path DESC LIMIT 500");
    wxSQLite3ResultSet q = stmt.ExecuteQuery();

    gszFile = wxGetCwd() + wxT("/db/hhs.db");
    wxSQLite3Database hhsdb;
    hhsdb.Open( gszFile );
    wxSQLite3ResultSet q2;

    wxString hhsno;
    while ( q.NextRow() ) {
        hhsno = q.GetString(0);

        recenthhs.Add(hhsno);

        wxSQLite3Statement stmt2 = hhsdb.PrepareStatement("SELECT name FROM hhs_master WHERE hhsno = ?");
        stmt2.Bind( 1, hhsno );
        q2 = stmt2.ExecuteQuery();
        if ( !q2.IsNull(0) ) {
            while ( q2.NextRow() ) {
                recentname.Add(q2.GetString(0));
            }
        }
        else {
            recentname.Add(wxEmptyString);
        }
        stmt2.Finalize();
    }
    stmt.Finalize();

    hhsdb.Close();
    ccndb.Close();
}

// destructor
MyCmdBox::~MyCmdBox()
{
}

// Event Table
BEGIN_EVENT_TABLE( MyCmdBox, wxTextCtrl )
    EVT_CHAR( MyCmdBox::OnChar )
	EVT_TEXT_ENTER( ID_CMD, MyCmdBox::OnCmd )
END_EVENT_TABLE()

// Event Handlers
void MyCmdBox::OnChar( wxKeyEvent& event )
{
    if ( event.GetKeyCode() == 13 ) {
        event.Skip();
        return;
    }

    if ( event.GetKeyCode() == 45 ) {   // テンキーの"-"キーで一文字削除
        wxString s = this->GetStringSelection();
        if ( s.IsEmpty() ) {
            long p = this->GetInsertionPoint();
            this->Remove( p-1, p );
        }
        else {
            this->Cut();
        }
        return;
    }

    MyFrame *mf = (MyFrame*)FindWindowById( ID_MAIN );

    if ( event.GetKeyCode() == WXK_UP ) {  // ↑
        mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
        histpos--;
        if ( histpos < 0 )  histpos = 0;
        this->ChangeValue( hist[histpos] );
        return;
    }
    else if ( event.GetKeyCode() == WXK_DOWN ) {    // ↓
        mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
        histpos++;
        if ( histpos >= hist.GetCount() ) {
            histpos = hist.GetCount();
            this->Clear();
            return;
        }
        this->ChangeValue( hist[histpos] );
        return;
    }

    if ( event.GetKeyCode() == WXK_ESCAPE ) {    // clear by ESC
        this->Clear();
        mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
        return;
    }

    this->Cut();
    int c = event.GetKeyCode();
    if ( c >= 48 && c <= 57 ) { // [0-9]
        c -= 48;
        wxString input = this->GetLineText(0) + wxString::Format(wxT("%d"),c);
        if ( input.Len() < 5 ) {
            event.Skip();
            return;
        }
        // autocomplete
        mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
        for ( int i=0; i<recenthhs.GetCount(); i++ ) {
            if ( recenthhs[i].StartsWith( input ) ) {
                this->ChangeValue( recenthhs[i] );
                this->SetSelection( input.Len(), 10 );

				wxString msg = wxT("もしかして... ") + recentname[i] + wxT(" ?!");
				mf->m_statusBar->SetStatusText( msg, 0 );

                return;
            }
        }
        event.Skip();
        return;
    }

    event.Skip();
}

void MyCmdBox::OnCmd( wxCommandEvent& event )
{
	wxHtmlWindow *h     = (wxHtmlWindow*)FindWindowById( ID_HTML );
	wxGrid *g           = (wxGrid*)FindWindowById( ID_CCN );
    wxSplitterWindow *s = (wxSplitterWindow*)FindWindowById( ID_SPLT );
	s->ReplaceWindow( h, g );
    h->Show(true);
    g->Show(false);

	wxRegEx reHhs(wxT("^0[1238][0-9]{8}$"));	// 1:被保番チェック
	wxRegEx reCno(wxT("^[0-9]{1,2}$"));         // 2:開くフォルダの番号
	wxRegEx rePrint(wxT("^.[0-9]{1,2}$"));     // 3:印刷するフォルダの番号

	wxString cmd;
	cmd = this->GetLineText(0);
    int cond = 0;
	if ( reHhs.Matches( cmd ) )
		cond = 1;
	else if ( reCno.Matches( cmd ) )
		cond = 2;
	else if ( rePrint.Matches( cmd ) )
		cond = 3;

	wxString htmlbody;

	MyFrame *mf = (MyFrame*)FindWindowById( ID_MAIN );
	wxHtmlWindow *hr = (wxHtmlWindow*)FindWindowById( ID_HTML );
	switch (cond) {
		// 被保険者番号が入力されたら
		case 1: {
			wxString hhs = cmd;
            mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
            this->SetSelection( 0, this->GetLastPosition() );

			// 被保険者検索
			wxString gszFile = wxGetCwd() + wxT("/db/hhs.db");
			wxSQLite3Database hhsdb;
			hhsdb.Open( gszFile );

			wxSQLite3Statement stmt = hhsdb.PrepareStatement("SELECT name FROM hhs_master WHERE hhsno = ?");
			stmt.Bind( 1, hhs );
			wxSQLite3ResultSet q = stmt.ExecuteQuery();

            wxString name = wxT("登録なし");
			if ( q.IsNull(0) ) {
				wxString msg = wxT("データベースに存在しない被保険者です.") + hhs;
				mf->m_statusBar->SetStatusText( msg, 0 );
            }
            else {
                name = q.GetString(0);
                hist.Add( hhs );
                histpos++;
            }
            stmt.Finalize();
            hhsdb.Close();

			// パス検索
			gszFile = wxGetCwd() + wxT("/db/ccn.db");
			wxSQLite3Database ccndb;
			ccndb.Open( gszFile );

			stmt = ccndb.PrepareStatement("SELECT path FROM path WHERE hhsno = ? ORDER BY path DESC");
			stmt.Bind( 1, hhs );
			q = stmt.ExecuteQuery();
			if ( q.IsNull(0) ) {
				hr->LoadPage( wxT("html/notfound.html") );
				mf->m_statusBar->SetStatusText( wxT("データが存在しません."), 0 );
				return;
			}

            // HTML 生成
            path.Clear();
            htmlbody = wxT("<html><body>");
            htmlbody += wxT("該当者: ");
            htmlbody += wxT("<b>") + name + wxT("</b>");
            htmlbody += wxT(" ( ") + hhs + wxT(" )");
            htmlbody += wxT("<br /><br />検索結果");
            htmlbody += wxT("<table border=1>");
            htmlbody += wxT("<tr bgcolor=\"#ffcc33\"><th>番号</th><th>日付</th><th>フォルダ</th></tr>");

            wxRegEx reDate(wxT("(^.*20[0-9]{2}.)(20[0-9]{2})([0-2][0-9])([0-9]{2})(.*$)"));

            int i=1;
            int clrflg = 1;
            while ( q.NextRow() ) {
                wxString filepath;
                filepath = q.GetString(0);
                // 氏名画像生成
                if ( 0 ) {
                    wxDir dir(filepath);
                    wxString file;
                    if ( !dir.IsOpened() ) return;

                    bool cout = dir.GetFirst( &file, wxT("*.jpg"), wxDIR_FILES );
                    if ( cout ) {
                        wxString s = filepath + wxFILE_SEP_PATH + file;
                        wxImage img_org( s, wxBITMAP_TYPE_JPEG );
                        wxImage img_name;
                        img_name = img_org.GetSubImage( wxRect( wxPoint(328,556), wxSize(626,288) ) );
                        img_name.Scale( 92, 200 );
                        img_name.SaveFile( wxT("tmp/tmp.jpg") );
                    }
                } 

                path.Add(filepath);
				wxString date = filepath;
                reDate.ReplaceAll( &date, wxT("\\2-\\3-\\4") );

                if ( clrflg ) {
                    htmlbody += wxT("<tr bgcolor=\"#ffffcc\">");
                    clrflg = 0;
                }
                else {
                    htmlbody += wxT("<tr bgcolor=\"#ffff99\">");
                    clrflg = 1;
                }
                htmlbody += wxT("<td align=\"center\">") + wxString::Format(wxT("%d"),i++) + wxT("</td>");  // 番号
                htmlbody += wxT("<td>") + date + wxT("</td>");  // 日付
                htmlbody += wxT("<td>") + q.GetString(0) + wxT("</td></tr>"); // フォルダパス
            }
            stmt.Finalize();
            ccndb.Close();
            path.Shrink();

            htmlbody += wxT("</table>");
            htmlbody += wxT("<br />");
            htmlbody += wxT("<div>");
            htmlbody += wxT("番号1の画像情報");
            htmlbody += wxT("<img src=\"tmp/name.jpg\" />");
            htmlbody += wxT("</div>");
            htmlbody += wxT("<div>");
            htmlbody += wxT("フォルダを開くには,番号を入力してください.<br />");
            htmlbody += wxT("他の被保険者を検索するには,被保番を入力してください.");
            htmlbody += wxT("</div>");
            htmlbody += wxT("</body></html>");

            hr->SetPage( htmlbody );

			break;
		}
		// フォルダ表示
		case 2: {
            this->SetSelection( 0, this->GetLastPosition() );
			long val;
			cmd.ToLong( &val, 10 );
			val--;
			if ( path.IsEmpty()
					|| val < 0 
					|| val > path.GetCount()-1 ) {
				mf->m_statusBar->SetStatusText( wxT("不適切な入力です."), 0 );
				break;
			}
			wxString execmd = wxT("explorer ") + path[val];
			wxExecute( execmd );
			mf->m_statusBar->SetStatusText( wxEmptyString, 0 );

            // 検索履歴をログに保存
			wxString logfn = wxGetCwd() + wxT("/tmp/log.txt");
            wxTextFile logFile;
            logFile.Open( logfn );
            wxDateTime now = wxDateTime::Now();
            wxString log = now.Format() + wxT(" " ) + cmd + wxT(" ") + path[val];
            logFile.AddLine( log );
            logFile.Write();
            logFile.Close();

			break;
		}
		// ファイル印刷
		case 3: {
			break;
		}
		// 制御用コマンド
		case 0: {

            path.Clear();
			if ( cmd.Cmp(wxT("s")) == 0 ) {
				hr->LoadPage( wxT("html/start.html") );
				this->ChangeValue( wxEmptyString );
				mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
				return;
			}
			if ( cmd.Cmp(wxT("c")) == 0 ) {
				hr->LoadPage( wxT("Searcher2.conf") );
				this->ChangeValue( wxEmptyString );
				mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
				return;
			}
			if ( cmd.Cmp(wxT("t")) == 0 ) {
				hr->LoadPage( wxT("html/todo.html") );
				this->ChangeValue( wxEmptyString );
				mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
				return;
			}
			if ( cmd.Cmp(wxT("l")) == 0 ) {
				hr->LoadPage( wxT("tmp/log.txt") );
				this->ChangeValue( wxEmptyString );
				mf->m_statusBar->SetStatusText( wxEmptyString, 0 );
				return;
			}
			if ( cmd.Cmp(wxT("**")) == 0 ) {
				mf->m_statusBar->SetStatusText( wxT("Now Saving..."), 0 );
                mf->Close();
				return;
			}

			mf->m_statusBar->SetStatusText( wxT("不適切な入力です."), 0 );
			this->SetSelection( 0, this->GetLastPosition() );

			break;
		}
        //
		default: {
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// frame constructor
MyFrame::MyFrame( wxWindow* parent, wxWindowID id, const wxString& title )
    : wxFrame( parent, id, title )
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
    // set the frame icon
    SetIcon(wxICON(sample));
	
    // メニューバー
	m_menubar  = new wxMenuBar();

	m_menuFile = new wxMenu();
    m_menuFile->Append( ID_MUPHHS,  wxT("被保険者DB更新"),       wxT("Update hhs-db") );
    m_menuFile->Append( ID_MLSCCN,  wxT("インデックス更新一覧"), wxT("List index") );
    m_menuFile->AppendSeparator(); //----
	wxMenu *menuMaintain = new wxMenu();
    m_menuFile->AppendSubMenu( menuMaintain,  wxT("メンテナンス") );
    menuMaintain->Append( ID_MDBBKUP, wxT("データベースバックアップ"), wxT("Backup DBs") );
    menuMaintain->Append( ID_MDBOPT,  wxT("データベース最適化"),       wxT("Optimize DBs") );
    menuMaintain->Enable( ID_MDBOPT, false );
    menuMaintain->Append( ID_MCHKHHS, wxT("被保者整合性チェック"),     wxT("Check hhs") );
    m_menuFile->AppendSeparator(); //----
	wxMenu *menuOpendir = new wxMenu();
    m_menuFile->AppendSubMenu( menuOpendir,  wxT("フォルダを開く") );
    menuOpendir->Append( ID_MOAD, wxT("アプリケーションフォルダ"), wxT("Open App Folder") );
    menuOpendir->Append( ID_MODD, wxT("データフォルダ"),           wxT("Open Data Folder") );
    m_menuFile->AppendSeparator(); //----
    m_menuFile->Append( wxID_EXIT, wxT("終了(&X)\tAlt-X"), wxT("Quit this program") );

	m_menuHelp = new wxMenu();
    m_menuHelp->Append( ID_MHELP,   wxT("&Help"),         wxT("Show help") );
    m_menuHelp->Append( wxID_ABOUT, wxT("&About...\tF1"), wxT("Show about dialog") );
	
    // now append the freshly created menu to the menu bar...
	m_menubar->Append( m_menuFile, wxT("ファイル(&F)") ); 
	m_menubar->Append( m_menuHelp, wxT("ヘルプ(&H)")   ); 
	
	this->SetMenuBar( m_menubar );

    // ツールバー
    //m_toolBar = new wxToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL|wxNO_BORDER );
    //wxBitmap bmpPrint( print_xpm );
    //wxBitmap bmpIndex( index_xpm );

    // ステータスバー
    int widths[] = { -1, 120, 100 };
    m_statusBar = this->CreateStatusBar( WXSIZEOF(widths), wxST_SIZEGRIP );
    m_statusBar->SetStatusWidths( WXSIZEOF(widths), widths );
    m_statusBar->SetStatusText( wxEmptyString, 0 );
	
	wxBoxSizer* bSizer;
	bSizer = new wxBoxSizer( wxVERTICAL );
	
    // controls here
	m_panelHead = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize );
	wxBoxSizer* bSizerHead;
	bSizerHead = new wxBoxSizer( wxHORIZONTAL );
	
    /* after version 2.11
	m_staticTextHname = new wxStaticText( m_panelHead, wxID_ANY, wxT("氏名カナ検索"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizerHead->Add( m_staticTextHname, 0, wxALL, 5 );
	
	m_searchCtrlHname = new wxSearchCtrl( m_panelHead, ID_SRCHHHS, wxT("3字以上入力"), wxDefaultPosition, wxSize(200,20), 0 );
	#ifndef __WXMAC__
	m_searchCtrlHname->ShowSearchButton( true );
	#endif
	bSizerHead->Add( m_searchCtrlHname, 0, wxALL, 1 );
	
	m_bitmapMkidx = new wxStaticBitmap( m_panelHead, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
	bSizerHead->Add( m_bitmapMkidx, 0, wxALL, 1 );
    */

	bSizerHead->AddStretchSpacer( 1 );    // spacer

	m_staticTextIdx = new wxStaticText( m_panelHead, wxID_ANY, wxT("インデックス"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizerHead->Add( m_staticTextIdx, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_datePicker = new wxDatePickerCtrl( m_panelHead, ID_DTIDX, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_SHOWCENTURY|wxDP_DROPDOWN );
	bSizerHead->Add( m_datePicker, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	
	m_buttonMkidx = new wxButton( m_panelHead, ID_MKIDX, wxT("作成"), wxDefaultPosition, wxSize(50,25), 0 );
	bSizerHead->Add( m_buttonMkidx, 0, wxALL, 5 );
	
	m_panelHead->SetSizer( bSizerHead );
	m_panelHead->Layout();
	bSizerHead->Fit( m_panelHead );
	
    // メインペイン
	wxBoxSizer* bSizerHtml;
	bSizerHtml = new wxBoxSizer( wxVERTICAL );
	m_splitter = new wxSplitterWindow( this, ID_SPLT, wxDefaultPosition, wxDefaultSize, 0 );

    // 検索結果Html
	m_html = new wxHtmlWindow( m_splitter, ID_HTML, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
    m_html->LoadPage( wxT("html/start.html") );
	
    /* after version 2.11
	// 被保険者カナ検索Grid
	m_gridHhs = new wxGrid( m_panelHtml, ID_HLST, wxDefaultPosition, wxDefaultSize, 0 );
	m_gridHhs->CreateGrid( 0, 5 );
	m_gridHhs->EnableEditing( true );
	m_gridHhs->EnableGridLines( true );
	m_gridHhs->EnableDragGridSize( false );
	m_gridHhs->SetMargins( 0, 0 );
	
	// Columns
	m_gridHhs->AutoSizeColumns();
	m_gridHhs->EnableDragColMove( false );
	m_gridHhs->SetColLabelValue( 0, wxT("番号") );
	m_gridHhs->SetColLabelValue( 1, wxT("氏名") );
	m_gridHhs->SetColLabelValue( 2, wxT("カナ") );
	m_gridHhs->SetColLabelValue( 3, wxT("生年月日") );
	m_gridHhs->SetColLabelValue( 4, wxT("住所") );
	m_gridHhs->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
	
	// Cell Defaults
	m_gridHhs->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_BOTTOM );
	m_gridHhs->Hide();
	
	bSizerHtml->Add( m_gridHhs, 0, wxALL, 5 );
    */

	// 審査会合議体表示Grid
	m_gridCcn = new wxGrid( m_splitter, ID_CCN, wxDefaultPosition, wxDefaultSize, 0 );
	m_gridCcn->CreateGrid( 0, 2 );
	m_gridCcn->EnableEditing( true );
	m_gridCcn->EnableGridLines( true );
	m_gridCcn->EnableDragGridSize( false );
	m_gridCcn->SetMargins( 0, 0 );
	m_gridCcn->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_BOTTOM );
    m_gridCcn->Show(false);
	
	// Columns
	m_gridCcn->AutoSizeColumns();
	m_gridCcn->EnableDragColMove( false );
	m_gridCcn->SetColLabelValue( 0, wxT("審査会年月日") );
	m_gridCcn->SetColLabelValue( 1, wxT("DB更新時刻") );
    m_gridCcn->SetColSize( 0, 100 );
    m_gridCcn->SetColSize( 1, 200 );
	m_gridCcn->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
	
    m_splitter->Initialize( m_html );
	m_splitter->SetSizer( bSizerHtml );
	m_splitter->Layout();
	bSizerHtml->Fit( m_splitter );
	
    // コマンドライン	
	m_panelCmd = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize );
	wxBoxSizer* bSizerCmd;
	bSizerCmd = new wxBoxSizer( wxHORIZONTAL );
	
	m_staticTextCmd = new wxStaticText( m_panelCmd, wxID_ANY, wxT("コマンド?"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizerCmd->Add( m_staticTextCmd, 0, wxALL, 5 );
	
	m_cmdbox = new MyCmdBox( m_panelCmd, ID_CMD, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
	bSizerCmd->Add( m_cmdbox, 1, wxALL, 3 );
	m_cmdbox->SetFocus(); 

	m_panelCmd->SetSizer( bSizerCmd );
	m_panelCmd->Layout();
	bSizerCmd->Fit( m_panelCmd );


	bSizer->Add( m_panelHead, 0, wxEXPAND|wxTOP, 1 );
	bSizer->Add( m_splitter,  1, wxEXPAND|wxALL, 1 );
	bSizer->Add( m_panelCmd,  0, wxEXPAND|wxALL, 0 );
	
	this->SetSizer( bSizer );
	this->Layout();
}

// destructor
MyFrame::~MyFrame()
{
}

// Event Table
BEGIN_EVENT_TABLE( MyFrame, wxFrame )
    EVT_MENU( wxID_EXIT,  MyFrame::OnQuit )
    EVT_MENU( wxID_ABOUT, MyFrame::OnAbout )
    EVT_MENU( ID_MUPHHS,  MyFrame::OnUpdateHhsDb )
    EVT_MENU( ID_MLSCCN,  MyFrame::OnListCcn )
    EVT_MENU( ID_MDBBKUP, MyFrame::OnBackupDB )
    EVT_MENU( ID_MDBOPT,  MyFrame::OnOptimizeDB )
    EVT_MENU( ID_MCHKHHS, MyFrame::OnCheckHhs )
    EVT_MENU( ID_MOAD,    MyFrame::OnOpenAppDir )
    EVT_MENU( ID_MODD,    MyFrame::OnOpenDataDir )
    EVT_MENU( ID_MHELP,   MyFrame::OnHelp )

	//EVT_TEXT_ENTER( ID_SRCHHHS, MyFrame::OnHhsSearch ) after version 2.11
    EVT_BUTTON( ID_MKIDX, MyFrame::OnMkIndex )

    EVT_CLOSE( MyFrame::SaveConfig )
END_EVENT_TABLE()

// Event Handlers
/* 終了 */
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}

/* オンラインヘルプ */
void MyFrame::OnHelp(wxCommandEvent& WXUNUSED(event))
{
    HtmlHelpFrame *f = (HtmlHelpFrame*)FindWindowById( ID_HELP );

    if ( f == NULL ) {
        HtmlHelpFrame *helpframe = new HtmlHelpFrame( wxT("Online Help"), ID_HELP ); 
        helpframe->Show(true);
    }
    else {
        f->Raise();
    }
}

/* バージョン情報 */
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
    wxSQLite3Database sqlite;
    wxMessageBox(
        wxString::Format(
              wxT("Version %d.%d ( build %d ) by %s\n") 
              wxT("with SQLite library %s\n") 
              wxT("running under %s."), 
              VER, REV, BLD, wxVERSION_STRING, 
              sqlite.GetVersion().c_str(),
              wxGetOsDescription().c_str()
        ),
        wxT("About this program"), wxOK | wxICON_INFORMATION, this );
}

/* 被保険者検索 */
/* after version 2.11
void MyFrame::OnHhsSearch(wxCommandEvent& WXUNUSED(event))
{
    this->m_html->Hide();
	this->m_gridCcn->Hide();
    this->m_gridHhs->Show(true);

    wxString gszFile = wxGetCwd() + wxT("/db/hhs.db");
    wxSQLite3Database hhsdb;
    hhsdb.Open( gszFile );

    wxSQLite3Statement stmt = hhsdb.PrepareStatement("SELECT count(*) FROM hhs_master WHERE kana LIKE ?");
    stmt.Bind( 1, this->m_searchCtrlHname->GetValue() );
    wxSQLite3ResultSet q = stmt.ExecuteQuery();
    wxString cnt = q.GetString(0);

    if ( cnt.Cmp(wxT("0")) == '0' ) {
        wxString msg = cnt + wxT("指定した条件の被保険者はいませんでした.");
    }
    else {
        wxString msg = cnt + wxT("件マッチしました.");
        return ; // test now

        stmt = hhsdb.PrepareStatement("SELECT hhs, name, kana, addr, birth, sex FROM hhs_master ORDER BY birth DESC");
        q = stmt.ExecuteQuery();
        wxSQLite3ResultSet q = stmt.ExecuteQuery();
        while ( q.NextRow() ) {
            wxString hhs   = q.GetString(0);
            wxString name  = q.GetString(1);
            wxString kana  = q.GetString(2);
            wxString addr  = q.GetString(3);
            wxString birth = q.GetString(4);
            wxString sex   = q.GetString(5);
            // ここに gridに 追加するコード
        }
    }

    stmt.Finalize();
    hhsdb.Close();
}
*/

/* インデックス作成 */
void MyFrame::OnMkIndex(wxCommandEvent& WXUNUSED(event))
{
	wxDateTime dt = m_datePicker->GetValue();
    wxString month = dt.Format(wxT("%m"));
    wxString year  = dt.Format(wxT("%Y"));
    if ( month.IsSameAs(wxT("01")) || month.IsSameAs(wxT("02")) || month.IsSameAs(wxT("03")) ) {
        long y;
        year.ToLong( &y, 10 );
        y--;
        year = wxString::Format(wxT("%d"),y);
    }
    wxString pathroot = wxGetApp().rootdir + wxFILE_SEP_PATH + year + dt.Format(wxT("\\%Y%m%d"));
    wxDir rootd(pathroot);
    if ( !wxDir::Exists(pathroot) ) {
        wxMessageBox( wxT("フォルダが存在しません.")+pathroot );
        return;
    }

    wxProgressDialog pd( wxT("進行状況"), wxT("処理開始..."), 200, this, wxPD_APP_MODAL|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE );
    pd.SetSize( wxSize(320,140) );
    int count=0;

    wxString ccndir;
    bool cont = rootd.GetFirst( &ccndir, wxT("*.*"), wxDIR_DIRS );
    while ( cont ) {
        wxString gszFile = wxGetCwd() + wxT("/db/ccn.db");
        wxSQLite3Database ccndb;
        ccndb.Open( gszFile );

        wxSQLite3Statement stmt = ccndb.PrepareStatement("INSERT OR REPLACE INTO ccn VALUES( ?, datetime('now','localtime') )");
        stmt.Bind( 1, dt.Format(wxT("%Y-%m-%d")) );
        stmt.ExecuteQuery();

        stmt.Finalize();

        wxDir ccnd( pathroot + wxFILE_SEP_PATH + ccndir );
        if ( !ccnd.IsOpened() ) return;
        wxString hhsdir;
        bool c = ccnd.GetFirst( &hhsdir, wxT("*.*"), wxDIR_DIRS );
	    wxRegEx reHhs(wxT("^0[1238][0-9]{8}$"));	// 被保番チェック
        while ( c ) {
            if ( reHhs.Matches(hhsdir) ) {
                wxString path = pathroot + wxFILE_SEP_PATH + ccndir + wxFILE_SEP_PATH + hhsdir;

                stmt = ccndb.PrepareStatement("INSERT OR REPLACE INTO path VALUES( ?, ? )");
                stmt.Bind( 1, hhsdir );
                stmt.Bind( 2, path );
                stmt.ExecuteQuery();

                stmt.Finalize();
            }
            c = ccnd.GetNext(&hhsdir);
            pd.Update( count++, hhsdir+wxT("@")+ccndir+wxT("を処理しました.") );
        }
        ccndb.Close();

        cont = rootd.GetNext(&ccndir);
    }
    wxMessageBox(wxT("インデックス作成が終了しました."));
}

/* インデックス更新一覧 */
void MyFrame::OnListCcn(wxCommandEvent& WXUNUSED(event))
{
	this->m_splitter->ReplaceWindow( this->m_html, this->m_gridCcn );
    this->m_gridCcn->Show(true);
    this->m_html->Show(false);
	MyCmdBox *c = (MyCmdBox*)FindWindowById( ID_CMD );
    c->Clear();

    wxString gszFile = wxGetCwd() + wxT("/db/ccn.db");
    wxSQLite3Database ccndb;
    ccndb.Open( gszFile );

    wxSQLite3Statement stmt = ccndb.PrepareStatement("SELECT ymd, time FROM ccn ORDER BY ymd DESC, time DESC");
    wxSQLite3ResultSet q = stmt.ExecuteQuery();
    int r=0;
    while ( q.NextRow() ) {
        wxString ymd  = q.GetString(0);
        wxString time = q.GetString(1);
        this->m_gridCcn->AppendRows(1);
        this->m_gridCcn->SetCellValue(r,0,ymd);
        this->m_gridCcn->SetCellValue(r,1,time);
        r++;
    }

    stmt.Finalize();
    ccndb.Close();
}

/* 被保険者DB更新 */
void MyFrame::OnUpdateHhsDb(wxCommandEvent& WXUNUSED(event))
{
    FrameHhsDB *f = (FrameHhsDB*)FindWindowById( ID_HHSDB );

    if ( f == NULL ) {
        FrameHhsDB *hhsdb = new FrameHhsDB( this, ID_HHSDB ); 
        hhsdb->Show(true);
    }
    else {
        f->Raise();
    }
    return;
}

/* 被保険者整合性チェック */
void MyFrame::OnCheckHhs(wxCommandEvent& WXUNUSED(event))
{
    wxString logfn = wxGetCwd() + wxT("/tmp/checkhhs.log");
    wxTextFile logFile;
    logFile.Open( logfn );
    logFile.Clear();

    wxString gszFile = wxGetCwd() + wxT("/db/ccn.db");
    wxSQLite3Database ccndb;
    ccndb.Open( gszFile );
    wxSQLite3Statement stmt = ccndb.PrepareStatement("ATTACH 'db/hhs.db' AS hhs");
    wxSQLite3ResultSet q = stmt.ExecuteQuery();
    stmt = ccndb.PrepareStatement("SELECT hhsno FROM path EXCEPT SELECT hhsno FROM hhs.hhs_master");
    q = stmt.ExecuteQuery();

    while ( q.NextRow() ) {
        logFile.AddLine( q.GetString(0) );
    }
    stmt.Finalize();
    ccndb.Close();

    logFile.Write();
    logFile.Close();

    wxString msg = wxT("結果を ") + logfn + wxT(" に保存しました.");
    wxMessageBox( msg );
    return;
}

/* DBバックアップ */
void MyFrame::OnBackupDB(wxCommandEvent& WXUNUSED(event))
{
    wxDateTime now = wxDateTime::Now();
    wxString nowstr = now.Format(wxT("%Y%m%d%H%M%S"));

    wxString org = wxGetCwd() + wxT("/db/ccn.db");
    wxString bk  = wxGetCwd() + wxT("/db/") + nowstr + wxT("_ccn.db");
    wxCopyFile( org, bk, 0 );

    org = wxGetCwd() + wxT("/db/hhs.db");
    bk  = wxGetCwd() + wxT("/db/") + nowstr + wxT("_hhs.db");
    wxCopyFile( org, bk, 0 );

    wxMessageBox( wxT("バックアップ終了.") );
    return;
}

/* DB最適化 */
void MyFrame::OnOptimizeDB(wxCommandEvent& WXUNUSED(event))
{
    return;
}

/* アプリケーションフォルダを開く */
void MyFrame::OnOpenAppDir(wxCommandEvent& WXUNUSED(event))
{
    wxStandardPaths appdir;
    wxString execmd = wxT("explorer ") + appdir.GetDataDir();
    wxExecute( execmd );
    return;
}

/* データフォルダを開く */
void MyFrame::OnOpenDataDir(wxCommandEvent& WXUNUSED(event))
{
    wxString datadir = wxGetApp().rootdir;
    wxString execmd = wxT("explorer ") + datadir;
    wxExecute( execmd );
    return;
}


/* 設定を保存 */
void MyFrame::SaveConfig(wxCloseEvent& WXUNUSED(event))
{
    if ( !IsIconized() && !IsMaximized() ) {
        wxGetApp().rect = this->GetRect();
    }

    int i = m_cmdbox->hist.GetCount();
    for ( int j=0; j<5; j++ ) {
        wxGetApp().searchhist[j] = m_cmdbox->hist[--i];
    }

    Destroy();
}