Example #1
0
void gui_download_window_error(struct gui_download_window *dw,
		const char *error_msg)
{
	os_error *error;

	if (dw->ctx != NULL)
		download_context_destroy(dw->ctx);
	dw->ctx = NULL;
	dw->error = true;

	schedule_remove(ro_gui_download_update_status_wrapper, dw);

	/* place error message in status icon in red */
	strncpy(dw->status, error_msg, sizeof dw->status);
	error = xwimp_set_icon_state(dw->window,
			ICON_DOWNLOAD_STATUS,
			wimp_COLOUR_RED << wimp_ICON_FG_COLOUR_SHIFT,
			wimp_ICON_FG_COLOUR);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* grey out pathname icon */
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
			wimp_ICON_SHADED, 0);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* grey out file icon */
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
			wimp_ICON_SHADED, wimp_ICON_SHADED);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	ro_gui_download_window_hide_caret(dw);
}
Example #2
0
query_id query_user_xy(const char *query, const char *detail,
		const query_callback *cb, void *pw,
		const char *yes, const char *no,
		int x, int y)
{
	struct gui_query_window *qw;
	char query_buffer[300];
	os_error *error;
	wimp_icon *icn;
	int width;
	int len;
	int tx;
	char *local_text = NULL;
	nserror err;

	qw = malloc(sizeof(struct gui_query_window));
	if (!qw) {
		warn_user("NoMemory", NULL);
		return QUERY_INVALID;
	}

	qw->cb = cb;
	qw->pw = pw;
	qw->id = next_id++;
	qw->default_confirm = false;

	if (next_id == QUERY_INVALID)
		next_id++;

	if (!yes) yes = messages_get("Yes");
	if (!no) no = messages_get("No");

	/* set the text of the 'Yes' button and size accordingly */
	err = utf8_to_local_encoding(yes, 0, &local_text);
	if (err != NSERROR_OK) {
		assert(err != NSERROR_BAD_ENCODING);
		LOG(("utf8_to_local_encoding_failed"));
		local_text = NULL;
	}

	icn = &query_template->icons[ICON_QUERY_YES];
	len = strlen(local_text ? local_text : yes);
	len = max(len, icn->data.indirected_text.size - 1);
	memcpy(icn->data.indirected_text.text,
			local_text ? local_text: yes, len);
	icn->data.indirected_text.text[len] = '\0';

	free(local_text);
	local_text = NULL;

	error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
	if (error) {
		LOG(("xwimptextop_string_width: 0x%x:%s",
			error->errnum, error->errmess));
		width = len * 16;
	}
	if (!query_yes_width) query_yes_width = icn->extent.x1 - icn->extent.x0;
	width += 44;
	if (width < query_yes_width)
		width = query_yes_width;
	icn->extent.x0 = tx = icn->extent.x1 - width;

	/* set the text of the 'No' button and size accordingly */
	err = utf8_to_local_encoding(no, 0, &local_text);
	if (err != NSERROR_OK) {
		assert(err != NSERROR_BAD_ENCODING);
		LOG(("utf8_to_local_encoding_failed"));
		local_text = NULL;
	}

	icn = &query_template->icons[ICON_QUERY_NO];
	len = strlen(local_text ? local_text : no);
	len = max(len, icn->data.indirected_text.size - 1);
	memcpy(icn->data.indirected_text.text,
			local_text ? local_text : no, len);
	icn->data.indirected_text.text[len] = '\0';

	free(local_text);
	local_text = NULL;

	if (!query_no_width) query_no_width = icn->extent.x1 - icn->extent.x0;
	icn->extent.x1 = tx - 16;
	error = xwimptextop_string_width(icn->data.indirected_text.text, len, &width);
	if (error) {
		LOG(("xwimptextop_string_width: 0x%x:%s",
			error->errnum, error->errmess));
		width = len * 16;
	}
	width += 28;
	if (width < query_no_width)
		width = query_no_width;
	icn->extent.x0 = icn->extent.x1 - width;

	error = xwimp_create_window(query_template, &qw->window);
	if (error) {
		warn_user("WimpError", error->errmess);
		free(qw);
		return QUERY_INVALID;
	}

	snprintf(query_buffer, sizeof query_buffer, "%s %s",
			messages_get(query), detail ? detail : "");
	query_buffer[sizeof query_buffer - 1] = 0;

	ro_gui_set_icon_string(qw->window, ICON_QUERY_MESSAGE,
			query_buffer, true);

	xwimp_set_icon_state(qw->window, ICON_QUERY_HELP,
			wimp_ICON_DELETED, wimp_ICON_DELETED);

	if (x >= 0 && y >= 0) {
		x -= tx - 8;
		y += (query_template->visible.y1 - query_template->visible.y0) / 2;
		ro_gui_dialog_open_xy(qw->window, x, y);
	}
	else
		ro_gui_dialog_open(qw->window);

	ro_gui_wimp_event_set_user_data(qw->window, qw);
	ro_gui_wimp_event_register_mouse_click(qw->window, ro_gui_query_click);
	ro_gui_wimp_event_register_cancel(qw->window, ICON_QUERY_NO);
	ro_gui_wimp_event_register_ok(qw->window, ICON_QUERY_YES, ro_gui_query_apply);
	ro_gui_wimp_event_register_close_window(qw->window, ro_gui_query_close);

	error = xwimp_set_caret_position(qw->window, (wimp_i)-1, 0, 0, 1 << 25, -1);
	if (error) {
		LOG(("xwimp_get_caret_position: 0x%x : %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* put this query window at the head of our list */
	if (gui_query_window_list)
		gui_query_window_list->prev = qw;

	qw->prev = NULL;
	qw->next = gui_query_window_list;
	gui_query_window_list = qw;

	return qw->id;
}
Example #3
0
nserror gui_download_window_data(struct gui_download_window *dw,
		const char *data, unsigned int size)
{
	while (true) {
		const char *msg;
		int unwritten;
		os_error *error;

		error = xosgbpb_writew(dw->file, (const byte *) data, size,
				&unwritten);
		if (error) {
			LOG(("xosgbpb_writew: 0x%x: %s",
					error->errnum, error->errmess));
			msg = error->errmess;

		} else if (unwritten) {
			LOG(("xosgbpb_writew: unwritten %i", unwritten));
			msg = messages_get("Unwritten");
		}
		else {
			dw->received += size;
			return NSERROR_OK;
		}

		warn_user("SaveError", msg);

		if (dw->saved) {
			/* try to continue with the temporary file */
			const char *temp_name = ro_gui_download_temp_name(dw);

			error = ro_gui_download_move(dw, temp_name, dw->path);
			if (!error) {

				/* re-allow saving */
				dw->saved = false;

				error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
						wimp_ICON_SHADED, 0);
				if (error) {
					LOG(("xwimp_set_icon_state: 0x%x: %s",
							error->errnum, error->errmess));
					warn_user("WimpError", error->errmess);
				}

				error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_DESTINATION,
						wimp_ICON_DELETED, wimp_ICON_DELETED);
				if (error) {
					LOG(("xwimp_set_icon_state: 0x%x: %s",
							error->errnum, error->errmess));
					warn_user("WimpError", error->errmess);
				}
				error = xwimp_set_icon_state(dw->window,
						ICON_DOWNLOAD_PATH, wimp_ICON_DELETED, 0);
				if (error) {
					LOG(("xwimp_set_icon_state: 0x%x: %s",
							error->errnum, error->errmess));
					warn_user("WimpError", error->errmess);
				}

				continue;
			}
		}

		/* give up then */
		assert(dw->ctx);
		download_context_abort(dw->ctx);
		gui_download_window_error(dw, msg);

		return NSERROR_SAVE_FAILED;
	}
}
Example #4
0
void ro_gui_download_update_status(struct gui_download_window *dw)
{
	char *received;
	char *total_size;
	char *speed;
	char time[20] = "?";
	struct timeval t;
	float dt;
	unsigned int left;
	float rate;
	os_error *error;
	int width;
	char *local_status;
	utf8_convert_ret err;

	gettimeofday(&t, 0);
	dt = (t.tv_sec + 0.000001 * t.tv_usec) - (dw->last_time.tv_sec +
			0.000001 * dw->last_time.tv_usec);
	if (dt == 0)
		dt = 0.001;

	total_size = human_friendly_bytesize(max(dw->received, dw->total_size));

	if (dw->ctx) {
		rate = (dw->received - dw->last_received) / dt;
		received = human_friendly_bytesize(dw->received);
		/* A simple 'modified moving average' download rate calculation
		 * to smooth out rate fluctuations: chosen for simplicity.
		 */
		dw->average_points++;
		dw->average_rate =
				((dw->average_points - 1) *
				dw->average_rate + rate) /
				dw->average_points;
		speed = human_friendly_bytesize(dw->average_rate);
		if (dw->total_size) {
			float f;

			if (dw->average_rate > 0) {
				left = (dw->total_size - dw->received) /
						dw->average_rate;
				sprintf(time, "%u:%.2u", left / 60, left % 60);
			}

			/* convert to local encoding */
			err = utf8_to_local_encoding(
				messages_get("Download"), 0, &local_status);
			if (err != UTF8_CONVERT_OK) {
				/* badenc should never happen */
				assert(err != UTF8_CONVERT_BADENC);
				/* hide nomem error */
				snprintf(dw->status, sizeof dw->status,
					messages_get("Download"),
					received, total_size, speed, time);
			}
			else {
				snprintf(dw->status, sizeof dw->status,
					local_status,
					received, total_size, speed, time);
				free(local_status);
			}

			f = (float) dw->received / (float) dw->total_size;
			width = download_progress_width * f;
		} else {
			left = t.tv_sec - dw->start_time.tv_sec;
			sprintf(time, "%u:%.2u", left / 60, left % 60);

			err = utf8_to_local_encoding(
				messages_get("DownloadU"), 0, &local_status);
			if (err != UTF8_CONVERT_OK) {
				/* badenc should never happen */
				assert(err != UTF8_CONVERT_BADENC);
				/* hide nomem error */
				snprintf(dw->status, sizeof dw->status,
					messages_get("DownloadU"),
					received, speed, time);
			}
			else {
				snprintf(dw->status, sizeof dw->status,
					local_status,
					received, speed, time);
				free(local_status);
			}

			/* length unknown, stay at 0 til finished */
			width = 0;
		}
	} else {
		left = dw->last_time.tv_sec - dw->start_time.tv_sec;
		if (left == 0)
			left = 1;
		rate = (float) dw->received / (float) left;
		sprintf(time, "%u:%.2u", left / 60, left % 60);
		speed = human_friendly_bytesize(rate);

		err = utf8_to_local_encoding(messages_get("Downloaded"), 0,
				&local_status);
		if (err != UTF8_CONVERT_OK) {
			/* badenc should never happen */
			assert(err != UTF8_CONVERT_BADENC);
			/* hide nomem error */
			snprintf(dw->status, sizeof dw->status,
				messages_get("Downloaded"),
				total_size, speed, time);
		}
		else {
			snprintf(dw->status, sizeof dw->status, local_status,
					total_size, speed, time);
			free(local_status);
		}

		/* all done */
		width = download_progress_width;
	}

	dw->last_time = t;
	dw->last_received = dw->received;

	error = xwimp_resize_icon(dw->window, ICON_DOWNLOAD_PROGRESS,
			download_progress_x0,
			download_progress_y0,
			download_progress_x0 + width,
			download_progress_y1);
	if (error) {
		LOG(("xwimp_resize_icon: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_STATUS, 0, 0);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	if (dw->ctx)
		schedule(100, ro_gui_download_update_status_wrapper, dw);
	else
		schedule_remove(ro_gui_download_update_status_wrapper, dw);
}
Example #5
0
bool ro_gui_download_save(struct gui_download_window *dw,
		const char *file_name, bool force_overwrite)
{
	fileswitch_object_type obj_type;
	const char *temp_name;
	os_error *error;

	if (dw->saved || dw->error)
		return true;

	temp_name = ro_gui_download_temp_name(dw);

	/* does the user want to check for collisions when saving? */
	if (!force_overwrite) {
		/* check whether the destination file/dir already exists */
		error = xosfile_read_stamped(file_name, &obj_type,
				NULL, NULL, NULL, NULL, NULL);
		if (error) {
			LOG(("xosfile_read_stamped: 0x%x:%s", error->errnum, error->errmess));
			return false;
		}

		switch (obj_type) {
			case osfile_NOT_FOUND:
				break;

			case osfile_IS_FILE:
				dw->query = query_user("OverwriteFile", NULL, &overwrite_funcs, dw,
							messages_get("Replace"), messages_get("DontReplace"));
				dw->query_rsn = QueryRsn_Overwrite;
				return false;

			default:
				error = xosfile_make_error(file_name, obj_type);
				assert(error);
				warn_user("SaveError", error->errmess);
				return false;
		}
	}

	if (!ro_gui_download_check_space(dw, file_name, temp_name)) {
		warn_user("SaveError", messages_get("NoDiscSpace"));
		return false;
	}

	error = ro_gui_download_move(dw, file_name, temp_name);
	if (error) {
		warn_user("SaveError", error->errmess);

		/* try to reopen at old location so that the download can continue
		   to the temporary file */
		error = xosfind_openupw(osfind_NO_PATH | osfind_ERROR_IF_DIR,
				temp_name, 0, &dw->file);
		if (error) {
			LOG(("xosfind_openupw: 0x%x: %s",
					error->errnum, error->errmess));

		} else {
			error = xosargs_set_ptrw(dw->file, dw->received);
			if (error) {
				LOG(("xosargs_set_ptrw: 0x%x: %s",
						error->errnum, error->errmess));
			}
		}

		if (error) {
			if (dw->ctx)
				download_context_abort(dw->ctx);
			gui_download_window_error(dw, error->errmess);
		}
		return false;
	}

	dw->saved = true;
	strncpy(dw->path, file_name, sizeof dw->path);

	if (!dw->send_dataload || dw->save_message.data.data_xfer.est_size != -1)
		ro_gui_download_remember_dir(file_name);

	/* grey out file icon */
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_ICON,
			wimp_ICON_SHADED, wimp_ICON_SHADED);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	/* hide writeable path icon and show destination icon
	   Note: must redraw icon bounding box because the destination icon
		has rounded edges on RISC OS Select/Adjust and doesn't
		completely cover the writeable icon */

	ro_gui_force_redraw_icon(dw->window, ICON_DOWNLOAD_PATH);
	error = xwimp_set_icon_state(dw->window, ICON_DOWNLOAD_PATH,
			wimp_ICON_DELETED, wimp_ICON_DELETED);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}
	error = xwimp_set_icon_state(dw->window,
			ICON_DOWNLOAD_DESTINATION, wimp_ICON_DELETED, 0);
	if (error) {
		LOG(("xwimp_set_icon_state: 0x%x: %s",
				error->errnum, error->errmess));
		warn_user("WimpError", error->errmess);
	}

	ro_gui_download_window_hide_caret(dw);

	return true;
}