changeset 56:7396e7407abd

searcher version up.
author pyon@macmini
date Sat, 27 Jun 2020 16:25:13 +0900
parents 4877160411cc
children 05f3d51ad966
files src/kaigo/horori/searcher/include/searcher.h src/kaigo/horori/searcher/include/utils.h src/kaigo/horori/searcher/server/searcher.go src/kaigo/horori/searcher/src/searcher.cpp src/kaigo/horori/searcher/src/utils.cpp
diffstat 5 files changed, 225 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/src/kaigo/horori/searcher/include/searcher.h	Sat Jun 27 16:19:45 2020 +0900
+++ b/src/kaigo/horori/searcher/include/searcher.h	Sat Jun 27 16:25:13 2020 +0900
@@ -1,5 +1,5 @@
 // Filename   : searcher.h
-// Last Change: 2020-04-24 金 09:50:28.
+// Last Change: 2020-06-26 金 10:07:26.
 //
 #pragma once
 
@@ -78,7 +78,7 @@
 		wxString m_addr, m_port;
 		wxRect m_mask1, m_mask2, m_mask3;
 		int m_searchmode;
-		wxArrayString m_hist;
+		wxList m_hist;
 		wxString m_user, m_usergroup;
 
         MyStaticBitmap* m_staticBitmap1;
@@ -142,7 +142,7 @@
 		wxDataViewColumn*   m_dataViewListColumnDrvHno;
 		wxDataViewColumn*   m_dataViewListColumnDrvName;
 
-		wxStaticLine* m_staticline;
+		wxStaticLine* m_staticline1;
 
 		wxStaticText*     m_staticTextDBmainte;
 		wxStaticText*     m_staticTextHhsDB;
@@ -155,6 +155,15 @@
 		wxButton*         m_buttonRegImg;
 		wxTextCtrl*       m_textCtrlLastIndex;
 
+		wxStaticText*     m_staticTextCSV;
+		wxFilePickerCtrl* m_filePickerCSV;
+		wxButton*         m_buttonCSV;
+
+		wxStaticLine*     m_staticline2;
+
+		wxStaticText*     m_staticTextVersion;
+		wxTextCtrl*       m_textCtrlVersion;
+
 		// Setup
 		wxPanel*            m_panelSetup;
 		wxDataViewListCtrl* m_dataViewListCtrlPw;
@@ -167,7 +176,7 @@
 
 		// Right-Pane
 		wxSearchCtrl*       m_searchCtrl;
-		wxButton*           m_buttonHist;
+		wxButton*           m_buttonPaste;
 		wxTextCtrl*         m_textCtrlName;
 		wxTextCtrl*         m_textCtrlAddr;
 		wxDataViewListCtrl* m_dataViewListCtrlAny;
@@ -205,12 +214,13 @@
 
 		virtual void OnUploadHhsDB(wxCommandEvent& event);
 		virtual void OnUploadImage(wxCommandEvent& event);
+		virtual void OnDB2CSV(wxCommandEvent& event);
 
 		virtual void OnUPassword(wxCommandEvent& event);
 		virtual void OnSavePw(wxCommandEvent& event);
 
 		virtual void OnChar(wxKeyEvent& event);
-		virtual void OnHist(wxCommandEvent& event);
+		virtual void OnPaste(wxCommandEvent& event);
 		virtual void OnSelectAnyListItem(wxDataViewEvent& event);
 		virtual void OnPrint(wxCommandEvent& event);
 		virtual void OnPassword(wxCommandEvent& event);
@@ -219,8 +229,9 @@
 
 		void CreateControls();
 		void InitializeControlsValue();
+		void SearchByHno(wxString hno);
 		void SetHhsInfo(wxString h);
-		void SetListAny(wxString s);
+		void SetListAnyHeader(int mode);
 		void SetImages();
 		void LoadBookImage(MyStaticBitmap& mysb, wxString file);
 		void LoadBookImages();
