From: Julian Smart <julian@anthemion.co.uk> Date: Sat, 14 Jun 2003 16:25:26 +0000 (+0000) Subject: Added Find dialog X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e776786754b4a54f90873b0f1801ba50f79c2d90 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 --- diff --git a/utils/configtool/docs/manual/configtool.tex b/utils/configtool/docs/manual/configtool.tex index 0dbc4b4b73..5c513ef2e1 100644 --- a/utils/configtool/docs/manual/configtool.tex +++ b/utils/configtool/docs/manual/configtool.tex @@ -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} diff --git a/utils/configtool/docs/manual/tex2rtf.ini b/utils/configtool/docs/manual/tex2rtf.ini index b78245dbab..27ab24f489 100644 --- a/utils/configtool/docs/manual/tex2rtf.ini +++ b/utils/configtool/docs/manual/tex2rtf.ini @@ -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} diff --git a/utils/configtool/src/appsettings.cpp b/utils/configtool/src/appsettings.cpp index 41cbfccc05..4693cc4d27 100644 --- a/utils/configtool/src/appsettings.cpp +++ b/utils/configtool/src/appsettings.cpp @@ -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); diff --git a/utils/configtool/src/appsettings.h b/utils/configtool/src/appsettings.h index ac218f6d21..037efc7b7d 100644 --- a/utils/configtool/src/appsettings.h +++ b/utils/configtool/src/appsettings.h @@ -117,6 +117,10 @@ public: int m_mainSashSize; bool m_showTrayIcon; bool m_trayIconIsShown; + + // Search settings + bool m_matchCase; + bool m_matchWholeWord; }; #endif diff --git a/utils/configtool/src/configtooldoc.cpp b/utils/configtool/src/configtooldoc.cpp index 5dd41d2461..e89e6640ec 100644 --- a/utils/configtool/src/configtooldoc.cpp +++ b/utils/configtool/src/configtooldoc.cpp @@ -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; } + diff --git a/utils/configtool/src/configtooldoc.h b/utils/configtool/src/configtooldoc.h index 72baa93f61..4d069533b4 100644 --- a/utils/configtool/src/configtooldoc.h +++ b/utils/configtool/src/configtooldoc.h @@ -100,6 +100,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; diff --git a/utils/configtool/src/configtoolview.cpp b/utils/configtool/src/configtoolview.cpp index c9549799ab..5f62dcb51a 100644 --- a/utils/configtool/src/configtoolview.cpp +++ b/utils/configtool/src/configtoolview.cpp @@ -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); +} diff --git a/utils/configtool/src/configtoolview.h b/utils/configtool/src/configtoolview.h index 85e9e58a50..02ea972f5b 100644 --- a/utils/configtool/src/configtoolview.h +++ b/utils/configtool/src/configtoolview.h @@ -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_ diff --git a/utils/configtool/src/mainframe.cpp b/utils/configtool/src/mainframe.cpp index e0d9d79788..c965758bf7 100644 --- a/utils/configtool/src/mainframe.cpp +++ b/utils/configtool/src/mainframe.cpp @@ -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; diff --git a/utils/configtool/src/mainframe.h b/utils/configtool/src/mainframe.h index d8c9460753..9057369d05 100644 --- a/utils/configtool/src/mainframe.h +++ b/utils/configtool/src/mainframe.h @@ -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; }; /*! diff --git a/utils/configtool/src/settingsdialog.cpp b/utils/configtool/src/settingsdialog.cpp index 7bcb2fb022..15b5833054 100644 --- a/utils/configtool/src/settingsdialog.cpp +++ b/utils/configtool/src/settingsdialog.cpp @@ -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()) diff --git a/utils/configtool/src/symbols.h b/utils/configtool/src/symbols.h index ad5cd536a4..8490e92163 100644 --- a/utils/configtool/src/symbols.h +++ b/utils/configtool/src/symbols.h @@ -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 diff --git a/utils/configtool/src/utils.cpp b/utils/configtool/src/utils.cpp index 13826439a6..05849af70c 100644 --- a/utils/configtool/src/utils.cpp +++ b/utils/configtool/src/utils.cpp @@ -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; +} diff --git a/utils/configtool/src/utils.h b/utils/configtool/src/utils.h index af00ed3273..87fd293836 100644 --- a/utils/configtool/src/utils.h +++ b/utils/configtool/src/utils.h @@ -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_