Added Find dialog

Bumped version to 1.01


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21153 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2003-06-14 16:25:26 +00:00
parent 8cb4919bd4
commit e776786754
14 changed files with 369 additions and 3 deletions

View File

@@ -151,6 +151,12 @@ the licence files in the installation directory:
\section{What's New?}\label{whatsnew}
{\bf Version 1.01, June 14th 2003}
\begin{itemize}\itemsep=10pt
\item Added Find facility.
\end{itemize}
{\bf Version 1.0, June 11th 2003}
\begin{itemize}\itemsep=10pt
@@ -397,6 +403,9 @@ item in the tree control and select one of the paste commands.}
\twocolitem{\hrule}{\htmlonly{\hrule}}
\twocolitem{{\bf Delete Option}}{Deletes the selected option.}
\twocolitem{{\bf Rename Option}}{Shows a dialog for renaming the selected option.}
\twocolitem{\hrule}{\htmlonly{\hrule}}
\twocolitem{{\bf Find...}}{Shows the Find dialog, allowing you to search for text
within name, description and notes for each item.}
\end{twocollist}
\section{View menu}

View File

@@ -34,7 +34,7 @@ htmlFaceName = "Arial, Lucida, Helvetica"
\ctgiftversiononly [1] {}
%\ctgiftversiononly [1] {#1}
\ctcustomversiononly [1] {#1}
\ctversion [0] {1.0}
\ctversion [0] {1.01}
\ctname [0] {wxWindows Configuration Tool}
\ctshortname [0] {Configuration Tool}
\cttitle [0] {\ctname \ctversion}

View File

@@ -73,6 +73,8 @@ ctSettings::ctSettings()
m_trayIconIsShown = FALSE;
m_useEnvironmentVariable = TRUE;
m_frameworkDir = wxEmptyString;
m_matchWholeWord = FALSE;
m_matchCase = FALSE;
}
// Copy constructor
@@ -114,6 +116,8 @@ void ctSettings::Copy (const ctSettings& settings)
m_useEnvironmentVariable = settings.m_useEnvironmentVariable;
m_frameworkDir = settings.m_frameworkDir;
m_matchWholeWord = settings.m_matchWholeWord;
m_matchCase = settings.m_matchCase;
}
// Do some initialisation within stApp::OnInit
@@ -173,6 +177,8 @@ bool ctSettings::LoadConfig()
config.Read(wxT("Misc/ShowWelcomeDialog"), (bool*) & m_showWelcomeDialog);
config.Read(wxT("Misc/Ran"), & m_noUses);
config.Read(wxT("Misc/ShowTrayIcon"), (bool*) & m_showTrayIcon);
config.Read(wxT("Misc/MatchWholeWord"), (bool*) & m_matchWholeWord);
config.Read(wxT("Misc/MatchCase"), (bool*) & m_matchCase);
m_noUses ++;
@@ -231,6 +237,8 @@ bool ctSettings::SaveConfig()
config.Write(wxT("Misc/ShowWelcomeDialog"), (long) m_showWelcomeDialog);
config.Write(wxT("Misc/Ran"), m_noUses);
config.Write(wxT("Misc/ShowTrayIcon"), (long) m_showTrayIcon);
config.Write(wxT("Misc/MatchWholeWord"), (long) m_matchWholeWord);
config.Write(wxT("Misc/MatchCase"), (long) m_matchCase);
config.Write(wxT("Windows/ShowToolBar"), m_showToolBar);
config.Write(wxT("Windows/WindowX"), (long) m_frameSize.x);

View File

@@ -117,6 +117,10 @@ public:
int m_mainSashSize;
bool m_showTrayIcon;
bool m_trayIconIsShown;
// Search settings
bool m_matchCase;
bool m_matchWholeWord;
};
#endif

View File

