35#include <wx/filedlg.h> 
   37#include <wx/tokenzr.h> 
   40#define GRID_CELL_MARGIN 4 
   53                                          std::shared_ptr<PLUGIN_CONTENT_MANAGER> aPcm,
 
   68    m_splitter1->SetPaneMinimums( FromDIP( 350 ), FromDIP( 450 ) );
 
   73    m_searchCtrl->SetMinSize( wxSize( -1, GetTextExtent( wxT( 
"qb" ) ).y + 10 ) );
 
   79    m_panelList->SetBorders( 
false, 
true, 
false, 
false );
 
   96    wxColor background = wxStaticText::GetClassDefaultAttributes().colBg;
 
 
  142                [package_panel, 
this] ()
 
 
  173    details << wxT( 
"<h5>" ) + package.
name + wxT( 
"</h5>" );
 
  176            []( 
const wxString& 
text ) -> wxString
 
  182                for( 
unsigned i = 0; i < 
text.length(); ++i )
 
  184                    wxUniChar c = 
text[i];
 
  188                        if( c == 
' ' || c == 
'\n')
 
  190                            result += wxString::Format( wxT( 
"<a href='%s'>%s</a>" ), url, url );
 
  194                                result += wxT( 
"</p><p>" );
 
  203                    else if( 
text.Mid( i, 5 ) == wxT( 
"http:" )
 
  204                                || 
text.Mid( i, 6 ) == wxT( 
"https:" ) )
 
  211                        result += wxT( 
"</p><p>" );
 
  220                    result += wxString::Format( wxT( 
"<a href='%s'>%s</a>" ), url, url );
 
  225    wxString desc = package.description_full;
 
  226    details << wxT( 
"<p>" ) + format_desc( desc ) + wxT( 
"</p>" );
 
  228    details << wxT( 
"<p><b>" ) + 
_( 
"Metadata" ) + wxT( 
"</b></p>" );
 
  229    details << wxT( 
"<ul>" );
 
  230    details << wxT( 
"<li>" ) + 
_( 
"Package identifier: " ) + package.identifier + wxT( 
"</li>" );
 
  231    details << wxT( 
"<li>" ) + 
_( 
"License: " ) + package.license + wxT( 
"</li>" );
 
  233    if( package.tags.size() > 0 )
 
  237        for( 
const std::string& tag : package.tags )
 
  239            if( !tags_str.IsEmpty() )
 
  245        details << wxT( 
"<li>" ) + 
_( 
"Tags: " ) + tags_str + wxT( 
"</li>" );
 
  249            []( 
const std::pair<const std::string, wxString>& entry ) -> wxString
 
  251                wxString 
name = entry.first;
 
  254                if( 
name == wxT( 
"email" ) )
 
  255                    return wxString::Format( wxT( 
"<a href='mailto:%s'>%s</a>" ), url, url );
 
  256                else if( url.StartsWith( wxT( 
"http:" ) ) || url.StartsWith( wxT( 
"https:" ) ) )
 
  257                    return wxString::Format( wxT( 
"<a href='%s'>%s</a>" ), url, url );
 
  263            [&]( 
const wxString& type, 
const PCM_CONTACT& contact )
 
  265                details << wxT( 
"<li>" ) + type + wxT( 
": " ) + contact.name + wxT( 
"<ul>" );
 
  267                for( 
const std::pair<const std::string, wxString>& entry : contact.contact )
 
  269                    details << wxT( 
"<li>" );
 
  270                    details << entry.first << wxT( 
": " ) + format_entry( entry );
 
  271                    details << wxT( 
"</li>" );
 
  274                details << wxT( 
"</ul>" );
 
  277    write_contact( 
_( 
"Author" ), package.author );
 
  279    if( package.maintainer )
 
  280        write_contact( 
_( 
"Maintainer" ), *package.maintainer );
 
  282    if( package.resources.size() > 0 )
 
  284        details << wxT( 
"<li>" ) + 
_( 
"Resources" ) + wxT( 
"<ul>" );
 
  286        for( 
const std::pair<const std::string, wxString>& entry : package.resources )
 
  288            details << wxT( 
"<li>" );
 
  289            details << entry.first << wxT( 
": " );
 
  290            details << format_entry( entry ) + wxT( 
"</li>" );
 
  293        details << wxT( 
"</ul>" );
 
  296    details << wxT( 
"</ul>" );
 
  308    wxString current_version;
 
  311        current_version = 
m_pcm->GetInstalledPackageVersion( package.identifier );
 
  330        if( current_version == version.
version )
 
  350        if( version.IsEmpty() )
 
  353        if( !version.IsEmpty() )
 
 
  408    if( b >= 1024 * 1024 )
 
  409        return wxString::Format( wxT( 
"%.1f MB" ), b / 1000.0 / 1000.0 );
 
  412        return wxString::Format( wxT( 
"%lld kB" ), b / 1000 );
 
  414    return wxString::Format( wxT( 
"%lld B" ), b );
 
 
  434    switch( packageData.
state )
 
 
  453        it->second->SetState( aState, aPinned );
 
 
  491    const wxArrayInt selectedRows = 
