diff src/myframe.cpp @ 0:c174ac668e9f

First commit ! (ver2.8)
author pyon@macmini
date Tue, 05 Apr 2011 18:44:57 +0900
parents
children e0cf49906039
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/myframe.cpp	Tue Apr 05 18:44:57 2011 +0900
@@ -0,0 +1,811 @@
+// Filename   : mainframe.cpp
+// Last Change: 31-Mar-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}$"));	// 被保番チェック
+	wxRegEx reCno(wxT("^[0-9]{1,2}$"));         // 開くフォルダの番号
+
+	wxString cmd;
+	cmd = this->GetLineText(0);
+    int cond = 0;
+	if ( reHhs.Matches( cmd ) )
+		cond = 1;
+	else if ( reCno.Matches( cmd ) )
+		cond = 2;
+
+	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;
+			}
+
+            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() ) {
+                path.Add(q.GetString(0));
+				wxString date = q.GetString(0);
+                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("フォルダを開くには,番号を入力してください.<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("/db/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 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("db/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.7
+	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.7
+	// 被保険者カナ検索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.7
+    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.7
+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("/db/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();
+}
+