Update-Installer/src/UpdateDialogGtk.cpp
Robert Knight 2c70cebd05 Make the GTK update dialog wider
gtk_window_set_default_size() has no effect when the dialog
is marked as non-resizable with gtk_window_set_resizable(),
so the minimum size is instead achieved by setting a minimum width
on the progress bar.
2011-08-29 20:20:42 +01:00

170 lines
4.6 KiB
C++

#include "UpdateDialogGtk.h"
#include "AppInfo.h"
#include "StringUtils.h"
#include <glib.h>
#include <gtk/gtk.h>
UpdateDialogGtk* update_dialog_gtk_new(int argc, char** argv)
{
UpdateDialogGtk* dialog = new UpdateDialogGtk;
dialog->init(argc,argv);
return dialog;
}
void update_dialog_gtk_exec(UpdateDialogGtk* dialog)
{
dialog->exec();
}
void update_dialog_gtk_handle_error(UpdateDialogGtk* dialog, const std::string& errorMessage)
{
dialog->updateError(errorMessage);
}
void update_dialog_gtk_handle_progress(UpdateDialogGtk* dialog, int percentage)
{
dialog->updateProgress(percentage);
}
void update_dialog_gtk_handle_finished(UpdateDialogGtk* dialog)
{
dialog->updateFinished();
}
UpdateDialogGtk::UpdateDialogGtk()
: m_hadError(false)
{
}
void UpdateDialogGtk::init(int argc, char** argv)
{
gtk_init(&argc,&argv);
m_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(m_window),AppInfo::name().c_str());
m_progressLabel = gtk_label_new("Installing Updates");
GtkWidget* windowLayout = gtk_vbox_new(FALSE,3);
GtkWidget* buttonLayout = gtk_hbox_new(FALSE,3);
GtkWidget* labelLayout = gtk_hbox_new(FALSE,3);
m_finishButton = gtk_button_new_with_label("Finish");
gtk_widget_set_sensitive(m_finishButton,false);
m_progressBar = gtk_progress_bar_new();
// give the dialog a sensible default size by setting a minimum
// width on the progress bar. This is used instead of setting
// a default size for the dialog since gtk_window_set_default_size()
// is ignored when a dialog is marked as non-resizable
gtk_widget_set_usize(m_progressBar,350,-1);
gtk_signal_connect(GTK_OBJECT(m_finishButton),"clicked",
GTK_SIGNAL_FUNC(UpdateDialogGtk::finish),this);
gtk_container_add(GTK_CONTAINER(m_window),windowLayout);
gtk_container_set_border_width(GTK_CONTAINER(m_window),12);
gtk_box_pack_start(GTK_BOX(labelLayout),m_progressLabel,false,false,0);
gtk_box_pack_end(GTK_BOX(buttonLayout),m_finishButton,false,false,0);
gtk_box_pack_start(GTK_BOX(windowLayout),labelLayout,false,false,0);
gtk_box_pack_start(GTK_BOX(windowLayout),m_progressBar,false,false,0);
gtk_box_pack_start(GTK_BOX(windowLayout),buttonLayout,false,false,0);
gtk_widget_show(m_progressLabel);
gtk_widget_show(labelLayout);
gtk_widget_show(windowLayout);
gtk_widget_show(buttonLayout);
gtk_widget_show(m_finishButton);
gtk_widget_show(m_progressBar);
gtk_window_set_resizable(GTK_WINDOW(m_window),false);
gtk_window_set_position(GTK_WINDOW(m_window),GTK_WIN_POS_CENTER);
gtk_widget_show(m_window);
}
void UpdateDialogGtk::exec()
{
gtk_main();
}
void UpdateDialogGtk::finish(GtkWidget* widget, gpointer _dialog)
{
gtk_main_quit();
}
gboolean UpdateDialogGtk::notify(void* _message)
{
UpdateMessage* message = static_cast<UpdateMessage*>(_message);
UpdateDialogGtk* dialog = static_cast<UpdateDialogGtk*>(message->receiver);
switch (message->type)
{
case UpdateMessage::UpdateProgress:
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->m_progressBar),message->progress/100.0);
break;
case UpdateMessage::UpdateFailed:
{
dialog->m_hadError = true;
std::string errorMessage = AppInfo::updateErrorMessage(message->message);
GtkWidget* errorDialog = gtk_message_dialog_new (GTK_WINDOW(dialog->m_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s",
errorMessage.c_str());
gtk_dialog_run (GTK_DIALOG (errorDialog));
gtk_widget_destroy (errorDialog);
gtk_widget_set_sensitive(dialog->m_finishButton,true);
}
break;
case UpdateMessage::UpdateFinished:
{
std::string message;
if (dialog->m_hadError)
{
message = "Update failed.";
}
else
{
message = "Update installed.";
}
message += " Click 'Finish' to restart the application.";
gtk_label_set_text(GTK_LABEL(dialog->m_progressLabel),message.c_str());
gtk_widget_set_sensitive(dialog->m_finishButton,true);
}
break;
}
delete message;
// do not invoke this function again
return false;
}
// callbacks during update installation
void UpdateDialogGtk::updateError(const std::string& errorMessage)
{
UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateFailed);
message->message = errorMessage;
g_idle_add(&UpdateDialogGtk::notify,message);
}
void UpdateDialogGtk::updateProgress(int percentage)
{
UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateProgress);
message->progress = percentage;
g_idle_add(&UpdateDialogGtk::notify,message);
}
void UpdateDialogGtk::updateFinished()
{
UpdateMessage* message = new UpdateMessage(this,UpdateMessage::UpdateFinished);
g_idle_add(&UpdateDialogGtk::notify,message);
}