diff -r 2b9f54d14cc2 -r 4af9b57a647f plover-gtk/transactionhelper.c --- a/plover-gtk/transactionhelper.c Sat Nov 15 19:04:45 2014 +0000 +++ b/plover-gtk/transactionhelper.c Mon Jun 13 10:35:50 2016 +0100 @@ -31,6 +31,23 @@ G_DEFINE_TYPE(PloverTransactionHelper,plover_transaction_helper,G_TYPE_OBJECT) +enum plover_transaction_type { + TRANSACTION_TYPE_NULL=0, + TRANSACTION_TYPE_INSTALL=1UL<<0, + TRANSACTION_TYPE_REMOVE=1UL<<1, + TRANSACTION_TYPE_UPDATE=TRANSACTION_TYPE_INSTALL|TRANSACTION_TYPE_REMOVE +}; + +typedef struct _PloverTransactionHelperPrivate { + enum plover_transaction_type transaction_type; + gchar *default_prefix; +} PloverTransactionHelperPrivate; + +#define PLOVER_TRANSACTION_HELPER_GET_PRIVATE(obj)\ + G_TYPE_INSTANCE_GET_PRIVATE(obj,\ + PLOVER_TYPE_TRANSACTION_HELPER,\ + PloverTransactionHelperPrivate) + enum { CLOSE=0, N_SIGNALS @@ -40,6 +57,9 @@ static void plover_transaction_helper_finalize(PloverTransactionHelper *helper) { + PloverTransactionHelperPrivate *priv; + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); + g_free(priv->default_prefix); g_free(helper->error_primary_text); g_free(helper->base); g_free(helper->unsatisfied); @@ -80,6 +100,7 @@ (void (*)(GObject *))plover_transaction_helper_finalize; gobject_class->dispose= (void (*)(GObject *))plover_transaction_helper_dispose; + g_type_class_add_private(klass,sizeof(PloverTransactionHelperPrivate)); signals[CLOSE]=g_signal_newv("close", G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL, g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL); @@ -185,6 +206,12 @@ } else plover_transaction_helper_run(helper); + /* + * There may be status updates queued by transaction as idle events. + * Process them now before we disconnect so that we don't lose them. + */ + while(g_main_context_pending(NULL)) + g_main_context_iteration(NULL,FALSE); g_signal_handlers_disconnect_by_data(transaction,helper); g_object_unref(transaction); } @@ -248,11 +275,35 @@ GError *error=NULL; GtkToggleButton *button; PloverTransaction *transaction; + GSList *save_transactions; + PloverTransactionHelperPrivate *priv; + enum plover_transaction_type save_transaction_type; + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); button=GTK_TOGGLE_BUTTON(gtk_builder_get_object(helper->ui, "SIRemoveExisting")); if (gtk_toggle_button_get_active(button)) { transaction=plover_transaction_new_remove(NULL,&error); + if (transaction) + { + save_transactions=helper->transactions; + helper->transactions=NULL; + save_transaction_type=priv->transaction_type; + priv->transaction_type=0; + if (!plover_transaction_helper_add_transaction(helper,transaction, + NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,&error)) + { + g_object_unref(transaction); + transaction=NULL; + helper->transactions=save_transactions; + priv->transaction_type=save_transaction_type; + } + else + { + g_slist_foreach(save_transactions,(GFunc)g_object_unref,NULL); + g_slist_free(save_transactions); + } + } if (!transaction) { if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT)) @@ -260,14 +311,11 @@ if (error) { plover_transaction_helper_set_error(helper,error, - "Software installation failed"); + "Failed to remove existing packages"); g_error_free(error); return; } } - else - helper->transactions= - g_slist_prepend(helper->transactions,transaction); } /* * Note that PloverTransaction does support cancelling a transaction, but @@ -427,71 +475,15 @@ GError **error) { const char *base; -#if 0 - const char *prefix; - struct razor_relocations *relocations=NULL; -#endif g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); if (!helper->upstream) { -#if 0 - prefix=plover_transaction_helper_get_prefix(helper,error); - if (!prefix) - return NULL; -#endif base=plover_transaction_helper_get_base(helper); -#if 0 - if (prefix) - { - relocations=razor_relocations_create(); - razor_relocations_add(relocations,"/usr",prefix); - } -#endif helper->upstream=plover_repository_new_from_yum(base,error); -#if 0 - if (relocations) - razor_relocations_destroy(relocations); -#endif } return helper->upstream; } -static PloverPackageSet *plover_transaction_helper_get_relocated_upstream( - PloverTransactionHelper *helper,GError **error) -{ - const char *prefix; - struct razor_relocations *relocations=NULL; - GError *tmp_error=NULL; - PloverRepository *upstream; - PloverPackageSet *set; - if (!helper->relocated_upstream) - { - upstream=plover_transaction_helper_get_upstream(helper,error); - if (!upstream) - return NULL; - prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); - if (tmp_error) - { - g_propagate_error(error,tmp_error); - return NULL; - } - set=plover_repository_get_package_set(upstream); - if (prefix) - { - relocations=razor_relocations_create(); - razor_relocations_add(relocations,"/usr",prefix); - helper->relocated_upstream= - plover_package_set_new_from_repository(upstream,relocations, - error); - if (relocations) - razor_relocations_destroy(relocations); - } - else - helper->relocated_upstream=g_object_ref(set); - } - return helper->relocated_upstream; -} - void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper, PloverRepository *upstream) { @@ -541,14 +533,18 @@ { const char *prefix; struct comps *comps; + PloverTransactionHelperPrivate *priv; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL); + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); if (helper->base) { comps=plover_transaction_helper_get_comps(helper,error); if (!comps) return NULL; - return plover_default_prefix_for_vendor(comps->vendor); + g_free(priv->default_prefix); + priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor); + return priv->default_prefix; } prefix=plover_package_set_guess_prefix(helper->installed,error); return prefix; @@ -583,7 +579,7 @@ int i; gchar *prefix=NULL,*s; struct comps *comps=NULL; - GtkWidget *container,*page; + GtkWidget *container,*summary,*page; GtkButton *button; GtkLabel *label; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); @@ -598,6 +594,7 @@ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE); container=GTK_WIDGET(gtk_builder_get_object(helper->ui, "SIIncompatibleInstallation")); + summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork")); page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm")); if (helper->check_vendor && prefix && !plover_installed_files_match_prefix(prefix)) @@ -615,15 +612,18 @@ gtk_button_set_label(button,s); g_free(s); gtk_widget_show(container); + gtk_widget_hide(summary); if (helper->assistant) gtk_assistant_set_page_complete(helper->assistant,page,FALSE); } else { gtk_widget_hide(container); + gtk_widget_show(summary); if (helper->assistant) gtk_assistant_set_page_complete(helper->assistant,page,TRUE); } + g_free(prefix); return TRUE; } @@ -653,22 +653,31 @@ return helper->unsatisfied; } +#define PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(action) \ + ((action)==PLOVER_TRANSACTION_HELPER_REPORT_INSTALL || \ + (action)==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE || \ + (action)==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) + gboolean plover_transaction_helper_add_transaction(PloverTransactionHelper *helper, PloverTransaction *transaction,struct plover_vector *report_packages, - enum razor_install_action report_action,GError **error) + PloverTransactionHelperReportAction report_action,GError **error) { int i,count; gboolean other_packages; const char *s,*name; enum razor_install_action action; struct razor_install_iterator *ii; - struct razor_set *next; + struct razor_set *report_set; struct razor_package *package; struct plover_vector *tasked_packages; + PloverTransactionHelperPrivate *priv; + GtkWidget *w; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE); - g_return_val_if_fail(report_action==RAZOR_INSTALL_ACTION_ADD || report_action==RAZOR_INSTALL_ACTION_REMOVE,FALSE); + g_return_val_if_fail(PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(report_action),FALSE); + g_return_val_if_fail(plover_transaction_get_system_set(transaction)!=NULL,FALSE); + priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper); g_free(helper->unsatisfied); helper->unsatisfied=NULL; if (!plover_transaction_resolve(transaction,error)) @@ -680,17 +689,21 @@ ii=plover_transaction_get_install_iterator(transaction,error); if (!ii) return FALSE; - next=plover_transaction_get_next_set(transaction,error); - if (!next) + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE) + report_set=plover_transaction_get_system_set(transaction); + else + report_set=plover_transaction_get_next_set(transaction,error); + if (!report_set) return FALSE; tasked_packages=plover_vector_new(); other_packages=FALSE; while (razor_install_iterator_next(ii,&package,&action,&count)) { - if (action==report_action) + if (action==report_action || action==RAZOR_INSTALL_ACTION_ADD && + report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) { - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name, - RAZOR_DETAIL_LAST); + razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME, + &name,RAZOR_DETAIL_LAST); if (!report_packages || plover_vector_contains(report_packages,name)) plover_vector_append(tasked_packages,name); @@ -710,8 +723,8 @@ { if (action==report_action) { - razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name, - RAZOR_DETAIL_LAST); + razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME, + &name,RAZOR_DETAIL_LAST); plover_vector_append(tasked_packages,name); } } @@ -720,7 +733,8 @@ { g_set_error(error,PLOVER_GENERAL_ERROR, PLOVER_GENERAL_ERROR_NO_WORK,"Transaction includes no %s actions", - report_action==RAZOR_INSTALL_ACTION_ADD?"add":"remove"); + report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE? + "remove":"add"); plover_vector_free(tasked_packages); return FALSE; } @@ -728,8 +742,22 @@ plover_transaction_helper_check_vendor(helper,error); g_object_ref(transaction); helper->transactions=g_slist_append(helper->transactions,transaction); - if (report_action==RAZOR_INSTALL_ACTION_ADD) + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE) { + priv->transaction_type|=TRANSACTION_TYPE_REMOVE; + for(i=0;ilen;i++) + { + s=tasked_packages->strings[i]; + if (!plover_vector_contains(helper->report_removing,s)) + plover_vector_append(helper->report_removing,s); + } + helper->report_removing_dependants|=other_packages; + } + else + { + if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE) + priv->transaction_type|=TRANSACTION_TYPE_REMOVE; + priv->transaction_type|=TRANSACTION_TYPE_INSTALL; for(i=0;ilen;i++) { s=tasked_packages->strings[i]; @@ -738,15 +766,31 @@ } helper->report_adding_dependencies|=other_packages; } - else + w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgressLabel")); + switch(priv->transaction_type) { - for(i=0;ilen;i++) - { - s=tasked_packages->strings[i]; - if (!plover_vector_contains(helper->report_removing,s)) - plover_vector_append(helper->report_removing,s); - } - helper->report_removing_dependants|=other_packages; + case TRANSACTION_TYPE_INSTALL: + gtk_label_set_markup(GTK_LABEL(w), + "Installing the Software\n\n" + "Please wait while the Installation Assistant " + "installs the software.\n" + "This may take several minutes."); + break; + case TRANSACTION_TYPE_REMOVE: + gtk_label_set_markup(GTK_LABEL(w), + "Removing Packages\n\n" + "Please wait while the Installation Assistant " + "removes packages.\n" + "This may take several minutes."); + break; + default: + case TRANSACTION_TYPE_UPDATE: + gtk_label_set_markup(GTK_LABEL(w), + "Updating the Software\n\n" + "Please wait while the Installation Assistant " + "updates the software.\n" + "This may take several minutes."); + break; } plover_vector_free(tasked_packages); return TRUE; @@ -761,6 +805,7 @@ GError *tmp_error=NULL; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL); + g_return_val_if_fail(helper->installed != NULL,NULL); prefix=plover_transaction_helper_get_prefix(helper,&tmp_error); if (tmp_error) { @@ -814,7 +859,7 @@ continue; if (pkg->type==COMPS_REQUIREMENT_DEFAULT || pkg->type==COMPS_REQUIREMENT_MANDATORY || - pkg->type==COMPS_REQUIREMENT_CONDITIONAL && + pkg->type==COMPS_REQUIREMENT_CONDITIONAL && pkg->requires && plover_vector_contains(default_packages,pkg->requires)) { changed=TRUE; @@ -852,7 +897,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - packages,RAZOR_INSTALL_ACTION_ADD,error); + packages,PLOVER_TRANSACTION_HELPER_REPORT_INSTALL,error); g_object_unref(transaction); return retval; } @@ -896,6 +941,7 @@ struct plover_vector *selected_packages; PloverTransaction *transaction; g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE); + g_return_val_if_fail(helper->installed != NULL,FALSE); selected_packages=plover_transaction_helper_group_get_default_packages( helper,group,error); if (!selected_packages) @@ -917,7 +963,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - NULL,RAZOR_INSTALL_ACTION_REMOVE,error); + NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,error); g_object_unref(transaction); plover_vector_free(selected_packages); return retval; @@ -942,7 +988,7 @@ return FALSE; } retval=plover_transaction_helper_add_transaction(helper,transaction, - NULL,RAZOR_INSTALL_ACTION_ADD,error); + NULL,PLOVER_TRANSACTION_HELPER_REPORT_UPDATE,error); g_object_unref(transaction); return retval; }