@@ -229,6 +240,7 @@
 		void SavePasswd();
 		void RemoveTemp();
 		void MaskImage1();
+		void SetVersionInfo();
 
 	public:
 		SearchFrame(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800,697 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL);
--- a/src/kaigo/horori/searcher/include/utils.h	Sat Jun 27 16:19:45 2020 +0900
+++ b/src/kaigo/horori/searcher/include/utils.h	Sat Jun 27 16:25:13 2020 +0900
@@ -1,5 +1,5 @@
 // Filename   : utils.h
-// Last Change: 2020-04-24 ‹à 14:33:33.
+// Last Change: 2020-06-26 ‹à 09:09:48.
 //
 #pragma once
 
@@ -10,4 +10,7 @@
 bool TarDir(wxString dir, wxString tarfile);
 bool Gzip(wxString infile, wxString gzfile);
 wxString XoR(wxString s, int x);
+bool IsHiragana(wxString s);
+bool IsKatakana(wxString s);
+wxString Hiragara2Katakana(wxString s);
 
--- a/src/kaigo/horori/searcher/server/searcher.go	Sat Jun 27 16:19:45 2020 +0900
+++ b/src/kaigo/horori/searcher/server/searcher.go	Sat Jun 27 16:25:13 2020 +0900
@@ -1,5 +1,5 @@
  /*
-  Last Change: 2020-05-01 金 10:46:51.
+  Last Change: 2020-06-23 ç« 15:48:49.
  */
 
 package main
@@ -96,17 +96,18 @@
 
 	// Http-Handler
 	http.HandleFunc("/h/",  hhs_handler)     // Get /h/0800012345 -> name:addr:20200101#20210701#...
-	http.HandleFunc("/hn/", hhsnm_handler)   // Get /h/0800012345:0800098765:... -> name1:name2:...
+	http.HandleFunc("/hn/", hhsnm_handler)   // Get /hn/0800012345:0800098765:... -> name1:name2:...
 	http.HandleFunc("/ht/", hhstm_handler)   // Get /ht/ -> 2020-03-14 12:34 (2020-04-02)
 	http.HandleFunc("/ha/", hhsdb_handler)   // Get /ha/ -> hhsdb.csv for Mover
 	http.HandleFunc("/i/",  image_handler)   // Get /i/20200110/0800012345.tgz
 	http.HandleFunc("/r/",  recent_handler)  // Get /r/0800012345:0800067890:0800099999:... -> 0800012345,name1,20200101:0800067890,name2,20210405:...
 	http.HandleFunc("/d/",  index_handler)   // Get /d/20xx -> 20xx0401:20xx0408:... , /d/20xx0401 -> 0800012345:0800098765:...
 	http.HandleFunc("/dt/", indextm_handler) // Get /dt/ -> 2020-03-14 12:34 (2020-04-02)
+	http.HandleFunc("/hd/", hhsdbidx_handler)// Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n...
 	http.HandleFunc("/ud/", upidx_handler)   // Get /ud/20200402
 	http.HandleFunc("/u/",  uphhsdb_handler) // POST /u/
 	http.HandleFunc("/ui/", upimage_handler) // POST /ui/20200401/0800012345.tgz
-	http.HandleFunc("/ci/", climage_handler) // Get /ci/20200402
+	http.HandleFunc("/ci/", climage_handler) // Get /ci/20200402 -> remove dir
 	http.HandleFunc("/pw/", pw_handler)      // Get /pw/ -> id1:pw1:id2:pw2:...
 
 	log.Fatal(http.ListenAndServe(server, nil))
@@ -388,6 +389,28 @@
 	w.Write([]byte(date))
 }
 
