diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index a57c3c10..fc8d5ebc 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -526,12 +526,14 @@ button: close: &Close # Packages window - install package: &Install - upgrade package: &Upgrade - remove package: &Remove - install group: &Install All - upgrade group: &Upgrade All - remove group: &Remove All + keep package: &Don't change + don't install package: &Don't install + install package: &Install + upgrade package: &Upgrade + remove package: &Remove + install group: &Install All + upgrade group: &Upgrade All + remove group: &Remove All ############################################################## Titles in the GUI title: @@ -715,6 +717,9 @@ error: Removing them can not be undone. Do you want to continue? + install packages successful: %s package(s) were successfully installed. + remove packages successful: %s package(s) were successfully removed. + change packages successful: %s package(s) were successfully changed. cannot create file: Can not create file '%s', continue installation? diff --git a/src/data/installer.cpp b/src/data/installer.cpp index 10aa64a0..0239d0e8 100644 --- a/src/data/installer.cpp +++ b/src/data/installer.cpp @@ -306,6 +306,9 @@ bool InstallablePackage::can(PackageAction act) const { } return ok; } + if (act & PACKAGE_NOTHING) { + return true; + } else return false; } bool InstallablePackage::has(PackageAction act) const { diff --git a/src/gui/packages_window.cpp b/src/gui/packages_window.cpp index 7902808d..a3bd16ea 100644 --- a/src/gui/packages_window.cpp +++ b/src/gui/packages_window.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include DECLARE_POINTER_TYPE(Installer); @@ -156,6 +158,10 @@ END_EVENT_TABLE() // ----------------------------------------------------------------------------- : PackagesWindow +enum Action { + KEEP, INSTALL, UPGRADE, REMOVE +}; + PackagesWindow::PackagesWindow(Window* parent, bool download_package_list) : waiting_for_list(download_package_list) { @@ -169,7 +175,12 @@ PackagesWindow::PackagesWindow(Window* parent, const InstallerP& installer) init(parent, true); // add installer merge(installable_packages, new_intrusive1(installer)); - // TODO: mark all packages in the installer for installation + // mark all packages in the installer for installation + FOR_EACH(p, installable_packages) { + if (p->installer) { + set_package_action(installable_packages, p, PACKAGE_INSTALL | where); + } + } // update window package_list->rebuild(); package_list->expandAll(); @@ -191,10 +202,16 @@ void PackagesWindow::init(Window* parent, bool show_only_installable) { package_list = new PackageUpdateList(this, installable_packages, show_only_installable, ID_PACKAGE_LIST); package_info = new PackageInfoPanel(this); - //wxToolbar* buttons = new wxToolbar - 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")); + wxToggleButton* keep_button = new wxToggleButton(this, ID_KEEP, _BUTTON_("keep package")); + wxToggleButton* install_button = new wxToggleButton(this, ID_INSTALL, _BUTTON_("install package")); + wxToggleButton* upgrade_button = new wxToggleButton(this, ID_UPGRADE, _BUTTON_("upgrade package")); + wxToggleButton* remove_button = new wxToggleButton(this, ID_REMOVE, _BUTTON_("remove package")); + /* + wxRadioButton* keep_button = new wxRadioButton(this, ID_KEEP, _BUTTON_("keep package")); + wxRadioButton* install_button = new wxRadioButton(this, ID_INSTALL, _BUTTON_("install package")); + wxRadioButton* upgrade_button = new wxRadioButton(this, ID_UPGRADE, _BUTTON_("upgrade package")); + wxRadioButton* remove_button = new wxRadioButton(this, ID_REMOVE, _BUTTON_("remove package")); + */ // Init sizer wxBoxSizer* v = new wxBoxSizer(wxVERTICAL); @@ -203,15 +220,19 @@ void PackagesWindow::init(Window* parent, bool show_only_installable) { wxBoxSizer* h = new wxBoxSizer(wxHORIZONTAL); h->Add(package_info, 1, wxRIGHT, 4); wxBoxSizer* v2 = new wxBoxSizer(wxVERTICAL); - v2->Add(install_button, 0, wxEXPAND | wxBOTTOM, 4); - v2->Add(upgrade_button, 0, wxEXPAND | wxBOTTOM, 4); - v2->Add(remove_button, 0, wxEXPAND | wxBOTTOM, 4); + v2->Add(keep_button, 0, wxEXPAND | wxBOTTOM, 4); v2->AddStretchSpacer(); + v2->Add(install_button, 0, wxEXPAND | wxBOTTOM, 4); + v2->AddStretchSpacer(); + v2->Add(upgrade_button, 0, wxEXPAND | wxBOTTOM, 4); + v2->AddStretchSpacer(); + v2->Add(remove_button, 0, wxEXPAND | wxBOTTOM, 0); h->Add(v2); v->Add(h, 0, wxEXPAND | wxALL & ~wxTOP, 8); v->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxALL & ~wxTOP, 8); SetSizer(v); + wxUpdateUIEvent::SetMode(wxUPDATE_UI_PROCESS_SPECIFIED); UpdateWindowUI(wxUPDATE_UI_RECURSE); } @@ -231,12 +252,8 @@ void PackagesWindow::onActionChange(wxCommandEvent& ev) { : ev.GetId() == ID_REMOVE ? PACKAGE_REMOVE : PACKAGE_NOTHING; act = act | where; - // toggle action - if (package->has(act)) { - set_package_action(installable_packages, package, PACKAGE_NOTHING | where); - } else { - set_package_action(installable_packages, package, act); - } + // set action + set_package_action(installable_packages, package, act); package_list->Refresh(false); UpdateWindowUI(wxUPDATE_UI_RECURSE); } @@ -244,12 +261,18 @@ void PackagesWindow::onActionChange(wxCommandEvent& ev) { void PackagesWindow::onOk(wxCommandEvent& ev) { // Do we need a new version of MSE first? + // count number of packages to change + int to_change = 0; + int to_download = 0; + FOR_EACH(ip, installable_packages) { + if (!ip->has(PACKAGE_NOTHING)) ++to_change; + if ((ip->action & PACKAGE_INSTALL) && ip->installer && !ip->installer->installer) ++to_download; + } // progress dialog - int total = (int)installable_packages.size(); wxProgressDialog progress( _TITLE_("installing updates"), - String::Format(_ERROR_("downloading updates"), 0, total), - 2*total, + String::Format(_ERROR_("downloading updates"), 0, to_download), + to_change + to_download, this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_SMOOTH ); @@ -258,11 +281,10 @@ void PackagesWindow::onOk(wxCommandEvent& ev) { // Download installers int package_pos = 0, step = 0; FOR_EACH(ip, installable_packages) { - ++package_pos; ++step; - if (!progress.Update(step, String::Format(_ERROR_("downloading updates"), package_pos, total))) { - return; // aborted - } if ((ip->action & PACKAGE_INSTALL) && ip->installer && !ip->installer->installer) { + if (!progress.Update(step++, String::Format(_ERROR_("downloading updates"), ++package_pos, to_download))) { + return; // aborted + } // download installer wxURL url(ip->installer->installer_url); wxInputStream* is = url.GetInputStream(); @@ -279,15 +301,27 @@ void PackagesWindow::onOk(wxCommandEvent& ev) { } } // Install stuff - package_pos = 0 ; + package_pos = 0; + int success = 0, install = 0, remove = 0; FOR_EACH(ip, installable_packages) { - ++package_pos; ++step; - if (!progress.Update(step, String::Format(_ERROR_("installing updates"), package_pos, total))) { + if (ip->has(PACKAGE_NOTHING)) continue; // package unchanged + if (!progress.Update(step++, String::Format(_ERROR_("installing updates"), ++package_pos, to_change))) { // don't allow abort. } - package_manager.install(*ip); + bool ok = package_manager.install(*ip); + if (ok) { + install += ip->has(PACKAGE_INSTALL) && !ip->installed; + remove += ip->has(PACKAGE_REMOVE); + success += 1; + } } // Done + progress.Update(step++); + wxMessageBox( + install == success ? _ERROR_1_("install packages successful",String()<SetValue(package && package->has(PACKAGE_NOTHING)); + w->Enable (package && package->can(PACKAGE_NOTHING | where)); + w->SetLabel(package && package->installed ? _BUTTON_("keep package") : _BUTTON_("don't install package")); + break; case ID_INSTALL: - ev.Check (package && package->has(PACKAGE_INSTALL | where) && !package->installed); - ev.Enable(package && package->can(PACKAGE_INSTALL | where) && !package->installed); + w->SetValue(package && package->has(PACKAGE_INSTALL | where) && !package->installed); + w->Enable (package && package->can(PACKAGE_INSTALL | where) && !package->installed); break; case ID_UPGRADE: - ev.Check (package && package->has(PACKAGE_INSTALL | where) && package->installed); - ev.Enable(package && package->can(PACKAGE_INSTALL | where) && package->installed); + w->SetValue(package && package->has(PACKAGE_INSTALL | where) && package->installed); + w->Enable (package && package->can(PACKAGE_INSTALL | where) && package->installed); break; case ID_REMOVE: - ev.Check (package && package->has(PACKAGE_REMOVE | where)); - ev.Enable(package && package->can(PACKAGE_REMOVE | where)); + w->SetValue(package && package->has(PACKAGE_REMOVE | where)); + w->Enable (package && package->can(PACKAGE_REMOVE | where)); + //w->SetLabel(package && package->... ? _BUTTON_("remove group") : _BUTTON_("remove package")); break; } // TODO: change labels to _BUTTON_("install group"), _BUTTON_("remove group"), _BUTTON_("upgrade group") @@ -338,9 +379,10 @@ bool PackagesWindow::checkInstallerList(bool refresh) { BEGIN_EVENT_TABLE(PackagesWindow, wxDialog) 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_TOGGLEBUTTON(ID_KEEP, PackagesWindow::onActionChange) + EVT_TOGGLEBUTTON(ID_INSTALL, PackagesWindow::onActionChange) + EVT_TOGGLEBUTTON(ID_REMOVE, PackagesWindow::onActionChange) + EVT_TOGGLEBUTTON(ID_UPGRADE, PackagesWindow::onActionChange) EVT_BUTTON(wxID_OK, PackagesWindow::onOk) EVT_UPDATE_UI(wxID_ANY, PackagesWindow::onUpdateUI) EVT_IDLE ( PackagesWindow::onIdle) diff --git a/src/resource/common/expected_locale_keys b/src/resource/common/expected_locale_keys index 6266c7f0..a2fe1f0f 100644 --- a/src/resource/common/expected_locale_keys +++ b/src/resource/common/expected_locale_keys @@ -1,6 +1,6 @@ # This file contains the keys expected to be in MSE locales # It was automatically generated by tools/locale/locale.pl -# Generated on Fri May 30 22:05:19 2008 +# Generated on Sat May 31 18:40:22 2008 action: add control point: 0 @@ -46,6 +46,7 @@ button: check updates: 0 close: 0 defaults: 0 + don't install package: 0 edit symbol: 0 enabled: 0 hide: 0 @@ -55,6 +56,7 @@ button: install group: optional, 0 install package: 0 keep old: 0 + keep package: 0 last opened set: 0 move down: 0 move up: 0 @@ -88,6 +90,7 @@ error: can't convert value: 3 can't download installer: 2 cannot create file: 1 + change packages successful: 1 checking updates failed: 0 coordinates for blending overlap: 0 dependency not given: 4 @@ -102,6 +105,7 @@ error: images used for blending must have the same size: 0 in function: 2 in parameter: 2 + install packages successful: 1 installing updates: 0 internal error: 1 newer version: 2 @@ -113,6 +117,7 @@ error: package too new: 4 remove packages: optional, 1 remove packages modified: optional, 2 + remove packages successful: 1 stylesheet and set refer to different game: 0 successful install: optional, 2 unable to open output file: 0 diff --git a/src/util/file_utils.cpp b/src/util/file_utils.cpp index 3715098f..3ac9dac5 100644 --- a/src/util/file_utils.cpp +++ b/src/util/file_utils.cpp @@ -56,18 +56,29 @@ class RecursiveDeleter : public wxDirTraverser { public: RecursiveDeleter(const String& start) { to_delete.push_back(start); + ok = true; } - ~RecursiveDeleter() { + + bool ok; + + void remove() { FOR_EACH_REVERSE(dir, to_delete) { - wxRmdir(dir); + if (!wxRmdir(dir)) { + ok = false; + handle_error(_("Cannot delete ") + dir + _("\n") + _("The remainder of the package has still been removed, if possible.\n") + _("Other packages may have been removed, including packages that this on is dependent on. Please remove manually.")); + } } } wxDirTraverseResult OnFile(const String& filename) { - if (!wxRemoveFile(filename)) - handle_error(_("Cannot delete ") + filename + _(". ") - _("The remainder of the package has still been removed, if possible.") + if (!wxRemoveFile(filename)) { + ok = false; + handle_error(_("Cannot delete ") + filename + _("\n") + _("The remainder of the package has still been removed, if possible.\n") _("Other packages may have been removed, including packages that this on is dependent on. Please remove manually.")); + } return wxDIR_CONTINUE; } wxDirTraverseResult OnDir(const String& dirname) { @@ -82,12 +93,15 @@ bool remove_file_or_dir(const String& name) { if (wxFileExists(name)) { return wxRemoveFile(name); } else if (wxDirExists(name)) { - wxDir dir(name); RecursiveDeleter rd(name); - dir.Traverse(rd); - return true; + { + wxDir dir(name); + dir.Traverse(rd); + } + rd.remove(); + return rd.ok; } else { - return false; + return true; } } diff --git a/src/util/file_utils.hpp b/src/util/file_utils.hpp index 2d722181..43431612 100644 --- a/src/util/file_utils.hpp +++ b/src/util/file_utils.hpp @@ -30,7 +30,7 @@ bool create_parent_dirs(const String& file); /// Remove the given file or directory /** It is not an error if the file doesn't exist. * Removes all files in a directory. - * Returns true if something was removed + * Returns true if the file is gone or was never there to begin with */ bool remove_file_or_dir(const String& file); diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index 7e618bdf..ee8d394c 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -199,7 +199,7 @@ InputStreamP Package::openIn(const String& file) { } else if (wxFileExists(filename) && it->second.zipEntry) { // a file in a zip archive // somebody in wx thought seeking was no longer needed, it now only works with the 'compatability constructor' - stream = new_shared2(filename, it->second.zipEntry->GetName()); + stream = new_shared2(filename, it->second.zipEntry->GetInternalName()); //stream = static_pointer_cast( // new_shared2(filename, it->second.zipEntry)); } else { diff --git a/src/util/io/package_manager.cpp b/src/util/io/package_manager.cpp index b06a55f3..19282c40 100644 --- a/src/util/io/package_manager.cpp +++ b/src/util/io/package_manager.cpp @@ -160,9 +160,9 @@ void PackageManager::findAllInstalledPackages(vector& packa sort(packages); } -void PackageManager::install(const InstallablePackage& package) { +bool PackageManager::install(const InstallablePackage& package) { bool install_local = package.action & PACKAGE_LOCAL; - (install_local ? local : global).install(package); + return (install_local ? local : global).install(package); } // ----------------------------------------------------------------------------- : PackageDirectory @@ -292,14 +292,14 @@ String PackageDirectory::databaseFile() { bool PackageDirectory::install(const InstallablePackage& package) { String n = name(package.description->name); if (package.action & PACKAGE_REMOVE) { - remove_file_or_dir(n); + if (!remove_file_or_dir(n)) return false; } else if (package.action & PACKAGE_INSTALL) { - remove_file_or_dir(n + _(".new")); + if (!remove_file_or_dir(n + _(".new"))) return false; bool ok = actual_install(package, n + _(".new")); if (!ok) return false; - move_ignored_files(n, n + _(".new")); - remove_file_or_dir(n); - rename_file_or_dir(n + _(".new"), n); + move_ignored_files(n, n + _(".new")); // copy over files from the old installed version to the new one + if (!remove_file_or_dir(n)) return false; + if (!rename_file_or_dir(n + _(".new"), n)) return false; } return true; } @@ -317,11 +317,11 @@ bool PackageDirectory::actual_install(const InstallablePackage& package, const S String file = it->first; if (!is_substr(file,0,name)) continue; // not the right package // correct filename - file = install_dir + file.substr(name.length()); - create_parent_dirs(file); + String local_file = install_dir + file.substr(name.length()); + create_parent_dirs(local_file); // copy file InputStreamP is = installer.openIn(file); - wxFileOutputStream os (install_dir + _("/") + file); + wxFileOutputStream os (local_file); if (!os.IsOk()) { int act = wxMessageBox(_ERROR_1_("cannot create file", file), _TITLE_("cannot create file"), wxICON_ERROR | wxYES_NO); if (act == wxNO) return false; @@ -329,6 +329,7 @@ bool PackageDirectory::actual_install(const InstallablePackage& package, const S os.Write(*is); } // update package database + // TODO: bless the package? return true; } diff --git a/src/util/io/package_manager.hpp b/src/util/io/package_manager.hpp index 5712940c..300e1fb8 100644 --- a/src/util/io/package_manager.hpp +++ b/src/util/io/package_manager.hpp @@ -151,8 +151,8 @@ class PackageManager { /// Get all installed packages void findAllInstalledPackages(vector& packages); - /// Install/uninstall a package - void install(const InstallablePackage& package); + /// Install/uninstall a package, returns success + bool install(const InstallablePackage& package); // --------------------------------------------------- : Packages on a server diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index 446e82cd..10358b57 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -240,6 +240,7 @@ enum ControlID { , ID_SHARPEN_AMOUNT // Updates window , ID_PACKAGE_LIST +, ID_KEEP , ID_INSTALL , ID_UPGRADE , ID_REMOVE