view src/rsearcher.cpp @ 15:c262e17de9b1

db download skip-mode.
author pyon@macmini
date Sat, 08 Jun 2019 15:50:59 +0900
parents c1dc1fcee7fe
children b651aa41b9d4
line wrap: on
line source

// Filename   : rsearcher.cpp
// Last Change: 2019-05-29 水 15:37:32.
//

#include <wx/arrstr.h> 
#include <wx/html/htmprint.h>
#include <wx/clipbrd.h>
#include "id.h"
#include "mngdb.h"
#include "rsearcher.h"
#include "main.h"


/********************/
/** HhsClass       **/
/********************/
HhsClass::HhsClass( wxArrayString& buf )
{
	no    = buf[0];
	birth = buf[1];
	name  = buf[2];
	kana  = buf[3];
	addr  = buf[4];
	sex   = buf[5];
}

/********************/
/** MySearchCtrl   **/
/********************/
MySearchCtrl::MySearchCtrl( wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style )
    : wxSearchCtrl( parent, id, value, pos, size, style )
{
	m_parent = parent;
    SetMaxLength( 10 );
	#ifndef __WXMAC__
	ShowSearchButton( true );
	#endif
	ShowCancelButton( false );

    wxFont font( 12, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD );
    SetFont( font );
}
 
MySearchCtrl::~MySearchCtrl()
{
}

// Event Table
BEGIN_EVENT_TABLE( MySearchCtrl, wxSearchCtrl )
    EVT_CHAR( MySearchCtrl::OnKey )
END_EVENT_TABLE()

// Event Handlers & Functions
void MySearchCtrl::OnKey( wxKeyEvent& event )
{
    int kc = event.GetKeyCode();

    if ( kc == 13 ) {	// Enter
		SelectAll();

		MainFrame* f = (MainFrame*)FindWindowById( ID_MAIN );
		f->Cmd( GetValue() );

        event.Skip();
        return;
    }

    if (  kc == 45 ) {   // Num-Key '-' as Backspace
        wxString t = GetStringSelection();
        if ( t.IsEmpty() ) {
            long p = GetInsertionPoint();
            if ( p > 0 ) Remove( p - 1, p );
        }
        else {
            Cut();
        }
        return;
    }

    if ( kc == WXK_ESCAPE ) {    // clear by ESC
        this->Clear();
        return;
    }

    event.Skip();
}

/********************/
/** MyStaticBitmap **/
/********************/
MyStaticBitmap::MyStaticBitmap( wxScrolledWindow *parent, wxWindowID id, const wxBitmap &label, const wxPoint &pos, const wxSize &size, long style, const wxString &name )
    : wxStaticBitmap( parent, id, label, pos, size, style, name )
{
	m_parent = parent;
    Connect( wxEVT_LEFT_DOWN,    wxMouseEventHandler( OnLeftDown      ), NULL, this );
    Connect( wxEVT_LEFT_UP,      wxMouseEventHandler( OnLeftUp        ), NULL, this );
    Connect( wxEVT_LEFT_DCLICK,  wxMouseEventHandler( OnLeftDClick    ), NULL, this );
    Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OnRightDClick   ), NULL, this );
    Connect( wxEVT_MOTION,       wxMouseEventHandler( OnMotion        ), NULL, this );
    Connect( wxEVT_MOUSEWHEEL,   wxMouseEventHandler( OnWheel         ), NULL, this );
    Connect( wxEVT_RIGHT_DOWN,   wxMouseEventHandler( OnStartRGesture ), NULL, this );
    Connect( wxEVT_RIGHT_UP,     wxMouseEventHandler( OnEndRGesture   ), NULL, this );
}

MyStaticBitmap::~MyStaticBitmap()
{
    Disconnect( wxEVT_LEFT_DOWN,    wxMouseEventHandler( OnLeftDown      ), NULL, this );
    Disconnect( wxEVT_LEFT_UP,      wxMouseEventHandler( OnLeftUp        ), NULL, this );
    Disconnect( wxEVT_LEFT_DCLICK,  wxMouseEventHandler( OnLeftDClick    ), NULL, this );
    Disconnect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( OnRightDClick   ), NULL, this );
    Disconnect( wxEVT_MOTION,       wxMouseEventHandler( OnMotion        ), NULL, this );
    Disconnect( wxEVT_MOUSEWHEEL,   wxMouseEventHandler( OnWheel         ), NULL, this );
    Disconnect( wxEVT_RIGHT_DOWN,   wxMouseEventHandler( OnStartRGesture ), NULL, this );
    Disconnect( wxEVT_RIGHT_UP,     wxMouseEventHandler( OnEndRGesture   ), NULL, this );
}

// Event Handlers
void MyStaticBitmap::OnWheel( wxMouseEvent& event )
{
	/*
    if ( event.ControlDown() ) {
        if ( event.GetWheelRotation() < 0 ) {
        }
        else {
        }
        return;
    }
    event.Skip();
	*/
}

void MyStaticBitmap::OnLeftDown( wxMouseEvent& event )
{
    event.GetPosition( &m_dragx, &m_dragy );
    SetCursor( wxCursor( wxCURSOR_SIZING ) );
}

void MyStaticBitmap::OnLeftUp( wxMouseEvent& WXUNUSED(event) )
{
    SetCursor( wxCursor( wxCURSOR_ARROW ) );
}

void MyStaticBitmap::OnLeftDClick( wxMouseEvent& event )
{
	if ( with_stl ) return;
	MainFrame* mf = (MainFrame*)FindWindowById( ID_MAIN );
	mf->ChangeCZoom( 1 );
}

void MyStaticBitmap::OnRightDClick( wxMouseEvent& event )
{
	if ( with_stl ) return;
	MainFrame* mf = (MainFrame*)FindWindowById( ID_MAIN );
	mf->ChangeCZoom( -1 );
}