@@ -791,6 +791,51 @@ wxString ctConfigToolDoc::GetFrameworkDir(bool makeUnix)
return path;
}
/// Finds the next item in the tree
ctConfigItem* ctConfigToolDoc::FindNextItem(ctConfigItem* item, bool wrap)
{
if (!item)
return GetTopItem();
// First, try to find the first child
if (item->GetChildCount() > 0)
{
return item->GetChild(0);
}
else
{
ctConfigItem* p = item;
while (p)
{
ctConfigItem* toFind = FindNextSibling(p);
if (toFind)
return toFind;
p = p->GetParent();
}
}
// Finally, wrap around to the root.
if (wrap)
return GetTopItem();
else
return NULL;
}
/// Finds the next sibling in the tree
ctConfigItem* ctConfigToolDoc::FindNextSibling(ctConfigItem* item)
{
if (item->GetParent())
{
wxNode* node = item->GetParent()->GetChildren().Member(item);
if (node && node->GetNext())
{
ctConfigItem* nextItem = (ctConfigItem*) node->GetNext()->GetData();
return nextItem;
}
}
return NULL;
}
/*
* Implements a document editing command.
@@ -990,3 +1035,4 @@ bool ctConfigCommand::DoAndUndo(bool doCmd)
return TRUE;
}

View File

@@ -101,6 +101,12 @@ public:
/// Helper function
void GenerateConfigureCommand(ctConfigItem* item, wxString& str);
/// Finds the next item in the tree
ctConfigItem* FindNextItem(ctConfigItem* item, bool wrap);
/// Finds the next sibling in the tree
ctConfigItem* FindNextSibling(ctConfigItem* item);
protected:
ctConfigItem* m_topItem;
ctConfigItem* m_clipboardItem;

View File

@@ -87,6 +87,10 @@ BEGIN_EVENT_TABLE(ctConfigToolView, wxView)
EVT_MENU(ctID_SAVE_CONFIGURE_COMMAND, ctConfigToolView::OnSaveConfigureCommand)
EVT_UPDATE_UI(ctID_SAVE_SETUP_FILE, ctConfigToolView::OnUpdateSaveSetupFile)
EVT_UPDATE_UI(ctID_SAVE_CONFIGURE_COMMAND, ctConfigToolView::OnUpdateSaveConfigureCommand)
EVT_MENU(wxID_FIND, ctConfigToolView::OnFind)
EVT_UPDATE_UI(wxID_FIND, ctConfigToolView::OnUpdateFind)
END_EVENT_TABLE()
ctConfigToolView::ctConfigToolView()
@@ -966,3 +970,192 @@ void ctConfigToolView::OnUpdateSaveConfigureCommand(wxUpdateUIEvent& event)
{
event.Enable(TRUE);
}
/// Find text
void ctConfigToolView::OnFind(wxCommandEvent& event)
{
ctFindReplaceDialog* dialog = wxGetApp().GetMainFrame()->GetFindDialog();
if (dialog)
{
dialog->Raise();
}
if (!dialog)
{
int style = wxFR_NOUPDOWN;
wxString caption(wxT("Find text in settings"));
int flags = wxFR_DOWN;
if (wxGetApp().GetSettings().m_matchCase)
flags|=wxFR_MATCHCASE;
if (wxGetApp().GetSettings().m_matchWholeWord)
flags|=wxFR_WHOLEWORD;
ctFindReplaceDialog::sm_findData.SetFlags(flags);
dialog = new ctFindReplaceDialog(wxGetApp().GetMainFrame(), caption, style);
dialog->Show(TRUE);
}
}
/// Update find text
void ctConfigToolView::OnUpdateFind(wxUpdateUIEvent& event)
{
event.Enable(TRUE);
}
//----------------------------------------------------------------------------
// ctFindReplaceDialog
//----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(ctFindReplaceDialog, wxFindReplaceDialog)
EVT_FIND(-1, ctFindReplaceDialog::OnFind)
EVT_FIND_NEXT(-1, ctFindReplaceDialog::OnFind)
EVT_FIND_CLOSE(-1, ctFindReplaceDialog::OnClose)
END_EVENT_TABLE()
wxFindReplaceData ctFindReplaceDialog::sm_findData;
wxString ctFindReplaceDialog::sm_currentItem = wxEmptyString;
ctFindReplaceDialog::ctFindReplaceDialog( wxWindow *parent, const wxString& title,
long style):
wxFindReplaceDialog( parent, & sm_findData, title, style )
{
sm_currentItem = wxEmptyString;
if (parent)
((ctMainFrame*) parent)->SetFindDialog(this);
}
void ctFindReplaceDialog::OnFind(wxFindDialogEvent& event)
{
wxString textToFind = event.GetFindString();
bool matchCase = ((event.GetFlags() & wxFR_MATCHCASE) != 0);
bool wholeWord = ((event.GetFlags() & wxFR_WHOLEWORD) != 0);
wxGetApp().GetSettings().m_matchCase = matchCase;
wxGetApp().GetSettings().m_matchWholeWord = wholeWord;
if (!DoFind(textToFind, matchCase, wholeWord))
{
wxMessageBox(wxT("No more matches."), wxT("Search"), wxOK|wxICON_INFORMATION, this);
}
}
bool ctFindReplaceDialog::DoFind(const wxString& textToFind, bool matchCase, bool wholeWord, bool wrap)
{
ctConfigToolDoc* doc = wxGetApp().GetMainFrame()->GetDocument();
if (!doc)
return FALSE;
ctConfigToolView* view = (ctConfigToolView*) doc->GetFirstView();
ctConfigItem* currentItem = NULL;
ctConfigItem* focusItem = view->GetSelection();
if (!focusItem)
{
focusItem = doc->GetTopItem();
if (!focusItem)
return FALSE;
}
if (!sm_currentItem.IsEmpty())
{
currentItem = doc->GetTopItem()->FindItem(sm_currentItem);
}
// If we were at this item last time, skip the first one.
bool skipFirstItem = (currentItem == focusItem);
currentItem = FindNextItem(doc, currentItem, textToFind, matchCase, wholeWord, wrap,
skipFirstItem);
if (currentItem)
{
sm_currentItem = currentItem->GetName();
wxGetApp().GetMainFrame()->GetConfigTreeCtrl()->SelectItem(currentItem->GetTreeItemId());
return TRUE;
}
else
{
sm_currentItem = wxEmptyString;
}
return FALSE;
}
ctConfigItem* ctFindReplaceDialog::FindNextItem(ctConfigToolDoc* doc,
ctConfigItem* item,
const wxString& text,
bool matchCase,
bool matchWordOnly,
bool wrap,
bool skipFirst)
{
ctConfigItem* firstInDoc = NULL;
wxString text2(text);
if (!matchCase)
text2.MakeLower();
ctConfigItem* found = NULL;
ctConfigItem* next = item;
int i = 0;
do
{
// If starting the search from beginning, we can now
// set the value of 'item' in the 2nd iteration without immediately
// dropping out of the while loop because card == next
if (!item && (i > 0))
item = firstInDoc;
// We might want to start from this item if skipFirst is false.
if ((i == 0) && !skipFirst && next)
{
}
else
next = doc->FindNextItem(next, wrap);
// Save to be used in iteration 2
if ((i == 0) && !item)
firstInDoc = next;
if (next)
{
wxString str(next->GetName());
wxString description(next->GetPropertyString(wxT("description")));
wxString notes(next->GetPropertyString(wxT("notes")));
if (!matchCase)
{
str.MakeLower();
description.MakeLower();
notes.MakeLower();
}
if (ctMatchString(str, text2, matchWordOnly) ||
ctMatchString(description, text2, matchWordOnly) ||
ctMatchString(notes, text2, matchWordOnly))
{
found = next;
}
}
else
break; // Didn't find an item at all
i ++;
}
while (!found && item != next);
if (item == found && !firstInDoc)
return NULL;
else
return found;
}
void ctFindReplaceDialog::OnClose(wxFindDialogEvent& event)
{
bool matchCase = ((event.GetFlags() & wxFR_MATCHCASE) != 0);
bool wholeWord = ((event.GetFlags() & wxFR_WHOLEWORD) != 0);
wxGetApp().GetSettings().m_matchCase = matchCase;
wxGetApp().GetSettings().m_matchWholeWord = wholeWord;
this->Destroy();
((ctMainFrame*) GetParent())->SetFindDialog(NULL);
}

View File

@@ -18,6 +18,7 @@
#include "wx/docview.h"
#include "wx/treectrl.h"
#include "wx/fdrepdlg.h"
#include "configitem.h"
class ctConfigTreeCtrl;
@@ -190,6 +191,14 @@ public:
/// Save configure command file update handler
void OnUpdateSaveConfigureCommand(wxUpdateUIEvent& event);
// Find
/// Find text
void OnFind(wxCommandEvent& event);
/// Update find text
void OnUpdateFind(wxUpdateUIEvent& event);
DECLARE_EVENT_TABLE()
protected:
@@ -221,5 +230,37 @@ public:
int m_op;
};
/*
* ctFindReplaceDialog
*/
class ctFindReplaceDialog: public wxFindReplaceDialog
{
public:
// constructors and destructors
ctFindReplaceDialog( wxWindow* parent, const wxString& title,
long style = 0 );
void OnFind(wxFindDialogEvent& event);
void OnClose(wxFindDialogEvent& event);
// If wrap is TRUE, go back to the beginning if at the end of the
// document.
bool DoFind(const wxString& textToFind, bool matchCase, bool wholeWord, bool wrap = TRUE);
ctConfigItem* FindNextItem(ctConfigToolDoc* doc,
ctConfigItem* item,
const wxString& text,
bool matchCase,
bool matchWordOnly,
bool wrap,
bool skipFirst);
static wxFindReplaceData sm_findData;
static wxString sm_currentItem; // card name
private:
DECLARE_EVENT_TABLE()
};
#endif
// _CT_CONFIGTOOLVIEW_H_