+/* Get /hd/ -> 20010401,0800012345,name1\n20010401,0300011111,name2\n... */
+func hhsdbidx_handler(w http.ResponseWriter, r *http.Request) {
+	s := ""
+	b, err := ioutil.ReadFile(indexdb)
+	if err != nil {
+		return
+	}
+	rd := csv.NewReader(strings.NewReader(string(b)))
+	for {
+		record, err := rd.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return
+		}
+		s += strings.Join([]string{record[1], record[0], hhash[record[0]].Name}, ",")
+		s += "\n"
+	}
+	w.Write([]byte(s))
+}
+
 /* Get /ud/20200402  */
 func upidx_handler(w http.ResponseWriter, r *http.Request) {
 	date := r.URL.Path[len("/ud/"):]
--- a/src/kaigo/horori/searcher/src/searcher.cpp	Sat Jun 27 16:19:45 2020 +0900
+++ b/src/kaigo/horori/searcher/src/searcher.cpp	Sat Jun 27 16:25:13 2020 +0900
@@ -1,11 +1,12 @@
 // Filename   : searcher.cpp
-// Last Change: 2020-05-21 木 15:20:02.
+// Last Change: 2020-06-26 金 10:32:52.
 //
 #include <wx/msgdlg.h>
 #include <wx/dir.h>
 #include <wx/fileconf.h>
 #include <wx/html/htmprint.h>
-
+#include <wx/clipbrd.h>
+#include <wx/regex.h>
 #include "searcher.h"
 #include "utils.h"
 #include "net.h"
@@ -158,6 +159,7 @@
 {
 	CreateControls();
 	InitializeControlsValue();
+	SetVersionInfo();
 
 	// Connect Events
 	m_notebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler(SearchFrame::OnPageChanged), NULL, this);
@@ -180,12 +182,13 @@
 
 	m_buttonRegHhs->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnUploadHhsDB), NULL, this);
 	m_buttonRegImg->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnUploadImage), NULL, this);
+	m_buttonCSV->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnDB2CSV), NULL, this);
 
 	m_textCtrlUPassword->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(SearchFrame::OnUPassword), NULL, this);
 	m_buttonPw->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnSavePw), NULL, this);
 
 	m_searchCtrl->Connect(wxEVT_CHAR, wxKeyEventHandler(SearchFrame::OnChar), NULL, this);
-	m_buttonHist->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnHist), NULL, this);
+	m_buttonPaste->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnPaste), NULL, this);
 	m_dataViewListCtrlAny->Connect(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler(SearchFrame::OnSelectAnyListItem), NULL, this);
 	m_buttonPrint->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnPrint), NULL, this);
 	m_textCtrlPasswd->Connect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(SearchFrame::OnPassword), NULL, this);
@@ -216,12 +219,13 @@
 
 	m_buttonRegHhs->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnUploadHhsDB), NULL, this);
 	m_buttonRegImg->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnUploadImage), NULL, this);
+	m_buttonCSV->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnDB2CSV), NULL, this);
 
 	m_textCtrlUPassword->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(SearchFrame::OnUPassword), NULL, this);
 	m_buttonPw->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnSavePw), NULL, this);
 
 	m_searchCtrl->Disconnect(wxEVT_CHAR, wxKeyEventHandler(SearchFrame::OnChar), NULL, this);
-	m_buttonHist->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnHist), NULL, this);
+	m_buttonPaste->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnPaste), NULL, this);
 	m_dataViewListCtrlAny->Disconnect(wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler(SearchFrame::OnSelectAnyListItem), NULL, this);
 	m_buttonPrint->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(SearchFrame::OnPrint), NULL, this);
 	m_textCtrlPasswd->Disconnect(wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(SearchFrame::OnPassword), NULL, this);
@@ -240,7 +244,7 @@
 		m_dataViewListCtrlAny->DeleteAllItems();
 		RemoveTemp();
 
-		wxString hno = m_searchCtrl->GetValue();
+		wxString s = m_searchCtrl->GetValue();
 		m_searchCtrl->SelectAll();
 
 		if (m_user.IsEmpty()) {
@@ -252,32 +256,33 @@
 			return;
 		}
 
