Update of /cvsroot/mahogany/M/src/gui
In directory usw-pr-cvs1:/tmp/cvs-serv19119/src/gui

Modified Files:
        wxFolderView.cpp wxMDialogs.cpp wxMainFrame.cpp 
        wxSearchDialog.cpp 
Log Message:
implemented searching in multiple folders, it compiles and seems to work for
single folder searches but dies horribly when searching in more than one
folder for now


Index: wxFolderView.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxFolderView.cpp,v
retrieving revision 1.599
retrieving revision 1.600
diff -b -u -2 -r1.599 -r1.600
--- wxFolderView.cpp    22 Jul 2002 00:02:30 -0000      1.599
+++ wxFolderView.cpp    23 Jul 2002 18:47:11 -0000      1.600
@@ -812,7 +812,4 @@
 // ----------------------------------------------------------------------------
 
-static
-bool ShowSearchResults(MailFolder *mf, const UIdArray& uids, wxFrame *frame);
-
 // return the n-th shown column (WXFLC_NONE if no more columns)
 static wxFolderListColumn GetColumnByIndex(const int *columns, size_t n)
@@ -4781,31 +4778,7 @@
       m_TicketList->Remove(t);
 
-      int ok = ((ASMailFolder::ResultInt *)result)->GetValue() != 0;
-
       String msg;
       switch ( result->GetOperation() )
       {
-         case ASMailFolder::Op_SearchMessages:
-            if( ok )
-            {
-               UIdArray *uidsMatching = result->GetSequence();
-               if ( !uidsMatching )
-               {
-                  FAIL_MSG( "searched ok but no search results??" );
-                  break;
-               }
-
-               MailFolder_obj mf = GetMailFolder();
-               ShowSearchResults(mf, *uidsMatching, m_Frame);
-
-               wxLogStatus(m_Frame, _("Found %lu messages."),
-                           uidsMatching->GetCount());
-            }
-            else
-            {
-               wxLogWarning(_("No matching messages found."));
-            }
-            break;
-
          case ASMailFolder::Op_GetMessage:
             // so far we only use GetMessage() when processing
@@ -5015,42 +4988,4 @@
 // other public functions (from include/FolderView.h)
 // ----------------------------------------------------------------------------
-
-static
-bool ShowSearchResults(MailFolder *mf, const UIdArray& uids, wxFrame *frame)
-{
-   MFolder_obj folder = MFolder::CreateTemp
-                        (
-                           _("Search results"),
-                           MF_VIRTUAL,
-                           mf->GetProfile()
-                        );
-   if ( !folder )
-      return false;
-
-   // FIXME: a hack to prevent the same search results folder from being reused
-   //        all the time
-   static unsigned int s_countSearch = 0;
-   folder->SetPath(String::Format("(%u)", ++s_countSearch));
-
-   MailFolder_obj mfVirt = MailFolder::OpenFolder(folder);
-   if ( !mfVirt )
-      return false;
-
-   HeaderInfoList_obj hil = mf->GetHeaders();
-   if ( !hil )
-      return false;
-
-   size_t count = uids.GetCount();
-   for ( size_t n = 0; n < count; n++ )
-   {
-      Message_obj message = mf->GetMessage(uids[n]);
-      if ( message )
-      {
-         mfVirt->AppendMessage(*message.Get());
-      }
-   }
-
-   return OpenFolderViewFrame(folder, frame);
-}
 
 bool OpenFolderViewFrame(MFolder *folder,

Index: wxMDialogs.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMDialogs.cpp,v
retrieving revision 1.377
retrieving revision 1.378
diff -b -u -2 -r1.377 -r1.378
--- wxMDialogs.cpp      22 Jul 2002 00:02:31 -0000      1.377
+++ wxMDialogs.cpp      23 Jul 2002 18:47:11 -0000      1.378
@@ -263,5 +263,5 @@
 {
 public:
-   MFolderDialog(wxWindow *parent, MFolder *folder, bool open = false);
+   MFolderDialog(wxWindow *parent, MFolder *folder, int flags);
    virtual ~MFolderDialog();
 
@@ -288,6 +288,6 @@
    bool m_userChoseFolder;
 
-   // are we going to open this folder or save to it?
-   bool m_selectForOpening;
+   // the combination of MDlg_Folder_XXX flags
+   int m_flags;
 
    DECLARE_EVENT_TABLE()
@@ -1398,10 +1398,10 @@
 // ----------------------------------------------------------------------------
 
-MFolderDialog::MFolderDialog(wxWindow *parent, MFolder *folder, bool open)
+MFolderDialog::MFolderDialog(wxWindow *parent, MFolder *folder, int flags)
              : wxManuallyLaidOutDialog(parent,
                                        _("Choose folder"),
                                        "FolderSelDlg")
 {
-   m_selectForOpening = open;
+   m_flags = flags;
    m_userChoseFolder = false;
 
@@ -1419,4 +1419,6 @@
 
    // File button
+   if ( !(m_flags & MDlg_Folder_NoFiles) )
+   {
    wxButton *btnFile = new wxButton(this, wxID_OPEN, _("&File..."));
    c = new wxLayoutConstraints;
@@ -1426,4 +1428,5 @@
    c->bottom.SameAs(btnOk, wxBottom);
    btnFile->SetConstraints(c);
+   }
 
    // Help button
@@ -1470,5 +1473,5 @@
                                       _("Mahogany: Please choose a folder file"),
                                       NULL, NULL, NULL, NULL,
-                                      m_selectForOpening
+                                      m_flags & MDlg_Folder_Open
                                        ? wxOPEN | wxFILE_MUST_EXIST
                                        : wxSAVE,
@@ -1558,8 +1561,8 @@
 
 MFolder *
-MDialog_FolderChoose(const wxWindow *parent, MFolder *folder, bool open)
+MDialog_FolderChoose(const wxWindow *parent, MFolder *folder, int flags)
 {
    // TODO store the last folder in config
-   MFolderDialog dlg((wxWindow *)parent, folder, open);
+   MFolderDialog dlg((wxWindow *)parent, folder, flags);
 
    return dlg.ShowModal() == wxID_OK ? dlg.GetFolder() : NULL;

Index: wxMainFrame.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxMainFrame.cpp,v
retrieving revision 1.152
retrieving revision 1.153
diff -b -u -2 -r1.152 -r1.153
--- wxMainFrame.cpp     22 Jul 2002 13:48:18 -0000      1.152
+++ wxMainFrame.cpp     23 Jul 2002 18:47:12 -0000      1.153
@@ -43,5 +43,8 @@
 #include "MFolder.h"
 
+// these 3 are needed only for SEARCH command processing
 #include "MSearch.h"
+#include "UIdArray.h"
+#include "HeaderInfo.h"
 
 #include "gui/wxMainFrame.h"
@@ -231,4 +234,280 @@
 };
 
+// ============================================================================
+// async search helper classes
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// AsyncSearchData: data for one search operation
+// ----------------------------------------------------------------------------
+
+class AsyncSearchData
+{
+public:
+   // default ctor
+   AsyncSearchData()
+   {
+      m_mfVirt = NULL;
+
+      m_folderVirt = NULL;
+
+      m_nMatchingMessages =
+      m_nMatchingFolders = 0;
+   }
+
+   ~AsyncSearchData()
+   {
+      if ( m_mfVirt )
+      {
+         m_mfVirt->DecRef();
+         m_folderVirt->DecRef();
+      }
+   }
+
+   // add a record for another folder being searched
+   //
+   // NB: we take ownership of the mf pointer and will DecRef() it
+   bool AddSearchFolder(MailFolder *mf, Ticket t)
+   {
+      CHECK( mf && t != ILLEGAL_TICKET, false,
+             "invalid params in AsyncSearchData::AddSearchFolder" );
+
+      m_listSingleSearch.push_back(new SingleSearchData(t, mf));
+
+      return true;
+   }
+
+   // process the search result if it concerns this search, in which case true
+   // is returned (even if there were errors), otherwise return false to
+   // indicate that we don't have anything to do with this result
+   bool HandleSearchResult(const ASMailFolder::Result& result)
+   {
+      const Ticket t = result.GetTicket();
+      for ( SingleSearchDataList::iterator i = m_listSingleSearch.begin();
+            i != m_listSingleSearch.end();
+            ++i )
+      {
+         if ( i->GetTicket() == t )
+         {
+            if ( ((const ASMailFolder::ResultInt&)result).GetValue() )
+            {
+               const UIdArray *uidsMatching = result.GetSequence();
+               if ( !uidsMatching )
+               {
+                  FAIL_MSG( "searched ok but no search results??" );
+               }
+               else // have some messages to show
+               {
+                  // create the virtual folder to show the results if not done
+                  // yet
+                  if ( GetResultsVFolder() )
+                  {
+                     const MailFolder *mf = i->GetMailFolder();
+
+                     // and append all matching messages to the results folder
+                     HeaderInfoList_obj hil = mf->GetHeaders();
+                     if ( hil )
+                     {
+                        size_t nMatches = 0;
+
+                        size_t count = uidsMatching->GetCount();
+                        for ( size_t n = 0; n < count; n++ )
+                        {
+                           Message_obj msg = mf->GetMessage((*uidsMatching)[n]);
+                           if ( msg )
+                           {
+                              m_mfVirt->AppendMessage(*msg.Get());
+
+                              nMatches++;
+                           }
+                        }
+
+                        if ( nMatches )
+                        {
+                           m_nMatchingMessages += nMatches;
+                           m_nMatchingFolders++;
+                        }
+                     }
+                  }
+               }
+            }
+            //else: nothing found at all in this folder, nothing to do
+
+            // we don't care about this one any more
+            m_listSingleSearch.erase(i);
+
+            // it was our result
+            return true;
+         }
+      }
+
+      // not the result of this search at all
+      return false;
+   }
+
+   // if we're still waiting for the completion of [another] search, return
+   // false, otherwise return true
+   bool IsSearchCompleted() const { return m_listSingleSearch.empty(); }
+
+   // show the search results to the user
+   void ShowSearchResults(wxFrame *frame)
+   {
+      ASSERT_MSG( IsSearchCompleted(), "shouldn't be called yet!" );
+
+      if ( m_folderVirt && m_nMatchingMessages )
+      {
+         OpenFolderViewFrame(m_folderVirt, frame);
+
+         wxLogStatus(frame, _("Found %lu messages in %lu folders."),
+                     (unsigned long)m_nMatchingMessages,
+                     (unsigned long)m_nMatchingFolders);
+
+      }
+      else
+      {
+         wxLogWarning(_("No matching messages found."));
+      }
+   }
+
+private:
+   // returns, creating if necessary, the virtual folder in which we show the
+   // search results
+   //
+   // NB: the returned pointer should not be DecRef()'d by caller
+   MailFolder *GetResultsVFolder()
+   {
+      if ( !m_mfVirt )
+      {
+         // FIXME: we should use the profile of the common parent of the
+         //        folders being searched instead of the global settings here
+         //        or, at the very least, the profile of the only folder being
+         //        searched if we search in only one folder
+         m_folderVirt = MFolder::CreateTemp
+                        (
+                         _("Search results"),
+                         MF_VIRTUAL,
+                         mApplication->GetProfile()
+                        );
+
+         if ( m_folderVirt )
+         {
+            // FIXME: a hack to prevent the same search results folder from
+            //        being reused all the time
+            static unsigned int s_countSearch = 0;
+            m_folderVirt->SetPath(String::Format("(%u)", ++s_countSearch));
+
+            m_mfVirt = MailFolder::OpenFolder(m_folderVirt);
+            if ( !m_mfVirt )
+            {
+               m_folderVirt->DecRef();
+               m_folderVirt = NULL;
+            }
+         }
+      }
+
+      if ( !m_mfVirt )
+      {
+         ERRORMESSAGE((_("Failed to create the search results folder")));
+      }
+
+      return m_mfVirt;
+   }
+
+   // SingleSearchData: struct containing info about search in one folder
+   class SingleSearchData
+   {
+   public:
+      SingleSearchData(Ticket ticket, MailFolder *mf)
+      {
+         m_ticket = ticket;
+         m_mf = mf;
+      }
+
+      ~SingleSearchData() { m_mf->DecRef(); }
+
+      /// get the associated async operation ticket
+      Ticket GetTicket() const { return m_ticket; }
+
+      /// get the the mail folder we're searching in (NOT IncRef()'d)
+      MailFolder *GetMailFolder() const { return m_mf; }
+
+   private:
+      /// the associated async ticket
+      Ticket m_ticket;
+
+      /// the folder we're searching in
+      MailFolder *m_mf;
+
+      /// the UIDs found so far
+      UIdArray m_uidsFound;
+   };
+
+   // the list containing the individual search records for all folders we're
+   // searching in
+   M_LIST_OWN(SingleSearchDataList, SingleSearchData) m_listSingleSearch;
+
+   // the virtual folder we show the search results in and the associated
+   // MFolder object for it
+   MailFolder *m_mfVirt;
+   MFolder *m_folderVirt;
+
+   // the number of messages found so far
+   size_t m_nMatchingMessages;
+
+   // the number of folders containing the matching messages
+   size_t m_nMatchingFolders;
+};
+
+// ----------------------------------------------------------------------------
+// GlobalSearchData: contains data for all search operations in progress
+// ----------------------------------------------------------------------------
+
+class GlobalSearchData
+{
+public:
+   // ctor
+   GlobalSearchData(wxFrame *frame) { m_frame = frame; }
+
+   // create a record for a new search operation
+   AsyncSearchData *StartNewSearch()
+   {
+      AsyncSearchData *ssd = new AsyncSearchData;
+      m_listAsyncSearch.push_back(ssd);
+      return ssd;
+   }
+
+   // process the result of the async search operation
+   void HandleSearchResult(const ASMailFolder::Result& result)
+   {
+      // leave the real handling to the search this result concerns
+      for ( AsyncSearchDataList::iterator i = m_listAsyncSearch.begin();
+            i != m_listAsyncSearch.end();
+            ++i )
+      {
+         if ( i->HandleSearchResult(result) )
+         {
+            // was it the last search result for this search
+            if ( i->IsSearchCompleted() )
+            {
+               // yes, show the results ...
+               i->ShowSearchResults(m_frame);
+
+               // ... and delete the stale stale search record
+               m_listAsyncSearch.erase(i);
+            }
+
+            return;
+         }
+      }
+
+      FAIL_MSG( "got search result for a search we hadn't ever started?" );
+   }
+
+private:
+   M_LIST_OWN(AsyncSearchDataList, AsyncSearchData) m_listAsyncSearch;
+
+   wxFrame *m_frame;
+};
+
 // ----------------------------------------------------------------------------
 // event tables
@@ -258,4 +537,6 @@
            : wxMFrame(iname,parent)
 {
+   m_searchData = NULL;
+
    SetIcon(ICON("MainFrame"));
    SetTitle(_("Copyright (C) 1997-2002 The Mahogany Developers Team"));
@@ -309,5 +590,5 @@
    // update the menu to match the initial selection
    MFolder_obj folder = m_FolderTree->GetSelection();
-   if ( folder.IsOk() )
+   if ( folder )
    {
       UpdateFolderMenuUI(folder);
@@ -568,14 +849,5 @@
 
          case WXMENU_FOLDER_SEARCH:
-            {
-               SearchCriterium crit;
-
-               Profile_obj profile(GetFolderProfile());
-               if ( ConfigureSearchMessages(&crit, profile, this) )
-               {
-                  //Ticket t = m_ASMailFolder->SearchMessages(&crit, this);
-                  //m_TicketList->Add(t);
-               }
-            }
+            DoFolderSearch();
             break;
 
@@ -722,4 +994,112 @@
 }
 
+void wxMainFrame::DoFolderSearch()
+{
+   SearchCriterium crit;
+
+   Profile_obj profile(GetFolderProfile());
+   MFolder_obj folder = m_FolderTree->GetSelection();
+   if ( ConfigureSearchMessages(&crit, profile, folder, this) )
+   {
+      AsyncSearchData *searchData = NULL;
+
+      const wxArrayString& folderNames = crit.m_Folders;
+      size_t count = folderNames.GetCount();
+      for ( size_t n = 0; n < count; n++ )
+      {
+         const String& name = folderNames[n];
+
+         MFolder_obj folder = name;
+         if ( !folder )
+         {
+            wxLogError(_("Can't search for messages in a "
+                         "non existent folder '%s'."),
+                       name.c_str());
+            continue;
+         }
+
+         if ( folder->CanOpen() )
+         {
+            ASMailFolder *asmf = ASMailFolder::OpenFolder(folder);
+            if ( !asmf )
+            {
+               wxLogError(_("Can't search for messages in the "
+                            "folder '%s'."),
+                          name.c_str());
+
+               continue;
+            }
+
+            // opened ok, search in it
+            Ticket t = asmf->SearchMessages(&crit, this);
+            if ( t != ILLEGAL_TICKET )
+            {
+               // create a new single search data on the fly
+               if ( !searchData )
+               {
+                  // create the search data on demand as well if necessary
+                  InitSearchData();
+
+                  searchData = m_searchData->StartNewSearch();
+               }
+
+               searchData->AddSearchFolder(asmf->GetMailFolder(), t);
+            }
+
+            asmf->DecRef();
+         }
+         //else: silently skip this one
+      }
+   }
+   //else: cancelled by user
+}
+
+void wxMainFrame::InitSearchData()
+{
+   if ( m_searchData )
+      return;
+
+   m_searchData = new GlobalSearchData(this);
+
+   m_cookieASMf = MEventManager::Register(*this, MEventId_ASFolderResult);
+}
+
+bool wxMainFrame::OnMEvent(MEventData& ev)
+{
+   if ( ev.GetId() == MEventId_ASFolderResult )
+   {
+      const MEventASFolderResultData& event = (MEventASFolderResultData &)ev;
+
+      ASMailFolder::Result *result = event.GetResult();
+      if ( result )
+      {
+         if ( result->GetUserData() == this )
+         {
+            switch ( result->GetOperation() )
+            {
+               case ASMailFolder::Op_SearchMessages:
+                  if ( m_searchData )
+                  {
+                     m_searchData->HandleSearchResult(*result);
+                  }
+                  else
+                  {
+                     FAIL_MSG( "search in progress but no search data?" );
+                  }
+                  break;
+
+               default:
+                  FAIL_MSG( "unexpected ASMailFolder::Result in wxMainFrame" );
+            }
+         }
+
+         result->DecRef();
+      }
+   }
+
+   // continue evaluating this event
+   return true;
+}
+
 wxMainFrame::~wxMainFrame()
 {
@@ -732,4 +1112,11 @@
    delete m_FolderView;
    delete m_FolderTree;
+
+   if ( m_searchData )
+   {
+      delete m_searchData;
+
+      MEventManager::Deregister(m_cookieASMf);
+   }
 }
 

Index: wxSearchDialog.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/gui/wxSearchDialog.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -b -u -2 -r1.1 -r1.2
--- wxSearchDialog.cpp  22 Jul 2002 00:02:31 -0000      1.1
+++ wxSearchDialog.cpp  23 Jul 2002 18:47:12 -0000      1.2
@@ -24,4 +24,6 @@
    #include "Mcommon.h"
 
+   #include "MFolder.h"
+
    #include "MHelp.h"
 
@@ -82,5 +84,7 @@
 public:
    wxMessageSearchDialog(SearchCriterium *crit,
-                         Profile *profile, wxWindow *parent);
+                         Profile *profile,
+                         const MFolder *folder,
+                         wxWindow *parent);
 
    // reset the selected options to their default values
@@ -89,11 +93,9 @@
 
 protected:
-   void UpdateCritStruct(void)
-   {
-      m_CritStruct->m_What = (SearchCriterium::Type)
-         m_Choices->GetSelection();
-      m_CritStruct->m_Invert = m_Invert->GetValue();
-      m_CritStruct->m_Key = m_Keyword->GetValue();
-   }
+   // event handlers
+   void OnUpdateUIOk(wxUpdateUIEvent& event);
+   void OnUpdateUIRemove(wxUpdateUIEvent& event);
+   void OnButtonAdd(wxCommandEvent& event);
+   void OnButtonRemove(wxCommandEvent& event);
 
    SearchCriterium *m_CritStruct;
@@ -102,18 +104,37 @@
 
    // GUI controls
-   wxChoice     *m_Choices;
-   wxCheckBox   *m_Invert;
-   wxPTextEntry *m_Keyword;
+   wxChoice     *m_choiceWhere;
+   wxCheckBox   *m_chkInvert;
+   wxPTextEntry *m_textWhat;
    wxListBox *m_lboxFolders;
+
+   DECLARE_EVENT_TABLE()
 };
 
+// ----------------------------------------------------------------------------
+// event tables
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxMessageSearchDialog, wxOptionsPageSubdialog)
+   EVT_BUTTON(Btn_Add, wxMessageSearchDialog::OnButtonAdd)
+   EVT_BUTTON(Btn_Remove, wxMessageSearchDialog::OnButtonRemove)
+
+   EVT_UPDATE_UI(wxID_OK, wxMessageSearchDialog::OnUpdateUIOk)
+   EVT_UPDATE_UI(Btn_Remove, wxMessageSearchDialog::OnUpdateUIRemove)
+END_EVENT_TABLE()
+
 // ============================================================================
 // wxMessageSearchDialog implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// ctor
+// ----------------------------------------------------------------------------
+
 wxMessageSearchDialog::wxMessageSearchDialog(SearchCriterium *crit,
                                              Profile *profile,
+                                             const MFolder *folder,
                                              wxWindow *parent)
-                     : wxOptionsPageSubdialog(profile,parent,
+                     : wxOptionsPageSubdialog(profile, parent,
                                               _("Search for messages"),
                                               "MessageSearchDialog")
@@ -136,5 +157,5 @@
 
    // first line: [x] Not containing [Text___]
-   m_Invert = new wxCheckBox(this, -1, _("&Not"));
+   m_chkInvert = new wxCheckBox(this, -1, _("&not"));
    c = new wxLayoutConstraints;
    c->left.SameAs(box, wxLeft, 2*LAYOUT_X_MARGIN);
@@ -142,15 +163,15 @@
    c->top.SameAs(box, wxTop, 5*LAYOUT_Y_MARGIN);
    c->height.AsIs();
-   m_Invert->SetConstraints(c);
+   m_chkInvert->SetConstraints(c);
 
    label = new wxStaticText(this, -1, _("&containing"));
    c = new wxLayoutConstraints;
-   c->left.RightOf(m_Invert, 2*LAYOUT_X_MARGIN);
+   c->left.RightOf(m_chkInvert, 2*LAYOUT_X_MARGIN);
    c->width.AsIs();
-   c->centreY.SameAs(m_Invert, wxCentreY);
+   c->centreY.SameAs(m_chkInvert, wxCentreY);
    c->height.AsIs();
    label->SetConstraints(c);
 
-   m_Keyword = new wxPTextEntry("SearchFor", this, -1);
+   m_textWhat = new wxPTextEntry("SearchFor", this, -1);
    c = new wxLayoutConstraints;
    c->left.RightOf(label, 2*LAYOUT_X_MARGIN);
@@ -158,24 +179,24 @@
    c->centreY.SameAs(label, wxCentreY);
    c->height.AsIs();
-   m_Keyword->SetConstraints(c);
+   m_textWhat->SetConstraints(c);
 
    // second line: In [Where___]
-   label = new wxStaticText(this, -1, _("&In"));
+   m_choiceWhere = new wxPChoice("SearchWhere", this, -1,
+                                 wxDefaultPosition, wxDefaultSize,
+                                 WXSIZEOF(searchCriteria), searchCriteria);
    c = new wxLayoutConstraints;
-   c->left.SameAs(box, wxLeft, 2*LAYOUT_X_MARGIN);
-   c->width.AsIs();
-   c->top.Below(m_Keyword, 2*LAYOUT_Y_MARGIN);
+   c->left.SameAs(m_textWhat, wxLeft);
+   c->right.SameAs(m_textWhat, wxRight);
+   c->top.Below(m_textWhat, 2*LAYOUT_Y_MARGIN);
    c->height.AsIs();
-   label->SetConstraints(c);
+   m_choiceWhere->SetConstraints(c);
 
-   m_Choices = new wxPChoice("SearchWhere", this, -1,
-                             wxDefaultPosition, wxDefaultSize,
-                             WXSIZEOF(searchCriteria), searchCriteria);
+   label = new wxStaticText(this, -1, _("&in"));
    c = new wxLayoutConstraints;
-   c->left.RightOf(label, 2*LAYOUT_X_MARGIN);
-   c->right.SameAs(box, wxRight, 2*LAYOUT_X_MARGIN);
-   c->centreY.SameAs(label, wxCentreY);
+   c->right.LeftOf(m_choiceWhere, 2*LAYOUT_X_MARGIN);
+   c->width.AsIs();
+   c->centreY.SameAs(m_choiceWhere, wxCentreY);
    c->height.AsIs();
-   m_Choices->SetConstraints(c);
+   label->SetConstraints(c);
 
    c = new wxLayoutConstraints;
@@ -183,5 +204,5 @@
    c->right.SameAs(this, wxRight, LAYOUT_X_MARGIN);
    c->top.SameAs(this, wxTop, LAYOUT_Y_MARGIN);
-   c->bottom.SameAs(m_Choices, wxBottom, -3*LAYOUT_Y_MARGIN);
+   c->bottom.SameAs(m_choiceWhere, wxBottom, -3*LAYOUT_Y_MARGIN);
    box->SetConstraints(c);
 
@@ -198,5 +219,16 @@
    btnAdd->SetConstraints(c);
 
+   wxButton *btnRemove = new wxButton(this, Btn_Remove, _("&Remove"));
+   c = new wxLayoutConstraints;
+   c->width.AsIs();
+   c->right.SameAs(box, wxRight, 2*LAYOUT_X_MARGIN);
+   c->top.SameAs(box, wxCentreY, LAYOUT_Y_MARGIN);
+   c->height.AsIs();
+   btnRemove->SetConstraints(c);
+
    m_lboxFolders = new wxListBox(this, -1);
+   if ( folder )
+      m_lboxFolders->Append('/' + folder->GetFullName());
+
    c = new wxLayoutConstraints;
    c->left.SameAs(box, wxLeft, 2*LAYOUT_X_MARGIN);
@@ -209,5 +241,5 @@
    c->left.SameAs(this, wxLeft, LAYOUT_X_MARGIN);
    c->right.SameAs(this, wxRight, LAYOUT_X_MARGIN);
-   c->top.SameAs(m_Choices, wxBottom, 5*LAYOUT_Y_MARGIN);
+   c->top.SameAs(m_choiceWhere, wxBottom, 5*LAYOUT_Y_MARGIN);
    c->bottom.SameAs(FindWindow(wxID_OK), wxTop, 3*LAYOUT_Y_MARGIN);
    box->SetConstraints(c);
@@ -216,45 +248,104 @@
 }
 
+// ----------------------------------------------------------------------------
+// wxMessageSearchDialog data transfer
+// ----------------------------------------------------------------------------
+
+bool wxMessageSearchDialog::TransferDataToWindow()
+{
+   // see TransferDataFromWindow() for the explanation of SEARCH_CRIT_MASK: now
+   // we simply unpack that word back
+   m_Criterium = READ_CONFIG(GetProfile(), MP_MSGS_SEARCH_CRIT);
+   m_choiceWhere->SetSelection(m_Criterium & SEARCH_CRIT_MASK);
+
+   m_chkInvert->SetValue((m_Criterium & SEARCH_CRIT_INVERT_FLAG) != 0);
+
+   m_Arg = READ_CONFIG_TEXT(GetProfile(), MP_MSGS_SEARCH_ARG);
+   m_textWhat->SetValue(m_Arg);
+
+   m_choiceWhere->SetFocus();
+
+   return TRUE;
+}
 
 bool wxMessageSearchDialog::TransferDataFromWindow()
 {
-   m_Criterium = m_Choices->GetSelection();
-   if(m_Invert->GetValue() != 0)
+   m_Criterium = m_choiceWhere->GetSelection();
+   m_CritStruct->m_What = (SearchCriterium::Type) m_Criterium;
+
+   m_CritStruct->m_Invert = m_chkInvert->GetValue();
+   if ( m_CritStruct->m_Invert )
+   {
+      // we combine the values of m_chkInvert and m_choiceWhere into one config
+      // entry
       m_Criterium |= SEARCH_CRIT_INVERT_FLAG;
+   }
+
+   m_Arg = m_textWhat->GetValue();
 
-   m_Arg = m_Keyword->GetValue();
    GetProfile()->writeEntry(MP_MSGS_SEARCH_CRIT, m_Criterium);
    GetProfile()->writeEntry(MP_MSGS_SEARCH_ARG, m_Arg);
 
-   UpdateCritStruct();
+   m_CritStruct->m_Key = m_Arg;
+
+   wxString s;
+   m_CritStruct->m_Folders.Empty();
+   size_t count = m_lboxFolders->GetCount();
+   for ( size_t n = 0; n < count; n++ )
+   {
+      s = m_lboxFolders->GetString(n);
+      m_CritStruct->m_Folders.Add(s.c_str() + 1); // skip leading slash
+   }
+
    return TRUE;
 }
 
-bool wxMessageSearchDialog::TransferDataToWindow()
-{
-   m_Criterium = READ_CONFIG(GetProfile(), MP_MSGS_SEARCH_CRIT);
-   m_Arg = READ_CONFIG_TEXT(GetProfile(), MP_MSGS_SEARCH_ARG);
-
-   if ( m_Criterium & SEARCH_CRIT_MASK )
-      m_Choices->SetSelection(m_Criterium & SEARCH_CRIT_MASK);
+// ----------------------------------------------------------------------------
+// wxMessageSearchDialog event handlers
+// ----------------------------------------------------------------------------
 
-   m_Invert->SetValue((m_Criterium & SEARCH_CRIT_INVERT_FLAG) != 0);
+void wxMessageSearchDialog::OnUpdateUIOk(wxUpdateUIEvent& event)
+{
+   // we must have something and somewhere to search for
+   event.Enable( !m_textWhat->GetValue().empty() &&
+                     m_lboxFolders->GetCount() != 0 );
+}
 
-   if ( !m_Arg.empty() )
-      m_Keyword->SetValue(m_Arg);
+void wxMessageSearchDialog::OnUpdateUIRemove(wxUpdateUIEvent& event)
+{
+   event.Enable( m_lboxFolders->GetSelection() != -1 );
+}
 
-   UpdateCritStruct();
+void wxMessageSearchDialog::OnButtonAdd(wxCommandEvent& event)
+{
+   MFolder_obj folder = MDialog_FolderChoose(this, NULL, MDlg_Folder_NoFiles);
+   if ( folder )
+   {
+      m_lboxFolders->Append('/' + folder->GetFullName());
+   }
+}
 
-   m_Choices->SetFocus();
+void wxMessageSearchDialog::OnButtonRemove(wxCommandEvent& event)
+{
+   int sel = m_lboxFolders->GetSelection();
+   if ( sel == -1 )
+      return;
 
-   return TRUE;
+   m_lboxFolders->Delete(sel);
 }
 
-/* Configuration dialog for searching messages. */
+// ----------------------------------------------------------------------------
+// wxMessageSearchDialog public API
+// ----------------------------------------------------------------------------
+
+// Configuration dialog for searching message
 extern
 bool ConfigureSearchMessages(SearchCriterium *crit,
-                             Profile *profile, wxWindow *parent)
+                             Profile *profile,
+                             const MFolder *folder,
+                             wxWindow *parent)
 {
-   wxMessageSearchDialog dlg(crit, profile, parent);
+   wxMessageSearchDialog dlg(crit, profile, folder, parent);
+
    return dlg.ShowModal() == wxID_OK;
 }



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to