View File

@@ -80,6 +80,8 @@ BEGIN_EVENT_TABLE(ctMainFrame, wxDocParentFrame)
EVT_UPDATE_UI(ctID_SAVE_SETUP_FILE, ctMainFrame::OnUpdateDisable)
EVT_UPDATE_UI(ctID_SAVE_CONFIGURE_COMMAND, ctMainFrame::OnUpdateDisable)
EVT_UPDATE_UI(wxID_FIND, ctMainFrame::OnUpdateDisable)
END_EVENT_TABLE()
// Define my frame constructor
@@ -92,6 +94,7 @@ ctMainFrame::ctMainFrame(wxDocManager *manager, wxFrame *parent, wxWindowID id,
m_configurePage = NULL;
m_setupPage = NULL;
m_mainNotebook = NULL;
m_findDialog = NULL;
m_treeSplitterWindow = new wxSplitterWindow(this, -1, wxDefaultPosition, wxSize(400, 300),
wxSP_3DSASH|wxSP_3DBORDER);
@@ -151,6 +154,12 @@ void ctMainFrame::OnCloseWindow(wxCloseEvent& event)
}
}
if (m_findDialog)
{
m_findDialog->Destroy();
m_findDialog = NULL;
}
Show(FALSE);
if (IsMaximized())
@@ -293,6 +302,8 @@ wxMenuBar* ctMainFrame::CreateMenuBar()
editMenu->AppendSeparator();
editMenu->Append(ctID_DELETE_ITEM, _("&Delete Option"), _("Delete a configuration option"));
editMenu->Append(ctID_RENAME_ITEM, _("&Rename Option"), _("Rename a configuration option"));
editMenu->AppendSeparator();
editMenu->Append(wxID_FIND, _("&Find...\tCtrl+F"), _("Search for a string in the settings document"));
// Save for the command processor.
m_editMenu = editMenu;