-		if (hno.StartsWith(wxT("0"))) {
-			// hno search mode
-			wxString url = wxT("/h/") + hno;
-			wxString h = HttpGetText(m_addr, m_port, url); // Get /h/0800012345 -> name:addr:ymd1#ymd2#...
+		if (s.IsSameAs(wxT("9")) || s.IsSameAs(wxT("q"))) {
+			Close();
+			return;
+		}
 
-			if (h.IsEmpty()) {
-				m_textCtrlName->Clear();
-				m_textCtrlAddr->Clear();
-				wxMessageBox(wxT("no data."));
-				return;
-			} else {
-				SetHhsInfo(h);
-				SetImages();
-			}
-
-			m_searchmode = 0;
-			SetListAny(h);
-			m_notebook->SetSelection(0);
+		wxRegEx reHhs(wxT("^0[1238][0-9]{8}$"));
+		if (reHhs.Matches(s)) {
+			// hno search mode
+			SetListAnyHeader(0);
+			SearchByHno(s);
+			return;
 		}
 
-		if (0) {
-			// kana search mode
-			m_searchmode = 2;
-			SetListAny("aaaaaa");
+		if (s.IsEmpty()) {
+			// history mode
+			SetListAnyHeader(1);
+			return;
 		}
 
+		if (IsHiragana(s) || IsKatakana(s)) {
+			// kana search mode
+			s = Hiragara2Katakana(s);
+			SetListAnyHeader(2);
+			return;
+		}
+
+		wxMessageBox(wxT("bad input !"));
 		return;
 	}
 
@@ -390,8 +395,7 @@
 	SetHhsInfo(h);
 	SetImages();
 
-	m_searchmode = 0;
-	SetListAny(h);
+	SetListAnyHeader(0);
 	m_notebook->SetSelection(0);
 }
 
@@ -640,6 +644,24 @@
 	wxMessageBox(wxT("upload done."));
 }
 
+void SearchFrame::OnDB2CSV(wxCommandEvent& WXUNUSED(event))
+{
+	wxString outcsv = m_filePickerCSV->GetPath();
+	if (wxFileExists(outcsv)) wxRemoveFile(outcsv);
+
+	wxFFile output;
+	if (!output.Open(outcsv, wxT("w"))) {
+        wxMessageBox(wxT("Cannot create file."));
+        return;
+	}
+	wxString url = wxT("/hd/");
+	wxString dbtxt = HttpGetText(m_addr, m_port, url);
+
+	output.Write(dbtxt);
+	output.Close();
+	wxMessageBox(wxT("finish !"));
+}
+
 void SearchFrame::OnUPassword(wxCommandEvent& WXUNUSED(event))
 {
 	wxMessageBox("upw");
@@ -650,10 +672,30 @@
 	wxMessageBox("save pw");
 }
 
-void SearchFrame::OnHist(wxCommandEvent& WXUNUSED(event))
+void SearchFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
 {
-	m_searchmode = 1;
-	SetListAny(wxEmptyString);
+	if (m_user.IsEmpty()) return;
+		
+	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_searchCtrl->SelectAll();
+		SetListAnyHeader(0);
+		SearchByHno(s);
+		return;
+	}
+	wxMessageBox(wxT("Bad clipboard data !!"));
 }
 
 void SearchFrame::OnSelectBatchListCtrlA(wxKeyEvent& event)
@@ -680,8 +722,7 @@
 	SetHhsInfo(h);
 	SetImages();
 
-	m_searchmode = 0;
-	SetListAny(h);
+	SetListAnyHeader(0);
 	m_notebook->SetSelection(0);
 }
 
@@ -845,7 +886,7 @@
 		return;
 	}
 
-	wxMessageBox(wxString::Format(wxT("%s lonin..."), m_user));
+	wxMessageBox(wxString::Format(wxT("%s login..."), m_user));
 	m_textCtrlPasswd->SetValue(wxT("ora ora ora ora !"));
 
 	wxString sv;
