]> git.saurik.com Git - wxWidgets.git/commitdiff
Added Find dialog
authorJulian Smart <julian@anthemion.co.uk>
Sat, 14 Jun 2003 16:25:26 +0000 (16:25 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Sat, 14 Jun 2003 16:25:26 +0000 (16:25 +0000)
Bumped version to 1.01

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21153 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

14 files changed:
utils/configtool/docs/manual/configtool.tex
utils/configtool/docs/manual/tex2rtf.ini
utils/configtool/src/appsettings.cpp
utils/configtool/src/appsettings.h
utils/configtool/src/configtooldoc.cpp
utils/configtool/src/configtooldoc.h
utils/configtool/src/configtoolview.cpp
utils/configtool/src/configtoolview.h
utils/configtool/src/mainframe.cpp
utils/configtool/src/mainframe.h
utils/configtool/src/settingsdialog.cpp
utils/configtool/src/symbols.h
utils/configtool/src/utils.cpp
utils/configtool/src/utils.h

index 0dbc4b4b73b03a322180a8ad29aff1277cad20ca..5c513ef2e16785147aaec191ea1c47b20b5a8999 100644 (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}
index b78245dbab80365be593bd52c2e27fea67d2b64e..27ab24f4894123ada1af49f511b73f8dfa888338 100644 (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}
index 41cbfccc055c692453f330966e971f8dcd07a912..4693cc4d2764aefa577f83d8b6c255247c2912b3 100644 (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);
index ac218f6d2143216bcd89e692e4f25ee4413adec6..037efc7b7d5a1a34807e1d31f5e36d1e28ae2910 100644 (file)
@@ -117,6 +117,10 @@ public:
     int                     m_mainSashSize;
     bool                    m_showTrayIcon;
     bool                    m_trayIconIsShown;
+
+    // Search settings
+    bool                    m_matchCase;
+    bool                    m_matchWholeWord;
 };
 
 #endif
index 5dd41d2461976c1876122658d04ee373ff890ac5..e89e6640ec03581016176b37ee3d0ba2d7f2ddaf 100644 (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;
 }
 
+        
index 72baa93f6148e8821b9d0520a3eab4ce46cea96b..4d069533b4d4b8d6bba603124c681393aefc5e25 100644 (file)
@@ -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;
index c9549799ab24e386aa26606d9667cb11d49447e1..5f62dcb51a4adee2e35b397b6a022d48929943a6 100644 (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);
+}
index 85e9e58a50175c5e8c05bb43a528de3971db6cdf..02ea972f5b11a43d3d2351253f4ddccf680e592c 100644 (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_
index e0d9d7978866f0c908f7a5758f651b7fb594e145..c965758bf77391c175169def845ffbfe71614861 100644 (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;
index d8c9460753125f2209ebb250ea50266952dba38a..9057369d050a3dee8df58e9b6e0e401689aa1b69 100644 (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;
 };
 
 /*!
index 7bcb2fb02204fa9b8794897dbad56b7feae2bb28..15b58330542f789a70160349454b909c487d5793 100644 (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())
index ad5cd536a44130015d9ab2217682b8a3d9629172..8490e92163f7a5ace4f599f6da65c4e8f5fe74d8 100644 (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
index 13826439a691d854f4fbbbd7b23f505aa48df9a3..05849af70c606c10720889f2469d90e3fd3cbca9 100644 (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;
+}
index af00ed32736257db542e4930f08e46f911367cd5..87fd2938361d1e1171c378a3180a58ff254e2212 100644 (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_