aboutsummaryrefslogblamecommitdiffstats
path: root/apps/windoze/CBuilder5/BibleCS/searchfrm.cpp
blob: 43c069492ec73e85c1b073f57e17ce91a15e4e15 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                                             
                      






                                                                             
                            
                                       















                                                                           
                                  











































































                                                                                                                                                        

                                                                      



                                                                                                













                                                                             



                                                                            
                                                                                     









































                                                                                                                                                                   

                                    
                            

         
                                                          
                                                





                                                                            

                                                 

                                                                                

















































                                                                                                                                                                                                                                                                                                                                  
                                                                      






















                                                                                                                                           
                                                                                                                           








                                                                                                         
                                                                                                            








                                                                                                         
                                                                      
















































                                                                                                                                                                    
                             







                                                                                               
                                           











































































                                                                                                                      














                                                                                   
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop

#include "searchfrm.h"
#include <listkey.h>
#include "mainfrm.h"
#include <regex.h>
#include "RangeMaintFrm.h"
#include <unicode.hpp>
#include <unicodertf.h>
#include "rtfhintfrm.h"
#include <localemgr.h>
#include "vrslstfrm.h"

//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TsearchForm *searchForm;
//---------------------------------------------------------------------------
__fastcall TsearchForm::TsearchForm(TComponent* Owner)
	: TForm(Owner) {
	initializing = true;
	pvrtf = new TRxRichEditX(this);
	pvrtf->Parent = plPreview;
	pvrtf->Align = alClient;
	pvrtf->ScrollBars = ssVertical;
	pvrtf->ReadOnly = true;
//	pvrtf->PopupMenu = PopupMenu2;
//	SearchText = 0;
//	if (!SearchText) {
		SearchTextOld->Visible = false;
		SearchText = new TTntComboBox(this);
		SearchText->Parent = Panel3;
		SearchText->Align = alClient;
		SearchText->ParentFont = false;
		SearchText->Font->Size = 12;
//	}

//	mod->Disp(*displays.insert(displays.begin(), new RTFDisp(newrtf)));
//	mod->setKey(DefaultVSKey);
//	return 0;
	target = 0;
}
//--------------------------------------------------------------------------- 
void __fastcall TsearchForm::searchBtnClick(TObject *Sender)
{
//	ModMap::iterator target;
	class TWaitCursor {
	public:
	    TWaitCursor() : oldc(Screen->Cursor) { Screen->Cursor = crHourGlass; }
	    ~TWaitCursor()                       { Screen->Cursor = oldc; }
	private:
	    TCursor oldc;
	} wait; // show hourglass

	if (!SearchText->Text.Length())
		return;


	int index = SearchText->Items->IndexOf(SearchText->Text);
	SearchText->Items->Insert(0, SearchText->Text);

	if (index >= 0)
		SearchText->Items->Delete(index+1);
		
	SearchText->ItemIndex = 0;
		
	Caption = "";

	if (target) {
		Caption = _tr("Searching");
		Caption += (AnsiString)" [ " + (AnsiString)target->Description() + (AnsiString)" (" + (AnsiString)target->Name() + (AnsiString)") ]...";
		resultsLV->Items->Clear();
		int searchType;
		switch (searchTypeGroup->ItemIndex) {
		case 0:	searchType = -2; break;
		case 1:	searchType = -1; break;
		case 2:	searchType = 0;  break;
		}
		int searchOptions = (caseSensitiveCkBx->Checked) ? 0 : REG_ICASE;
		SWKey *scope = 0;
		switch (scopeGroup->ItemIndex) {
		case 2:
			if (ComboBox1->ItemIndex < 0)
				results = VerseKey().ParseVerseList(ComboBox1->Text.c_str(), "", true);
			else {
				TCustomRange *rs = (TCustomRange *)ComboBox1->Items->Objects[ComboBox1->ItemIndex];
				results = VerseKey().ParseVerseList(rs->text.c_str(), "", true);
			}
		case 1: 
			if (!results.Count())
				return;
			scope = &results; break;
		}
		
		searchBtn->Caption = _tr("Halt");
		searchBtn->OnClick = TerminateSearch;
		searchThread = new TSearchThread(this, WideStringToUTF8(SearchText->Text).c_str(), searchType, searchOptions, scope);
	}
	else Caption = "Error finding target module";
}