@@ -875,7 +916,8 @@
 	gbSizer->SetFlexibleDirection(wxBOTH);
 	gbSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
 
-	m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(1300, h - 40), wxNB_FIXEDWIDTH|wxNB_TOP);
+	m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(1300, h - 40), wxNB_FIXEDWIDTH|wxNB_TOP);	// for large-display
+	//m_notebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(1000, h - 50), wxNB_FIXEDWIDTH|wxNB_TOP);	// for note-pc
 
 	m_scrolledWindow1 = new wxScrolledWindow(m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL);
 	m_scrolledWindow1->SetScrollRate(5, 5);
@@ -902,7 +944,7 @@
 	gbSizerBatch->SetFlexibleDirection(wxBOTH);
 	gbSizerBatch->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
 
-	m_filePicker = new wxFilePickerCtrl(m_panelBatch, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("*.csv"), wxDefaultPosition, wxSize(300, -1), wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL);
+	m_filePicker = new wxFilePickerCtrl(m_panelBatch, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("CSV file(*.csv)|*.csv"), wxDefaultPosition, wxSize(300, -1), wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL);
 	gbSizerBatch->Add(m_filePicker, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALL|wxALIGN_CENTER_VERTICAL, 5);
 
 	m_buttonRead = new wxButton(m_panelBatch, wxID_ANY, wxT("読込ã¿"), wxDefaultPosition, wxDefaultSize, 0);
@@ -1011,8 +1053,8 @@
 	bSizerMainte->Add(fgSizerIdx, 0, wxLEFT|wxEXPAND, 30);
 
 	// ----
-	m_staticline = new wxStaticLine(m_panelMainte, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
-	bSizerMainte->Add(m_staticline, 0, wxEXPAND|wxALL, 5);
+	m_staticline1 = new wxStaticLine(m_panelMainte, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
+	bSizerMainte->Add(m_staticline1, 0, wxEXPAND|wxALL, 5);
 
 	m_staticTextDBmainte = new wxStaticText(m_panelMainte, wxID_ANY, wxT("DBæ›´æ–°"), wxDefaultPosition, wxDefaultSize, 0);
 	m_staticTextDBmainte->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, true, wxEmptyString));
@@ -1048,8 +1090,28 @@
 	m_textCtrlLastIndex->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENU));
 	gbSizerDB->Add(m_textCtrlLastIndex, wxGBPosition(1, 3), wxGBSpan(1, 1), wxALL, 5);
 
