20#include "../IconManager.h"
21#include "../globals.hpp"
22#include "../compositions/grouppanel.hpp"
23#include "../../kernel/core/ui/language.hpp"
24#include "../../kernel/core/utils/tools.hpp"
25#include "../../common/datastructures.h"
26#include "../../common/http.h"
27#include "../controls/searchctrl.hpp"
34#define WINDOWWIDTH 1000*g_pixelScale
35#define CTRLWIDTH WINDOWWIDTH-50*g_pixelScale
36#define WINDOWHEIGHT 600*g_pixelScale
52 virtual bool selectItem(
const wxString& value)
override;
53 wxTreeItemId
findItem(
const wxString& value, wxTreeItemId node);
54 virtual wxArrayString
getCandidates(
const wxString& enteredText)
override;
58 PackageListSearchCtrl(wxWindow* parent, wxWindowID
id,
const wxString& hint = wxEmptyString,
const wxString& calltip = wxEmptyString, wxcode::wxTreeListCtrl* associatedCtrl =
nullptr) :
SearchCtrl(parent, id, wxEmptyString),
m_associatedCtrl(associatedCtrl)
90 wxTreeItemIdValue cookie;
98 wxTreeItemId match =
findItem(value[0] ==
' ' ? value.substr(1).Lower() : value.Lower(), child);
137 wxTreeItemIdValue cookie;
145 wxTreeItemId match =
findItem(value, child);
156 return wxTreeItemId();
175 wxTreeItemIdValue cookie;
187 return wxArrayString();
205 wxArrayString stringArray;
206 wxArrayString enteredWords = wxStringTokenize(enteredText);
214 for (
size_t i = 0; i < enteredWords.size(); i++)
217 ||
m_associatedCtrl->GetItemText(node, 1).Lower().find(enteredWords[i]) != std::string::npos
218 ||
m_associatedCtrl->GetItemText(node, 2).Lower().find(enteredWords[i]) != std::string::npos)
227 if (nCount && nCount >=
std::rint(2*enteredWords.size() / 3.0))
231 wxTreeItemIdValue cookie;
242 if (childArray.size())
247 stringArray.Add(match);
260#define REPO_LOCATION "http://svn.code.sf.net/p/numere/plugins/repository/"
261#define REPO_URL "Repository URL"
262#define DEPENDENCIES "Dependencies"
264#define PACKAGCOLUMN 0
266#define INSTALLEDCOLUMN 2
267#define CHANGELOGLENGTH 750
269#define INSTALLEDCOLOUR wxColour(220,255,220)
270#define UPDATECOLOUR wxColour(220,220,255)
271#define NEWERCOLOUR wxColour(255,255,160)
272#define OUTDATEDVERSIONCOLOUR wxColour(255,220,220)
273#define LOCALCOLOUR NEWERCOLOUR
296static std::
string getTagValue(const std::
string& sTaggedString, const std::
string& sTag)
301 return getArgAtPos(sTaggedString, nTag+sTag.length());
323 GroupPanel* panel =
new GroupPanel(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_STATIC);
333 panel->
getMainSizer()->Prepend(treesearch, 0, wxALL | wxEXPAND, 5);
363 std::vector<bool> vRemotePackage(vInstalled.size(),
false);
365 wxTreeItemIdValue cookie;
371 m_listCtrl->SetItemBackgroundColour(item, *wxWHITE);
374 size_t nRequiredVersion = 0u;
375 std::string sReqVersion =
getEntry(item,
"Required NumeRe version");
377 if (sReqVersion.length())
382 if (nRequiredVersion > nNumeReVersion)
386 if (
m_listCtrl->GetItemText(item,
REPOCOLUMN).find(
"(Requires newer NumeRe version)") == std::string::npos)
394 for (
size_t i = 0; i < vInstalled.size(); i++)
396 if (vInstalled[i].getName() ==
m_listCtrl->GetItemText(item))
398 vRemotePackage[i] =
true;
415 if (nRepoVersion > nInstalledVersion)
420 else if (nRepoVersion < nInstalledVersion)
445 wxTreeItemId itemToDelete = item;
454 for (
size_t i = 0; i < vRemotePackage.size(); i++)
456 if (!vRemotePackage[i])
458 wxTreeItemId currPackage =
m_listCtrl->AppendItem(
m_listCtrl->GetRootItem(), vInstalled[i].getName());
465 wxTreeItemId currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Author");
468 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Type");
469 m_listCtrl->SetItemText(currPackageInfo,
REPOCOLUMN, vInstalled[i].sType.find(
"PLUGIN") != std::string::npos ?
"Plugin" :
"Package");
471 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Description");
472 std::string sDesc = vInstalled[i].getDescription();
476 if (!sDesc.length() || sDesc ==
"Description")
477 sDesc =
"[No description. Please provide a description using the \"desc=DESC\" install info field.]";
480 m_listCtrl->SetItemToolTip(currPackageInfo, sDesc);
481 m_listCtrl->SetItemToolTip(currPackage, sDesc);
483 if (sDesc.front() ==
'[')
484 m_listCtrl->SetItemTextColour(currPackageInfo, *wxRED);
486 if (!vInstalled[i].getKeyWords().length() || vInstalled[i].getKeyWords() !=
"NONE")
488 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Keywords");
490 m_listCtrl->SetItemToolTip(currPackageInfo, vInstalled[i].getKeyWords());
493 if (!vInstalled[i].getChangesLog().length() || vInstalled[i].getChangesLog() !=
"NONE")
495 std::string sChangesLog = vInstalled[i].getChangesLog();
498 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Changelog");
504 m_listCtrl->SetItemToolTip(currPackageInfo, sChangesLog);
507 std::string sLicense = vInstalled[i].getLicense();
509 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"License");
511 if (sLicense.length() && sLicense !=
"???")
515 m_listCtrl->SetItemText(currPackageInfo,
REPOCOLUMN,
"[License unknown. Please provide a license using the \"license=LICENSE\" install info field.]");
516 m_listCtrl->SetItemTextColour(currPackageInfo, *wxRED);
542 if (!GetThread() || !GetThread()->IsRunning())
546 if (CreateThread(wxTHREAD_DETACHED) != wxTHREAD_NO_ERROR)
549 if (GetThread()->Run() != wxTHREAD_NO_ERROR)
567 m_statusText->SetLabel(
"Status: Fetching Package list ...");
572 m_statusText->SetLabel(
"Status: Reading Package information ...");
576 for (
size_t i = 0; i < vRepoContents.size(); i++)
579 if (GetThread()->TestDestroy())
582 return (wxThread::ExitCode)0;
589 m_statusText->SetLabel(
"Status: Detecting installations ...");
591 m_statusText->SetLabel(
"Status: Package database successfully loaded.");
595 m_statusText->SetLabel(
"Status: Retrieving packages ...");
601 for (
size_t i = 0; i <
m_vUrls.size(); i++)
604 if (GetThread()->TestDestroy())
607 return (wxThread::ExitCode)0;
617 m_statusText->SetLabel(
"Status: Packages successfully downloaded. Waiting for completion ... (You might need to accept licences in terminal)");
619 m_statusText->SetLabel(
"Status: One or more packages could not be downloaded.");
631 wxQueueEvent(GetEventHandler(),
new wxThreadEvent());
632 return (wxThread::ExitCode)0;
651 wxTreeItemIdValue cookie;
683 if (GetThread()->Delete() != wxTHREAD_NO_ERROR && event.CanVeto())
703 std::vector<std::string> vRepoContents;
705 sRepoContents = sRepoContents.substr(sRepoContents.find(
"<ul>")+4);
706 sRepoContents.erase(sRepoContents.find(
"</ul>"));
709 while (sRepoContents.length() && sRepoContents.find(
"</li>") != std::string::npos)
711 std::string sCurrentPackage = sRepoContents.substr(0, sRepoContents.find(
"</li>"));
712 sRepoContents.erase(0, sRepoContents.find(
"</li>")+5);
714 if (sCurrentPackage.find(
"href=\"") == std::string::npos)
718 sCurrentPackage = sCurrentPackage.substr(sCurrentPackage.find(
"href=\"") + 6);
719 sCurrentPackage.erase(sCurrentPackage.find(
'"'));
722 vRepoContents.push_back(sRepoUrl + sCurrentPackage);
725 return vRepoContents;
744 if (sUrl.find(
"/../") != std::string::npos)
749 if (sUrl.back() ==
'/')
751 std::vector<std::string> vRepoContents =
getRepoList(sUrl);
753 for (
const std::string& _url : vRepoContents)
762 if (sUrl.find(
".nscr") == std::string::npos)
768 std::string sInfo = sCurrentPackage.substr(sCurrentPackage.find(
"<info>"), sCurrentPackage.find(
"<endinfo>") - sCurrentPackage.find(
"<info>"));
774 std::string sPackageName =
getTagValue(sInfo,
"name");
780 wxTreeItemId currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Author");
783 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Type");
786 std::string sReqVersion =
getTagValue(sInfo,
"requireversion");
788 if (sReqVersion.length())
790 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Required NumeRe version");
791 m_listCtrl->SetItemText(currPackageInfo, 1,
"v" + sReqVersion);
794 std::string sDeps =
getTagValue(sInfo,
"requirepackages");
799 m_listCtrl->SetItemText(currPackageInfo, 1, sDeps);
802 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Description");
812 sDesc =
"[No description. Please provide a description using the \"desc=DESC\" install info field.]";
815 m_listCtrl->SetItemToolTip(currPackageInfo, sDesc);
816 m_listCtrl->SetItemToolTip(currPackage, sDesc);
818 if (sDesc.front() ==
'[')
819 m_listCtrl->SetItemTextColour(currPackageInfo, *wxRED);
821 std::string sKeyWords =
getTagValue(sInfo,
"keywords");
823 if (sKeyWords.length())
825 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Keywords");
827 m_listCtrl->SetItemToolTip(currPackageInfo, sKeyWords);
830 std::string sChangesLog =
getTagValue(sInfo,
"changelog");
832 if (sChangesLog.length())
837 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"Changelog");
843 m_listCtrl->SetItemToolTip(currPackageInfo, sChangesLog);
846 std::string sLicense =
getTagValue(sInfo,
"license");
848 currPackageInfo =
m_listCtrl->AppendItem(currPackage,
"License");
850 if (sLicense.length())
854 m_listCtrl->SetItemText(currPackageInfo,
REPOCOLUMN,
"[License unknown. Please provide a license using the \"license=LICENSE\" install info field.]");
855 m_listCtrl->SetItemTextColour(currPackageInfo, *wxRED);
873 wxTreeItemId item =
m_listCtrl->GetSelection();
875 if (item.IsOk() &&
m_listCtrl->HasChildren(item))
878 std::vector<std::string> vDeps;
888 if (sDepList.length())
892 for (
const std::string& sDep : vDeps)
919 wxTreeItemId item =
m_listCtrl->GetSelection();
923 wxString sName =
m_listCtrl->GetItemText(item);
926 m_listCtrl->SetItemBackgroundColour(item, *wxWHITE);
945 wxTreeItemId item =
event.GetItem();
976 return "?" + std::to_string(clock());
990 return item.IsOk() &&
m_listCtrl->GetItemBackgroundColour(item) == *wxWHITE;
1024 wxTreeItemIdValue cookie;
1025 wxTreeItemId child =
m_listCtrl->GetFirstChild(item, cookie);
1027 while (
m_listCtrl->GetItemText(child) != sIdentifier)
1077 wxTreeItemIdValue cookie;
1080 while (child.IsOk())
1082 std::string sPackageUrl =
getUrl(child);
1084 if (sPackageUrl.substr(sPackageUrl.rfind(
'/')) ==
"/" + sPackageFileName)
1109 while (sDepList.length())
1116 vDeps.push_back(sDep);
1134 std::string contents =
url::get(sUrl);
1135 std::string filename = sUrl;
1136 filename.erase(0, filename.rfind(
'/')+1);
1142 file.write(contents.c_str(), contents.length());
const std::string sVersion
This class simplifies the creation of simple windows and creates a common layout among all windows.
wxStaticText * AddStaticText(wxWindow *parent, wxSizer *sizer, const wxString &text, int id=wxID_STATIC, int alignment=wxALIGN_CENTER_VERTICAL)
Add some static test to the current sizer and window.
wxGauge * CreateGauge(wxWindow *parent, wxSizer *sizer, int style, int id=wxID_ANY, int alignment=wxALIGN_CENTER_VERTICAL)
This member function creates the layout for a progress bar.
wxcode::wxTreeListCtrl * CreateWxcTreeListCtrl(wxWindow *parent, wxSizer *sizer, int nStyle=wxTR_TWIST_BUTTONS|wxTR_FULL_ROW_HIGHLIGHT|wxTR_EXTENDED, wxSize size=wxDefaultSize, int id=wxID_ANY, int alignment=wxALIGN_CENTER_VERTICAL)
This member function creates the layout for a treelist control in the wxCode variant.
wxBoxSizer * getMainSizer()
Return the pointer to the current main layout sizer.
wxStaticBoxSizer * createGroup(const wxString &sGroupName, int orient=wxVERTICAL, wxWindow *parent=nullptr, wxSizer *sizer=nullptr, int expand=0)
Member function to create a group (a static box with a label) in the panel.
wxButton * CreateButton(wxWindow *parent, wxSizer *sizer, const wxString &description, int id=wxID_ANY, int alignment=wxALIGN_CENTER_VERTICAL)
This member function creates the layout for a button.
int GetIconIndex(wxString iconInfo)
wxImageList * GetImageList()
This class handles the internal language system and returns the language strings of the selected lang...
The terminal class for the GUI. It's a specialisation of the GenericTerminal.
const std::vector< Package > & getInstalledPackages()
Returns the installed plugins as a STL vector.
void pass_command(const std::string &command, bool isEvent)
Pass the external command to the kernel without printing it to the console.
std::vector< std::string > getPathSettings()
Returns the standard paths as a STL vector.
This class specializes the generic search control to interact with the package list of the package re...
PackageListSearchCtrl(wxWindow *parent, wxWindowID id, const wxString &hint=wxEmptyString, const wxString &calltip=wxEmptyString, wxcode::wxTreeListCtrl *associatedCtrl=nullptr)
virtual wxArrayString getCandidates(const wxString &enteredText) override
This method returns an array of strings containing possible candidates for the passed search string.
wxcode::wxTreeListCtrl * m_associatedCtrl
wxTreeItemId findItem(const wxString &value, wxTreeItemId node)
This method searches for the tree item, whose label corresponds to the passed string.
virtual bool selectItem(const wxString &value) override
This method searches and selects the item with the passed label in the associated tree.
wxArrayString getChildCandidates(const wxString &enteredText, wxTreeItemId node)
This method returns an array of strings containing possible candiates for the passed search string,...
This class represents a simple browser for the package repository with an install and uninstall capab...
std::string m_fileNameToInstall
std::string getDependencies(const wxTreeItemId &item)
Return the package dependencies.
bool getFileFromRepo(const std::string &sUrl)
Returns the contents of the passed URL as a file and writes it to its counterpart in the <SCRIPTPATH>...
std::string createSalt()
Simple function to make the URL more unique to avoid server caching (which might resolve in a very de...
std::string getUrl(const wxTreeItemId &item)
Return the package URL.
virtual wxThread::ExitCode Entry()
Secondary thread worker function.
wxButton * m_uninstallButton
void resolveDependencies(std::string sDepList, std::vector< std::string > &vDeps)
This member function resolves the dependencies of a selected file using a recursion....
std::string getEntry(const wxTreeItemId &item, const std::string &sIdentifier)
Returns the value of the selected identifier or an empty string, if the identifier cannot be found.
wxcode::wxTreeListCtrl * m_listCtrl
bool isUpdateable(const wxTreeItemId &item)
Returns, whether the current item is an updateable package (already installed but newer version avail...
NumeReTerminal * m_terminal
wxStaticText * m_statusText
wxButton * m_installButton
bool isInstallable(const wxTreeItemId &item)
Returns, whether the current item is an installable package (not already installed).
void OnClose(wxCloseEvent &event)
OnClose event handler. Will terminate the thread, if it's running.
void StartThread(ThreadTask task)
Start a new thread with the passed task.
void OnInstall(wxCommandEvent &event)
Button event handler linked to the "install/update" button.
std::vector< std::string > getRepoList(const std::string &sRepoUrl)
This member function fetches the repository main page as HTML and extracts the list of item links in ...
void OnUninstall(wxCommandEvent &event)
Button event handler linked to the "uninstall" button.
PackageRepoBrowser(wxWindow *parent, NumeReTerminal *terminal, IconManager *icons)
PackageRepositoryBrowser constructor. Starts the file loading task.
void OnItemSelect(wxTreeEvent &event)
Item select event handler to enable or disable the buttons depending on the state of the package or w...
wxTreeItemId findPackage(const std::string &sPackageFileName)
Find a package entry from its file name. The returned ID must be checked for validness via wxTreeItem...
std::vector< std::string > m_vUrls
void DetectInstalledPackages()
Detect installed packages by loading the list of installed and comparing them to the loaded contents ...
void populatePackageList(const std::string &sUrl)
Gets an URL and retrieve its counterpart from the repository. If the link does not reference a file b...
void OnThreadUpdate(wxThreadEvent &event)
Thread update event handler. Will trigger the actual installation, if the files were loaded successfu...
Implementation of a generic search control based on a combo box.
This class generalizes a set of basic floating window functionalities like being closable by pressing...
A class for URL exceptions.
virtual const char * what() const noexcept
CONSTCD11 std::enable_if<!std::chrono::treat_as_floating_point< T >::value, T >::type trunc(T t) NOEXCEPT
value_type rint(value_type v)
std::string get(const std::string &sUrl, const std::string &sUserName, const std::string &sPassWord)
Get the contents of a URL.
#define OUTDATEDVERSIONCOLOUR
static std::string getTagValue(const std::string &sTaggedString, const std::string &sTag)
Static helper function to extract the value of an install info tag.
#define PACKAGE_REPO_BROWSER_TITLE
int findParameter(const std::string &sCmd, const std::string &sParam, const char cFollowing)
This function searches the passed parameter in the passed command string. If something is found,...