summaryrefslogtreecommitdiffstats
path: root/mmc_updater/src/UpdateDialogGtk.cpp
blob: d91144f5dcbf908625b9f07a952ad68b71c5da5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "UpdateDialogGtk.h"

#include "AppInfo.h"
#include "StringUtils.h"

#include <glib.h>
#include <gtk/gtk.h>

UpdateDialogGtk* update_dialog_gtk_new()
{
	return new UpdateDialogGtk();
}

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)
{
	UpdateDialogGtk* dialog = static_cast<UpdateDialogGtk*>(_dialog);
	dialog->quit();
}

void UpdateDialogGtk::quit()
{
	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);
	UpdateDialog::updateFinished();
}