+	m_staticTextCSV = new wxStaticText(m_panelMainte, wxID_ANY, wxT("CSV出力"), wxDefaultPosition, wxDefaultSize, 0);
+	gbSizerDB->Add(m_staticTextCSV, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
+
+	m_filePickerCSV = new wxFilePickerCtrl(m_panelMainte, wxID_ANY, wxEmptyString, wxT("Select a file"), wxT("CSV file(*.csv)|*.csv"), wxDefaultPosition, wxSize(200, -1), wxFLP_OVERWRITE_PROMPT|wxFLP_SAVE|wxFLP_SMALL|wxFLP_USE_TEXTCTRL);
+	gbSizerDB->Add(m_filePickerCSV, wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL|wxALIGN_CENTER_VERTICAL, 5);
+
+	m_buttonCSV = new wxButton(m_panelMainte, wxID_ANY, wxT("出力"), wxDefaultPosition, wxDefaultSize, 0);
+	gbSizerDB->Add(m_buttonCSV, wxGBPosition(2, 2), wxGBSpan(1, 1), wxALL|wxALIGN_CENTER_VERTICAL, 5);
+
 	bSizerMainte->Add(gbSizerDB, 0, wxLEFT, 30);
 
+	m_staticline2 = new wxStaticLine(m_panelMainte, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
+	bSizerMainte->Add(m_staticline2, 0, wxEXPAND | wxALL, 5);
+
+	m_staticTextVersion = new wxStaticText(m_panelMainte, wxID_ANY, wxT("ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±"), wxDefaultPosition, wxDefaultSize, 0);
+	m_staticTextVersion->SetFont(wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, true, wxEmptyString));
+
+	bSizerMainte->Add(m_staticTextVersion, 0, wxALL, 5);
+
+	m_textCtrlVersion = new wxTextCtrl(m_panelMainte, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY|wxTE_MULTILINE);
+	bSizerMainte->Add(m_textCtrlVersion, 1, wxALL|wxEXPAND, 5);
+
 	m_panelMainte->SetSizer(bSizerMainte);
 	m_panelMainte->Layout();
 	bSizerMainte->Fit(m_panelMainte);
@@ -1086,8 +1148,8 @@
 	m_searchCtrl->SetMaxLength(10);
 	gbSizer->Add(m_searchCtrl, wxGBPosition(0, 1), wxGBSpan(1, 2), wxALL, 5);
 
-	m_buttonHist = new wxButton(this, wxID_ANY, wxT("履歴"), wxDefaultPosition, wxSize(50, -1), 0);
-	gbSizer->Add(m_buttonHist, wxGBPosition(0, 3), wxGBSpan(1, 1), wxALL, 5);
+	m_buttonPaste = new wxButton(this, wxID_ANY, wxT("貼付検索"), wxDefaultPosition, wxSize(60, -1), 0);
+	gbSizer->Add(m_buttonPaste, wxGBPosition(0, 3), wxGBSpan(1, 1), wxALL, 5);
 
 	m_textCtrlName = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
 	gbSizer->Add(m_textCtrlName, wxGBPosition(1, 1), wxGBSpan(1, 2), wxALL, 5);
@@ -1097,14 +1159,15 @@
 
 	m_dataViewListCtrlAny = new wxDataViewListCtrl(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 400), wxDV_ROW_LINES);
 	m_dataViewListColumnAnyNo = m_dataViewListCtrlAny->AppendTextColumn(wxT("番å·"),  wxDATAVIEW_CELL_INERT, 40, static_cast<wxAlignment>(wxALIGN_CENTER), wxDATAVIEW_COL_RESIZABLE);
-	m_dataViewListColumnAny1 = m_dataViewListCtrlAny->AppendTextColumn(wxT("日付"),   wxDATAVIEW_CELL_INERT, 90, static_cast<wxAlignment>(wxALIGN_LEFT),   wxDATAVIEW_COL_RESIZABLE);
+	m_dataViewListColumnAny1 = m_dataViewListCtrlAny->AppendTextColumn(wxT("  日付"), wxDATAVIEW_CELL_INERT, 90, static_cast<wxAlignment>(wxALIGN_LEFT),   wxDATAVIEW_COL_RESIZABLE);
 	m_dataViewListColumnAny2 = m_dataViewListCtrlAny->AppendTextColumn(wxEmptyString, wxDATAVIEW_CELL_INERT, 90, static_cast<wxAlignment>(wxALIGN_LEFT),   wxDATAVIEW_COL_RESIZABLE);
 	m_dataViewListColumnAny3 = m_dataViewListCtrlAny->AppendTextColumn(wxEmptyString, wxDATAVIEW_CELL_INERT, 90, static_cast<wxAlignment>(wxALIGN_LEFT),   wxDATAVIEW_COL_RESIZABLE);
 	m_dataViewListColumnAny4 = m_dataViewListCtrlAny->AppendTextColumn(wxEmptyString, wxDATAVIEW_CELL_INERT, -1, static_cast<wxAlignment>(wxALIGN_CENTER), wxDATAVIEW_COL_RESIZABLE);
 	m_dataViewListCtrlAny->SetAlternateRowColour(wxColour(230, 230, 255)) ;
 	gbSizer->Add(m_dataViewListCtrlAny, wxGBPosition(3, 1), wxGBSpan(1, 3), wxALL|wxEXPAND, 5);
 
