diff --git a/src/data/installer.cpp b/src/data/installer.cpp index 7ad82b51..4ce8152a 100644 --- a/src/data/installer.cpp +++ b/src/data/installer.cpp @@ -327,6 +327,7 @@ void merge(InstallablePackages& installed, const DownloadableInstallerP& install ip->installer = installer; ips.push_back(ip); } + sort(ips); merge(installed, ips); } diff --git a/src/gui/packages_window.cpp b/src/gui/packages_window.cpp index d8cb975c..97974ca7 100644 --- a/src/gui/packages_window.cpp +++ b/src/gui/packages_window.cpp @@ -11,14 +11,11 @@ #include //%#include #include -#include #include #include #include #include #include -//%#include -//%#include #include #include #include @@ -26,49 +23,16 @@ #include #include -//%DECLARE_POINTER_TYPE(VersionData); //%% TODO DECLARE_POINTER_TYPE(Installer); -//%DECLARE_POINTER_TYPE(PackageVersionData); -DECLARE_TYPEOF_COLLECTION(PackageVersionDataP); DECLARE_TYPEOF_COLLECTION(PackageDependencyP); DECLARE_TYPEOF_COLLECTION(InstallablePackageP); +DECLARE_TYPEOF_COLLECTION(DownloadableInstallerP); DECLARE_TYPEOF_COLLECTION(TreeList::ItemP); -//%DECLARE_TYPEOF(list); -//%DECLARE_TYPEOF(set); // ----------------------------------------------------------------------------- : TODO: MOVE /* -/// Information on available packages -class PackageVersionData : public IntrusivePtrVirtualBase { - public: - PackageVersionData() {} - - String name; ///< Name of the package - String type; ///< Type of package ("magic style" or "game") - String display_name; ///< Name to show on package list. - String description; ///< html description - String url; ///< Where can the package be downloaded? - Version version; ///< Version number of the download - Version app_version; ///< The minimium version of MSE required - vector depends; ///< Packages this depends on - - DECLARE_REFLECTION(); -}; - -/// Information on the latest available version -class VersionData : public IntrusivePtrBase { - public: - Version version; ///< Latest version number of MSE - String description; ///< html description of the latest MSE release - String new_updates_url; ///< updates url has moved? - vector packages; ///< Available packages - - DECLARE_REFLECTION(); -}; -extern VersionDataP update_version_data; - // A HTML control that opens all pages in an actual browser struct HtmlWindowToBrowser : public wxHtmlWindow { HtmlWindowToBrowser(Window* parent, int id, const wxPoint& pos, const wxSize& size, long flags) @@ -79,134 +43,61 @@ struct HtmlWindowToBrowser : public wxHtmlWindow { wxLaunchDefaultBrowser( info.GetHref() ); } }; - -// ----------------------------------------------------------------------------- : PackageUpdateList - -/* -class PackageUpdateList : public wxVListBox { - public: - PackageUpdateList(UpdatesWindow* parent) - : wxVListBox (parent, ID_PACKAGE_LIST, wxDefaultPosition, wxSize(540,210), wxNO_BORDER | wxVSCROLL) - , parent(parent) - { - if (!checking_updates && !update_version_data) { - check_updates_now(true); - } - SetItemCount(update_version_data ? update_version_data->packages.size() : 1); - } - - virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const { - static wxBrush greyBrush(Color(224,224,224)); - if (checking_updates) { - String text = _ERROR_("checking updates"); - - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(greyBrush); - dc.DrawRectangle(rect); - - int w, h; - dc.GetTextExtent(text, &w, &h); - dc.DrawText(text, rect.GetLeft() + (rect.GetWidth() - w) / 2, rect.GetTop() + (rect.GetHeight() - h) / 2); - } else if (!update_version_data || update_version_data->packages.empty()) { - String text = _ERROR_("no packages"); - - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(greyBrush); - dc.DrawRectangle(rect); - - int w, h; - dc.GetTextExtent(text, &w, &h); - dc.DrawText(text, rect.GetLeft() + (rect.GetWidth() - w) / 2, rect.GetTop() + (rect.GetHeight() - h) / 2); - } else { - static wxBrush darkBrush(Color(192,224,255)); - static wxBrush selectBrush(Color(96,96,192)); - - PackageVersionDataP pack = update_version_data->packages[n]; - UpdatesWindow::PackageStatus status = parent->package_data[pack].first; - UpdatesWindow::PackageAction action = parent->package_data[pack].second; - - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(IsSelected(n) ? selectBrush : (n % 2 ? *wxWHITE_BRUSH : darkBrush)); - - dc.DrawRectangle(rect); - - // These two arrays correspond to PackageStatus and PackageAction, respectively - static Color status_colors [] = { - Color(32,160,32) - ,Color(32,32,255) - ,Color(192,32,32) - }; - - static Color action_colors [] = { - Color(32,160,32) - ,Color(192,32,32) - ,Color(192,192,32) - ,Color(32,32,255) - ,Color(32,32,32) - }; - - // Ditto here (these are the locale names) - static String status_texts [] = { - _TYPE_("installed") - ,_TYPE_("uninstalled") - ,_TYPE_("upgradeable") - }; - - static String action_texts [] = { - _TYPE_("install") - ,_TYPE_("uninstall") - ,_TYPE_("upgrade") - ,_TYPE_("do nothing") - ,_TYPE_("new mse") - }; - - static Color packageFront(64,64,64); - - #define SELECT_WHITE(color) (IsSelected(n) ? *wxWHITE : color) - - dc.SetClippingRegion(wxRect(rect.x, rect.y, 180, rect.height)); - dc.SetTextForeground(SELECT_WHITE(packageFront)); - dc.DrawText(pack->display_name, rect.GetLeft() + 1, rect.GetTop()); - dc.DestroyClippingRegion(); - - dc.SetClippingRegion(wxRect(rect.x + 180, rect.y, 120, rect.height)); - dc.DrawText(pack->type, rect.GetLeft() + 180, rect.GetTop()); - dc.DestroyClippingRegion(); - - dc.SetTextForeground(SELECT_WHITE(status_colors[status])); - dc.DrawText(status_texts[status], rect.GetLeft() + 300, rect.GetTop()); - - dc.SetTextForeground(SELECT_WHITE(action_colors[action])); - dc.DrawText(action_texts[action], rect.GetLeft() + 420, rect.GetTop()); - - #undef SELECT_WHITE - } - } - - virtual wxCoord OnMeasureItem(size_t) const { - return (update_version_data && !update_version_data->packages.empty()) ? 15 : 210; - } - - void onUpdateCheckingFinished(wxEvent& event) { - SetItemCount(update_version_data ? update_version_data->packages.size() : 1); - } - - virtual wxCoord EstimateTotalHeight() const { - return (update_version_data && !update_version_data->packages.empty()) - ? 15 * (int)update_version_data->packages.size() - : 210; - } - private: - DECLARE_EVENT_TABLE() - - UpdatesWindow* parent; -}; - -BEGIN_EVENT_TABLE(PackageUpdateList, wxVListBox) - EVT_CUSTOM(UPDATE_CHECK_FINISHED_EVT, wxID_ANY, PackageUpdateList::onUpdateCheckingFinished) -END_EVENT_TABLE() */ +// ----------------------------------------------------------------------------- : DownloadableInstallers + +class DownloadableInstallerList { + public: + DownloadableInstallerList() : status(NONE) {} + + /// are we done? if not, start downloading + bool done(); + + vector installers; + + private: + enum Status { NONE, DOWNLOADING, DONE } status; + wxMutex lock; + + struct Thread : public wxThread { + virtual ExitCode Entry(); + }; +}; + +DownloadableInstallerList downloadable_installers; + +bool DownloadableInstallerList::done() { + if (status == DONE) return true; + if (status == NONE) { + status = DOWNLOADING; + Thread* thread = new Thread(); + thread->Create(); + thread->Run(); + } + return false; +} + +wxThread::ExitCode DownloadableInstallerList::Thread::Entry() { + // open url + wxURL url(settings.installer_list_url); + wxInputStream* isP = url.GetInputStream(); + if (!isP) { + wxMutexLocker l(downloadable_installers.lock); + downloadable_installers.status = DONE; + return 0; + } + InputStreamP is(isP); + // Read installer list + Reader reader(is, nullptr, _("installers"), true); + vector installers; + reader.handle(_("installers"),installers); + // done + wxMutexLocker l(downloadable_installers.lock); + swap(installers, downloadable_installers.installers); + downloadable_installers.status = DONE; + return 0; +} // ----------------------------------------------------------------------------- : PackageUpdateList @@ -216,7 +107,6 @@ class PackageUpdateList : public TreeList { PackageUpdateList(PackagesWindow* parent, int id = wxID_ANY) : TreeList(parent, id) , parent(parent) - , images(16,16) { item_height = max(item_height,17); rebuild(); @@ -240,7 +130,6 @@ class PackageUpdateList : public TreeList { private: PackagesWindow* parent; - mutable wxImageList images; class TreeItem; public: typedef intrusive_ptr TreeItemP; @@ -250,9 +139,11 @@ class PackageUpdateList : public TreeList { String label; vector children; InstallablePackageP package; + Bitmap icon, icon_grey; void add(const InstallablePackageP& package, const String& path, int level = -1); void toItems(vector& items); + bool highlight() const; }; }; @@ -312,14 +203,21 @@ void PackageUpdateList::TreeItem::toItems(vector& items) { } } +bool PackageUpdateList::TreeItem::highlight() const { + if (package && ((package->installed && !(package->action & PACKAGE_REMOVE)) + || package->action & (PACKAGE_INSTALL | PACKAGE_UPGRADE))) { + return true; + } + FOR_EACH_CONST(c,children) if (c->highlight()) return true; + return false; +} + void PackageUpdateList::initItems() { // packages to tree TreeItem root; FOR_EACH(ip, parent->installable_packages) { String group = ip->description->installer_group; -//% if (group.empty()) group = _("Custom"); -//% group += _("/"); if (!group.empty()) group += _("/"); group += ip->description->short_name; root.add(ip, group); @@ -328,21 +226,25 @@ void PackageUpdateList::initItems() { items.clear(); root.toItems(items); // init image list - images.RemoveAll(); - Image resampled(16,16,false); FOR_EACH(i,items) { - const TreeItem& ti = static_cast(*i); + TreeItem& ti = static_cast(*i); const InstallablePackageP& p = ti.package; + Image image; if (p && p->description->icon.Ok()) { + Image resampled(16,16,false); resample_preserve_aspect(p->description->icon, resampled); - images.Add(resampled); + image = resampled; } else if (p) { - images.Add(load_resource_image(_("installer_package"))); + image = load_resource_image(_("installer_package")); } else if (ti.label == _("locales")) { - images.Add(load_resource_image(_("installer_locales"))); + image = load_resource_image(_("installer_locales")); } else { - images.Add(load_resource_image(_("installer_group"))); + image = load_resource_image(_("installer_group")); } + ti.icon = Bitmap(image); + desaturate(image); + set_alpha(image, 0.5); + ti.icon_grey = Bitmap(image); } } @@ -351,31 +253,41 @@ void PackageUpdateList::drawItem(DC& dc, size_t index, size_t column, int x, int Color color = wxSystemSettings::GetColour(selected ? wxSYS_COLOUR_HIGHLIGHTTEXT : wxSYS_COLOUR_WINDOWTEXT); if (column == 0) { // Name - images.Draw((int)index, dc, x, y); + const Bitmap& bmp = ti.highlight() ? ti.icon : ti.icon_grey; + if (bmp.Ok()) dc.DrawBitmap(bmp,x,y); dc.SetTextForeground(color); dc.DrawText(ti.label, x+18, y+2); } else if (column == 1 && ti.package) { // Status int stat = ti.package->status; if ((stat & PACKAGE_CONFLICTS) == PACKAGE_CONFLICTS) { + dc.SetTextForeground(lerp(color,Color(255,0,0),0.8)); dc.DrawText(_LABEL_("package conflicts"), x+1,y+2); } else if ((stat & PACKAGE_MODIFIED) == PACKAGE_MODIFIED) { + dc.SetTextForeground(lerp(color,Color(255,255,0),0.5)); dc.DrawText(_LABEL_("package modified"), x+1,y+2); } else if ((stat & PACKAGE_UPDATES) == PACKAGE_UPDATES) { + dc.SetTextForeground(lerp(color,Color(0,0,255),0.5)); dc.DrawText(_LABEL_("package updates"), x+1,y+2); } else if ((stat & PACKAGE_INSTALLED) == PACKAGE_INSTALLED) { + dc.SetTextForeground(color); dc.DrawText(_LABEL_("package installed"), x+1,y+2); } else if ((stat & PACKAGE_INSTALLABLE) == PACKAGE_INSTALLABLE) { + dc.SetTextForeground(lerp(color,Color(128,128,128),0.6)); + dc.SetTextForeground(color); dc.DrawText(_LABEL_("package installable"), x+1,y+2); } } else if (column == 2 && ti.package) { // Action int act = ti.package->action; if (act & PACKAGE_INSTALL) { + dc.SetTextForeground(lerp(color,Color(0,255,0),0.5)); dc.DrawText(_LABEL_("install package"), x+1,y+2); } else if (act & PACKAGE_UPGRADE) { + dc.SetTextForeground(lerp(color,Color(0,0,255),0.5)); dc.DrawText(_LABEL_("upgrade package"), x+1,y+2); } else if (act & PACKAGE_REMOVE) { + dc.SetTextForeground(lerp(color,Color(255,0,0),0.5)); dc.DrawText(_LABEL_("remove package"), x+1,y+2); } } @@ -457,11 +369,16 @@ END_EVENT_TABLE() PackagesWindow::PackagesWindow(Window* parent, bool download_package_list) : wxDialog(parent, wxID_ANY, _TITLE_("package list"), wxDefaultPosition, wxSize(640,480), wxDEFAULT_DIALOG_STYLE | wxCLIP_CHILDREN | wxRESIZE_BORDER) , where(is_install_local(settings.install_type) ? PACKAGE_LOCAL : PACKAGE_GLOBAL) + , waiting_for_list(download_package_list) { + // request download before searching disk so we do two things at once + if (download_package_list) downloadable_installers.done(); // get packages wxBusyCursor busy; packages.installedPackages(installable_packages); FOR_EACH(p, installable_packages) p->determineStatus(); + checkInstallerList(); + // ui elements SetIcon(wxIcon()); package_list = new PackageUpdateList(this, ID_PACKAGE_LIST); @@ -471,38 +388,8 @@ PackagesWindow::PackagesWindow(Window* parent, bool download_package_list) wxButton* install_button = new wxButton(this, ID_INSTALL, _BUTTON_("install package")); wxButton* upgrade_button = new wxButton(this, ID_UPGRADE, _BUTTON_("upgrade package")); wxButton* remove_button = new wxButton(this, ID_REMOVE, _BUTTON_("remove package")); -/* - description_window = new HtmlWindowToBrowser(this, wxID_ANY, wxDefaultPosition, wxSize(540,100), wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER); - setDefaultPackageStatus(); - - (install_button = new wxButton(this, ID_INSTALL, _MENU_("install package")))->Disable(); - (upgrade_button = new wxButton(this, ID_UPGRADE, _MENU_("upgrade package")))->Disable(); - (remove_button = new wxButton(this, ID_REMOVE, _MENU_("remove package")))->Disable(); - (cancel_button = new wxButton(this, ID_CANCEL, _MENU_("cancel changes")))->Disable(); - - apply_button = new wxButton(this, ID_APPLY, _MENU_("apply changes")); // Init sizer - - h2->AddStretchSpacer(); - h2->Add(install_button); - h2->AddStretchSpacer(); - h2->Add(upgrade_button); - h2->AddStretchSpacer(); - h2->Add(remove_button); - h2->AddStretchSpacer(); - h2->Add(cancel_button); - h2->AddStretchSpacer(); -*/ -/* wxBoxSizer *h2 = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer *h3 = new wxBoxSizer(wxHORIZONTAL); - - h3->AddStretchSpacer(); - h3->Add(apply_button); - h3->AddStretchSpacer(); -// v->Add(h2); -// v->Add(h3);*/ - wxBoxSizer* v = new wxBoxSizer(wxVERTICAL); v->Add(package_list, 1, wxEXPAND | wxALL & ~wxBOTTOM, 8); v->AddSpacer(4); @@ -522,16 +409,10 @@ PackagesWindow::PackagesWindow(Window* parent, bool download_package_list) } PackagesWindow::~PackagesWindow() { - //(new WelcomeWindow)->Show(); } -/* -void PackagesWindow::onUpdateCheckFinished(wxCommandEvent&) { - setDefaultPackageStatus(); -}*/ void PackagesWindow::onPackageSelect(wxCommandEvent& ev) { -// updateButtons(package_list->getSelection()); package_info->setPackage(package = package_list->getSelection()); UpdateWindowUI(wxUPDATE_UI_RECURSE); } @@ -620,265 +501,32 @@ void PackagesWindow::onUpdateUI(wxUpdateUIEvent& ev) { } } -/* -void PackagesWindow::onActionChange(wxCommandEvent& ev) { - PackageVersionDataP pack = package_list->getSelection(); - if (!pack) return; - PackageAction& action = package_data[pack].second; - switch (ev.GetId()) { - case ID_INSTALL: - action = ACTION_INSTALL; - SelectPackageDependencies(pack); - break; - case ID_REMOVE: - action = ACTION_UNINSTALL; - RemovePackageDependencies(pack); - break; - case ID_UPGRADE: - action = ACTION_UPGRADE; - SelectPackageDependencies(pack); - break; - case ID_CANCEL: - switch (package_data[pack].first) { - case STATUS_INSTALLED: - SelectPackageDependencies(pack); - break; - case STATUS_NOT_INSTALLED: - RemovePackageDependencies(pack); - break; - case STATUS_UPGRADEABLE: - if (action == ACTION_UPGRADE) - DowngradePackageDependencies(pack); - else - SelectPackageDependencies(pack); - break; - } - action = (pack->app_version > file_version) ? ACTION_NEW_MSE : ACTION_NOTHING; - break; - } - updateButtons(package_list->getSelection()); - package_list->Refresh(); +void PackagesWindow::onIdle(wxIdleEvent& ev) { + ev.RequestMore(!checkInstallerList()); } -void PackagesWindow::onApplyChanges(wxCommandEvent& ev) { - list to_install, to_remove; - - FOR_EACH(pack, update_version_data->packages) { - switch (package_data[pack].second) { - case ACTION_INSTALL: - to_install.push_back(pack); - break; - case ACTION_UPGRADE: - to_install.push_back(pack); - case ACTION_UNINSTALL: - to_remove.push_back(pack); - default:; - } +bool PackagesWindow::checkInstallerList() { + if (!waiting_for_list) return true; + if (!downloadable_installers.done()) return false; + waiting_for_list = false; + // merge installer lists + FOR_EACH(inst, downloadable_installers.installers) { + merge(installable_packages, inst); } - - FOR_EACH(pack, to_remove) { - String filename = packages.openAny(pack->name, true)->absoluteFilename(); - if (!remove_file_or_dir(filename)) { - handle_error(_("Cannot delete ") + filename + _(" to remove package ") + pack->name + _(". ") - _("Other packages may have been removed, including packages that this on is dependent on. Please remove manually.")); - } - } - - FOR_EACH(pack, to_install) { - wxURL url(pack->url); - wxInputStream* is = url.GetInputStream(); - if (!is) { - handle_error(_("Cannot fetch file ") + pack->url + _(" to install package ") + pack->name + _(". ") - _("Other packages may have been installed, including packages that depend on this one. ") - _("Please remove those packages manually or install this one manually.")); - } - wxString filename = wxFileName::CreateTempFileName(_("")); - wxFileOutputStream os (filename); - - os.Write(*is); - os.Close(); - - InstallerP inst(new Installer); - inst->open(filename); - inst->install(isInstallLocal(settings.install_type), false); - - delete is; - wxRemoveFile(filename); - } - - setDefaultPackageStatus(); - updateButtons(package_list->getSelection()); - package_list->Refresh(); - - handle_pending_errors(); - - packages.clearPackageCache(); + FOR_EACH(p, installable_packages) p->determineStatus(); + // refresh + package_list->rebuild(); + package_info->setPackage(package = package_list->getSelection()); + UpdateWindowUI(wxUPDATE_UI_RECURSE); + return true; } -void PackagesWindow::updateButtons(const PackageVersionDataP& pack) { - - description_window->SetPage(pack->description); - - PackageStatus status = package_data[pack].first; - PackageAction action = package_data[pack].second; - - if (action == ACTION_NEW_MSE) { - install_button->Disable(); - remove_button->Enable(status != STATUS_NOT_INSTALLED); - upgrade_button->Disable(); - cancel_button->Disable(); - } else if (status == STATUS_INSTALLED) { - install_button->Disable(); - remove_button->Enable(action != ACTION_UNINSTALL); - upgrade_button->Disable(); - cancel_button->Enable(action == ACTION_UNINSTALL); - } else if (status == STATUS_NOT_INSTALLED) { - install_button->Enable(action != ACTION_INSTALL); - remove_button->Disable(); - upgrade_button->Disable(); - cancel_button->Enable(action == ACTION_INSTALL); - } else /* status == STATUS_UPGRADEABLE * / { - install_button->Disable(); - remove_button->Enable(action != ACTION_UNINSTALL); - upgrade_button->Enable(action != ACTION_UPGRADE); - cancel_button->Enable(action != ACTION_NOTHING); - } -} - -void PackagesWindow::setDefaultPackageStatus() { - if (!update_version_data) return; - FOR_EACH(p, update_version_data->packages) { - PackagedP pack; - try { pack = packages.openAny(p->name, true); } - catch (PackageNotFoundError&) { } // We couldn't open a package... no cause for alarm - - if (!pack || !(wxFileExists(pack->absoluteFilename()) || wxDirExists(pack->absoluteFilename()))) { - // not installed - if (p->app_version > file_version) { - package_data[p] = PackageData(STATUS_NOT_INSTALLED, ACTION_NEW_MSE); - } else { - package_data[p] = PackageData(STATUS_NOT_INSTALLED, ACTION_NOTHING); - } - } else if (pack->version < p->version) { - // newer version - if (p->app_version > file_version) { - package_data[p] = PackageData(STATUS_UPGRADEABLE, ACTION_NEW_MSE); - } else { - package_data[p] = PackageData(STATUS_UPGRADEABLE, ACTION_UPGRADE); - } - } else { - package_data[p] = PackageData(STATUS_INSTALLED, ACTION_NOTHING); - } - } -} - -/// Select the dependencies for a package -/** - * \param pack The package data to check dependencies for. - * - * This function will select all the dependencies for the package, to ensure - * that the user can't install a package without it's dependencies. - * / -void PackagesWindow::SelectPackageDependencies (PackageVersionDataP pack) { - FOR_EACH(dep, pack->depends) { - if (packages.checkDependency(*dep, false)) //It's already installed. - continue; - FOR_EACH(p, update_version_data->packages) { - if (p->name == dep->package) { //We have a match. - if (p->version >= dep->version) { //Versions line up - - PackageStatus& status = package_data[p].first; - PackageAction& action = package_data[p].second; - if (status == STATUS_NOT_INSTALLED) - action = ACTION_INSTALL; - else if (status == STATUS_UPGRADEABLE) - action = ACTION_UPGRADE; - else //status == STATUS_INSTALLED - action = ACTION_NOTHING; - break; - } - } - } - // TODO: Decide what to do if a dependency can't be met. - // It shouldn't happen with a decently maintained updates list. - // But it could, and we need to decide what to do in this situation. - } -} - -/// This finds all packages that depend on the one provided and marks them for removal. -void PackagesWindow::RemovePackageDependencies (PackageVersionDataP pack) { - FOR_EACH(p, update_version_data->packages) { - FOR_EACH(dep, p->depends) { - if (pack->name == dep->package) { - PackageStatus& status = package_data[p].first; - PackageAction& action = package_data[p].second; - - if (status != STATUS_NOT_INSTALLED) - action = ACTION_UNINSTALL; - else // status == STATUS_NOT_INSTALLED - action = p->app_version > file_version ? ACTION_NEW_MSE : ACTION_NOTHING; - break; - } - } - } -} - -/// This deals with the complexities of a downgrade and its dependencies. -void PackagesWindow::DowngradePackageDependencies (PackageVersionDataP pack) { - PackagedP old_pack = packages.openAny(pack->name, true); - FOR_EACH(dep, old_pack->dependencies) { - // dependencies the old version has, but the new one might not. - if (packages.checkDependency(*dep, false)) //It's already installed. - continue; - FOR_EACH(p, update_version_data->packages) { - if (p->name == dep->package) { //We have a match. - if (p->version >= dep->version) { //Versions line up - if (p->app_version > file_version) //We can't install this - continue; - - PackageStatus& status = package_data[p].first; - PackageAction& action = package_data[p].second; - if (status == STATUS_NOT_INSTALLED) - action = ACTION_INSTALL; - else if (status == STATUS_UPGRADEABLE) - action = ACTION_UPGRADE; - break; - } - } - } - // TODO: Decide what to do if a dependency can't be met. - // It shouldn't happen with a decently maintained updates list. - // But it could, and we need to decide what to do in this situation. - // Ideally, some sort of error should occur, such that we don't have packages - // with unmet dependencies. - } - - FOR_EACH(p, update_version_data->packages) { - // dependencies that can no longer be met. - FOR_EACH(dep, p->depends) { - if (pack->name == dep->package) { - if (old_pack->version > dep->version) { - PackageStatus& status = package_data[p].first; - PackageAction& action = package_data[p].second; - - if (status != STATUS_NOT_INSTALLED) - action = ACTION_UNINSTALL; - else // status == STATUS_NOT_INSTALLED - action = p->app_version > file_version ? ACTION_NEW_MSE : ACTION_NOTHING; - break; - } - } - } - } -} -*/ - BEGIN_EVENT_TABLE(PackagesWindow, wxDialog) -// EVT_COMMAND(wxID_ANY, UPDATE_CHECK_FINISHED_EVT, PackagesWindow::onUpdateCheckFinished) EVT_LISTBOX(ID_PACKAGE_LIST, PackagesWindow::onPackageSelect) EVT_BUTTON(ID_INSTALL, PackagesWindow::onActionChange) EVT_BUTTON(ID_REMOVE, PackagesWindow::onActionChange) EVT_BUTTON(ID_UPGRADE, PackagesWindow::onActionChange) EVT_BUTTON(wxID_OK, PackagesWindow::onOk) EVT_UPDATE_UI(wxID_ANY, PackagesWindow::onUpdateUI) + EVT_IDLE ( PackagesWindow::onIdle) END_EVENT_TABLE() diff --git a/src/gui/packages_window.hpp b/src/gui/packages_window.hpp index 06d09f6d..b6bd06dd 100644 --- a/src/gui/packages_window.hpp +++ b/src/gui/packages_window.hpp @@ -44,13 +44,17 @@ class PackagesWindow : public wxDialog { InstallablePackageP package; ///< Selected package PackageAction where; ///< Where to install? (PACKAGE_LOCAL or PACKAGE_GLOBAL) + bool waiting_for_list; ///< waiting for the list of installers? + DECLARE_EVENT_TABLE(); void onOk(wxCommandEvent&); void onActionChange(wxCommandEvent&); void onPackageSelect(wxCommandEvent&); void onUpdateUI(wxUpdateUIEvent&); + void onIdle(wxIdleEvent&); + bool checkInstallerList(); /* wxHtmlWindow* description_window; diff --git a/src/gui/update_checker.cpp b/src/gui/update_checker.cpp index 85105735..ab0e33ed 100644 --- a/src/gui/update_checker.cpp +++ b/src/gui/update_checker.cpp @@ -14,49 +14,16 @@ #include #include #include -#include