void MyStaticBitmap::OnMotion( wxMouseEvent& event )
{
	if ( event.RightIsDown() ) return;
    if ( event.Dragging() ) {
        int xv, yv, x, y;
        m_parent->GetViewStart( &xv, &yv );

        event.GetPosition( &x, &y );

        int xa = abs( x - m_dragx );
        int ya = abs( y - m_dragy );
        int xs = x - m_dragx < 0 ? -1 : 1;
        int ys = y - m_dragy < 0 ? -1 : 1;

        /* handai dakedo sumu-zu
        m_parent->Scroll( xv + xs * log10( xa + 1 ), yv + ys * log10( ya + 1 ) );
        */
        m_parent->Scroll( xv + xs * log10( xa + 1 ), yv + ys * log10( ya + 1 ) );

        m_dragx = x; m_dragy = y;
    }
}

/* right-gesture: start detect */
void MyStaticBitmap::OnStartRGesture( wxMouseEvent& event )
{
    event.GetPosition( &cx, &cy );
}

/* right-gesture: judge */
void MyStaticBitmap::OnEndRGesture( wxMouseEvent& event )
{
	if ( with_stl ) return;
    int x, y;
    event.GetPosition( &x, &y );

    int dx = x - cx;
    int dy = y - cy;
    float rad = fabs( atan2( dy, dx ) );
    float pi = 3.14159;

    // to right
    if ( rad < pi / 8 && dx > 0 ) {
		ChangeBook( 1 );
    }
    // to left
    else if ( rad > pi / 8 * 7 && rad < pi && dx < 0 ) { 
		ChangeBook( -1 );
    }
    // to up-right
    else if ( rad > pi / 8 && rad < pi / 8 * 3 && dx > 0 ) {
		MainFrame* mf = (MainFrame*)FindWindowById( ID_MAIN );
		mf->Close();
    }
	// down
    else if ( rad > pi / 8 * 3 && rad < pi / 8 * 5 && dy > 0 ) {
		MainFrame* mf = (MainFrame*)FindWindowById( ID_MAIN );
		mf->PrintImages();
    }
	//wxMessageBox( wxString::Format( "%d %d %f", dx, dy, rad ));
}

// Functions
void MyStaticBitmap::ChangeBook( int i )
{
	wxNotebook* nb = (wxNotebook*)FindWindowById( ID_NBOOK );
	int n = nb->GetSelection();
	if ( i > 0 ) {
		if ( n == nb->GetPageCount() - 1 ) return;
		nb->SetSelection( ++n );
	} else {
		if ( n == 0 ) return;
		nb->SetSelection( --n );
	}
}

/********************/
/** SatteliteView  **/
/********************/
StlFrame::StlFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) 
	: wxFrame( parent, id, title, pos, size, style )
{
	wxBoxSizer* bSizerTop = new wxBoxSizer( wxHORIZONTAL );

	m_scrolledWindow = new wxScrolledWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow->SetScrollRate( 5, 5 );

    m_staticBitmap = new MyStaticBitmap( m_scrolledWindow, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
	m_staticBitmap->WithSatellite( true );

	bSizerTop->Add( m_scrolledWindow, 1, wxEXPAND|wxALL, 0 );

	this->SetSizer( bSizerTop );
	this->Layout();
}

StlFrame::~StlFrame()
{
}

/********************/
/** Main Frame     **/
/********************/
MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) 
	: wxFrame( parent, id, title, pos, size, style )
{
	http = RsHttp();
	CreateControls();
	SetAccelerator();
    LoadBitmaps( wxEmptyString, false );
	m_timer.SetOwner( this, ID_TIMER );
}

MainFrame::~MainFrame()
{
}

// Event Table
BEGIN_EVENT_TABLE( MainFrame, wxFrame )
    EVT_SPLITTER_DCLICK( ID_SPLIT, MainFrame::OnSplitWin )
    EVT_DATAVIEW_SELECTION_CHANGED( ID_LIST, MainFrame::OnItemSelected )
    EVT_DATAVIEW_ITEM_ACTIVATED( ID_LIST, MainFrame::OnItemDClicked )
    EVT_DATAVIEW_SELECTION_CHANGED( ID_LISTKANA, MainFrame::OnKanaItemSelected )
    EVT_DATAVIEW_ITEM_ACTIVATED( ID_LISTKANA, MainFrame::OnKanaItemDClicked )
    EVT_NOTEBOOK_PAGE_CHANGED( ID_NBOOK, MainFrame::OnNBookChanged )
	EVT_BUTTON( ID_PSEARCH, MainFrame::OnPasteSearch )
	EVT_BUTTON( wxID_PRINT, MainFrame::OnPrint )
	EVT_CLOSE( MainFrame::OnClose )
    EVT_IDLE( MainFrame::OnIdle )
    EVT_TIMER( ID_TIMER, MainFrame::OnTimer )
	// shortcut-key
	EVT_BUTTON( ID_FOCUS, MainFrame::OnFocus )
	EVT_BUTTON( ID_PZOOM, MainFrame::OnPlusZoom )
	EVT_BUTTON( ID_MZOOM, MainFrame::OnMinusZoom )
	EVT_BUTTON( ID_DARK, MainFrame::OnDark )
	EVT_BUTTON( ID_SWIN, MainFrame::OnSatellite )
	EVT_BUTTON( ID_UPIDX, MainFrame::OnUpdateIndex )
	EVT_BUTTON( ID_DLMAN, MainFrame::OnDownloadManual )
	EVT_BUTTON( wxID_HELP, MainFrame::OnHelp )
	EVT_BUTTON( wxID_CLOSE, MainFrame::OnBClose )
	EVT_BUTTON( ID_LOGOUT, MainFrame::OnLogout )
END_EVENT_TABLE()


// Event Handler
void MainFrame::OnSplitWin( wxSplitterEvent& WXUNUSED(event) )
{
	int w, h;
	this->GetSize( &w, &h );
	m_splitter->SetSashPosition( w - 200, true );
}