-	gbSizer->Add(0, 220, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND, 5);
+	//gbSizer->Add(0, 220, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND, 5);
+	gbSizer->Add(0, 20, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND, 5);
 
 	m_checkBoxMask = new wxCheckBox(this, wxID_ANY, wxT("マスク処ç†"), wxDefaultPosition, wxDefaultSize, 0);
 	gbSizer->Add(m_checkBoxMask, wxGBPosition(5, 1), wxGBSpan(1, 1), wxALL, 5);
@@ -1192,8 +1255,6 @@
 
 	m_searchmode = 0;
 	m_textCtrlPasswd->SetFocus();
-
-	m_buttonHist->Enable(false);
 }
 
 void SearchFrame::SetHhsInfo(wxString h)
@@ -1207,6 +1268,7 @@
 		ccn[i] = ccn[i].Left(4) + wxT("-") + ccn[i].Mid(4, 2) + wxT("-") + ccn[i].Right(2);
 	}
 
+	m_dataViewListCtrlAny->DeleteAllItems();
 	wxVector<wxVariant> data;
     for (int i = 0; i < ccn.GetCount(); i++) {
 		data.push_back(wxVariant(wxString::Format(wxT("%02d"), i + 1)));
@@ -1222,18 +1284,43 @@
 	if (ccn.GetCount() > 0) m_dataViewListCtrlAny->SelectRow(0);
 }
 
-void SearchFrame::SetListAny(wxString str)
+void SearchFrame::SetListAnyHeader(int mode)
 {
-	// change header
-	if (m_searchmode == 0) {
-		// hno: str = name:addr:ymd1#ymd2#...
+	m_textCtrlName->Clear();
+	m_textCtrlAddr->Clear();
+	m_dataViewListColumnAny1->SetTitle(wxEmptyString);
+	m_dataViewListColumnAny2->SetTitle(wxEmptyString);
+	m_dataViewListColumnAny3->SetTitle(wxEmptyString);
+
+	if (mode == 0) { // hno 
+		m_dataViewListColumnAny1->SetTitle(wxT("  日付"));
+	}
+	if (mode == 1) { // history
+		m_dataViewListColumnAny1->SetTitle(wxT("被ä¿ç•ª"));
+		m_dataViewListColumnAny2->SetTitle(wxT("  æ°å"));
 	}
-	if (m_searchmode == 1) {
-		// history
+	if (mode == 2) { // kana
+		m_dataViewListColumnAny1->SetTitle(wxT("被ä¿ç•ª"));
+		m_dataViewListColumnAny2->SetTitle(wxT("  æ°å"));
+		m_dataViewListColumnAny3->SetTitle(wxT("  使‰€"));
 	}
-	if (m_searchmode == 2) {
-		// kana
+	m_searchmode = mode;
+}
+
+void SearchFrame::SearchByHno(wxString hno)
+{
+	wxString url = wxT("/h/") + hno;
+	wxString h = HttpGetText(m_addr, m_port, url); // Get /h/0800012345 -> name:addr:ymd1#ymd2#...
+
+	if (h.IsEmpty()) {
+		wxMessageBox(wxT("no data."));
+		return;
+	} else {
+		SetHhsInfo(h);
+		SetImages();
 	}
+
+	m_notebook->SetSelection(0);
 }
 
 void SearchFrame::SetImages()
@@ -1305,7 +1392,6 @@
 			} else {
 				iklist.Add(wxT("1"));
 			}
-			m_hist.Add(buf.Left(10));
 		}
 	}
     input.Close();
@@ -1384,3 +1470,12 @@
 	}
 }
 