void __fastcall TsearchForm::TerminateSearch(TObject *Sender)
{
	target->terminateSearch = true;
}

//---------------------------------------------------------------------------
void __fastcall TsearchForm::ListBox1DblClick(TObject *Sender)
{
	if (!resultsLV->Items->Count) return;	// assert items in list view

	TListItem *focused = resultsLV->ItemFocused;
	if (focused) {
		int row = focused->Index;
		SWKey *key = (SWKey *)*target;
		(*key) = resultsLV->Items->Item[row]->Caption.c_str();
		if (targetpc == Form1->LexDictPageControl) {
			Form1->DictKeyEdit->Text = resultsLV->Items->Item[row]->Caption.c_str();
		}
		else {
			Form1->TextKeyChanged();
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TsearchForm::ListBox1Click(TObject *Sender)
{
	if (!resultsLV->Items->Count) return;	// assert items in list view
	
	if (target) {
		TListItem *focused = resultsLV->ItemFocused;
		if (focused) {
			int row = focused->Index;
			ListKey verse;
			SWKey *key = target->CreateKey();
			*key = resultsLV->Items->Item[row]->Caption.c_str();
			verse << *key;
			delete key;
			pvrtf->fillWithVerses(target, &verse, true, false, "Search");
		}
	}
}

//---------------------------------------------------------------------------

__fastcall TsearchForm::TSearchThread::TSearchThread(TsearchForm *parent, string searchText, int searchType, int searchOptions, SWKey *scope, bool CreateSuspended)
	: TThread(CreateSuspended)
{
	this->parent = parent;
	this->searchText = searchText;
	this->searchType = searchType;
	this->searchOptions = searchOptions;
	this->scope = scope;
	Priority = tpNormal;
	FreeOnTerminate = true;
}


void __fastcall TsearchForm::TSearchThread::updateProgressBar(void) {
	parent->progressBar->Position = parent->status;
	parent->progressBar->Repaint();
}


void __fastcall TsearchForm::TSearchThread::updateStatus(void) {
	Synchronize((TThreadMethod)&updateProgressBar);
}


void TsearchForm::TSearchThread::searchProgressCallback(char status, void *searchThread) {
	TsearchForm::TSearchThread *thread = (TsearchForm::TSearchThread *)searchThread;
	thread->parent->status = status;
	thread->updateStatus();
}


void __fastcall TsearchForm::TSearchThread::FillListBox(void)
{
	TListItem *pItem;

	SWKey *savekey = (SWKey *)*(parent->target);
	SWKey origKeyVal = *savekey;
	if (!savekey->Persist()) {
		savekey = 0;
	}

	for (results = TOP; !results.Error(); results++) {
		parent->target->setKey(results);
		pItem = parent->resultsLV->Items->Add();
		pItem->Caption = (const char *)results;
		pItem->SubItems->Add("");
//		pItem->SubItems->Add((*parent->target).second->StripText());
//		pItem = resultsLV->Items->Add(
	}
	if (savekey)
		parent->target->setKey(*savekey);
	else parent->target->setKey(origKeyVal);	//remove our persist key
		
// 	ListBox1->Items->Pack();	// so Count is set correctly (per helpfile)
	parent->Caption = ((AnsiString)parent->resultsLV->Items->Count + (AnsiString)" " + (AnsiString)((parent->resultsLV->Items->Count == 1) ? _tr("match") : _tr("matches"))) + (AnsiString)" from [ " + (AnsiString)parent->target->Description() + (AnsiString)" (" + (AnsiString)parent->target->Name() + (AnsiString)") ]";
	parent->searchBtn->Caption = _tr("Search");
	parent->searchBtn->OnClick = parent->searchBtnClick;
}

void __fastcall TsearchForm::TSearchThread::Execute()
{
	results = parent->target->Search(searchText.c_str(), searchType, searchOptions, scope, 0, searchProgressCallback, this);
		
	Synchronize((TThreadMethod)&FillListBox);
	parent->results = results;
}




void __fastcall TsearchForm::scopeGroupClick(TObject *Sender) {
	bool enabled = (scopeGroup->ItemIndex == 2);
	
	customRangeBtn->Enabled = enabled;
	ComboBox1->Enabled = enabled;
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::customRangeBtnClick(TObject *Sender)
{
	RangeMaintForm->ShowModal();
	populateRanges();	
}
//---------------------------------------------------------------------------

void TsearchForm::populateRanges() {
	ConfigEntMap::iterator loop, end;
	SWConfig config("./options.conf");	
	ComboBox1->Clear();
	loop = config.Sections["CustomRanges"].begin();
	end = config.Sections["CustomRanges"].end();
	while (loop != end) {
		TCustomRange *rs = new TCustomRange(loop->first.c_str(), loop->second.c_str());
		ComboBox1->Items->AddObject(rs->name.c_str(), rs);
		loop++;
	}
}


void __fastcall TsearchForm::FormShow(TObject *Sender)
{
	populateRanges();
	fillList();
	Button1Click(0);	//initially hide the modSelect sidebar
}
//---------------------------------------------------------------------------


void __fastcall TsearchForm::resultsLVChange(TObject *Sender, TListItem *Item,
	 TItemChange Change)
{
	ListBox1Click(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::resultsLVCustomDrawItem(TCustomListView *Sender, TListItem *Item, TCustomDrawState State, bool &DefaultDraw) {

	if (target && !Form1->closing) {
		TRect rect = Item->DisplayRect(drSelectBounds);
		static UnicodeRTF filter;
		char buf[255];
		strcpy(buf, Item->Caption.c_str());

		SWKey *key = *target;
		if (!SWDYNAMIC_CAST(VerseKey, key))
			filter.ProcessText(buf, 253, *target, target);

		RTFHintForm->searchListDrawer->fillWithRTFString(target, ((String)" \\b  " + buf + " ").c_str(), "Search");
		if (resultsLV->Selected == Item) RTFHintForm->searchListDrawer->Color = TColor(0xB4CDBB);
		Sender->Canvas->Brush->Color = RTFHintForm->searchListDrawer->Color;
		Sender->Canvas->FillRect(rect);

		rect.Right = resultsLV->Column[0]->Width;
		RTFHintForm->searchListDrawer->paintTo(Sender->Canvas->Handle, &rect, 0);

		ListKey verse;
		verse << Item->Caption.c_str();
		RTFHintForm->searchListDrawer->fillWithVerses(target, &verse, false, false, "Search", true);
		//set color back in case it got changed in fill*
		if (resultsLV->Selected == Item) RTFHintForm->searchListDrawer->Color = TColor(0xB4CDBB);

		RTFHintForm->searchListDrawer->SelStart = 3;
		RTFHintForm->searchListDrawer->SelLength = 1;
		double textHeight = RTFHintForm->searchListDrawer->SelAttributes->Height;
		double multiplier = 1.2;
		textHeight *= multiplier;
		int textWithMargin = 3 + textHeight;
		if (resultsLV->StateImages->Height < textWithMargin) {
			resultsLV->StateImages->Height = textWithMargin;
			DefaultDraw = false;	
			return;
		}
		RTFHintForm->searchListDrawer->SelLength = 0;

		rect = Item->DisplayRect(drSelectBounds);
		rect.Left = rect.Left + resultsLV->Column[0]->Width;// + 5;
		RTFHintForm->searchListDrawer->paintTo(Sender->Canvas->Handle, &rect, 0);
	}
	DefaultDraw = false;	
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::resultsLVInfoTip(TObject *Sender,
	 TListItem *Item, AnsiString &InfoTip)
{
	InfoTip = "";	
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::Button1Click(TObject *Sender)
{
	bool newVisible = !pnlChooseMod->Visible;
	ChooseModSplitter->Visible = newVisible;
	pnlChooseMod->Visible = newVisible;
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::FormActivate(TObject *Sender)
{
	if (!Form1->closing) {
		Mouse->Capture = 0;
		if (searchBtn->OnClick != TerminateSearch) {
			TPageControl *targetpc = Form1->TextPageControl;
	
			if ((Form1->ActiveControl == Form1->CommentaryPageControl) || (IsChild(Form1->CommentaryPageControl->Handle, Form1->ActiveControl->Handle)))
				targetpc = Form1->CommentaryPageControl;
			if ((Form1->ActiveControl == Form1->LexDictPageControl) || (IsChild(Form1->LexDictPageControl->Handle, Form1->ActiveControl->Handle)))
				targetpc = Form1->LexDictPageControl;

	
			ModMap::iterator it = Form1->mainmgr->Modules.find(targetpc->ActivePage->Caption.c_str());
			if (it != Form1->mainmgr->Modules.end()) {
				setTarget(it->second);
			}
			SearchText->SetFocus();
		}
	}
	initializing = false;
}

void TsearchForm::setTarget(SWModule *itarget) {
	target = itarget;
	moduleName->Caption = target->Description() + (AnsiString) " (" + target->Name() + ")";
	RTFHintForm->searchListDrawer->fillWithRTFString(target, "yoyo");
	SearchText->Font->Name = RTFHintForm->searchListDrawer->dispAttribs.fontName;
//	SearchText->Font->Size = RTFHintForm->searchListDrawer->dispAttribs.fontSize;
	resultsLV->StateImages->Height = 1;
}
//---------------------------------------------------------------------------

void TsearchForm::fillList()
{
	BibleCSMGR *manager;
	ModMap::iterator mods;
	TTreeNode *node;
	string nodeName;
	manager = Form1->mainmgr;

	modTreeView->Items->Clear();

	if (!manager->configPath)
		return;

	for (mods = manager->Modules.begin(); mods != manager->Modules.end(); mods++) {
		for (node = modTreeView->Items->GetFirstNode(); node; node = node->getNextSibling()) {
			if (!strcmp(node->Text.c_str(), mods->second->Type())) {
				break;
			}
		}
		if (!node) {	// Add Section
			if (!strncmp(mods->second->Type(), "Bibl", 4))	// If Bibles, put first in list
				node = modTreeView->Items->AddChildFirst(0, mods->second->Type());
			else	node = modTreeView->Items->AddChild(0, mods->second->Type());
		}
		nodeName = "[";
		nodeName += mods->second->Name();
		nodeName += "] ";
		nodeName += mods->second->Description();
		node = modTreeView->Items->AddChildObject(node, nodeName.c_str(), mods->second->Name());

	}
	//for (node = modTreeView->Items->GetFirstNode(); node; node = node->getNextSibling())
	//	node->Expand(true);
	node = modTreeView->Items->GetFirstNode();
	if (node)
		node->MakeVisible();
}

void __fastcall TsearchForm::modTreeViewChange(TObject *Sender, TTreeNode *Node) {
	BibleCSMGR *manager;
	ModMap::iterator mods;
	TTreeNode *node;
	string nodeName;
	manager = Form1->mainmgr;
	TTreeNode* currNode = modTreeView->Selected;
	AnsiString nodeSubString;
	AnsiString modName;

	for (mods = manager->Modules.begin(); mods != manager->Modules.end(); mods++) {
		if (currNode->Text.SubString(2, currNode->Text.Pos("]") - 2) == mods->second->Name()) {	// Add Section
			setTarget(mods->second);
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::Button2Click(TObject *Sender)
{
	string helpDir;
	ConfigEntMap::iterator it = Form1->optionsconf->Sections["Help"].find("Directory");
	if (it != Form1->optionsconf->Sections["Help"].end())
		helpDir = (*it).second;
	else helpDir = ".\\help";

	string helpExe = helpDir + "\\Sword.chm::searchh.html";
	if ((int)ShellExecute(this->Handle, "open", "hh", helpExe.c_str(), NULL, SW_SHOWNORMAL) < 33) {
		helpExe = helpDir + "\\searchh.html";
		ShellExecute(this->Handle, "open", helpExe.c_str(), NULL, NULL, SW_SHOWNORMAL);
	}
	
}
//---------------------------------------------------------------------------

void __fastcall TsearchForm::Button3Click(TObject *Sender)
{
	if (resultsLV->Items->Count > 0) {
		ListKey tmpVerseList;
		for (int i = 0; i < resultsLV->Items->Count; i++) {
			tmpVerseList << resultsLV->Items->Item[i]->Caption.c_str();
		}
		TVerseListForm *tmpForm = new TVerseListForm(this, tmpVerseList);
		tmpForm->Caption = _tr("Search Verse List");
		tmpForm->Show();
	}
	
}
//---------------------------------------------------------------------------