mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2024-11-29 23:22:04 +00:00
2c70cebd05
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.
170 lines
4.6 KiB
C++
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);
|
|
}
|
|
|
|
|