// packages.cc - class for working with packages, pkg_list. // Copyright (C) 2000-2002 Laurynas Biveinis // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #include "packages.h" #include "kite.h" #include "scroldlg.h" #include #include #include #include #include #include #include #include #include #define Uses_TButton #define Uses_TDeskTop #define Uses_TDialog #define Uses_TProgram #define Uses_TRect #define Uses_TStaticText #include pkg_list::pkg_list(const char * dj_dir, const char * zip_dir, const log_file & where_to_log) : log(&where_to_log), packages(NULL) { // Possible directories to find DJGPP packages. Includes current // directory and SimtelNet directory structure. char * search_paths[] = { "./", "v2/", "v2apps/", "v2gnu/", "v2misc/", "v2tk/", "../v2apps/", "../v2gnu/", "../v2misc/", "../v2tk/", NULL }; struct ffblk file_info; char current_path[FILENAME_MAX + 1]; char archive_name[FILENAME_MAX + 1]; PACKAGE_INFO * package = NULL; DSM_ERROR * dsm_errors = NULL; DSM_FILE_ERROR * dsm_file_errors = NULL; wait_box * wait_dialog = new wait_box("Scanning packages..."); // Add platform DSMs char *dsm_path = new char[FILENAME_MAX + 1]; strcpy(dsm_path, dj_dir); strcat(dsm_path, "share/pakke/db"); packages = dsm_load_dir(dsm_path, packages, &dsm_file_errors); char ** path_suffix = &search_paths[0]; while (*path_suffix) { strcpy(current_path, zip_dir); strcat(current_path, *path_suffix); strcpy(dsm_path, current_path); packages = dsm_load_dir(dsm_path, packages, &dsm_file_errors); strcat(current_path, "*.zip"); log->print_log("Searching for packages in %s\n", current_path); int done = findfirst(current_path, &file_info, FA_RDONLY | FA_ARCH); while (!done) { strcpy(archive_name, zip_dir); strcat(archive_name, *path_suffix); strcat(archive_name, file_info.ff_name); log->print_log("Package found: %s\n", archive_name); if (dsm_get_and_parse(archive_name, package, NULL, &dsm_errors)) { log->print_log("Warning! DSM extraction from %s failed.\n", archive_name); dsm_free_error_list(dsm_errors); package_free(package); } else { package->q_forw = packages; package->q_back = NULL; if (packages) packages->q_back = package; packages = package; } done = findnext(&file_info); } path_suffix++; } packlist_xref(packages); packlist_dedupe(packages); delete wait_dialog; } pkg_list::~pkg_list(void) { packlist_free(packages); } void pkg_list::install(void) { pkg_dialog * dialog = new pkg_dialog(packages); TProgram::deskTop->execView(dialog); destroy(dialog); } pkg_list::pkg_checkbox::pkg_checkbox(PACKAGE_INFO * package) : TCheckBoxes(TRect(0, 0, 0, 0), // Bounds will be set later new TSItem(package->short_description, NULL)), pkg(package) { // Link package information and its checkbox. It is used to update // status of other checkboxes according to dependencies of packages. pkg->info = this; } void pkg_list::pkg_checkbox::press(int item) { TCheckBoxes::press(item); // When user checks a checkbox of current package, also mark for // installation all its 'required' dependencies. // If user unchecks it, uncheck it only if all deps are still met. } // Titles for each package group static char * titles[] = {"", // TYPE_NONE " Binaries ---------- ", // TYPE_BINARIES " Sources ----------- ", // TYPE_SOURCES " Documentation ----- ", // TYPE_DOCUMENTATION "", // TYPE_VIRTUAL " Task selections --- "};// TYPE_GROUP pkg_list::pkg_dialog::pkg_dialog(PACKAGE_INFO * list) : scroll_dialog(TProgram::deskTop->getExtent(), "Packages selection"), TWindowInit(&TDialog::initFrame), packages(list) { insert_scroll_group(new scrollable_group( TRect(2, 2, size.x / 4 * 3, size.y / 4 * 3))); // Create a checkbox list of available packages. // Group DSM go first insert_packages(TYPE_GROUP); insert_packages(TYPE_BINARIES); insert_packages(TYPE_DOCUMENTATION); insert_packages(TYPE_SOURCES); insert(new TButton(TRect(2, size.y / 4 * 3 + 2, 12, size.y / 4 * 3 + 4), "~O~K", cmOK, bfDefault)); selectNext(False); } void pkg_list::pkg_dialog::handleEvent(TEvent & event) { scroll_dialog::handleEvent(event); } int pkg_list::pkg_dialog::list_browser(PACKAGE_INFO * pkg, void * info) { struct info * inf = (struct info *)info; if (pkg->version.type == inf->type) { if (!inf->encountered) { int i; switch (inf->type) { case TYPE_NONE: i = 0; break; case TYPE_BINARIES: i = 1; break; case TYPE_SOURCES: i = 2; break; case TYPE_DOCUMENTATION: i = 3; break; case TYPE_VIRTUAL: i = 4; break; case TYPE_GROUP: i = 5; break; default: /* Huh? */ i = 0; break; } inf->dialog->fill_next_row(new TStaticText(TRect(0, 0, 0, 0), titles[i])); inf->encountered = 1; }; inf->dialog->fill_next_row(new pkg_list::pkg_checkbox(pkg)); } return 0; }