void MainFrame::OnItemSelected( wxDataViewEvent& WXUNUSED(event) )
{
    int r = m_dataViewListCtrl->GetSelectedRow();
	if ( r == wxNOT_FOUND ) return;

    wxString ready = m_dataViewListCtrl->GetTextValue( r, 2 );
	if ( ready.IsSameAs( wxT( "OK" ), true ) ) {
		wxString date = m_dataViewListCtrl->GetTextValue( r, 1 );
		date.Replace( wxT( "-" ), wxEmptyString, true );
		LoadBitmaps( date, false );
	} else {
		LoadBitmaps( wxEmptyString, false );
	}
}

void MainFrame::OnItemDClicked( wxDataViewEvent& WXUNUSED(event) )
{
    int r = m_dataViewListCtrl->GetSelectedRow();
	wxString status = m_dataViewListCtrl->GetTextValue( r, 2 );
	if ( status.IsSameAs( wxT( "OK" ), true ) )	return;

    wxString date = m_dataViewListCtrl->GetTextValue( r, 1 );
	date.Replace( wxT( "-" ), wxEmptyString, true );
	GetImages( m_hhs, date );
	if ( LoadBitmaps( date, true ) )
		m_dataViewListCtrl->SetTextValue( wxT( "OK" ), r, 2 );
}

void MainFrame::OnKanaItemSelected( wxDataViewEvent& WXUNUSED(event) )
{
    int r = m_dataViewListKana->GetSelectedRow();
	if ( r == wxNOT_FOUND ) return;
}

void MainFrame::OnKanaItemDClicked( wxDataViewEvent& WXUNUSED(event) )
{
	m_dataViewListCtrl->DeleteAllItems();
	wxGetApp().RemoveFile( wxT( ".cache/*" )  );
	LoadBitmaps( wxEmptyString, false );

    int r = m_dataViewListKana->GetSelectedRow();
	m_searchCtrl->SetValue( m_dataViewListKana->GetTextValue( r, 0 ) );
	m_textCtrlName->SetValue( m_dataViewListKana->GetTextValue( r, 1 ) );
	m_textCtrlAddr->SetValue( m_dataViewListKana->GetTextValue( r, 2 ) );
	m_hhs = m_searchCtrl->GetValue();
	Search();
}

void MainFrame::OnNBookChanged( wxBookCtrlEvent& WXUNUSED(event) )
{
    for ( int i = 0; i < m_notebook->GetPageCount(); i++ ) {
        m_notebook->SetPageImage( i, 1 );
    }
    m_notebook->SetPageImage( m_notebook->GetSelection(), 0 );
}

void MainFrame::OnBClose( wxCommandEvent& WXUNUSED(event) )
{
	Close();
}

void MainFrame::OnClose( wxCloseEvent& WXUNUSED(event) )
{
	Close();
}

void MainFrame::OnFocus( wxCommandEvent& WXUNUSED(event) )
{
	m_searchCtrl->SetFocus();
}

void MainFrame::OnPasteSearch( wxCommandEvent& WXUNUSED(event) )
{
	m_textCtrlName->SetValue( wxEmptyString );
	m_textCtrlAddr->SetValue( wxEmptyString );
	m_dataViewListCtrl->DeleteAllItems();
	PasteSearch();
}

void MainFrame::OnPrint( wxCommandEvent& WXUNUSED(event) )
{
	PrintImages();
}

void MainFrame::OnPlusZoom( wxCommandEvent& WXUNUSED(event) )
{
	ChangeCZoom( 1 );
}

void MainFrame::OnMinusZoom( wxCommandEvent& WXUNUSED(event ) )
{
	ChangeCZoom( -1 );
}

void MainFrame::OnDark( wxCommandEvent& WXUNUSED(event ) )
{
	ChangeColor( m_staticBitmap1 );
	ChangeColor( m_staticBitmap2 );
	ChangeColor( m_staticBitmap3 );
	ChangeColor( m_staticBitmap4 );
	ChangeColor( m_staticBitmap5 );
	m_dark = !m_dark;
}

void MainFrame::OnSatellite( wxCommandEvent& WXUNUSED(event ) )
{
	int n = m_notebook->GetSelection();
	StlFrame *stl = new StlFrame( this, wxID_ANY, wxT( "Re:Searcher - satellite view" ), wxPoint( 0, 0 ), wxSize( 500, 600 ), wxFRAME_NO_TASKBAR|wxCLOSE_BOX|wxCAPTION|wxRESIZE_BORDER );
	wxBitmap bmp;
	if ( n == 0 ) bmp = m_staticBitmap1->GetBitmap();
	if ( n == 1 ) bmp = m_staticBitmap2->GetBitmap();
	if ( n == 2 ) bmp = m_staticBitmap3->GetBitmap();
	if ( n == 3 ) bmp = m_staticBitmap4->GetBitmap();
	if ( n == 4 ) bmp = m_staticBitmap5->GetBitmap();
	stl->SetBitmap( bmp );

    int w = bmp.GetWidth();
    int h = bmp.GetHeight();
	stl->SetScroll( w, h );

	stl->Show();
}

void MainFrame::OnUpdateIndex( wxCommandEvent& WXUNUSED(event ) )
{
	GetDB( false, false, true );
	UpdateIndex();
	wxMessageBox( wxT( "update index done." ) );
}

void MainFrame::OnDownloadManual( wxCommandEvent& WXUNUSED(event) )
{
	wxString execmd = wxT( "cmd /c start manual.pdf" );
	wxExecute( execmd );
}

void MainFrame::OnHelp( wxCommandEvent& WXUNUSED(event) )
{
	wxString version, build;
	version = wxString::Format( wxT( "Re:Searcher -- version %s / %s\n\n" ), RSVER, RSRELEASE );
	build   = wxString::Format( wxT( "build with %s\nrunning under %s." ), wxVERSION_STRING, wxGetOsDescription() );

	wxMessageBox( version + build, wxT( "Help" ) );
	return;
}

void MainFrame::OnLogout( wxCommandEvent& WXUNUSED(event) )
{
	wxMessageBox("logout");
	return;
}

