plover-gtk/transactionhelper.c
changeset 39 4af9b57a647f
parent 24 2b9f54d14cc2
child 42 419a02fa70db
     1.1 --- a/plover-gtk/transactionhelper.c	Sat Nov 15 19:04:45 2014 +0000
     1.2 +++ b/plover-gtk/transactionhelper.c	Mon Jun 13 10:35:50 2016 +0100
     1.3 @@ -31,6 +31,23 @@
     1.4  
     1.5  G_DEFINE_TYPE(PloverTransactionHelper,plover_transaction_helper,G_TYPE_OBJECT)
     1.6  
     1.7 +enum plover_transaction_type {
     1.8 +    TRANSACTION_TYPE_NULL=0,
     1.9 +    TRANSACTION_TYPE_INSTALL=1UL<<0,
    1.10 +    TRANSACTION_TYPE_REMOVE=1UL<<1,
    1.11 +    TRANSACTION_TYPE_UPDATE=TRANSACTION_TYPE_INSTALL|TRANSACTION_TYPE_REMOVE
    1.12 +};
    1.13 +
    1.14 +typedef struct _PloverTransactionHelperPrivate {
    1.15 +    enum plover_transaction_type transaction_type;
    1.16 +    gchar *default_prefix;
    1.17 +} PloverTransactionHelperPrivate;
    1.18 +
    1.19 +#define PLOVER_TRANSACTION_HELPER_GET_PRIVATE(obj)\
    1.20 +                                G_TYPE_INSTANCE_GET_PRIVATE(obj,\
    1.21 +				  PLOVER_TYPE_TRANSACTION_HELPER,\
    1.22 +				  PloverTransactionHelperPrivate)
    1.23 +
    1.24  enum {
    1.25      CLOSE=0,
    1.26      N_SIGNALS
    1.27 @@ -40,6 +57,9 @@
    1.28  
    1.29  static void plover_transaction_helper_finalize(PloverTransactionHelper *helper)
    1.30  {
    1.31 +    PloverTransactionHelperPrivate *priv;
    1.32 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
    1.33 +    g_free(priv->default_prefix);
    1.34      g_free(helper->error_primary_text);
    1.35      g_free(helper->base);
    1.36      g_free(helper->unsatisfied);
    1.37 @@ -80,6 +100,7 @@
    1.38        (void (*)(GObject *))plover_transaction_helper_finalize;
    1.39      gobject_class->dispose=
    1.40        (void (*)(GObject *))plover_transaction_helper_dispose;
    1.41 +    g_type_class_add_private(klass,sizeof(PloverTransactionHelperPrivate));
    1.42      signals[CLOSE]=g_signal_newv("close",
    1.43        G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
    1.44        g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
    1.45 @@ -185,6 +206,12 @@
    1.46      }
    1.47      else
    1.48  	plover_transaction_helper_run(helper);
    1.49 +    /*
    1.50 +     * There may be status updates queued by transaction as idle events.
    1.51 +     * Process them now before we disconnect so that we don't lose them.
    1.52 +     */
    1.53 +    while(g_main_context_pending(NULL))
    1.54 +	g_main_context_iteration(NULL,FALSE);
    1.55      g_signal_handlers_disconnect_by_data(transaction,helper);
    1.56      g_object_unref(transaction);
    1.57  }
    1.58 @@ -248,11 +275,35 @@
    1.59      GError *error=NULL;
    1.60      GtkToggleButton *button;
    1.61      PloverTransaction *transaction;
    1.62 +    GSList *save_transactions;
    1.63 +    PloverTransactionHelperPrivate *priv;
    1.64 +    enum plover_transaction_type save_transaction_type;
    1.65 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
    1.66      button=GTK_TOGGLE_BUTTON(gtk_builder_get_object(helper->ui,
    1.67        "SIRemoveExisting"));
    1.68      if (gtk_toggle_button_get_active(button))
    1.69      {
    1.70  	transaction=plover_transaction_new_remove(NULL,&error);
    1.71 +	if (transaction)
    1.72 +	{
    1.73 +	    save_transactions=helper->transactions;
    1.74 +	    helper->transactions=NULL;
    1.75 +	    save_transaction_type=priv->transaction_type;
    1.76 +	    priv->transaction_type=0;
    1.77 +	    if (!plover_transaction_helper_add_transaction(helper,transaction,
    1.78 +	      NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,&error))
    1.79 +	    {
    1.80 +		g_object_unref(transaction);
    1.81 +		transaction=NULL;
    1.82 +		helper->transactions=save_transactions;
    1.83 +		priv->transaction_type=save_transaction_type;
    1.84 +	    }
    1.85 +	    else
    1.86 +	    {
    1.87 +		g_slist_foreach(save_transactions,(GFunc)g_object_unref,NULL);
    1.88 +		g_slist_free(save_transactions);
    1.89 +	    }
    1.90 +	}
    1.91  	if (!transaction)
    1.92  	{
    1.93  	    if (g_error_matches(error,PLOVER_POSIX_ERROR,ENOENT))
    1.94 @@ -260,14 +311,11 @@
    1.95  	    if (error)
    1.96  	    {
    1.97  		plover_transaction_helper_set_error(helper,error,
    1.98 -		  "Software installation failed");
    1.99 +		  "Failed to remove existing packages");
   1.100  		g_error_free(error);
   1.101  		return;
   1.102  	    }
   1.103  	}
   1.104 -	else
   1.105 -	    helper->transactions=
   1.106 -	      g_slist_prepend(helper->transactions,transaction);
   1.107      }
   1.108      /*
   1.109       * Note that PloverTransaction does support cancelling a transaction, but
   1.110 @@ -427,71 +475,15 @@
   1.111    GError **error)
   1.112  {
   1.113      const char *base;
   1.114 -#if 0
   1.115 -    const char *prefix;
   1.116 -    struct razor_relocations *relocations=NULL;
   1.117 -#endif
   1.118      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
   1.119      if (!helper->upstream)
   1.120      {
   1.121 -#if 0
   1.122 -	prefix=plover_transaction_helper_get_prefix(helper,error);
   1.123 -	if (!prefix)
   1.124 -	    return NULL;
   1.125 -#endif
   1.126  	base=plover_transaction_helper_get_base(helper);
   1.127 -#if 0
   1.128 -	if (prefix)
   1.129 -	{
   1.130 -	    relocations=razor_relocations_create();
   1.131 -	    razor_relocations_add(relocations,"/usr",prefix);
   1.132 -	}
   1.133 -#endif
   1.134  	helper->upstream=plover_repository_new_from_yum(base,error);
   1.135 -#if 0
   1.136 -	if (relocations)
   1.137 -	    razor_relocations_destroy(relocations);
   1.138 -#endif
   1.139      }
   1.140      return helper->upstream;
   1.141  }
   1.142  
   1.143 -static PloverPackageSet *plover_transaction_helper_get_relocated_upstream(
   1.144 -  PloverTransactionHelper *helper,GError **error)
   1.145 -{
   1.146 -    const char *prefix;
   1.147 -    struct razor_relocations *relocations=NULL;
   1.148 -    GError *tmp_error=NULL;
   1.149 -    PloverRepository *upstream;
   1.150 -    PloverPackageSet *set;
   1.151 -    if (!helper->relocated_upstream)
   1.152 -    {
   1.153 -	upstream=plover_transaction_helper_get_upstream(helper,error);
   1.154 -	if (!upstream)
   1.155 -	    return NULL;
   1.156 -	prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
   1.157 -	if (tmp_error)
   1.158 -	{
   1.159 -	    g_propagate_error(error,tmp_error);
   1.160 -	    return NULL;
   1.161 -	}
   1.162 -	set=plover_repository_get_package_set(upstream);
   1.163 -	if (prefix)
   1.164 -	{
   1.165 -	    relocations=razor_relocations_create();
   1.166 -	    razor_relocations_add(relocations,"/usr",prefix);
   1.167 -	    helper->relocated_upstream=
   1.168 -	      plover_package_set_new_from_repository(upstream,relocations,
   1.169 -	      error);
   1.170 -	    if (relocations)
   1.171 -		razor_relocations_destroy(relocations);
   1.172 -	}
   1.173 -	else
   1.174 -	    helper->relocated_upstream=g_object_ref(set);
   1.175 -    }
   1.176 -    return helper->relocated_upstream;
   1.177 -}
   1.178 -
   1.179  void plover_transaction_helper_set_upstream(PloverTransactionHelper *helper,
   1.180    PloverRepository *upstream)
   1.181  {
   1.182 @@ -541,14 +533,18 @@
   1.183  {
   1.184      const char *prefix;
   1.185      struct comps *comps;
   1.186 +    PloverTransactionHelperPrivate *priv;
   1.187      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
   1.188      g_return_val_if_fail(helper->base != NULL || helper->installed != NULL,NULL);
   1.189 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
   1.190      if (helper->base)
   1.191      {
   1.192  	comps=plover_transaction_helper_get_comps(helper,error);
   1.193  	if (!comps)
   1.194  	    return NULL;
   1.195 -	return plover_default_prefix_for_vendor(comps->vendor);
   1.196 +	g_free(priv->default_prefix);
   1.197 +	priv->default_prefix=plover_default_prefix_for_vendor(comps->vendor);
   1.198 +	return priv->default_prefix;
   1.199      }
   1.200      prefix=plover_package_set_guess_prefix(helper->installed,error);
   1.201      return prefix;
   1.202 @@ -583,7 +579,7 @@
   1.203      int i;
   1.204      gchar *prefix=NULL,*s;
   1.205      struct comps *comps=NULL;
   1.206 -    GtkWidget *container,*page;
   1.207 +    GtkWidget *container,*summary,*page;
   1.208      GtkButton *button;
   1.209      GtkLabel *label;
   1.210      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
   1.211 @@ -598,6 +594,7 @@
   1.212      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),FALSE);
   1.213      container=GTK_WIDGET(gtk_builder_get_object(helper->ui,
   1.214        "SIIncompatibleInstallation"));
   1.215 +    summary=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SISummaryOfWork"));
   1.216      page=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIConfirm"));
   1.217      if (helper->check_vendor && prefix &&
   1.218        !plover_installed_files_match_prefix(prefix))
   1.219 @@ -615,15 +612,18 @@
   1.220  	gtk_button_set_label(button,s);
   1.221  	g_free(s);
   1.222  	gtk_widget_show(container);
   1.223 +	gtk_widget_hide(summary);
   1.224  	if (helper->assistant)
   1.225  	    gtk_assistant_set_page_complete(helper->assistant,page,FALSE);
   1.226      }
   1.227      else
   1.228      {
   1.229  	gtk_widget_hide(container);
   1.230 +	gtk_widget_show(summary);
   1.231  	if (helper->assistant)
   1.232  	    gtk_assistant_set_page_complete(helper->assistant,page,TRUE);
   1.233      }
   1.234 +    g_free(prefix);
   1.235      return TRUE;
   1.236  }
   1.237  
   1.238 @@ -653,22 +653,31 @@
   1.239      return helper->unsatisfied;
   1.240  }
   1.241  
   1.242 +#define PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(action) \
   1.243 +  ((action)==PLOVER_TRANSACTION_HELPER_REPORT_INSTALL || \
   1.244 +  (action)==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE || \
   1.245 +  (action)==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
   1.246 +
   1.247  gboolean
   1.248    plover_transaction_helper_add_transaction(PloverTransactionHelper *helper,
   1.249    PloverTransaction *transaction,struct plover_vector *report_packages,
   1.250 -  enum razor_install_action report_action,GError **error)
   1.251 +  PloverTransactionHelperReportAction report_action,GError **error)
   1.252  {
   1.253      int i,count;
   1.254      gboolean other_packages;
   1.255      const char *s,*name;
   1.256      enum razor_install_action action;
   1.257      struct razor_install_iterator *ii;
   1.258 -    struct razor_set *next;
   1.259 +    struct razor_set *report_set;
   1.260      struct razor_package *package;
   1.261      struct plover_vector *tasked_packages;
   1.262 +    PloverTransactionHelperPrivate *priv;
   1.263 +    GtkWidget *w;
   1.264      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
   1.265      g_return_val_if_fail(PLOVER_IS_TRANSACTION(transaction),FALSE);
   1.266 -    g_return_val_if_fail(report_action==RAZOR_INSTALL_ACTION_ADD || report_action==RAZOR_INSTALL_ACTION_REMOVE,FALSE);
   1.267 +    g_return_val_if_fail(PLOVER_TRANSACTION_HELPER_IS_VALID_REPORT_ACTION(report_action),FALSE);
   1.268 +    g_return_val_if_fail(plover_transaction_get_system_set(transaction)!=NULL,FALSE);
   1.269 +    priv=PLOVER_TRANSACTION_HELPER_GET_PRIVATE(helper);
   1.270      g_free(helper->unsatisfied);
   1.271      helper->unsatisfied=NULL;
   1.272      if (!plover_transaction_resolve(transaction,error))
   1.273 @@ -680,17 +689,21 @@
   1.274      ii=plover_transaction_get_install_iterator(transaction,error);
   1.275      if (!ii)
   1.276  	return FALSE;
   1.277 -    next=plover_transaction_get_next_set(transaction,error);
   1.278 -    if (!next)
   1.279 +    if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE)
   1.280 +	report_set=plover_transaction_get_system_set(transaction);
   1.281 +    else
   1.282 +	report_set=plover_transaction_get_next_set(transaction,error);
   1.283 +    if (!report_set)
   1.284  	return FALSE;
   1.285      tasked_packages=plover_vector_new();
   1.286      other_packages=FALSE;
   1.287      while (razor_install_iterator_next(ii,&package,&action,&count))
   1.288      {
   1.289 -	if (action==report_action)
   1.290 +	if (action==report_action || action==RAZOR_INSTALL_ACTION_ADD &&
   1.291 +	  report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
   1.292  	{
   1.293 -	    razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
   1.294 -	      RAZOR_DETAIL_LAST);
   1.295 +	    razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME,
   1.296 +	      &name,RAZOR_DETAIL_LAST);
   1.297  	    if (!report_packages ||
   1.298  	      plover_vector_contains(report_packages,name))
   1.299  		plover_vector_append(tasked_packages,name);
   1.300 @@ -710,8 +723,8 @@
   1.301  	{
   1.302  	    if (action==report_action)
   1.303  	    {
   1.304 -		razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
   1.305 -		  RAZOR_DETAIL_LAST);
   1.306 +		razor_package_get_details(report_set,package,RAZOR_DETAIL_NAME,
   1.307 +		  &name,RAZOR_DETAIL_LAST);
   1.308  		plover_vector_append(tasked_packages,name);
   1.309  	    }
   1.310  	}
   1.311 @@ -720,7 +733,8 @@
   1.312      {
   1.313  	g_set_error(error,PLOVER_GENERAL_ERROR,
   1.314  	  PLOVER_GENERAL_ERROR_NO_WORK,"Transaction includes no %s actions",
   1.315 -	  report_action==RAZOR_INSTALL_ACTION_ADD?"add":"remove");
   1.316 +	  report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE?
   1.317 +	  "remove":"add");
   1.318  	plover_vector_free(tasked_packages);
   1.319  	return FALSE;
   1.320      }
   1.321 @@ -728,8 +742,22 @@
   1.322  	plover_transaction_helper_check_vendor(helper,error);
   1.323      g_object_ref(transaction);
   1.324      helper->transactions=g_slist_append(helper->transactions,transaction);
   1.325 -    if (report_action==RAZOR_INSTALL_ACTION_ADD)
   1.326 +    if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_REMOVE)
   1.327      {
   1.328 +	priv->transaction_type|=TRANSACTION_TYPE_REMOVE;
   1.329 +	for(i=0;i<tasked_packages->len;i++)
   1.330 +	{
   1.331 +	    s=tasked_packages->strings[i];
   1.332 +	    if (!plover_vector_contains(helper->report_removing,s))
   1.333 +		plover_vector_append(helper->report_removing,s);
   1.334 +	}
   1.335 +	helper->report_removing_dependants|=other_packages;
   1.336 +    }
   1.337 +    else
   1.338 +    {
   1.339 +	if (report_action==PLOVER_TRANSACTION_HELPER_REPORT_UPDATE)
   1.340 +	    priv->transaction_type|=TRANSACTION_TYPE_REMOVE;
   1.341 +	priv->transaction_type|=TRANSACTION_TYPE_INSTALL;
   1.342  	for(i=0;i<tasked_packages->len;i++)
   1.343  	{
   1.344  	    s=tasked_packages->strings[i];
   1.345 @@ -738,15 +766,31 @@
   1.346  	}
   1.347  	helper->report_adding_dependencies|=other_packages;
   1.348      }
   1.349 -    else
   1.350 +    w=GTK_WIDGET(gtk_builder_get_object(helper->ui,"SIProgressLabel"));
   1.351 +    switch(priv->transaction_type)
   1.352      {
   1.353 -	for(i=0;i<tasked_packages->len;i++)
   1.354 -	{
   1.355 -	    s=tasked_packages->strings[i];
   1.356 -	    if (!plover_vector_contains(helper->report_removing,s))
   1.357 -		plover_vector_append(helper->report_removing,s);
   1.358 -	}
   1.359 -	helper->report_removing_dependants|=other_packages;
   1.360 +	case TRANSACTION_TYPE_INSTALL:
   1.361 +	    gtk_label_set_markup(GTK_LABEL(w),
   1.362 +	      "<b>Installing the Software</b>\n\n"
   1.363 +	      "Please wait while the Installation Assistant "
   1.364 +	      "installs the software.\n"
   1.365 +	      "This may take several minutes.");
   1.366 +	    break;
   1.367 +	case TRANSACTION_TYPE_REMOVE:
   1.368 +	    gtk_label_set_markup(GTK_LABEL(w),
   1.369 +	      "<b>Removing Packages</b>\n\n"
   1.370 +	      "Please wait while the Installation Assistant "
   1.371 +	      "removes packages.\n"
   1.372 +	      "This may take several minutes.");
   1.373 +	    break;
   1.374 +	default:
   1.375 +	case TRANSACTION_TYPE_UPDATE:
   1.376 +	    gtk_label_set_markup(GTK_LABEL(w),
   1.377 +	      "<b>Updating the Software</b>\n\n"
   1.378 +	      "Please wait while the Installation Assistant "
   1.379 +	      "updates the software.\n"
   1.380 +	      "This may take several minutes.");
   1.381 +	    break;
   1.382      }
   1.383      plover_vector_free(tasked_packages);
   1.384      return TRUE;
   1.385 @@ -761,6 +805,7 @@
   1.386      GError *tmp_error=NULL;
   1.387      PloverTransaction *transaction;
   1.388      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),NULL);
   1.389 +    g_return_val_if_fail(helper->installed != NULL,NULL);
   1.390      prefix=plover_transaction_helper_get_prefix(helper,&tmp_error);
   1.391      if (tmp_error)
   1.392      {
   1.393 @@ -814,7 +859,7 @@
   1.394  		continue;
   1.395  	    if (pkg->type==COMPS_REQUIREMENT_DEFAULT ||
   1.396  	      pkg->type==COMPS_REQUIREMENT_MANDATORY ||
   1.397 -	      pkg->type==COMPS_REQUIREMENT_CONDITIONAL &&
   1.398 +	      pkg->type==COMPS_REQUIREMENT_CONDITIONAL && pkg->requires &&
   1.399  	      plover_vector_contains(default_packages,pkg->requires))
   1.400  	    {
   1.401  		changed=TRUE;
   1.402 @@ -852,7 +897,7 @@
   1.403  	return FALSE;
   1.404      }
   1.405      retval=plover_transaction_helper_add_transaction(helper,transaction,
   1.406 -      packages,RAZOR_INSTALL_ACTION_ADD,error);
   1.407 +      packages,PLOVER_TRANSACTION_HELPER_REPORT_INSTALL,error);
   1.408      g_object_unref(transaction);
   1.409      return retval;
   1.410  }
   1.411 @@ -896,6 +941,7 @@
   1.412      struct plover_vector *selected_packages;
   1.413      PloverTransaction *transaction;
   1.414      g_return_val_if_fail(PLOVER_IS_TRANSACTION_HELPER(helper),FALSE);
   1.415 +    g_return_val_if_fail(helper->installed != NULL,FALSE);
   1.416      selected_packages=plover_transaction_helper_group_get_default_packages(
   1.417        helper,group,error);
   1.418      if (!selected_packages)
   1.419 @@ -917,7 +963,7 @@
   1.420  	return FALSE;
   1.421      }
   1.422      retval=plover_transaction_helper_add_transaction(helper,transaction,
   1.423 -      NULL,RAZOR_INSTALL_ACTION_REMOVE,error);
   1.424 +      NULL,PLOVER_TRANSACTION_HELPER_REPORT_REMOVE,error);
   1.425      g_object_unref(transaction);
   1.426      plover_vector_free(selected_packages);
   1.427      return retval;
   1.428 @@ -942,7 +988,7 @@
   1.429  	return FALSE;
   1.430      }
   1.431      retval=plover_transaction_helper_add_transaction(helper,transaction,
   1.432 -      NULL,RAZOR_INSTALL_ACTION_ADD,error);
   1.433 +      NULL,PLOVER_TRANSACTION_HELPER_REPORT_UPDATE,error);
   1.434      g_object_unref(transaction);
   1.435      return retval;
   1.436  }