View File

@@ -26,6 +26,7 @@ class WXDLLEXPORT wxNotebookEvent;
class ctConfigTreeCtrl;
class ctPropertyEditor;
class ctOutputWindow;
class ctFindReplaceDialog;
/*!
* \brief The main window of the application.
@@ -120,6 +121,12 @@ class ctMainFrame: public wxDocParentFrame
/// Returns the main notebook containing editor and text tabs
wxNotebook* GetMainNotebook() const { return m_mainNotebook; }
/// Sets the find dialog for future closing
void SetFindDialog(ctFindReplaceDialog* findDialog) { m_findDialog = findDialog; }
/// Gets the find dialog
ctFindReplaceDialog* GetFindDialog() const { return m_findDialog ; }
DECLARE_EVENT_TABLE()
protected:
@@ -145,6 +152,8 @@ protected:
wxNotebook* m_mainNotebook;
ctOutputWindow* m_setupPage;
ctOutputWindow* m_configurePage;
ctFindReplaceDialog* m_findDialog;
};
/*!

View File

@@ -153,7 +153,7 @@ void ctSettingsDialog::OnHelp( wxCommandEvent& event )
}
else if (page->GetId() == ID_LOCATION_SETTINGS_DIALOG)
{
helpTopic = wxT("Location dialog");
helpTopic = wxT("Location settings dialog");
}
if (!helpTopic.IsEmpty())

View File

@@ -15,7 +15,7 @@
//// Build settings
// Version
#define ctVERSION_NUMBER 1.0
#define ctVERSION_NUMBER 1.01
// Whether to have a splash screen
#define ctUSE_SPLASH_SCREEN 0

View File

@@ -477,3 +477,37 @@ wxString ctEscapeHTMLCharacters(const wxString& str)
}
return s;
}
// Match 'matchText' against 'matchAgainst', optionally constraining to
// whole-word only.
bool ctMatchString(const wxString& matchAgainst, const wxString& matchText, bool wholeWordOnly)
{
// Fast operation if not matching against whole words only
if (!wholeWordOnly)
return (matchAgainst.Find(matchText) != -1);
wxString left(matchAgainst);
bool success = FALSE;
int pos = 0;
int matchTextLen = (int) matchText.Length();
while (!success && !matchAgainst.IsEmpty())
{
pos = left.Find(matchText);
if (pos == -1)
return FALSE;
bool firstCharOK = FALSE;
bool lastCharOK = FALSE;
if (pos == 0 || !wxIsalnum(left[(size_t) (pos-1)]))
firstCharOK = TRUE;
if (((pos + matchTextLen) == (int) left.Length()) || !wxIsalnum(left[(size_t) (pos + matchTextLen)]))
lastCharOK = TRUE;
if (firstCharOK && lastCharOK)
success = TRUE;
left = left.Mid(pos+1);
}
return success;
}

View File

@@ -196,5 +196,10 @@ wxOutputStream& operator <<(wxOutputStream&, long l);
// Convert characters to HTML equivalents
wxString ctEscapeHTMLCharacters(const wxString& str);
// Match 'matchText' against 'matchAgainst', optionally constraining to
// whole-word only.
bool ctMatchString(const wxString& matchAgainst, const wxString& matchText, bool wholeWordOnly);
#endif
// _AP_UTILS_H_