proppanel_packaging.cpp

00001 
00002 // Name:        proppanel_packaging.cpp
00003 // Purpose:     wxPackagePropertiesPanel
00004 //              (stuff for handling the "packaging" page)
00005 // Author:      Francesco Montorsi
00006 // Modified by:
00007 // Created:     28/06/2006 19:22:47
00008 // RCS-ID:      $Id: proppanel_packaging.cpp,v 1.17 2007/01/28 17:58:50 frm Exp $
00009 // Copyright:   (c) 2006 Julian Smart, Francesco Montorsi
00010 // Licence:     wxWidgets license
00012 
00013 
00014 // For compilers that support precompilation, includes "wx/wx.h".
00015 #include "wx/wxprec.h"
00016 
00017 #ifdef __BORLANDC__
00018 #pragma hdrstop
00019 #endif
00020 
00021 #ifndef WX_PRECOMP
00022 #include "wx/wx.h"
00023 #endif
00024 
00025 #include <wx/filepicker.h>
00026 #include <wx/dir.h>
00027 
00028 #include "guipkg/proppanel.h"
00029 #include "guipkg/excludedlg.h"
00030 
00031 #include "wxp/package.h"
00032 #include "wxp/wxp.h"
00033 #include "wxp/packagewxp.h"
00034 
00035 #include "wx/miscutils.h"
00036 #include "wx/explorertreectrl.h"
00037 
00038 
00039 // ----------------------------------------------------------------------------
00040 // wxPackagePropertiesPanel - packaging stuff - I/O
00041 // ----------------------------------------------------------------------------
00042 
00043 void wxPackagePropertiesPanel::InitPackagingPage()
00044 {
00045     UpdateRelativeRoot();
00046     UpdateUncompressedSize();
00047 }
00048 
00049 void wxPackagePropertiesPanel::GetPackagingPackageInfo(wxPackageInfo &ret) const
00050 {
00051     // PACKAGING info
00052     ret.SetCompressionMode(m_pZip->GetValue() ? wxPCM_ZIP : wxPCM_TAR_GZ);
00053     if (m_bRelativeRootValid)
00054     {
00055         // the relative root
00056         ret.SetRoot(m_pRelativeRoot->GetValue());
00057     }
00058 
00059     // the exclude list
00060     for (size_t i=0; i<wxPEM_MAX; i++)
00061     {
00062         wxPackageExcludeMode curr = (wxPackageExcludeMode)i;
00063         ret.SetExcluded(curr, m_pExcluded->Get(curr));
00064     }
00065 
00066     ret.SetFileName(m_pFileName->GetValue());
00067     ret.SetUploadDestination(m_pUpload->GetValue());
00068 }
00069 
00070 void wxPackagePropertiesPanel::DoSetPackagingPackageInfo(const wxPackageInfo &p,
00071                                                          const wxString &filename)
00072 {
00073     // compression system
00074     switch (p.GetCompressionMode())
00075     {
00076     case wxPCM_ZIP:
00077     case wxPCM_TAR_GZ:
00078         m_pZip->SetValue(p.GetCompressionMode() == wxPCM_ZIP);
00079         m_pTar->SetValue(p.GetCompressionMode() == wxPCM_TAR_GZ);
00080         break;
00081 
00082     default:        // invalid compression mode. Use zip by default
00083         m_pZip->SetValue(true);
00084     }
00085 
00086     // output file name
00087     m_pFileName->SetValue(p.GetOutputFileName());
00088 
00089     // destination (if present)
00090     m_pUpload->SetValue(p.GetUploadDestination());
00091 
00092 
00093     // clear all our controls which need a valid filename/relative root:
00094 
00095     m_pProjectDir->SetPath(wxEmptyString);
00096     m_pWXPDir->SetPath(wxEmptyString);
00097 
00098     m_pRelativeRoot->SetValue(wxEmptyString);
00099     m_pIncludedTree->SetPath(wxEmptyString);
00100     m_pExcluded->Clear();
00101 
00102     // set the WXP path
00103     wxFileName fn(filename);
00104     m_pWXPDir->SetPath(fn.GetPath());
00105 
00106     // set the project dir too
00107     m_strRoot = p.GetProjectFolder(filename);   // UpdateRelativeRoot() uses m_strRoot!
00108     m_pProjectDir->SetPath(m_strRoot);
00109 
00110     // the relative root should now be automatically set to
00111     // the correct value which is already in the wxPackageInfo:
00112     UpdateRelativeRoot();
00113     if (!m_bRelativeRootValid)
00114         return;
00115 
00116     wxASSERT(m_pRelativeRoot->GetValue() == p.GetRelativeRoot());
00117 
00118     // we can set the include folder now
00119     SetIncludePath(m_strRoot);
00120 
00121     // add excluded things to our list
00122     m_pExcluded->Clear();
00123     for (size_t i=0; i<wxPEM_MAX; i++)
00124     {
00125         wxPackageExcludeMode curr = (wxPackageExcludeMode)i;
00126         m_pExcluded->Add(curr, p.GetExcluded(curr));
00127     }
00128 
00129     // and last, synchronize the tree with the list
00130     // (since the list contains the updated data while the tree
00131     //  has all items unchecked)
00132     m_pExcluded->SynchTree(m_pIncludedTree);
00133 
00134     UpdateUncompressedSize();
00135 }
00136 
00137 bool wxPackagePropertiesPanel::IsPackagingPageOk() const
00138 {
00139     bool isok = true;
00140 
00141     // check relative root
00142     if (!m_bRelativeRootValid)
00143     {
00144         wxLogWarning(wxT("The root relative to the package's WXP is not correctly set"));
00145         isok = false;
00146     }
00147 
00148     // check output file name
00149     if (m_pFileName->GetValue().IsEmpty())
00150     {
00151         wxLogError(wxT("The output file name is not optional"));
00152         isok = false;
00153     }
00154 
00155     // check included stuff
00156     wxArrayString includedfiles = m_pIncludedTree->GetFilesChecked(),
00157                   includeddirs = m_pIncludedTree->GetDirsChecked();
00158 
00159     // does it makes sense to show the dialog?
00160     if (includedfiles.GetCount() == 0 &&
00161         includeddirs.GetCount() == 0)
00162     {
00163         wxLogError(wxT("No files are included in the package"));
00164         isok = false;
00165     }
00166 
00167     // check uncompressed size
00168 #define MEGABYTE        (1024*1024)
00169     if (m_szUncompressed > 50*MEGABYTE)
00170     {
00171         wxLogWarning(wxT("The package uncompressed size is very big (%s)"),
00172                      wxFileName::GetHumanReadableSize(m_szUncompressed).c_str());
00173         isok = false;
00174     }
00175 
00176     return isok;
00177 }
00178 
00179 
00180 // ----------------------------------------------------------------------------
00181 // wxPackagePropertiesPanel - packaging stuff
00182 // ----------------------------------------------------------------------------
00183 
00184 wxString wxPackagePropertiesPanel::GetProjectParent() const
00185 {
00186     // get the parent of the project root
00187     wxFileName dir(m_pProjectDir->GetDirName());
00188     wxASSERT(dir.GetDirCount() > 0);
00189     dir.RemoveLastDir();
00190 
00191     // that's our prefix
00192     return dir.GetPath(wxPATH_GET_VOLUME);
00193 }
00194 
00195 void wxPackagePropertiesPanel::SetIncludePath(const wxString &path)
00196 {
00197     // update the tree control
00198     m_pIncludedTree->SetPath(path);
00199 
00200     // this is an handy thing that the user will surely like:
00201     m_pIncludedTree->Expand(m_pIncludedTree->GetRootItem());
00202 }
00203 
00204 void wxPackagePropertiesPanel::GetNewExcludedStuff()
00205 {
00206     wxArrayString includedfiles = m_pIncludedTree->GetFilesChecked(),
00207                   includeddirs = m_pIncludedTree->GetDirsChecked();
00208 
00209     // does it makes sense to show the dialog?
00210     if (includedfiles.GetCount() == 0 &&
00211         includeddirs.GetCount() == 0)
00212     {
00213         wxString str;
00214         str.Printf(wxT("All files of the '%s' directory are already excluded.\n")
00215                    wxT("There are no files or directories to exclude."),
00216                    m_strRoot.c_str());
00217 
00218         wxMessageBox(str, wxT("Warning"), wxOK, this);
00219         return;
00220     }
00221 
00222     wxPackageExcludeDlg dlg(this);
00223     wxString prefix = GetProjectParent();
00224 
00225     // add the list of all checked files & folders
00226     dlg.SetFileList(prefix, includedfiles);
00227     dlg.SetDirList(prefix, includeddirs);
00228 
00229     if (dlg.ShowModal() == wxID_OK)
00230     {
00231         wxArrayString arr;
00232 
00233         if (dlg.GetMode() == wxPEM_FILE)
00234             arr = dlg.GetSelectedFiles();
00235         else if (dlg.GetMode() == wxPEM_DIRECTORY)
00236             arr = dlg.GetSelectedDirs();
00237         else if (dlg.GetMode() == wxPEM_PATTERN)
00238         {
00239             // if we don't add to the list the exclusion pattern _before_
00240             // doing the SynchFromTree() call below, then the exclusion
00241             // list would be filled with all the files matched by the pattern!
00242             m_pExcluded->Add(wxPEM_PATTERN, dlg.GetPattern());
00243 
00244             arr = dlg.GetMatchingFiles();
00245         }
00246 
00247         for (size_t i=0; i < arr.GetCount(); i++)
00248         {
00249             // arr[i] is using wxPATH_NATIVE
00250             wxTreeItemId item = m_pIncludedTree->FindItem(arr[i], wxPATH_NATIVE);
00251             wxASSERT(item.IsOk());
00252             
00253             m_pIncludedTree->UnCheck(item);
00254         }
00255 
00256         m_pExcluded->SynchFromTree(m_pIncludedTree);
00257     }
00258 }
00259 
00260 void wxPackagePropertiesPanel::UpdateRelativeRoot()
00261 {
00262     wxFileName absroot = wxFileName::DirName(m_strRoot);
00263     wxFileName wxpdir = wxFileName::DirName(m_pWXPDir->GetPath());
00264 
00265     bool valid = absroot.IsOk() && 
00266                  wxpdir.IsOk() &&
00267                  !absroot.GetPath().IsEmpty() &&
00268                  !wxpdir.GetPath().IsEmpty();
00269 
00270     // we cannot accept volumes as absolute root of a project
00271     // since we need to be able to reference the parent directory
00272     // of absroot!
00273     valid &= absroot.GetDirCount() > 0;
00274 
00275     bool exist = absroot.DirExists() && wxpdir.DirExists();
00276     bool parent = wxIsSubfolderOf(absroot, wxpdir);
00277 
00278     if (valid && exist && parent)
00279     {
00280         m_bRelativeRootValid = true;
00281 
00282         // we can set the relative root
00283         m_pRootCheckLabel->SetLabel(wxT("Valid!"));
00284         m_pRootBitmap->SetBitmap(GetBitmapResource(wxT("valid")));
00285 
00286         // if project dir is c:\myproject and the WXP directory is
00287         // c:\myproject\build we want to have as relative root path
00288         // "../.." and not just ".."
00289         wxFileName rootParent(absroot);
00290         rootParent.RemoveLastDir();
00291 
00292         bool success = rootParent.MakeRelativeTo(wxpdir.GetPath());
00293         wxASSERT(success);
00294 
00295         // wxPATH_UNIX is because we always want to have forward slashes!
00296         wxString str = rootParent.GetPath(0, wxPATH_UNIX);
00297 #ifdef __WXDEBUG__
00298         // only the '.' and the '/' characters should be part of the relative root!
00299         for (size_t i=0; i<str.Len(); i++)
00300             wxASSERT(str[i] == wxT('.') || str[i] == wxT('/'));
00301 #endif
00302 
00303         m_pRelativeRoot->SetValue(str.IsEmpty() ? wxT(".") : str);
00304     }
00305     else
00306     {
00307         m_bRelativeRootValid = false;
00308         m_pRootCheckLabel->SetLabel(wxT("Invalid"));
00309         m_pRootBitmap->SetBitmap(GetBitmapResource(wxT("invalid")));
00310 
00311         if (!valid)
00312         {
00313             m_pRelativeRoot->SetValue(wxT("Both paths must be non-empty"));
00314         }
00315         else if (!exist)
00316         {
00317             m_pRelativeRoot->SetValue(wxT("Both paths must exist"));
00318         }
00319         else if (!parent)
00320         {
00321             m_pRelativeRoot->SetValue(
00322                 wxT("The WXP dir must be a subfolder of the project root"));
00323         }
00324     }
00325 }
00326 
00327 void wxPackagePropertiesPanel::UpdateUncompressedSize()
00328 {
00329     wxArrayString arr;
00330     m_szUncompressed = wxDir::GetTotalSize(m_strRoot, &arr);
00331 
00332     if (arr.GetCount() > 0)
00333     {
00334         wxString list;
00335         for (size_t i=0; i<arr.GetCount(); i++)
00336             list += arr[i] + wxT('\n');
00337 
00338         wxLogWarning(wxT("Could not determine the size of the following files:\n%s"),
00339                      list.c_str());
00340     }
00341 
00342     m_pUncompressedSize->SetLabel(
00343         wxFileName::GetHumanReadableSize(m_szUncompressed));
00344 }
00345 
00346 
00347 
00348 // ----------------------------------------------------------------------------
00349 // wxPackagePropertiesPanel - event handlers
00350 // ----------------------------------------------------------------------------
00351 
00352 void wxPackagePropertiesPanel::OnPackagingButton(wxCommandEvent &ev)
00353 {
00354     switch (ev.GetId())
00355     {
00356     case ID_PROP_REFRESH_INCLUDED:
00357         {
00358             int reply = wxMessageBox(
00359                 _("Refreshing the tree, all the current state of checked/unchecked files and folders will be lost. Are you sure you want to proceed?"),
00360                 wxT("Question"), wxYES_NO, this);
00361             if (reply == wxNO)
00362                 return;
00363 
00364             // refresh the contents and expand the root
00365             m_pIncludedTree->RefreshContents();
00366             m_pIncludedTree->Expand(m_pIncludedTree->GetRootItem());
00367 
00368             // all items of the tree are now unchecked... reset them to
00369             // checked and make empty the exclude list
00370             wxEventBlocker blocker(this);
00371             m_pIncludedTree->CheckAll();
00372 
00373             m_pExcluded->Clear();
00374             
00375             // check status has changed...
00376             OnUserChange();
00377             UpdateUncompressedSize();
00378         }
00379         break;
00380 
00381     case ID_PROP_EXPAND_INCLUDED:
00382         m_pIncludedTree->ExpandAll();
00383         break;
00384 
00385     case ID_PROP_COLLAPSE_INCLUDED:
00386         m_pIncludedTree->CollapseAll();
00387         break;
00388         
00389     case ID_PROP_NEW_EXCLUDED:
00390         // add a new excluded file/dir/pattern
00391         // (this works in a different way than other lists handled below)
00392         GetNewExcludedStuff();
00393         OnUserChange();
00394         UpdateUncompressedSize();
00395         break;
00396 
00397     case ID_PROP_DELETE_EXCLUDED:
00398         m_pExcluded->DeleteSelected();
00399         m_pExcluded->SynchTree(m_pIncludedTree);
00400         OnUserChange();
00401         UpdateUncompressedSize();
00402         break;
00403     }
00404 }
00405 
00406 void wxPackagePropertiesPanel::OnIncludedTreeCheck(wxExplorerTreeEvent &ev)
00407 {
00408     m_pExcluded->SynchFromTree(m_pIncludedTree);
00409 
00410     OnUserChange();
00411     UpdateUncompressedSize();
00412 }
00413 
00414 void wxPackagePropertiesPanel::OnProjectRootChange(wxFileDirPickerEvent &ev)
00415 {
00416     // see wxPackagePropertiesPanel header for more info about the m_strRoot variable:
00417     m_strRoot = ev.GetPath();
00418 
00419     // if the user has not selected a WXP directory yet,
00420     // set it now to be the same of the project root...
00421     if (m_pWXPDir->GetPath().IsEmpty())
00422         m_pWXPDir->SetPath(m_strRoot);
00423 
00424     // update the relative root
00425     UpdateRelativeRoot();
00426 
00427     // the SetPath() and CheckAll() operations may require some time
00428     wxBusyCursor wait;
00429 
00430     // update the tree control
00431     SetIncludePath(m_strRoot);
00432 
00433     {
00434         // performance optimization: avoid that OnIncludedTreeCheck()
00435         // gets called hundreds of times because of the initial CheckAll()
00436         wxEventBlocker blocker(this);
00437         m_pIncludedTree->CheckAll();
00438     }
00439 
00440     // no files excluded now
00441     m_pExcluded->Clear();
00442 
00443     OnUserChange();
00444     UpdateUncompressedSize();
00445 }
00446 
00447 void wxPackagePropertiesPanel::OnWXPDirChange(wxFileDirPickerEvent &ev)
00448 {
00449     UpdateRelativeRoot();
00450     OnUserChange();
00451 }
00452 
00453 void wxPackagePropertiesPanel::OnPackagingPageUpdateUI(wxUpdateUIEvent &WXUNUSED(ev))
00454 {
00455     FindWindowById(ID_PROP_DELETE_EXCLUDED)->Enable(!m_pExcluded->IsEmpty());
00456 
00457     // all buttons make no sense with an empty tree:
00458     bool nonempty = !m_pIncludedTree->IsEmpty();
00459     FindWindowById(ID_PROP_NEW_EXCLUDED)->Enable(nonempty);
00460     FindWindowById(ID_PROP_REFRESH_INCLUDED)->Enable(nonempty);
00461     FindWindowById(ID_PROP_EXPAND_INCLUDED)->Enable(nonempty);
00462     FindWindowById(ID_PROP_COLLAPSE_INCLUDED)->Enable(nonempty);
00463 }
00464 
00465 
00466 
00467 
00468 // ----------------------------------------------------------------------------
00469 // wxPackageExcludeListBox
00470 // ----------------------------------------------------------------------------
00471 
00472 IMPLEMENT_DYNAMIC_CLASS( wxPackageExcludeListBox, wxListBox )
00473 
00474 bool wxPackageExcludeListBox::Create( wxWindow* parent, wxWindowID id, 
00475                                       const wxPoint& pos, const wxSize& size, 
00476                                       long style )
00477 {
00478     if (!wxListBox::Create(parent, id, pos, size, style))
00479         return false;
00480 
00481     return true;
00482 }
00483 
00484 void wxPackageExcludeListBox::Add(wxPackageExcludeMode type, 
00485                                   const wxString &str)
00486 {
00487     wxString toadd =
00488         wxT("[") + wxPackageExcludeMode2String(type) + wxT("] ") + str;
00489 
00490     // we always want to have unix paths in this control
00491     toadd.Replace(wxString(wxFileName::GetPathSeparator(), 1), wxT("/"));
00492 
00493     wxASSERT(FindString(toadd) == wxNOT_FOUND);
00494     Append(toadd);
00495 }
00496 
00497 void wxPackageExcludeListBox::Delete(wxPackageExcludeMode type, 
00498                                      const wxString &str)
00499 {
00500     wxString toremove =
00501         wxT("[") + wxPackageExcludeMode2String(type) + wxT("] ") + str;
00502 
00503     int n = FindString(toremove);
00504     wxASSERT(n != wxNOT_FOUND);
00505     wxListBox::Delete(n);
00506 }
00507 
00508 wxArrayString wxPackageExcludeListBox::Get(wxPackageExcludeMode type) const
00509 {
00510     wxArrayString ret;
00511     wxString str;
00512 
00513     for (size_t i=0; i < GetCount(); i++)
00514     {
00515         str = GetString(i);
00516         if (GetType(str) == type)
00517             ret.Add(GetContent(str));
00518     }
00519 
00520     return ret;
00521 }
00522 
00523 wxString wxPackageExcludeListBox::GetSelection(wxPackageExcludeMode *type) const
00524 {
00525     wxString sel = GetStringSelection();
00526 
00527     if (type)
00528         *type = GetType(sel);
00529 
00530     return GetContent(sel);
00531 }
00532 
00533 void wxPackageExcludeListBox::DeleteSelected()
00534 {
00535     int n = wxListBox::GetSelection();
00536     wxASSERT(n != wxNOT_FOUND);
00537     wxListBox::Delete(n);
00538 }
00539 
00540 /* static */
00541 wxPackageExcludeMode wxPackageExcludeListBox::GetType(const wxString &str)
00542 {
00543     // look at the part in square brackets
00544     wxString prefix = str.AfterFirst(wxT('[')).BeforeFirst(wxT(']'));
00545     return wxString2PackageExcludeMode(prefix);
00546 }
00547 
00548 /* static */
00549 wxString wxPackageExcludeListBox::GetContent(const wxString &str)
00550 {
00551     // look at the part in square brackets
00552     return wxString(str).AfterFirst(wxT(']')).Remove(0, 1);
00553 }
00554 
00555 void wxPackageExcludeListBox::SynchFromTree(const wxExplorerTreeCtrl *tree)
00556 {
00557     wxEventBlocker block(this);     // performance optimizations: avoid
00558                                     // redraws in the middle of the list update
00559 
00560     // before clearing this listbox, save the patterns
00561     wxArrayString patterns = Get(wxPEM_PATTERN);
00562     Clear();
00563 
00564     // readd the patterns
00565     Add(wxPEM_PATTERN, patterns);
00566 
00567     // now add completely unchecked dirs which do not match our patterns
00568     wxArrayString dirs = tree->GetDirsRecursivelyUnChecked();
00569     for (size_t i=0; i<dirs.GetCount(); i++)
00570     {
00571         // NO NEED to remove the prefix since GetDirsRecursivelyUnChecked()
00572         // does not return prefixed directories
00573 
00574         bool nomatches = true;
00575         for (size_t j=0; j<patterns.GetCount(); j++)
00576         {
00577             if (wxMatchWild(patterns[j], dirs[i], false /* special_dot */))
00578             {
00579                 nomatches = false;
00580                 break;
00581             }
00582         }
00583 
00584         if (nomatches)
00585             Add(wxPEM_DIRECTORY, dirs[i]);
00586     }
00587 
00588     // now add all unchecked files which do not match our patterns
00589     // and are not contained in the already added directories
00590     wxArrayString files = tree->GetFilesChecked(false /* get unchecked files */);
00591     for (size_t i=0; i<files.GetCount(); i++)
00592     {
00593         // remove the prefix
00594         wxString f = files[i];
00595         f.Remove(0, tree->GetPathPrefix().Len()+1);
00596 
00597         bool nomatches = true;
00598         for (size_t j=0; j<patterns.GetCount(); j++)
00599         {
00600             if (wxMatchWild(patterns[j], f, false /* special_dot */))
00601             {
00602                 nomatches = false;
00603                 break;
00604             }
00605         }
00606 
00607         for (size_t j=0; j<dirs.GetCount(); j++)
00608         {
00609             if (f.StartsWith(dirs[j]))
00610             {
00611                 nomatches = false;
00612                 break;
00613             }
00614         }
00615 
00616         if (nomatches)
00617             Add(wxPEM_FILE, f);
00618     }
00619 }
00620 
00621 void wxPackageExcludeListBox::SynchTree(wxExplorerTreeCtrl *tree) const
00622 {
00623     wxEventBlocker blocker(tree);   // for better performances (even if 
00624                                     // it doesn't make a big difference)
00625 
00626     // build the arrays once and pass them recursively
00627     wxArrayString files = Get(wxPEM_FILE),
00628                   dirs = Get(wxPEM_DIRECTORY),
00629                   patterns = Get(wxPEM_PATTERN);
00630 
00631     wxTreeItemId root = tree->GetRootItem();
00632     bool allchecked = DoSynchTree(root, tree, tree->GetItemText(root) + wxT("/"), 
00633                                   files, dirs, patterns);
00634 
00635     // see HACK comment below
00636     tree->SetItemBold(root, allchecked);
00637 }
00638 
00639 bool wxPackageExcludeListBox::DoSynchTree(const wxTreeItemId &item,
00640                                           wxExplorerTreeCtrl *tree,
00641                                           const wxString &prefix,
00642                                           const wxArrayString &files,
00643                                           const wxArrayString &dirs,
00644                                           const wxArrayString &patterns) const
00645 {
00646     bool allchecked = true;
00647     wxTreeItemIdValue cookie;
00648     for (wxTreeItemId i = tree->GetFirstChild(item, cookie);
00649          i.IsOk();
00650          i = tree->GetNextChild(item, cookie))
00651     {
00652         // don't use tree->GetItemFullPath() for better performances
00653         wxString name = prefix + tree->GetItemText(i);
00654 
00655         if (tree->IsFolder(i))
00656         {
00657             // is this a folder to uncheck?
00658             if (dirs.Index(name) != wxNOT_FOUND)
00659             {
00660                 tree->UnCheck(i);
00661                 allchecked = false;
00662             }
00663             else
00664             {
00665                 bool childchecked = 
00666                     DoSynchTree(i, tree, name + wxT("/"), files, dirs, patterns);
00667 
00668                 // HACK: we should do a tree->UnCheck(i) if allchecked==false
00669                 //       but this would result yet in another recursive walk of
00670                 //       the tree (in wxExplorerTreeCtrl) which would slow down
00671                 //       everything without altering anything (we did already
00672                 //       modify all item's status in our recursive DoSynchTree
00673                 //       call done above); so we just alter the bold status of the
00674                 //       folder ourselves here:
00675                 tree->SetItemBold(i, childchecked);
00676 
00677                 allchecked &= childchecked;
00678             }
00679         }
00680         else
00681         {
00682             // is this a file to uncheck?
00683             if (files.Index(name) != wxNOT_FOUND)
00684             {
00685                 tree->UnCheck(i);
00686                 allchecked = false;
00687             }
00688             else
00689             {
00690                 bool matches = false;
00691                 for (size_t j=0; j<patterns.GetCount(); j++)
00692                 {
00693                     if (wxMatchWild(patterns[j], name, false /* special_dot */))
00694                     {
00695                         matches = true;
00696                         break;
00697                     }
00698                 }
00699 
00700                 if (matches)
00701                 {
00702                     tree->UnCheck(i);
00703                     allchecked = false;
00704                 }
00705                 else
00706                     tree->Check(i);
00707             }
00708         }
00709     }
00710 
00711     return allchecked;
00712 }
00713 

Generated on Thu Feb 1 22:14:31 2007 for wxWidgets Package Manager by  doxygen 1.5.1-p1