00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013
00014
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
00041
00042
00043 void wxPackagePropertiesPanel::InitPackagingPage()
00044 {
00045 UpdateRelativeRoot();
00046 UpdateUncompressedSize();
00047 }
00048
00049 void wxPackagePropertiesPanel::GetPackagingPackageInfo(wxPackageInfo &ret) const
00050 {
00051
00052 ret.SetCompressionMode(m_pZip->GetValue() ? wxPCM_ZIP : wxPCM_TAR_GZ);
00053 if (m_bRelativeRootValid)
00054 {
00055
00056 ret.SetRoot(m_pRelativeRoot->GetValue());
00057 }
00058
00059
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
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:
00083 m_pZip->SetValue(true);
00084 }
00085
00086
00087 m_pFileName->SetValue(p.GetOutputFileName());
00088
00089
00090 m_pUpload->SetValue(p.GetUploadDestination());
00091
00092
00093
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
00103 wxFileName fn(filename);
00104 m_pWXPDir->SetPath(fn.GetPath());
00105
00106
00107 m_strRoot = p.GetProjectFolder(filename);
00108 m_pProjectDir->SetPath(m_strRoot);
00109
00110
00111
00112 UpdateRelativeRoot();
00113 if (!m_bRelativeRootValid)
00114 return;
00115
00116 wxASSERT(m_pRelativeRoot->GetValue() == p.GetRelativeRoot());
00117
00118
00119 SetIncludePath(m_strRoot);
00120
00121
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
00130
00131
00132 m_pExcluded->SynchTree(m_pIncludedTree);
00133
00134 UpdateUncompressedSize();
00135 }
00136
00137 bool wxPackagePropertiesPanel::IsPackagingPageOk() const
00138 {
00139 bool isok = true;
00140
00141
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
00149 if (m_pFileName->GetValue().IsEmpty())
00150 {
00151 wxLogError(wxT("The output file name is not optional"));
00152 isok = false;
00153 }
00154
00155
00156 wxArrayString includedfiles = m_pIncludedTree->GetFilesChecked(),
00157 includeddirs = m_pIncludedTree->GetDirsChecked();
00158
00159
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
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
00182
00183
00184 wxString wxPackagePropertiesPanel::GetProjectParent() const
00185 {
00186
00187 wxFileName dir(m_pProjectDir->GetDirName());
00188 wxASSERT(dir.GetDirCount() > 0);
00189 dir.RemoveLastDir();
00190
00191
00192 return dir.GetPath(wxPATH_GET_VOLUME);
00193 }
00194
00195 void wxPackagePropertiesPanel::SetIncludePath(const wxString &path)
00196 {
00197
00198 m_pIncludedTree->SetPath(path);
00199
00200
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
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
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
00240
00241
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
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
00271
00272
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
00283 m_pRootCheckLabel->SetLabel(wxT("Valid!"));
00284 m_pRootBitmap->SetBitmap(GetBitmapResource(wxT("valid")));
00285
00286
00287
00288
00289 wxFileName rootParent(absroot);
00290 rootParent.RemoveLastDir();
00291
00292 bool success = rootParent.MakeRelativeTo(wxpdir.GetPath());
00293 wxASSERT(success);
00294
00295
00296 wxString str = rootParent.GetPath(0, wxPATH_UNIX);
00297 #ifdef __WXDEBUG__
00298
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
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
00365 m_pIncludedTree->RefreshContents();
00366 m_pIncludedTree->Expand(m_pIncludedTree->GetRootItem());
00367
00368
00369
00370 wxEventBlocker blocker(this);
00371 m_pIncludedTree->CheckAll();
00372
00373 m_pExcluded->Clear();
00374
00375
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
00391
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
00417 m_strRoot = ev.GetPath();
00418
00419
00420
00421 if (m_pWXPDir->GetPath().IsEmpty())
00422 m_pWXPDir->SetPath(m_strRoot);
00423
00424
00425 UpdateRelativeRoot();
00426
00427
00428 wxBusyCursor wait;
00429
00430
00431 SetIncludePath(m_strRoot);
00432
00433 {
00434
00435
00436 wxEventBlocker blocker(this);
00437 m_pIncludedTree->CheckAll();
00438 }
00439
00440
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
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
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
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
00541 wxPackageExcludeMode wxPackageExcludeListBox::GetType(const wxString &str)
00542 {
00543
00544 wxString prefix = str.AfterFirst(wxT('[')).BeforeFirst(wxT(']'));
00545 return wxString2PackageExcludeMode(prefix);
00546 }
00547
00548
00549 wxString wxPackageExcludeListBox::GetContent(const wxString &str)
00550 {
00551
00552 return wxString(str).AfterFirst(wxT(']')).Remove(0, 1);
00553 }
00554
00555 void wxPackageExcludeListBox::SynchFromTree(const wxExplorerTreeCtrl *tree)
00556 {
00557 wxEventBlocker block(this);
00558
00559
00560
00561 wxArrayString patterns = Get(wxPEM_PATTERN);
00562 Clear();
00563
00564
00565 Add(wxPEM_PATTERN, patterns);
00566
00567
00568 wxArrayString dirs = tree->GetDirsRecursivelyUnChecked();
00569 for (size_t i=0; i<dirs.GetCount(); i++)
00570 {
00571
00572
00573
00574 bool nomatches = true;
00575 for (size_t j=0; j<patterns.GetCount(); j++)
00576 {
00577 if (wxMatchWild(patterns[j], dirs[i], false ))
00578 {
00579 nomatches = false;
00580 break;
00581 }
00582 }
00583
00584 if (nomatches)
00585 Add(wxPEM_DIRECTORY, dirs[i]);
00586 }
00587
00588
00589
00590 wxArrayString files = tree->GetFilesChecked(false );
00591 for (size_t i=0; i<files.GetCount(); i++)
00592 {
00593
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 ))
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);
00624
00625
00626
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
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
00653 wxString name = prefix + tree->GetItemText(i);
00654
00655 if (tree->IsFolder(i))
00656 {
00657
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
00669
00670
00671
00672
00673
00674
00675 tree->SetItemBold(i, childchecked);
00676
00677 allchecked &= childchecked;
00678 }
00679 }
00680 else
00681 {
00682
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 ))
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