browsepanel.cpp

00001 
00002 // Name:        browsepanel.cpp
00003 // Purpose:     wxPackageBrowserPanel
00004 // Author:      Julian Smart, Francesco Montorsi
00005 // Modified by:
00006 // Created:     04/06/2006 12:04:43
00007 // RCS-ID:      $Id: browsepanel.cpp,v 1.7 2007/02/01 20:57:15 frm Exp $
00008 // Copyright:   (c) 2004 Francesco Montorsi
00009 // Licence:     wxWidgets license
00011 
00012 
00013 // For compilers that support precompilation, includes "wx/wx.h".
00014 #include "wx/wxprec.h"
00015 
00016 #ifdef __BORLANDC__
00017 #pragma hdrstop
00018 #endif
00019 
00020 #ifndef WX_PRECOMP
00021 #include "wx/wx.h"
00022 #endif
00023 
00024 #include <wx/notebook.h>
00025 #include <wx/config.h>
00026 #include <wx/uri.h>
00027 #include <wx/stdpaths.h>
00028 #include <wx/dialup.h>
00029 #include <wx/mstream.h>
00030 #include <wx/zstream.h>
00031 
00032 #include "guipm/smartmsgdlg.h"
00033 #include "guipm/browsepanel.h"
00034 #include "guipm/filterpanel.h"
00035 #include "guipm/viewerpanel.h"
00036 #include "guipm/extcmddlg.h"
00037 #include "guipm/builddlg.h"
00038 #include "guipm/batchdownloaddlg.h"
00039 #include "guipm/decompressdlg.h"
00040 #include "guipm/dependencydlg.h"
00041 
00042 #include "wx/download.h"
00043 #include "wxp/wxp.h"
00044 
00045 // statics:
00046 
00047 wxString wxPackageBrowserPanel::s_strDefaultWxlName;
00048 wxString wxPackageBrowserPanel::s_strDefaultWxlURL;
00049 
00050 
00051 // ----------------------------------------------------------------------------
00052 // wxPackageBrowserPanel
00053 // ----------------------------------------------------------------------------
00054 
00055 IMPLEMENT_DYNAMIC_CLASS( wxPackageBrowserPanel, wxPanel )
00056 
00057 BEGIN_EVENT_TABLE( wxPackageBrowserPanel, wxPanel )
00058     EVT_BUTTON( wxID_ANY, wxPackageBrowserPanel::OnButtonClick )
00059     EVT_UPDATE_UI( wxID_ANY, wxPackageBrowserPanel::OnUpdateUI )
00060     EVT_IDLE( wxPackageBrowserPanel::OnIdle )
00061     EVT_LISTBOX( wxID_ANY, wxPackageBrowserPanel::OnListBoxSelected )
00062     EVT_NOTEBOOK_PAGE_CHANGED( wxID_ANY, wxPackageBrowserPanel::OnPageChanged )
00063 
00064     EVT_FILTER_PACKAGES( wxID_ANY, wxPackageBrowserPanel::OnFilterPackages )
00065 
00066     EVT_PROGRESS_END(wxID_ANY, wxPackageBrowserPanel::OnProgressPanelEnd)
00067 
00068     // source list
00069     EVT_TEXT_ENTER( ID_BROWSER_SOURCELIST, wxPackageBrowserPanel::OnSourceListEnter )
00070     EVT_COMBOBOX( ID_BROWSER_SOURCELIST, wxPackageBrowserPanel::OnSourceListSelected )
00071 END_EVENT_TABLE()
00072 
00073 wxPackageBrowserPanel::wxPackageBrowserPanel( )
00074 {
00075 }
00076 
00077 wxPackageBrowserPanel::wxPackageBrowserPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
00078 {
00079     Create(parent, id, pos, size, style);
00080 }
00081 
00082 wxPackageBrowserPanel::~wxPackageBrowserPanel( )
00083 {
00084 }
00085 
00086 bool wxPackageBrowserPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
00087 {
00088     // auxiliary stuff
00089     m_pViewerPanel = NULL;
00090     m_pStatusBar = NULL;
00091     m_pMenuBar = NULL;
00092     m_bNeedLocalPackageRefresh = false;
00093     m_bAutoLoadLocalPackages = true;
00094 
00095     SetExtraStyle(GetExtraStyle()|wxWS_EX_VALIDATE_RECURSIVELY);
00096     wxPanel::Create( parent, id, pos, size, style );
00097 
00098     CreateControls();
00099     GetSizer()->Fit(this);
00100     GetSizer()->SetSizeHints(this);
00101 
00102     return true;
00103 }
00104 
00105 void wxPackageBrowserPanel::CreateControls()
00106 {
00108     wxPackageBrowserPanel* itemPanel1 = this;
00109 
00110     wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
00111     itemPanel1->SetSizer(itemBoxSizer2);
00112 
00113     m_pNotebook = new wxNotebook( itemPanel1, ID_BROWSER_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxNB_TOP );
00114 
00115     wxPanel* itemPanel4 = new wxPanel( m_pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
00116     wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL);
00117     itemPanel4->SetSizer(itemBoxSizer5);
00118 
00119     m_pLocalFilter = new wxPackageFilterPanel( itemPanel4, ID_BROWSER_INSTALLED_FILTER, wxDefaultPosition, wxDefaultSize, 0 );
00120     itemBoxSizer5->Add(m_pLocalFilter, 0, wxGROW|wxALL, 5);
00121 
00122     wxStaticText* itemStaticText7 = new wxStaticText( itemPanel4, wxID_STATIC, _("Local packages:"), wxDefaultPosition, wxDefaultSize, 0 );
00123     itemBoxSizer5->Add(itemStaticText7, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5);
00124 
00125     wxBoxSizer* itemBoxSizer8 = new wxBoxSizer(wxHORIZONTAL);
00126     itemBoxSizer5->Add(itemBoxSizer8, 1, wxGROW, 5);
00127     m_pLocalList = new wxPackageListBox( itemPanel4, ID_BROWSER_INSTALLED_PACKAGELIST, wxDefaultPosition, wxDefaultSize, 0 );
00128     itemBoxSizer8->Add(m_pLocalList, 1, wxGROW|wxALL, 5);
00129 
00130     wxBoxSizer* itemBoxSizer10 = new wxBoxSizer(wxVERTICAL);
00131     itemBoxSizer8->Add(itemBoxSizer10, 0, wxALIGN_BOTTOM, 5);
00132     wxButton* itemButton11 = new wxButton( itemPanel4, ID_BROWSER_INSTALLED_REFRESH, _("&Refresh"), wxDefaultPosition, wxDefaultSize, 0 );
00133     itemBoxSizer10->Add(itemButton11, 0, wxGROW|wxALL, 5);
00134 
00135     itemBoxSizer10->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
00136 
00137     wxButton* itemButton13 = new wxButton( itemPanel4, ID_BROWSER_DECOMPRESS, _("&Unpack..."), wxDefaultPosition, wxDefaultSize, 0 );
00138     itemBoxSizer10->Add(itemButton13, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00139 
00140     wxButton* itemButton14 = new wxButton( itemPanel4, ID_BROWSER_REBUILD, _("(Re)&build..."), wxDefaultPosition, wxDefaultSize, 0 );
00141     itemBoxSizer10->Add(itemButton14, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00142 
00143     wxButton* itemButton15 = new wxButton( itemPanel4, ID_BROWSER_REINSTALL, _("(Re)&install..."), wxDefaultPosition, wxDefaultSize, 0 );
00144     itemBoxSizer10->Add(itemButton15, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00145 
00146     wxButton* itemButton16 = new wxButton( itemPanel4, ID_BROWSER_UNINSTALL, _("&Uninstall..."), wxDefaultPosition, wxDefaultSize, 0 );
00147     itemBoxSizer10->Add(itemButton16, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00148 
00149     itemBoxSizer10->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
00150 
00151     wxButton* itemButton18 = new wxButton( itemPanel4, ID_BROWSER_UPDATECHECK, _("Update &check"), wxDefaultPosition, wxDefaultSize, 0 );
00152     itemButton18->SetDefault();
00153     itemBoxSizer10->Add(itemButton18, 0, wxGROW|wxALL, 5);
00154 
00155     m_pNotebook->AddPage(itemPanel4, _("Local packages"));
00156 
00157     wxPanel* itemPanel19 = new wxPanel( m_pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
00158     wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxVERTICAL);
00159     itemPanel19->SetSizer(itemBoxSizer20);
00160 
00161     wxStaticBox* itemStaticBoxSizer21Static = new wxStaticBox(itemPanel19, wxID_ANY, _("Package repository URL"));
00162     wxStaticBoxSizer* itemStaticBoxSizer21 = new wxStaticBoxSizer(itemStaticBoxSizer21Static, wxHORIZONTAL);
00163     itemBoxSizer20->Add(itemStaticBoxSizer21, 0, wxGROW|wxALL, 5);
00164     wxString* m_pSourceListStrings = NULL;
00165     m_pSourceList = new wxComboBox( itemPanel19, ID_BROWSER_SOURCELIST, _T(""), wxDefaultPosition, wxSize(100, -1), 0, m_pSourceListStrings, wxCB_DROPDOWN );
00166     itemStaticBoxSizer21->Add(m_pSourceList, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
00167 
00168     m_pNewFilter = new wxPackageFilterPanel( itemPanel19, ID_BROWSER_NEW_FILTER, wxDefaultPosition, wxDefaultSize, 0 );
00169     itemBoxSizer20->Add(m_pNewFilter, 0, wxGROW|wxALL, 5);
00170 
00171     wxStaticText* itemStaticText24 = new wxStaticText( itemPanel19, wxID_STATIC, _("Available packages:"), wxDefaultPosition, wxDefaultSize, 0 );
00172     itemBoxSizer20->Add(itemStaticText24, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5);
00173 
00174     wxBoxSizer* itemBoxSizer25 = new wxBoxSizer(wxHORIZONTAL);
00175     itemBoxSizer20->Add(itemBoxSizer25, 1, wxGROW, 5);
00176     m_pNewList = new wxPackageListBox( itemPanel19, ID_BROWSER_NEW_PACKAGELIST, wxDefaultPosition, wxDefaultSize, wxLB_MULTIPLE );
00177     itemBoxSizer25->Add(m_pNewList, 1, wxGROW|wxALL, 5);
00178 
00179     wxBoxSizer* itemBoxSizer27 = new wxBoxSizer(wxVERTICAL);
00180     itemBoxSizer25->Add(itemBoxSizer27, 0, wxALIGN_BOTTOM, 5);
00181     wxButton* itemButton28 = new wxButton( itemPanel19, ID_BROWSER_NEW_SELECTALL, _("Select &All"), wxDefaultPosition, wxDefaultSize, 0 );
00182     itemBoxSizer27->Add(itemButton28, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00183 
00184     wxButton* itemButton29 = new wxButton( itemPanel19, ID_BROWSER_NEW_DESELECTALL, _("&Deselect All"), wxDefaultPosition, wxDefaultSize, 0 );
00185     itemBoxSizer27->Add(itemButton29, 0, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5);
00186 
00187     wxButton* itemButton30 = new wxButton( itemPanel19, ID_BROWSER_NEW_REFRESH, _("&Refresh"), wxDefaultPosition, wxDefaultSize, 0 );
00188     itemBoxSizer27->Add(itemButton30, 0, wxGROW|wxALL, 5);
00189 
00190     itemBoxSizer27->Add(5, 5, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
00191 
00192     wxButton* itemButton32 = new wxButton( itemPanel19, ID_BROWSER_DOWNLOAD, _("&Download..."), wxDefaultPosition, wxDefaultSize, 0 );
00193     itemBoxSizer27->Add(itemButton32, 0, wxGROW|wxALL, 5);
00194 
00195     m_pNotebook->AddPage(itemPanel19, _("Get new packages"));
00196 
00197     itemBoxSizer2->Add(m_pNotebook, 1, wxGROW, 5);
00198 
00200 
00201     // every pixel is preciuos in the horizontal direction!
00202 #define RATIO 0.9
00203 
00204     m_pLocalFilter->SetMinSize(m_pLocalFilter->GetBestSize().Scale(RATIO, 1.0));
00205     m_pNewFilter->SetMinSize(m_pNewFilter->GetBestSize().Scale(RATIO, 1.0));
00206 
00207     // init POD
00208     m_bShowDupPackages = false;
00209     m_pNewList->ShowStatus(false);
00210 }
00211 
00212 
00213 
00214 // ----------------------------------------------------------------------------
00215 // wxPackageBrowserPanel - additional functions
00216 // ----------------------------------------------------------------------------
00217 
00218 void wxPackageBrowserPanel::SetAuxiliaryViewerPanel(wxPackageViewerPanel *p)
00219 {
00220     m_pViewerPanel=p;
00221     m_pViewerPanel->GetTaskQueuePanel()->SetEventHandler(this);
00222 }
00223 
00224 void wxPackageBrowserPanel::FilterNewPackages()
00225 {
00226     // since new packages listbox is a multiple selection listbox,
00227     // we will restore the selection only on the first package...
00228     wxPackage sel = m_pNewList->GetFirstSelectedPackage();
00229     m_pNewList->SetPackages(m_arrNew, m_pNewFilter);
00230     m_pNewList->RefreshAll();
00231 
00232     // eventually update selection
00233     m_pNewList->SetSelectedPackage(sel);
00234 
00235     size_t max = m_arrNew.GetCount();
00236     SetStatusText(
00237         wxString::Format(_("Filtered out %d package(s) on a total of %d..."),
00238                             max - m_pLocalList->GetCount(),
00239                             max));
00240 }
00241 
00242 void wxPackageBrowserPanel::FilterLocalPackages()
00243 {
00244     wxPackage sel = m_pLocalList->GetSelectedPackage();
00245     m_pLocalList->SetPackages(m_arrLocal, m_pLocalFilter);
00246     m_pLocalList->RefreshAll();
00247 
00248     // eventually update selection
00249     m_pLocalList->SetSelectedPackage(sel);
00250 
00251     size_t max = m_arrLocal.GetCount();
00252     SetStatusText(
00253         wxString::Format(_("Filtered out %d package(s) on a total of %d..."),
00254                             max - m_pLocalList->GetCount(),
00255                             max));
00256 }
00257 
00258 bool wxPackageBrowserPanel::SetRepositoryURL(const wxString &str)
00259 {
00260     wxString url(str);
00261  /*   if (wxIsFileProtocol(url))
00262     {
00263         wxLogError(_("To browse local repositories, just add the folder you want to browse in the 'Local repositories' path list in the 'Settings' dialog."));
00264         return false;
00265         /*
00266         // be sure that this is a folder or an url to a WXL file and that it does exist
00267         wxFileName fn(wxFileSystem::URLToFileName(url));
00268         if (fn.IsDir())
00269         {
00270             if (!fn.DirExists())
00271                 return false;
00272 
00273             // make sure this is a valid URL
00274             url = wxFileSystem::FileNameToURL(fn.GetPathWithSep());
00275         }
00276         else
00277         {
00278             if (fn.GetExt() != wxT("wxl"))
00279                 return false;
00280 
00281             url = wxFileSystem::FileNameToURL(fn.GetFullPath());
00282         }*
00283     }
00284     else if (wxIsWebProtocol(url))
00285     {*/
00286         if (!url.EndsWith(wxT(".wxl")) && !url.EndsWith(wxT("/")))
00287             url += wxT("/");
00288 
00289         // cannot do any existence test here...
00290    // }
00291 
00292     // prepend the given URL to the list (i.e. most recently added strings
00293     // are at the top of the list)
00294     int n = m_pSourceList->FindString(url);
00295     if (n == wxNOT_FOUND)
00296     {
00297         m_pSourceList->Insert(url, 0);
00298         m_pSourceList->SetSelection(0);
00299     }
00300     else
00301         m_pSourceList->SetSelection(n);
00302 
00303     //RefreshPackageList();  no refresh in this function !
00304 
00305     return true;
00306 }
00307 
00308 bool wxPackageBrowserPanel::BrowseTo(const wxString &path)
00309 {
00310     BrowseNewPackages();
00311     if (!SetRepositoryURL(path))
00312         return false;
00313 
00314     ResetFilter();
00315     RefreshPackageList();
00316     return true;
00317 }
00318 
00319 void wxPackageBrowserPanel::SelectLocalPackage(unsigned int n)
00320 {
00321     BrowseLocalPackages();
00322     m_pLocalList->SetSelection(n);
00323     wxCommandEvent fake;
00324     OnListBoxSelected(fake);
00325 }
00326 
00327 void wxPackageBrowserPanel::SelectLocalPackage(const wxPackageId &id)
00328 {
00329     BrowseLocalPackages();
00330 
00331     if (m_pLocalList->SetSelectedPackage(id))
00332     {
00333         wxCommandEvent fake;
00334         OnListBoxSelected(fake);
00335     }
00336 }
00337 
00338 void wxPackageBrowserPanel::SelectNewPackage(unsigned int n)
00339 {
00340     BrowseNewPackages();
00341     m_pNewList->SetSelection(n);
00342 
00343     wxCommandEvent fake;
00344     OnListBoxSelected(fake);
00345 }
00346 
00347 void wxPackageBrowserPanel::SelectNewPackage(const wxPackageId &id)
00348 {
00349     BrowseNewPackages();
00350 
00351     if (m_pNewList->SetSelectedPackage(id))
00352     {
00353         wxCommandEvent fake;
00354         OnListBoxSelected(fake);
00355     }
00356 }
00357 
00358 void wxPackageBrowserPanel::RefreshLocalPackages()
00359 {
00360     GetLocalPackages().Clear();
00361 
00362     // add list of local (maybe not-installed) package list
00363     GetLocalPackages().LoadCompressedPackagesFromLocalRepo();
00364 
00365     // do we want to remove duplicate packages ?
00366     if (!m_bShowDupPackages)
00367     {
00368         // FIXME: show a warning to the user about this !
00369         size_t n = GetLocalPackages().RemoveDuplicates();
00370 
00371         if (GetAuxiliaryStatusBar())
00372             GetAuxiliaryStatusBar()->SetStatusText(
00373                 wxString::Format(_("Removed %d duplicate package(s)"), n));
00374     }
00375 
00376     // load installed packages info
00377     // FIXME: wxConfigBase::Get() is used here!
00378     if (!GetLocalPackages().LoadPackagesStatusInfo(wxConfigBase::Get(), wxT("/Packages")))
00379     {
00380         wxLogError(_("Cannot load status of the local packages.\nCheck your wxConfig installation."));
00381         return;
00382     }
00383 
00384     // VERY IMPORTANT: LoadPackageStatusInfo() could have changed the status
00385     //                 of the packages from wxPS_DOWNLOADED to wxPS_REMOTE
00386     //                 (because, e.g. the WXZ file has not been found)
00387 
00388     // as last thing, apply the filter on the package list
00389     FilterLocalPackages();
00390 }
00391 
00392 void wxPackageBrowserPanel::RefreshNewPackages()
00393 {
00394     // the currently selected string in the combobox should always
00395     // point to a directory !
00396     wxString sourcedir(m_pSourceList->GetValue());
00397 
00398     // clear old list
00399     m_pNewList->Clear();
00400     m_pNewList->RefreshAll();   // this is indispensable to clear old list 
00401                                 // in case for some reason the download fails
00402                                 // and FilterNewPackages() is not called
00403 
00404     if (!sourcedir.EndsWith(wxT(".wxl")))
00405     {
00406         if (!sourcedir.EndsWith(wxT("/")))
00407             sourcedir += wxT("/");
00408         sourcedir += wxString(s_strDefaultWxlName);
00409     }
00410 
00411     // is this an URL to a local/remote WXL or
00412     // rather an URL to a local/remote directory ?
00413     if (sourcedir.EndsWith(wxT(".wxl")))
00414         //||  wxIsWebProtocol(sourcedir))
00415     {
00416         wxPackageRepositoryXMLDescriptor repo;
00417         if (true)//wxIsWebProtocol(sourcedir))
00418         {
00419             // are we connected ?
00420             wxDialUpManager *mng = wxDialUpManager::Create();
00421             if (mng->IsOk())
00422             {
00423                 if (!mng->IsOnline())
00424                 {
00425                     // we may be wrong so give the user a choice
00426                     int reply = wxSmartLogYesNoQuestion(wxT("internetconn"),
00427                         _("It has been detected that you _may_ be not connected to Internet !\nA working connection is required in order to download the '%s' package list...\nDo you want to proceed anyway?"),
00428                         sourcedir.c_str());
00429                     if (reply == wxID_NO)
00430                     {
00431                         wxDELETE(mng);
00432                         return;
00433                     }
00434                 }
00435             }
00436             wxDELETE(mng);
00437 
00438             // do an asynchronous download of the package list
00439             wxMemoryOutputStream stream;
00440             wxDownloadDialog dlg;
00441             if (!dlg.Create(sourcedir, &stream, wxT("Downloading..."), wxEmptyString, 
00442                             wxTheApp->GetTopWindow()))
00443                 return;
00444 
00445             if (dlg.ShowModal() == wxDRF_FAILED)
00446             {
00447                 wxLogError(_("Invalid remote repository URL '%s'.\nCould not download it."),
00448                            sourcedir.c_str());
00449                 return;
00450             }
00451 
00452             if (dlg.GetReturnCode() == wxDRF_USER_ABORTED)
00453                 return;
00454 
00455             // decompress the list and load it
00456             wxMemoryInputStream input(stream);
00457             wxZlibInputStream unzipped(input);
00458             if (!repo.Load(unzipped))
00459             {
00460                 wxLogError(_("Invalid repository '%s'.\nIt's not a valid WXL file."),
00461                            sourcedir.c_str());
00462                 return;
00463             }
00464         }
00465         else
00466         {
00467             /*
00468             // do a synchronous load of the package list
00469             if (!repo.LoadLocalPackagesList(sourcedir))
00470             {
00471                 wxMessageBox(wxString::Format(_T("Invalid local repository URL '%s'.\nCould not find that WXL file."), sourcedir.c_str()),
00472                             _T("Error"), wxOK|wxICON_ERROR);
00473                 return;
00474             }*/
00475 
00476             wxASSERT(0);
00477         }
00478 
00479         // copy the list of packages loaded from this WXL
00480         m_arrNew = repo.GetPackageArray(sourcedir);
00481     }
00482     else
00483     {
00484         /*wxASSERT(wxIsFileProtocol(sourcedir));
00485 
00486         // use the synchronous version of wxPackageArray::Load for local packages
00487         // as we suppose the packages will be quickly available and thus there's
00488         // no need to show a progress dialog
00489         wxFileName fn(wxFileSystem::URLToFileName(sourcedir));
00490         if (!GetNewPackages().LoadCompressedPackagesFrom(fn.GetPath()))
00491         {
00492             wxMessageBox(wxString::Format(_T("Invalid local directory '%s'.\nCould not find any WXZ file."), sourcedir.c_str()),
00493                         _T("Error"), wxOK|wxICON_ERROR);
00494             return;
00495         }*/
00496     }
00497 
00498     FilterNewPackages();
00499 }
00500 
00501 void wxPackageBrowserPanel::RefreshPackageList()
00502 {
00503     if (IsBrowsingLocalPackages())
00504         RefreshLocalPackages();
00505     else
00506         RefreshNewPackages();
00507 
00508     wxCommandEvent fake;
00509     OnListBoxSelected(fake);
00510 }
00511 
00512 void wxPackageBrowserPanel::FilterPackageList()
00513 {
00514     if (IsBrowsingLocalPackages())
00515         FilterLocalPackages();
00516     else
00517         FilterNewPackages();
00518 
00519     wxCommandEvent fake;
00520     OnListBoxSelected(fake);
00521 }
00522 
00523 bool wxPackageBrowserPanel::IsPackageSourceLocal() const
00524 {
00525     wxURI uri(m_pSourceList->GetValue());
00526 
00527     if (uri.GetScheme() == wxT("http") ||
00528         uri.GetScheme() == wxT("ftp"))
00529         return false;
00530     return true;
00531 }
00532 
00533 void wxPackageBrowserPanel::EnableCmd(long id, bool enable)
00534 {
00535     wxWindow *win = FindWindowById(id, this);
00536     wxASSERT_MSG(win!=NULL, wxT("Invalid ID!"));
00537     win->Enable(enable);
00538 
00539     wxMenuItem *item;
00540     if (GetAuxiliaryMenuBar() && (item = GetAuxiliaryMenuBar()->FindItem(id)) != NULL)
00541         item->Enable(enable);
00542 }
00543 
00544 wxPackageArray wxPackageBrowserPanel::GetSelectedPackages() const
00545 {
00546     wxPackageArray arr;
00547 
00548     if (IsBrowsingNewPackages())
00549     {
00550         unsigned long cookie;
00551         int item = m_pNewList->GetFirstSelected(cookie);
00552         while ( item != wxNOT_FOUND )
00553         {
00554             // copy all selected packages to a temporary array
00555             arr.Add(m_pNewList->GetPackage(item));
00556             item = m_pNewList->GetNextSelected(cookie);
00557         }
00558     }
00559     else
00560     {
00561         // be sure to add a package != wxEmptyPackage
00562         if (m_pLocalList->GetSelection() != wxNOT_FOUND)
00563             arr.Add(m_pLocalList->GetSelectedPackage());
00564     }
00565 
00566     return arr;
00567 }
00568 
00569 bool wxPackageBrowserPanel::LoadCompressedPackage(const wxString &wxzpath)
00570 {
00571     wxPackage pkg;
00572     if (!pkg.LoadCompressedPackage(wxzpath))
00573         return false;
00574 
00575     m_arrLocal.Add(pkg);
00576     if (m_arrLocal.RemoveDuplicates() == 1)
00577         return false;
00578 
00579     FilterLocalPackages();
00580     return true;
00581 }
00582 
00583 void wxPackageBrowserPanel::Download(const wxPackageArray &todownload, bool skipdepcheck)
00584 {
00585     wxPackageArray arr(todownload);
00586 
00587 #ifdef __WXDEBUG__
00588     for (size_t i=0; i<todownload.GetCount(); i++)
00589         wxASSERT(m_arrNew.Contains(todownload[i]));
00590 #endif
00591 
00592     // show dep
00593     if (!skipdepcheck)
00594     {
00595         wxPackageDependencyDlg dlg;     // do not Create() it yet
00596         if (!dlg.SetPackageArray(arr, m_arrLocal, m_arrNew))
00597             return;
00598         if (!dlg.IsEmpty())
00599         {
00600             dlg.Create(this);
00601             if (dlg.ShowModal() == wxID_NO)
00602                 return;
00603 
00604             wxPackageArray temp(dlg.GetAdditionalPackages());
00605             WX_APPEND_ARRAY(arr, temp);
00606         }
00607     }
00608 
00609     //if (arr.GetCount() > 1)
00610     //{
00611         // queue a list of packages to download
00612         wxPackageBatchDownloadDlg dlg(this, wxID_ANY);
00613         dlg.SetDestination(m_strDefaultDownloadPath);
00614         dlg.SetPackages(arr);
00615 
00616         wxPackageDownloadQueuePanel *panel =
00617             GetAuxiliaryViewerPanel()->GetDownloadQueuePanel();
00618         if (dlg.ShowModal() == wxID_OK)
00619         {
00620             for (size_t i=0; i < arr.GetCount(); i++)
00621             {
00622                 wxString url = arr[i].GetDownloadLink();
00623                 if (url.IsEmpty())
00624                 {
00625                     wxLogError(wxT("No URLs are available for the download of '%s' package. Cannot download it."), arr[i].GetName().c_str());
00626                     continue;
00627                 }
00628 
00629                 // tell the package that it's still a remote package
00630                 // but nonetheless tell him also the path where it's being
00631                 // downloaded so that the download queue panel will be
00632                 // able to show it to the user
00633                 arr[i].SetRemoteStatus(
00634                     dlg.GetDestination() +
00635                     wxFileName::GetPathSeparator() +
00636                     url.AfterLast(wxT('/')));
00637 
00638                 // last, queue it
00639                 panel->QueueDownloadOf(arr[i]);
00640             }
00641 
00642             GetAuxiliaryViewerPanel()->SelectDownloadQueuePanel();
00643         }/*
00644     }
00645     else
00646     {
00647         // queue the single package selected directly
00648         GetAuxiliaryViewerPanel()->GetDownloadQueuePanel()->QueueDownloadOf(arr[0]);
00649         GetAuxiliaryViewerPanel()->SelectDownloadQueuePanel();
00650     }*/
00651 }
00652 
00653 void wxSafeMkdir(const wxString &path)
00654 {
00655     if (!wxFileName::DirExists(path))
00656     {
00657         // ignore any writing-permission error...
00658         wxLogNull nullLog;
00659         wxMkdir(path);
00660     }
00661 }
00662 
00663 bool wxPackageBrowserPanel::Load(wxConfigBase *p, const wxString &path)
00664 {
00665     wxString defpath = wxStandardPaths::Get().GetUserDataDir();
00666 
00667     // paths
00668     m_strDefaultDownloadPath =
00669         p->Read(path + wxT("/Directories/DownloadPath"), defpath);
00670     m_strDefaultDecompressionPath =
00671         p->Read(path + wxT("/Directories/DecompressionPath"), defpath);
00672     m_strDefaultInstallationPath =
00673         p->Read(path + wxT("/Directories/InstallationPath"), defpath);
00674 
00675     // be sure these exist
00676     wxSafeMkdir(m_strDefaultDownloadPath);
00677     wxSafeMkdir(m_strDefaultDecompressionPath);
00678     wxSafeMkdir(m_strDefaultInstallationPath);
00679 
00680     // load the sources from wxPackage
00681     m_pSourceList->Append(wxPackage::s_arrRemoteRepo);
00682     if (m_pSourceList->GetCount() > 0)
00683         m_pSourceList->Select(0);      // by default select first item
00684 
00685     if (m_pSourceList->GetCount() == 0)
00686     {
00687         // append & select the default source
00688         SetRepositoryURL(s_strDefaultWxlURL);
00689     }
00690 
00691     p->Read(path + wxT("/Packages/AutoLoadPackages"), &m_bAutoLoadLocalPackages, true);
00692 
00693     // we won't call any Refresh*Packages() function here
00694     // as it could take a lot of time (which goes in the app's startup time)!
00695     // Rather we'll call RefreshLocalPackages() in the idle event handler
00696     m_bNeedLocalPackageRefresh = m_bAutoLoadLocalPackages;
00697     // wxWakeUpIdle(); -- it seems that this is not needed
00698 
00699     return true;
00700 }
00701 
00702 void wxPackageBrowserPanel::Save(wxConfigBase *p, const wxString &path) const
00703 {
00704     // save our settings
00705 
00706     p->Write(path + wxT("/Directories/DownloadPath"), m_strDefaultDownloadPath);
00707     p->Write(path + wxT("/Directories/DecompressionPath"), m_strDefaultDecompressionPath);
00708     p->Write(path + wxT("/Directories/InstallationPath"), m_strDefaultInstallationPath);
00709 
00710     p->Write(path + wxT("/Packages/AutoLoadPackages"), m_bAutoLoadLocalPackages);
00711 
00712     // save sources
00713     wxPackage::s_arrRemoteRepo = m_pSourceList->GetStrings();
00714 
00715     // save local package status
00716     m_arrLocal.SavePackagesStatusInfo(p, path + wxT("/Packages"));
00717 }
00718 
00719 
00720 
00721 // ----------------------------------------------------------------------------
00722 // wxPackageBrowserPanel - event handlers
00723 // ----------------------------------------------------------------------------
00724 
00725 void wxPackageBrowserPanel::OnButtonClick(wxCommandEvent &ev)
00726 {
00727     wxCommandEvent fake;
00728 
00729     // the package selected in the 'local packages' list...
00730     wxPackage &p = m_pLocalList->GetSelectedPackage();
00731 
00732     switch (ev.GetId())
00733     {
00734     // buttons for the "Installed packages" tab
00735 /*
00736     case ID_BROWSER_INSTALLED_SELECTALL:
00737         for (size_t i=0; i<m_pLocalList->GetCount(); i++)
00738             m_pLocalList->Select(i);
00739 
00740         // send fake event to force update of auxiliary panels
00741         fake.SetId(ID_BROWSER_INSTALLED_PACKAGELIST);
00742         fake.SetEventObject(m_pLocalList);
00743         OnListBoxSelected(fake);
00744         break;
00745     case ID_BROWSER_INSTALLED_DESELECTALL:
00746         m_pLocalList->DeselectAll();
00747         if (GetAuxiliaryViewerPanel())
00748             GetAuxiliaryViewerPanel()->Reset();
00749         break;
00750 */
00751     case ID_BROWSER_INSTALLED_REFRESH:
00752         RefreshPackageList();
00753         break;
00754 
00755     case ID_BROWSER_DOWNLOAD:
00756         {
00757             wxASSERT(GetAuxiliaryViewerPanel());
00758 
00759             // get the array of selected packages
00760             wxPackageArray arr(GetSelectedPackages());
00761             wxASSERT(arr.GetCount() > 0);
00762 
00763             Download(arr);
00764         }
00765         break;
00766 
00767     case ID_BROWSER_DECOMPRESS:
00768         {
00769             wxPackageDecompressDlg dlg(this, wxID_ANY);
00770 
00771             // the package could already have a decompression path
00772             // so let's check first
00773             if (p.GetDecompressionPath().IsEmpty())
00774                 p.SetDecompressionPath(m_strDefaultDecompressionPath);
00775 
00776             dlg.SetPackage(p);
00777             if (dlg.ShowModal() == wxID_OK)
00778             {
00779                 // update decompression path
00780                 p.SetDecompressedStatus(dlg.GetDestination());
00781 
00782                 // update package also in our local array
00783                 m_arrLocal.UpdatePackage(p);
00784                 m_pLocalList->RefreshAll();
00785             }
00786         }
00787         break;
00788 
00789     case ID_BROWSER_REBUILD:
00790         {
00791             wxASSERT(GetAuxiliaryViewerPanel());
00792 
00793             // show dep
00794             {
00795                 wxPackageDependencyDlg dlg;     // do not Create() it yet
00796                 if (!dlg.SetPackage(p, m_arrLocal, m_arrNew))
00797                     return;
00798                 if (!dlg.IsEmpty())
00799                 {
00800                     dlg.Create(this);
00801                     if (dlg.ShowModal() == wxID_NO)
00802                         return;
00803 
00804                     // skip the dependency check control as we have just done it !
00805                     Download(dlg.GetAdditionalPackages(), true);
00806                     return;
00807                 }
00808             }
00809 
00810             wxPackageBuildDlg dlg(this, wxID_ANY, wxT("Build"));
00811             dlg.SetPackage(p);
00812             if (dlg.ShowModal() == wxID_OK)
00813             {
00814                 // NB: dlg.GetPackage() != p as user has edited its options!
00815                 GetAuxiliaryViewerPanel()->GetTaskQueuePanel()->
00816                     QueueBuildOf(dlg.GetPackage());
00817                 GetAuxiliaryViewerPanel()->SelectTaskQueuePage();
00818             }
00819         }
00820         break;
00821     case ID_BROWSER_REINSTALL:
00822         {
00823             wxExtCmdWizard dlg(this, wxID_ANY, wxT("Reinstall"));
00824             dlg.Set(p, wxPBSS_INSTALL);
00825             dlg.Run();
00826         }
00827         break;
00828     case ID_BROWSER_UNINSTALL:
00829         {
00830             wxExtCmdWizard dlg(this, wxID_ANY, wxT("Uninstall"));
00831             dlg.Set(p, wxPBSS_UNINSTALL);
00832             dlg.Run();
00833         }
00834         break;
00835     case ID_BROWSER_UPDATECHECK:
00836         {
00837             int n = m_arrNew.IndexByName(p.GetName());
00838             if (n == wxNOT_FOUND)
00839             {
00840                 wxLogMessage(_("Cannot find the '%s' package in the repository!\nNo update-check is possible..."),
00841                             p.GetName().c_str());
00842             }
00843             else if (m_arrNew[n].GetVersion() <= p.GetVersion())
00844             {
00845                 wxLogMessage(_("No updates available for %s %s in the repository...\nThe most updated version in the repository is %s."),
00846                             p.GetName().c_str(), p.GetVersion().GetAsString().c_str(),
00847                             m_arrNew[n].GetVersion().GetAsString().c_str());
00848             }
00849             else if (m_arrNew[n].GetVersion() > p.GetVersion())
00850             {
00851                 int reply = wxSmartLogYesNoQuestion(
00852                                 wxT("updatecheck"),
00853                                 _("%s %s is available for download in the repository...\nWould you like to download the updated package ?"),
00854                                 m_arrNew[n].GetName().c_str(),
00855                                 m_arrNew[n].GetVersion().GetAsString().c_str());
00856                 if (reply == wxID_YES)
00857                 {
00858                     Download(m_arrNew[n]);
00859                 }
00860             }
00861         }
00862         break;
00863 
00864 
00865     // buttons for the "Get new packages" tab
00866 
00867     case ID_BROWSER_NEW_SELECTALL:
00868         for (size_t i=0; i<m_pNewList->GetCount(); i++)
00869             m_pNewList->Select(i);
00870 
00871         // send fake event to force update of auxiliary panels
00872         fake.SetId(ID_BROWSER_NEW_PACKAGELIST);
00873         fake.SetEventObject(m_pNewList);
00874         OnListBoxSelected(fake);
00875         break;
00876     case ID_BROWSER_NEW_DESELECTALL:
00877         m_pNewList->DeselectAll();
00878         if (GetAuxiliaryViewerPanel())
00879             GetAuxiliaryViewerPanel()->Reset();
00880         break;
00881     case ID_BROWSER_NEW_REFRESH:
00882         RefreshPackageList();
00883         break;
00884     }
00885 }
00886 
00887 void wxPackageBrowserPanel::OnUpdateUI(wxUpdateUIEvent & WXUNUSED(ev))
00888 {
00889     bool hasauxiliaryviewer = GetAuxiliaryViewerPanel() != NULL;
00890     if (IsBrowsingLocalPackages())
00891     {
00892         wxPackage &p = m_pLocalList->GetSelectedPackage();
00893         bool enable = p.IsOk() && hasauxiliaryviewer;
00894 
00895         //EnableCmd(ID_BROWSER_INSTALLED_SELECTALL, !m_pLocalList->IsEmpty());
00896         //EnableCmd(ID_BROWSER_INSTALLED_DESELECTALL, enable);
00897 
00898         EnableCmd(ID_BROWSER_DECOMPRESS, p.GetStatus() >= wxPS_DOWNLOADED && enable);
00899         EnableCmd(ID_BROWSER_REBUILD, p.GetStatus() >= wxPS_DECOMPRESSED && enable);
00900         EnableCmd(ID_BROWSER_REINSTALL, p.GetStatus() >= wxPS_BUILT && enable);
00901         EnableCmd(ID_BROWSER_UNINSTALL, p.GetStatus() >= wxPS_INSTALLED && enable);
00902         EnableCmd(ID_BROWSER_UPDATECHECK, enable);
00903 
00904         // we must disable the new package stuff because EnableCmd
00905         // also works on menu items
00906         EnableCmd(ID_BROWSER_NEW_SELECTALL, false);
00907         EnableCmd(ID_BROWSER_NEW_DESELECTALL, false);
00908         EnableCmd(ID_BROWSER_DOWNLOAD, false);
00909         //EnableCmd(ID_BROWSER_BUILD, false);
00910         //EnableCmd(ID_BROWSER_INSTALL, false);
00911     }
00912     else
00913     {
00914         bool enable = m_pNewList->GetSelectedCount() != 0;
00915 
00916         EnableCmd(ID_BROWSER_NEW_SELECTALL, !m_pNewList->IsEmpty());
00917         EnableCmd(ID_BROWSER_NEW_DESELECTALL, enable);
00918         EnableCmd(ID_BROWSER_DOWNLOAD, enable);
00919         //EnableCmd(ID_BROWSER_BUILD, enable && hasauxiliaryviewer);
00920         //EnableCmd(ID_BROWSER_INSTALL, enable);
00921 
00922         //EnableCmd(ID_BROWSER_INSTALLED_SELECTALL, false);
00923         //EnableCmd(ID_BROWSER_INSTALLED_DESELECTALL, false);
00924         EnableCmd(ID_BROWSER_REBUILD, false);
00925         EnableCmd(ID_BROWSER_REINSTALL, false);
00926         EnableCmd(ID_BROWSER_UNINSTALL, false);
00927         EnableCmd(ID_BROWSER_UPDATECHECK, false);
00928     }
00929 }
00930 
00931 void wxPackageBrowserPanel::OnListBoxSelected(wxCommandEvent &WXUNUSED(ev))
00932 {
00933     wxPackageArray arr(GetSelectedPackages());
00934 
00935     // update auxiliary windows if present...
00936     if (GetAuxiliaryViewerPanel())
00937     {
00938         // this call may take some time as it may need to download
00939         // stuff from www; in the meanwhile show the busy cursor
00940         wxWindowDisabler disable;
00941         wxBusyCursor wait;
00942         GetAuxiliaryViewerPanel()->SetPackages(arr);
00943 
00944         // FIXME: under win at least, somehow the busy cursor disappear
00945         //        before the summary & details appear in the viewer panel...
00946         //        the following calls seems to have no effects
00947         wxYieldIfNeeded();
00948         GetAuxiliaryViewerPanel()->Refresh();
00949         GetAuxiliaryViewerPanel()->Update();
00950     }
00951 
00952     if (GetAuxiliaryStatusBar())
00953         GetAuxiliaryStatusBar()->SetStatusText(
00954             wxString::Format(_("Selected %d package(s)."), arr.GetCount()));
00955 }
00956 
00957 void wxPackageBrowserPanel::OnFilterPackages(wxCommandEvent &WXUNUSED(ev))
00958 {
00959     // run the filter
00960     FilterPackageList();
00961 }
00962 
00963 void wxPackageBrowserPanel::OnSourceListEnter(wxCommandEvent &ev)
00964 {
00965     // update the repository URL
00966     wxString str(ev.GetString());
00967     SetRepositoryURL(str);
00968 }
00969 
00970 void wxPackageBrowserPanel::OnSourceListSelected(wxCommandEvent & WXUNUSED(ev))
00971 {
00972     RefreshPackageList();
00973 }
00974 
00975 void wxPackageBrowserPanel::OnPageChanged(wxNotebookEvent & WXUNUSED(ev))
00976 {
00977     static bool firsttime = true;
00978     if (IsBrowsingNewPackages() && firsttime)
00979     {
00980         firsttime = false;
00981         RefreshPackageList();
00982     }
00983 
00984     wxCommandEvent fake;
00985     OnListBoxSelected(fake);
00986 }
00987 
00988 void wxPackageBrowserPanel::OnProgressPanelEnd(wxCommandEvent &ev)
00989 {
00990     // is a package build ended ?
00991     if (ev.GetInt() == wxPBSS_BUILD && ev.GetExtraLong() == 1)
00992     {
00993         wxString pkgname = ev.GetString();
00994         int idx = m_arrLocal.IndexByName(pkgname);
00995         wxASSERT(idx != wxNOT_FOUND);
00996 
00997         m_arrLocal[idx].SetBuiltStatus();
00998         RefreshPackageList();
00999     }
01000 }
01001 
01002 void wxPackageBrowserPanel::OnIdle(wxIdleEvent& WXUNUSED(ev))
01003 {
01004     if (m_bNeedLocalPackageRefresh)
01005     {
01006         RefreshLocalPackages();
01007         m_bNeedLocalPackageRefresh = false;
01008     }
01009 }
01010 
01011 
01012 
01013 // ----------------------------------------------------------------------------
01014 // wxPackageListBox
01015 // ----------------------------------------------------------------------------
01016 
01017 wxPackageListBox::wxPackageListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos,
01018                                             const wxSize& size, long style, const wxString& name)
01019 {
01020     // create base class
01021     wxHtmlListBox::Create(parent, id, pos, size, style|wxSUNKEN_BORDER, name);
01022     //SetSelectionBackground(wxColour(wxT("DARK GREEN")));
01023     SetMargins(5, 5);
01024 
01025     m_bShowStatus = true;
01026 }
01027 
01028 wxString wxPackageListBox::OnGetItem(size_t n) const
01029 {
01030     /*if (IsSelected(n) && !m_items[n].GetWorkingPath().IsEmpty())
01031         return wxString::Format(wxT("%s<div align='right'>(in path: <tt>%s</tt>)</div>"),
01032                                 m_items[n].GetCommand().c_str(),
01033                                 m_items[n].GetWorkingPath().c_str());*/
01034     if (!m_bShowStatus)
01035         return wxString::Format(wxT("<b>%s</b>"), m_items[n].GetName().c_str());
01036 
01037     return wxString::Format(wxT("<b>%s</b> [%s]"),
01038             m_items[n].GetName().c_str(),
01039             //m_items[n].GetVersion().c_str(),
01040             m_items[n].GetStatusStr().MakeLower().c_str());
01041 }
01042 
01043 void wxPackageListBox::SetPackages(const wxPackageArray &arr, wxPackageFilterPanel *filter)
01044 {
01045     Clear();
01046     for (size_t i=0; i < arr.GetCount(); i++)
01047     {
01048         if (filter->IsToPreserve(arr[i]))
01049             Append(arr[i]);
01050     }
01051 }
01052 

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