+void SearchFrame::SetVersionInfo()
+{
+	this->SetTitle(wxT("Searcher - v1.0.3"));
+	m_textCtrlVersion->AppendText(wxT("1.0.3 : new feature - paste search (2020-06-26)\n"));
+	m_textCtrlVersion->AppendText(wxT("1.0.2 : new feature - dump index (2020-06-24)\n"));
+	m_textCtrlVersion->AppendText(wxT("1.0.1 : bug fix (2020-06-22)\n"));
+	m_textCtrlVersion->AppendText(wxT("1.0.0 : release out (2020-05-01)\n"));
+}
+
--- a/src/kaigo/horori/searcher/src/utils.cpp	Sat Jun 27 16:19:45 2020 +0900
+++ b/src/kaigo/horori/searcher/src/utils.cpp	Sat Jun 27 16:25:13 2020 +0900
@@ -1,11 +1,12 @@
 // Filename   : utils.cpp
-// Last Change: 2020-04-24 ‹à 14:00:37.
+// Last Change: 2020-06-26 金 09:16:48.
 //
 #include <wx/wx.h>
 #include <wx/dir.h>
 #include <wx/wfstream.h>
 #include <wx/zstream.h>
 #include <wx/tarstrm.h>
+#include <wx/regex.h>
 #include "utils.h"
 
 wxRect Geo2Rect(wxString geo)
@@ -75,3 +76,30 @@
 	return t;
 }
 
+bool IsHiragana(wxString s)
+{
+	wxString hiragana = wxT("ã‚ã„ã†ãˆãŠã‹ããã‘ã“ã•ã—ã™ã›ããŸã¡ã¤ã¦ã¨ãªã«ã¬ã­ã®ã¯ã²ãµã¸ã»ã¾ã¿ã‚€ã‚もやゆよらりるれã‚ã‚ã‚’ã‚“ãŒãŽãã’ã”ã–ã˜ãšãœãžã ã¢ã¥ã§ã©ã°ã³ã¶ã¹ã¼ã±ã´ã·ãºã½ããƒã…ã‡ã‰ã‚ƒã‚…ょã£ã€€");
+    wxRegEx reHiragana(wxT("^[") + hiragana + wxT("]+$"));
+
+	if (reHiragana.Matches(s)) return true;
+	return false;
+}
+
+bool IsKatakana(wxString s)
+{
+	wxString katakana = wxT("アイウエオカキクケコサシスセソタãƒãƒ„テトナニヌãƒãƒŽãƒãƒ’フヘホマミムメモヤユヨラリルレロワヲンガギグゲコザジズゼゾダヂヅデドãƒãƒ“ブベボパピプペãƒã‚¡ã‚£ã‚¥ã‚§ã‚©ãƒ£ãƒ¥ãƒ§ãƒƒã€€");
+    wxRegEx reKatakana(wxT("^[") + katakana + wxT("]+$"));
+
+	if (reKatakana.Matches(s)) return true;
+	return false;
+}
+
+wxString Hiragara2Katakana(wxString s)
+{
+	wxString hiragana = wxT("ã‚ã„ã†ãˆãŠã‹ããã‘ã“ã•ã—ã™ã›ããŸã¡ã¤ã¦ã¨ãªã«ã¬ã­ã®ã¯ã²ãµã¸ã»ã¾ã¿ã‚€ã‚もやゆよらりるれã‚ã‚ã‚’ã‚“ãŒãŽãã’ã”ã–ã˜ãšãœãžã ã¢ã¥ã§ã©ã°ã³ã¶ã¹ã¼ã±ã´ã·ãºã½ããƒã…ã‡ã‰ã‚ƒã‚…ょã£ã€€");
+	wxString katakana = wxT("アイウエオカキクケコサシスセソタãƒãƒ„テトナニヌãƒãƒŽãƒãƒ’フヘホマミムメモヤユヨラリルレロワヲンガギグゲコザジズゼゾダヂヅデドãƒãƒ“ブベボパピプペãƒã‚¡ã‚£ã‚¥ã‚§ã‚©ãƒ£ãƒ¥ãƒ§ãƒƒã€€");
+	for (int i = 0; i < hiragana.Len(); i++)
+		s.Replace(hiragana[i], katakana[i], true);
+	return s;
+}
+