m_gridVersions->GetSelectedRows();
 
  494    const PCM_PACKAGE& 
package = m_currentSelected->GetPackageData().package;
 
  496    auto ver_it = std::find_if( package.versions.begin(), package.versions.end(),
 
  499                                    return ver.version == version;
 
  502    wxASSERT_MSG( ver_it != package.
versions.end(), 
"Could not find package version" );
 
  504    if( !ver_it->download_url )
 
  506        wxMessageBox( 
_( 
"Package download url is not specified" ), 
_( 
"Error downloading package" ),
 
  507                      wxICON_INFORMATION | wxOK, wxGetTopLevelParent( 
this ) );
 
  511    const wxString& url = *ver_it->download_url;
 
  514    wxWindow* topLevelParent = wxGetTopLevelParent( 
this );
 
  516                         wxString::Format( wxT( 
"%s_v%s.zip" ), package.identifier, version ),
 
  517                         wxT( 
"ZIP files (*.zip)|*.zip" ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
 
  519    if( dialog.ShowModal() == wxID_CANCEL )
 
  522    wxString 
path = dialog.GetPath();
 
  525    std::ofstream output( 
path.ToUTF8(), std::ios_base::binary );
 
  529    bool success = 
m_pcm->DownloadToStream( url, &output, &reporter, 0 );
 
  535        if( ver_it->download_sha256 )
 
  537            std::ifstream stream( 
path.ToUTF8(), std::ios_base::binary );
 
  539            bool matches = 
m_pcm->VerifyHash( stream, *ver_it->download_sha256 );
 
  543            if( !matches && wxMessageBox( 
_( 
"Integrity of the downloaded package could not be verified, hash " 
  544                                             "does not match. Are you sure you want to keep this file?" ),
 
  545                                          _( 
"Keep downloaded file" ), wxICON_EXCLAMATION | wxYES_NO,
 
  546                                          wxGetTopLevelParent( 
this ) )
 
  549                wxRemoveFile( 
path );
 
  555        if( wxFileExists( 
path ) )
 
  556            wxRemoveFile( 
path );
 
 
  581    const wxArrayInt selectedRows = 
m_gridVersions->GetSelectedRows();
 
  584    const PCM_PACKAGE& 
package = m_currentSelected->GetPackageData().package;
 
  586    auto ver_it = std::find_if( package.versions.begin(), package.versions.end(),
 
  589                                    return ver.version == version;
 
  592    wxCHECK_RET( ver_it != package.
versions.end(), 
"Could not find package version" );
 
  594    if( !ver_it->compatible && wxMessageBox( 
_( 
"This package version is incompatible with your KiCad version or " 
  595                                                "platform. Are you sure you want to install it anyway?" ),
 
  596                                             _( 
"Install package" ), wxICON_EXCLAMATION | wxYES_NO,
 
  597                                             wxGetTopLevelParent( 
this ) )
 
 
  635    std::vector<std::pair<int, int>> package_ranks;
 
  637    const wxString search_term = 
m_searchCtrl->GetValue().Trim();
 
  644        if( search_term.size() > 2 )
 
  645            rank = 
m_pcm->GetPackageSearchRank( pkg, search_term );
 
  651        package_ranks.emplace_back( rank, index );
 
  654    std::sort( package_ranks.begin(), package_ranks.end(),
 
  655               []( 
const std::pair<int, int>& a, 
const std::pair<int, int>& b )
 
  657                   return a.first > b.first || ( a.first == b.first && a.second < b.second );
 
  662    sizer->Clear( 
false ); 
 
  664    for( 
const std::pair<int, int>& pair : package_ranks )
 
  670            sizer->Add( panel, 0, wxEXPAND );
 
 
  719                  wxT( 
"getAction() called with ambiguous version selection" ) );
 
  721    int selected_row = 0;
 
  729    switch( package.state )
 
  732    case PPS_UNAVAILABLE:
 
  735    case PPS_UPDATE_AVAILABLE:
 
  736        if( version == package.current_version )
 
  737            return PPA_UNINSTALL;
 
 
  755    infoSize.y = 
m_infoText->GetInternalRepresentation()->GetHeight() + 12;
 
 
  767    const wxHtmlLinkInfo& 
info = aEvent.GetLinkInfo();
 
  768    ::wxLaunchDefaultBrowser( 
info.GetHref() );
 
 
  799    std::vector<wxString> packages;
 
  803    for( 
const wxString& pkg_id : packages )
 
 
PACKAGE_MANAGER m_PackageManager
 
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
 
wxString m_PcmLastDownloadDir
 
WX_SPLITTER_WINDOW * m_splitter1
 
wxScrolledWindow * m_packageListWindow
 
void m_splitter1OnIdle(wxIdleEvent &)
 
PANEL_PACKAGES_VIEW_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
 
wxButton * m_buttonAction
 
wxButton * m_buttonUpdateAll
 
wxButton * m_buttonDownload
 
wxBoxSizer * m_sizerVersions
 
wxCheckBox * m_showAllVersions
 
wxScrolledWindow * m_infoScrollWindow
 
wxSearchCtrl * m_searchCtrl
 
void OnInfoMouseWheel(wxMouseEvent &event) override
Replacement of wxFormBuilder's ill-advised m_splitter1OnIdle.
 
std::unordered_set< wxString > m_updateablePackages
 
void OnUpdateAllClicked(wxCommandEvent &event) override
 
void ClearData()
Selects full row of the clicked cell.
 
void updateDetailsButtons()
Called when package state changes, currently used to calculate Update All button state.
 
void OnVersionActionClicked(wxCommandEvent &event) override
Shows all versions including incompatible ones.
 
void OnSizeInfoBox(wxSizeEvent &aEvent) override
Respond to a URL in the info window.
 
bool canDownload() const
Returns true if the package action can be performed.
 
void OnDownloadVersionClicked(wxCommandEvent &event) override
Schedules relevant action for selected package version.
 
wxString toHumanReadableSize(const std::optional< uint64_t > size) const
Returns true if it the download operation can be performed.
 
void OnSearchTextChanged(wxCommandEvent &event)
 
void updateCommonState()
Updates details panel.
 
void updatePackageList()
< Updates package listing according to search term
 
const ActionCallback & m_actionCallback
 
std::unordered_map< wxString, PANEL_PACKAGE * > m_packagePanels
 
void setPackageDetails(const PACKAGE_VIEW_DATA &aPackageData)
Clears details panel.
 
const PinCallback & m_pinCallback
 
std::shared_ptr< PLUGIN_CONTENT_MANAGER > m_pcm
 
PCM_PACKAGE_ACTION getAction() const
 
bool canRunAction() const
Returns implied action for the action button.
 
PANEL_PACKAGE * m_currentSelected
 
void unsetPackageDetails()
Bytes to Kb/Mb/Gb string or "-" if absent.
 
void SetData(const std::vector< PACKAGE_VIEW_DATA > &aPackageData)
Recreates package panels and displays data.
 
void OnVersionsCellClicked(wxGridEvent &event) override
Opens file chooser dialog and downloads selected package version archive.
 
void OnURLClicked(wxHtmlLinkEvent &event) override
Respond to scrolling over the window.
 
void SetSashOnIdle(wxIdleEvent &)
Enqueues all available package updates.
 
static std::unordered_map< PCM_PACKAGE_VERSION_STATUS, wxString > STATUS_ENUM_TO_STR
 
void SetPackageState(const wxString &aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned)
Set the state of package.
 
std::vector< wxString > m_packageInitialOrder
 
PANEL_PACKAGES_VIEW(wxWindow *parent, std::shared_ptr< PLUGIN_CONTENT_MANAGER > aPcm, const ActionCallback &aCallback, const PinCallback &aPinCallback)
 
void OnShowAllVersionsClicked(wxCommandEvent &event) override
Ranks packages for entered search term and rearranges/hides panels according to their rank.
 
void OnClick(wxMouseEvent &event) override
 
const PACKAGE_VIEW_DATA & GetPackageData() const
 
void SetSelected(bool aSelected)
 
void SetSelectCallback(const std::function< void()> &aCallback)
Marks panel as selected.
 
virtual COMMON_SETTINGS * GetCommonSettings() const
 
Multi-thread safe progress reporter dialog, intended for use of tasks that parallel reporting back of...
 
std::function< void(const wxString &aPackageId, const PCM_PACKAGE_STATE aState, const bool aPinned)> PinCallback
 
std::function< void(const PACKAGE_VIEW_DATA &aData, PCM_PACKAGE_ACTION aAction, const wxString &aVersion)> ActionCallback
 
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
 
PGM_BASE & Pgm()
The global program "get" accessor.
 
T * GetAppSettings(const char *aFilename)
 
std::vector< FAB_LAYER_COLOR > dummy
 
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
 
< Package version metadataPackage metadata
 
std::optional< uint64_t > download_size
 
std::optional< uint64_t > install_size
 
PCM_PACKAGE_VERSION_STATUS status
 
< Collection of data relevant to the package display panelCallback for (un)install button
 
Repository reference to a resource.
 
std::vector< PACKAGE_VERSION > versions
 
wxString result
Test unit parsing edge cases and error handling.