void MainFrame::OnTimer( wxTimerEvent& WXUNUSED(event) )
{
	//wxMessageBox( "timer !" );
	// logout
}

void MainFrame::OnIdle( wxIdleEvent& event )
{
	if ( !m_timer.IsRunning() ) {
        m_timer.Start( 300 * 1000, wxTIMER_ONE_SHOT );
    }
    event.RequestMore();
    event.Skip();
}

// Functions
void MainFrame::CreateControls( void )
{
    this->SetIcon( wxIcon( wxT( "sample" ) ) );
	this->SetSizeHints( wxSize( 400, 300 ), wxDefaultSize );
	this->SetBackgroundColour( wxColour( 30, 80, 40 ) );
	//this->SetBackgroundColour( wxColour( 153, 153, 153 ) );

	wxBoxSizer* bSizerTop = new wxBoxSizer( wxHORIZONTAL );

	m_splitter = new wxSplitterWindow( this, ID_SPLIT, wxDefaultPosition, wxDefaultSize, wxSP_THIN_SASH );
	m_splitter->SetMinimumPaneSize( 20 );
	m_panelLeft = new wxPanel( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
	m_panelLeft->SetBackgroundColour( wxColour( 30, 80, 40 ) );
	m_panelRight = new wxPanel( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
	m_panelRight->SetBackgroundColour( wxColour( 30, 80, 40 ) );

	int w, h;
	this->GetSize( &w, &h );
	m_splitter->SplitVertically( m_panelLeft, m_panelRight, w - 200 );
	
    // Left
	wxBoxSizer* bSizerLeft = new wxBoxSizer( wxVERTICAL );

	wxImageList* imgList = new wxImageList( 16, 16, false, 1 );
    wxBitmap bmp( wxT( "image/blue.png" ), wxBITMAP_TYPE_PNG );
	imgList->Add( bmp, wxNullBitmap );
    bmp.LoadFile( wxT( "image/water.png" ), wxBITMAP_TYPE_PNG );
	imgList->Add( bmp, wxNullBitmap );

	m_notebook = new wxNotebook( m_panelLeft, ID_NBOOK, wxDefaultPosition, wxDefaultSize, 0 );
	m_notebook->SetImageList( imgList );

	m_scrolledWindow1 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow1->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow1, wxT( "Image-01" ), false, 0 );

	m_scrolledWindow2 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow2->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow2, wxT( "Image-02" ), false, 0 );

	m_scrolledWindow3 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow3->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow3, wxT( "Image-03" ), false, 0 );

	m_scrolledWindow4 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow4->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow4, wxT( "Image-04" ), false, 0 );

	m_scrolledWindow5 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow5->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow5, wxT( "Image-05" ), false, 0 );
	
	m_scrolledWindow6 = new wxScrolledWindow( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
	m_scrolledWindow6->SetScrollRate( 5, 5 );
	m_notebook->AddPage( m_scrolledWindow6, wxT( "Image-06" ), false, 0 );
	
	bSizerLeft->Add( m_notebook, 1, wxEXPAND|wxALL, 5 );
	m_panelLeft->SetSizer( bSizerLeft );
	
    // Right
	wxBoxSizer* bSizerRight = new wxBoxSizer( wxVERTICAL );
	
	m_searchCtrl = new MySearchCtrl( m_panelRight, ID_SEARCH, wxEmptyString, wxDefaultPosition, wxSize( -1, 24 ), wxTE_PROCESS_ENTER );
	bSizerRight->Add( m_searchCtrl, 0, wxALL, 5 );
	m_searchCtrl->SetFocus();
	
	m_textCtrlName = new wxTextCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 80, -1 ), wxTE_READONLY );
	m_textCtrlName->SetBackgroundColour( wxColour( 180, 210, 240 ) );
	bSizerRight->Add( m_textCtrlName, 0, wxALL, 5 );
	
	m_textCtrlAddr = new wxTextCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 160, -1 ), wxTE_READONLY );
	m_textCtrlAddr->SetBackgroundColour( wxColour( 180, 210, 240 ) );
	bSizerRight->Add( m_textCtrlAddr, 0, wxALL|wxEXPAND, 5 );
	
	m_dataViewListCtrl = new wxDataViewListCtrl( m_panelRight, ID_LIST, wxDefaultPosition, wxDefaultSize, wxDV_ROW_LINES|wxDV_SINGLE );
	m_dataViewListColumnNo    = m_dataViewListCtrl->AppendTextColumn( wxT( "No" ),      wxDATAVIEW_CELL_INERT, 30, wxALIGN_RIGHT,  wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	m_dataViewListColumnDate  = m_dataViewListCtrl->AppendTextColumn( wxT( "  Date" ),  wxDATAVIEW_CELL_INERT, 80, wxALIGN_LEFT,   wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	m_dataViewListColumnReady = m_dataViewListCtrl->AppendTextColumn( wxT( "Ready" ),   wxDATAVIEW_CELL_INERT, 60, wxALIGN_CENTER, wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	bSizerRight->Add( m_dataViewListCtrl, 1, wxALL|wxEXPAND, 5 );
	
	m_dataViewListKana = new wxDataViewListCtrl( m_panelRight, ID_LISTKANA, wxDefaultPosition, wxDefaultSize, wxDV_ROW_LINES|wxDV_SINGLE );
	m_dataViewListColumnKNo  = m_dataViewListKana->AppendTextColumn( wxT( "  No" ),      wxDATAVIEW_CELL_INERT, 70, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	m_dataViewListColumnName = m_dataViewListKana->AppendTextColumn( wxT( "  Name" ),    wxDATAVIEW_CELL_INERT, 80, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	m_dataViewListColumnAddr = m_dataViewListKana->AppendTextColumn( wxT( "  Address" ), wxDATAVIEW_CELL_INERT, -1, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE|wxDATAVIEW_COL_SORTABLE );
	bSizerRight->Add( m_dataViewListKana, 1, wxALL|wxEXPAND, 5 );
	
	m_checkListBox = new wxCheckListBox( m_panelRight, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
	m_checkListBox->Append( wxT( "1: Marksheet" ) );
	m_checkListBox->Append( wxT( "2: Marksheet ( R )" ) );
	m_checkListBox->Append( wxT( "3: Special Mention" ) );
	m_checkListBox->Append( wxT( "4: Opinion" ) );
	m_checkListBox->Append( wxT( "5: Opinion ( R )" ) );
	bSizerRight->Add( m_checkListBox, 0, wxALL|wxEXPAND, 5 );

	m_textCtrlLog = new wxTextCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1, 40 ), 0 );
	bSizerRight->Add( m_textCtrlLog, 0, wxALL|wxEXPAND, 5 );

	wxFlexGridSizer* fgSizerButton = new wxFlexGridSizer( 0, 2, 0, 0 );
	fgSizerButton->SetFlexibleDirection( wxBOTH );
	fgSizerButton->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );

	m_buttonPsearch = new wxButton( m_panelRight, ID_PSEARCH, wxT( "Paste-Search" ), wxDefaultPosition, wxDefaultSize, 0 );
	fgSizerButton->Add( m_buttonPsearch, 0, wxALL, 5 );
	
	fgSizerButton->Add( 0, 0, 1, wxEXPAND, 5 );

	m_buttonPrint = new wxButton( m_panelRight, wxID_PRINT, wxT( "Print" ), wxDefaultPosition, wxDefaultSize, 0 );
	fgSizerButton->Add( m_buttonPrint, 0, wxALL, 5 );
	
	m_spinCtrl = new wxSpinCtrl( m_panelRight, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 60, -1 ), wxALIGN_CENTER_HORIZONTAL|wxSP_ARROW_KEYS, 1, 100, 100 );
	fgSizerButton->Add( m_spinCtrl, 0, wxALL, 5 );

	bSizerRight->Add( fgSizerButton, 0, wxEXPAND, 5 );

	/* now building... */
	m_slider = new wxSlider( m_panelRight, ID_SLDR, 1, 1, 5, wxDefaultPosition, wxSize( -1, 200 ), wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_LABELS|wxSL_VERTICAL );
	//bSizerRight->Add( m_slider, 0, wxALL, 5 );
	
	m_buttonLogout = new wxButton( m_panelRight, ID_LOGOUT, wxT( "Logout" ), wxDefaultPosition, wxDefaultSize, 0 );
	//bSizerRight->Add( m_buttonLogout, 0, wxALL, 5 );
	
	// invisible buttons for shortcut-key
	m_buttonFocus = new wxButton( this, ID_FOCUS, wxT( "Focus" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonFocus->Hide();
	m_buttonPzoom = new wxButton( this, ID_PZOOM, wxT( "ZOOM" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonPzoom->Hide();
	m_buttonMzoom = new wxButton( this, ID_MZOOM, wxT( "zoom" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonMzoom->Hide();
	m_buttonDark = new wxButton( this, ID_DARK, wxT( "Dark" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonDark->Hide();
	m_buttonSatellite = new wxButton( this, ID_SWIN, wxT( "Satellite" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonSatellite->Hide();
	m_buttonDLMan = new wxButton( this, ID_DLMAN, wxT( "Manual" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonDLMan->Hide();
	m_buttonUpdateIndex = new wxButton( this, ID_UPIDX, wxT( "Update Index" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonUpdateIndex->Hide();
	m_buttonClose = new wxButton( this, wxID_CLOSE, wxT( "Close" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonClose->Hide();
	m_buttonHelp = new wxButton( this, wxID_HELP, wxT( "Help" ), wxDefaultPosition, wxDefaultSize, 0 );
	m_buttonHelp->Hide();
	
	m_panelRight->SetSizer( bSizerRight );
	
	//
	bSizerTop->Add( m_splitter, 1, wxEXPAND, 0 );

	this->SetSizer( bSizerTop );
	this->Layout();
	
	//this->Centre( wxBOTH );
	
	SetControlsValue();
}

void MainFrame::SetControlsValue( void )
{
    m_staticBitmap1 = new MyStaticBitmap( m_scrolledWindow1, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
    m_staticBitmap2 = new MyStaticBitmap( m_scrolledWindow2, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
    m_staticBitmap3 = new MyStaticBitmap( m_scrolledWindow3, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
    m_staticBitmap4 = new MyStaticBitmap( m_scrolledWindow4, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );
    m_staticBitmap5 = new MyStaticBitmap( m_scrolledWindow5, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString );

	for ( int i = 0; i < m_checkListBox->GetCount(); i++ )
		m_checkListBox->Check( i, true );

	m_spinCtrl->SetValue( wxGetApp().pzoom );
}

void MainFrame::SetAccelerator( void )
{
	wxAcceleratorEntry entries[11];
	entries[0].Set(  wxACCEL_CTRL,   (int)'P', wxID_PRINT );
	entries[1].Set(  wxACCEL_NORMAL, WXK_F1,   wxID_HELP );
	entries[2].Set(  wxACCEL_NORMAL, WXK_F2,   ID_DLMAN );
	entries[3].Set(  wxACCEL_NORMAL, WXK_F4,   ID_FOCUS );
	entries[4].Set(  wxACCEL_NORMAL, (int)'Z', ID_PZOOM );
	entries[5].Set(  wxACCEL_NORMAL, (int)'X', ID_MZOOM );
	entries[6].Set(  wxACCEL_NORMAL, (int)'D', ID_DARK );
	entries[7].Set(  wxACCEL_CTRL,   (int)'Q', wxID_CLOSE );
	entries[8].Set(  wxACCEL_SHIFT,  (int)'W', ID_SWIN );
	entries[9].Set(  wxACCEL_SHIFT,  (int)'R', ID_UPIDX );
	entries[10].Set( wxACCEL_SHIFT,  (int)'L', ID_DARK );	// now building ( logout )
	wxAcceleratorTable accel( 10, entries );
	SetAcceleratorTable( accel );
}

void MainFrame::Cmd( wxString cmd )
{
	m_textCtrlName->SetValue( wxEmptyString );
	m_textCtrlAddr->SetValue( wxEmptyString );
	m_dataViewListCtrl->DeleteAllItems();
	m_dataViewListKana->DeleteAllItems();
	wxGetApp().RemoveFile( wxT( ".cache/*" )  );
	LoadBitmaps( wxEmptyString, false );

    wxRegEx reHhs( wxT( "^0[1238][0-9]{8}$" ) );

    if ( cmd.IsSameAs( wxT( "q" ), true ) || cmd.IsSameAs( wxT( "9" ), true ) ) {
        Close();
		return;
    }

    if ( cmd.IsSameAs( wxT( "c" ), true ) || cmd.IsSameAs( wxT( "cmd" ), true ) ) {
		return;
    }

    if ( cmd.IsSameAs( wxT( "3915" ), true ) && m_user.IsSameAs( wxT( "root" ) ) ) {
		ManageDBFrame *mngframe = new ManageDBFrame( this, wxID_ANY, wxT( "Management Window" ), wxDefaultPosition, wxSize( 400, 160 ), wxCAPTION|wxTAB_TRAVERSAL );
		mngframe->SetDBdir( m_dbdir );
		mngframe->SetServer( m_server );
		mngframe->Show();
		m_searchCtrl->Clear();
        return;
	}

    if ( cmd.IsSameAs( wxT( "." ), false ) ) {
        wxString appdir = wxGetCwd();
        wxString execmd = wxT( "explorer " ) + appdir;
        wxExecute( execmd );
        return;
    }

    if ( cmd.IsSameAs( wxT( "*" ), false ) ) {
		PasteSearch();
		return;
	}

    if ( cmd.IsSameAs( wxT( "+" ), false ) ) {
		//PrintImages();
        return;
	}

    if ( reHhs.Matches( cmd ) ) {
		m_hhs = m_searchCtrl->GetValue();
		Search();
		return;
	}

	wxString hiragana = wxT( "あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽぁぃぅぇぉゃゅょっ " );
	wxString katakana = wxT( "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲンガギグゲコザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォャュョッ " );
    wxRegEx reHiraGana( wxT( "^[" ) + hiragana + wxT( "]+$" ) );
    wxRegEx reKataKana( wxT( "^[" ) + katakana + wxT( "]+$" ) );

	bool fuzzy = false;
	if ( cmd.Right( 1 ).IsSameAs( wxT( "%" ) ) ) {
		cmd.Replace( wxT( "%" ), wxEmptyString, true );
		fuzzy = true;
	}

    if ( reHiraGana.Matches( cmd ) || reKataKana.Matches( cmd ) ) {
		if ( cmd.Len() < 5 ) {
			wxMessageBox( wxT( "too short !" ) );
			return;
		}
		if ( reHiraGana.Matches( cmd ) ) {
			for ( int i = 0; i < hiragana.Len(); i++ )
				cmd.Replace( hiragana[i], katakana[i], true );
		}

		int match_cnt = 0;
		HhsHash::iterator it;
		for( it = hhash.begin(); it != hhash.end(); ++it ){
			wxString key = it->first, value = it->second->kana;
			value.Replace( wxT( " " ), wxEmptyString, true );
			if ( value.IsSameAs( cmd ) || ( fuzzy && value.StartsWith( cmd ) ) ) {
				wxVector<wxVariant> data;
				data.push_back( key );
				data.push_back( it->second->name );
				data.push_back( it->second->addr );
				m_dataViewListKana->AppendItem( data );
				data.clear();
				m_dataViewListKana->ToggleWindowStyle( wxHSCROLL );
				match_cnt++;
			}
		}

		if ( match_cnt == 1 ) {
			m_searchCtrl->SetValue( m_dataViewListKana->GetTextValue( 0, 0 ) );
			m_textCtrlName->SetValue( m_dataViewListKana->GetTextValue( 0, 1 ) );
			m_textCtrlAddr->SetValue( m_dataViewListKana->GetTextValue( 0, 2 ) );
			m_hhs = m_searchCtrl->GetValue();
			Search();
		}

		if ( match_cnt == 0 ) {
			wxMessageBox( wxT( "No name matched." ) );
		}
		return;
	}

	wxMessageBox( wxT( "Bad Input !!" ) );
}

bool MainFrame::LoadBitmap( wxScrolledWindow* sc, MyStaticBitmap* sb, wxString file )
{
	sb->SetBitmap( wxNullBitmap );
	sb->zoom = 0;
	sc->Scroll( 0, 0 );

	bool ok = true;
	if ( startup ) {
		file = wxT( "image/hello.jpg" );
		startup = false;
	}
	if ( !wxFileExists( file ) ) {
		file = wxT( "image/testpattern.jpg" );
		ok = false;
	}
    wxBitmap bmp( file, wxBITMAP_TYPE_JPEG );
	sb->SetOrigImage( bmp );
    int width  = bmp.GetWidth();
    int height = bmp.GetHeight();
    wxImage img = bmp.ConvertToImage();

    int ww, wh;
    sc->GetSize( &ww, &wh );

    float w = ww - 30;
    float h = w * height / width;
    sb->SetBitmap( wxBitmap( img.Scale( w, h, wxIMAGE_QUALITY_HIGH ) ) );
    sc->SetScrollbars( 10, 10, (int)w / 10, (int)h / 10 );

	return ok;
}

bool MainFrame::LoadBitmaps( wxString date, bool reload )
{
	bool ok;
    ok = LoadBitmap( m_scrolledWindow1, m_staticBitmap1, wxString::Format( wxT( ".cache/%08s_1" ), date ) );
    ok = LoadBitmap( m_scrolledWindow2, m_staticBitmap2, wxString::Format( wxT( ".cache/%08s_2" ), date ) );
    ok = LoadBitmap( m_scrolledWindow3, m_staticBitmap3, wxString::Format( wxT( ".cache/%08s_3" ), date ) );
    ok = LoadBitmap( m_scrolledWindow4, m_staticBitmap4, wxString::Format( wxT( ".cache/%08s_4" ), date ) );
    ok = LoadBitmap( m_scrolledWindow5, m_staticBitmap5, wxString::Format( wxT( ".cache/%08s_5" ), date ) );

	if ( !ok && reload ) {
		wxSleep( 5 );
		ok = LoadBitmaps( date, false );
	}
	return ok;
}

void MainFrame::ChangeCZoom( int z )
{
	int n = m_notebook->GetSelection();
	if ( n == 0 ) ChangeZoom( m_scrolledWindow1, m_staticBitmap1, z );
	if ( n == 1 ) ChangeZoom( m_scrolledWindow2, m_staticBitmap2, z );
	if ( n == 2 ) ChangeZoom( m_scrolledWindow3, m_staticBitmap3, z );
	if ( n == 3 ) ChangeZoom( m_scrolledWindow4, m_staticBitmap4, z );
	if ( n == 4 ) ChangeZoom( m_scrolledWindow5, m_staticBitmap5, z );
}

void MainFrame::ChangeZoom( wxScrolledWindow* sc, MyStaticBitmap* sb, int z )
{
	if ( z > 0 ) sb->zoom++;
	else         sb->zoom--;

	float zz = pow( 1.1, sb->zoom );

	int x, y;
	sc->GetViewStart( &x, &y );
	sc->Scroll( 0, 0 );
	wxBitmap bmp = sb->GetOrigImage();

    int width  = bmp.GetWidth();
    int height = bmp.GetHeight();
    wxImage img = bmp.ConvertToImage();

    int ww, wh;
    sc->GetSize( &ww, &wh );

    float w = ww * zz - 30;
    float h = w * height / width;
    sb->SetBitmap( wxBitmap( img.Scale( w, h, wxIMAGE_QUALITY_HIGH ) ) );
    sc->SetScrollbars( 10, 10, (int)w / 10, (int)h / 10 );
	sc->Scroll( x, y );

	if ( m_dark ) ChangeColor( sb );
}

void MainFrame::ChangeColor( MyStaticBitmap* sb )
{
	wxBitmap bmp = sb->GetBitmap();
    wxImage img = bmp.ConvertToImage();
	unsigned char r, g, b;
	for ( int x = 0; x < img.GetWidth(); x++ ) {
		for ( int y = 0; y < img.GetHeight(); y++ ) {
			r = 255 - img.GetRed( x, y );
			g = 255 - img.GetGreen( x, y );
			b = 255 - img.GetBlue( x, y );
			img.SetRGB( x, y, r, g, b );
		}
	}
    sb->SetBitmap( wxBitmap( img ) );
}

void MainFrame::GetImages( wxString hhs, wxString date )
{
	int estimate = http.GetImagesSize( hhs, date ) / 1000000;
    wxProgressDialog pd( wxT( "Connecting Server" ), wxT( "Start..." ), estimate, NULL, wxPD_APP_MODAL|wxPD_ELAPSED_TIME|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE );
    pd.SetSize( wxSize( 320, 140 ) );
	
	unsigned int flag = 0;
	if ( m_checkListBox->IsChecked( 0 ) ) flag += 1;
	if ( m_checkListBox->IsChecked( 1 ) ) flag += 10;
	if ( m_checkListBox->IsChecked( 2 ) ) flag += 100;
	if ( m_checkListBox->IsChecked( 3 ) ) flag += 1000;
	if ( m_checkListBox->IsChecked( 4 ) ) flag += 10000;
	http.GetImages( hhs, date, wxString::Format( wxT( "%d" ), flag ) );
	for ( int i = 0; i < estimate; i++ ) {
		wxMilliSleep( 1 );
		pd.Update( i, wxT( "Now Loading..." ) );
	}
}

void MainFrame::Search( void )
{
	// hhs info
	if ( hhash.count( m_hhs ) ) {
		m_textCtrlName->SetValue( hhash[ m_hhs ]->name );
		m_textCtrlAddr->SetValue( hhash[ m_hhs ]->addr );
	}

	// index
	wxString date;
	int match_cnt = 0;
	for ( int i = 0; i < m_index.GetCount(); i++ ) {
		if ( m_index[i].StartsWith( m_hhs, &date ) ) {
			wxVector<wxVariant> data;
			data.push_back( wxString::Format( wxT( "%02d" ), ++match_cnt ) );
			date = date.Mid( 1, 4 ) + wxT( "-" ) + date.Mid( 5, 2 ) + wxT( "-" ) + date.Mid( 7, 2 );
			data.push_back( date );
			data.push_back( wxEmptyString );
			m_dataViewListCtrl->AppendItem( data );
			data.clear();
		}
	}

	if ( match_cnt == 0 ) {
		wxMessageBox( wxT( "Not Matched !!" ) );
	} else {
		wxString date = m_dataViewListCtrl->GetTextValue( 0, 1 );
		date.Replace( wxT( "-" ), wxEmptyString, true );
		GetImages( m_hhs, date );
		if ( LoadBitmaps( date, true ) ) {
			m_dataViewListCtrl->SetTextValue( wxT( "OK" ), 0, 2 );
			m_dataViewListCtrl->SelectRow( 0 );
		}
	}

	WriteLog( wxT( "[search] " ) + m_hhs );
	Raise();
}

void MainFrame::LoadDB( bool load_hhsdb )
{
    wxProgressDialog pd( wxT( "Load Data" ), wxT( "Now loading..." ), 100, NULL, wxPD_APP_MODAL|wxPD_ELAPSED_TIME|wxPD_REMAINING_TIME|wxPD_AUTO_HIDE );
    pd.SetSize( wxSize( 320, 140 ) );
	
	// index
	UpdateIndex();

	if ( !load_hhsdb ) {
		return;
	}
	// decrypto hhs
	wxString key = wxT( "12345678900123456789abcdefabcdef" );
	wxArrayString args;
	args.Add( wxT( "crypto.exe" ) );
	args.Add( wxT( "-d" ) );
	args.Add( wxT( "hhs.db" ) );
	args.Add( wxT( "-k" ) );
	args.Add( key );

	wxArrayString output, errors;
	wxExecute( wxJoin( args, ' ', '\\' ), output, errors );

	for ( int i = 0; i < 100; i++ ) {
		wxMilliSleep( 2 );
		pd.Update( i, wxString::Format( wxT( "Now loding ... ( %0.1f %% )" ), (float)i ) );
	}
	if ( errors.GetCount() > 0 ) {
		wxMessageBox( wxT( "crypto error: " )+ errors[0] );
		return;
	}
	for ( int i = 0; i < output.GetCount(); i++ ) {
		wxArrayString buf = wxSplit( output[i], ',', '\\' );
		hhash[ buf[0] ] = new HhsClass( buf ); // no, birth, name, kana, addr, sex
	}
}

void MainFrame::UpdateIndex( void )
{
	wxString oldest = wxT( "30001231" );
	wxString newest = wxT( "20000401" );
	wxTextFile file;
	file.Open( wxT( "index.db" ) );
	for ( int i = 0; i < file.GetLineCount(); i++ ) {
		wxArrayString buf = wxSplit( file.GetLine( i ), ':', '\\' );
		if ( oldest.Cmp( buf[1] ) ==  1 ) oldest = buf[1];
		if ( newest.Cmp( buf[1] ) == -1 ) newest = buf[1];
		m_index.Add( file.GetLine( i ) );
	}
	file.Close();
	m_index.Sort( true );
	m_textCtrlLog->SetValue( wxT( "Index: " ) + oldest + wxT( " - " ) + newest );
}

void MainFrame::PasteSearch( void )
{
	wxString s;
	if ( wxTheClipboard->Open() ) {
		if ( wxTheClipboard->IsSupported( wxDF_TEXT ) ) {
			wxTextDataObject data;
			wxTheClipboard->GetData( data );
			s = data.GetText();
		}
		wxTheClipboard->Close();
	}

	s.Replace( wxT(" "), wxT(""), true );
    wxRegEx reHhs( wxT( "^0[1238][0-9]{8}$" ) );
	if ( reHhs.Matches( s ) ) {
		m_searchCtrl->SetValue( s );
		m_hhs = m_searchCtrl->GetValue();
		Search();
		return;
	}
	wxMessageBox( wxT( "Bad clipboard data !!" ) );
}

void MainFrame::PrintImages( void )
{
    int r = m_dataViewListCtrl->GetSelectedRow();
	if ( r == wxNOT_FOUND ) {
		wxMessageBox( wxT( "Not Ready for Print !!" ) );
		return;
	}
    wxString ready = m_dataViewListCtrl->GetTextValue( r, 2 );

	if ( !ready.IsSameAs( wxT( "OK" ), true ) ) {
		wxMessageBox( wxT( "Not Ready for Print !!" ) );
		return;
	}

	wxDateTime now = wxDateTime::Now();
	wxString nowstr = now.Format( "%Y/%m/%d %H:%M", wxDateTime::GMT9 ).c_str();

	wxString date = m_dataViewListCtrl->GetTextValue( r, 1 );
	date.Replace( wxT( "-" ), wxEmptyString, true );

	wxString html, file;
	html = wxT( "<html><body>\n" );

	int zoom = m_spinCtrl->GetValue();
	wxString imgsz = wxString::Format( wxT( "\" width=\"%d\" height=\"%d\"" ), 750 * zoom / 100, 1060 * zoom / 100 );
	for ( int i = 1; i < 6; i++ ) {
		file = wxString::Format( wxT( ".cache/%08s_%d" ), date, i );
		html = html + wxT( "<img src=\"" ) + file + imgsz + wxT( "/>\n" );
		html = html + wxT( "<div align=right><font size=-2><u>" ) + m_hhs + wxT( "@" ) + m_user + wxT( "#" ) + nowstr + wxT( "</u></font></div>\n\n" );
	}
	html = html + wxT( "</body></html>" );

	// start printing
	wxHtmlPrintout hpout( wxT( "Re:Searcher" ) );
	hpout.SetMargins( 0, 0, 0, 0, 0 );
	wxPrintDialogData pd;
	wxPrinter p( &pd );

	hpout.SetHtmlText( html, wxEmptyString, false );
	p.Print( NULL, &hpout, true );

	WriteLog( wxT( "[print]" ) );
}

void MainFrame::WriteLog( wxString msg )
{
	wxDateTime now = wxDateTime::Now();
	wxString file = wxGetCwd() + wxFILE_SEP_PATH + wxT( "log" ) + wxFILE_SEP_PATH + now.Format( wxT( "%Y%m%d" ) ) + wxT( ".log" );

	wxTextFile logfile;
	if ( !wxFileExists( file ) ) logfile.Create( file );

	logfile.Open( file );
	logfile.AddLine( now.Format( wxT("%Y-%m-%d %H:%M:%S ") ) + msg );
    logfile.Write();
    logfile.Close();
}

void MainFrame::Close( void )
{
	WriteLog( wxT( "[logout]" ) );
    if ( !IsIconized() && !IsMaximized() ) {
        wxGetApp().rect = this->GetRect();
    }
	wxGetApp().pzoom = m_spinCtrl->GetValue();
    Destroy();
}

void MainFrame::InDevelop( bool flag )
{
    if ( !flag ) return;
    
	bool cb = false;
	m_checkListBox->Enable( cb );
	//m_checkListBox->Show( cb );

	bool lo = false;
	m_buttonLogout->Enable( lo );
	m_buttonLogout->Show( lo );

	bool sl = false;
	m_slider->Enable( sl );
	m_slider->Show( sl );

	return;
}