+sub submit_failed($) {
+ my ($msg) = @_;
+ $status_label->set_markup("<span size='large'>Submit failed</span>");
+ $submitting_label->set_markup("<span size='large'>$msg</span>");
+ finish_submit();
+}
+
+sub run_submit() {
+ my ($task, $part) = split /\//, $selected_task;
+ defined $part or $part = $task;
+
+ if (defined $conn->{"History"}) {
+ busy("Submitting locally");
+ my $err = $conn->local_submit($task, $part, $submit_extension, $submit_filename);
+ if (defined $err) {
+ submit_failed("Recording to local history failed\n($err)");
+ return;
+ }
+ }
+
+ if ($conn->is_connected) {
+ busy("Checking server status...");
+ my $r = new Sherlock::Object("!" => "STATUS"); ### FIXME: use a NOP command
+ $r = $conn->request($r);
+ }
+ if (!$conn->is_connected) {
+ busy("Reconnecting to server...");
+ if (!$conn->connect) {
+ ready($conn->{"error"});
+ submit_failed("Unable to connect to the server"); ### FIXME: Mention local submit
+ return;
+ }
+ }
+ busy("Submitting...");
+
+ my $fh = new IO::File($submit_filename);
+ if (!$fh) {
+ submit_failed("Unable to open $submit_filename\n($!)");
+ return;
+ }
+ my $stat = File::stat::populate($fh->stat);
+ if (!$stat) {
+ submit_failed("Unable to stat $submit_filename\n($!)");
+ return;
+ }
+ my $size = $stat->size;
+
+ my $r = new Sherlock::Object("!" => "SUBMIT", "T" => $task, "P" => $part, "X" => $submit_extension, "S" => $size);
+ $r = $conn->request($r);
+ if (!defined($r)) {
+ submit_failed("Connection to the server lost");
+ return;
+ } elsif ($r->get("-")) {
+ submit_failed($r->get("-"));
+ return;
+ }
+
+ $r = $conn->send_file($fh, $size);
+ if (!defined($r)) {
+ submit_failed("Connection to the server lost");
+ return;
+ } elsif ($r->get("-")) {
+ submit_failed($r->get("-"));
+ return;
+ }
+
+ close $fh;
+ submit_ok();
+}
+
+sub checks_failed($) {
+ my ($msg) = @_;
+
+ $status_label->set_markup("<span size='large'>Check failed</span>");
+
+ my $text_buffer = Gtk2::TextBuffer->new;
+ $text_buffer->set_text($msg);
+
+ my $text_view = Gtk2::TextView->new_with_buffer($text_buffer);
+ $text_view->set_editable(0);
+ $text_view->set_cursor_visible(0);
+
+ $submitting_label->destroy;
+ $subwin_vbox->pack_start_defaults($text_view);
+
+ finish_submit();
+}
+
+sub checks_ok() {
+ if ($check_only) {
+ $status_label->set_markup("<span size='large'>Checked successfully</span>");
+ $submitting_label->set_markup("<span size='large'>The task has passed the checks.</span>");
+ finish_submit();
+ return;
+ }
+
+ ### FIXME: Record to local history here
+
+ $status_label->set_markup("<span size='large'>Submitting</span>");
+ $subwin->show_all;
+
+ # Continue when everything is displayed
+ Glib::Idle->add(sub {
+ $window->Gtk2::Gdk::flush;
+ run_submit();
+ return 0;
+ });
+}
+
+sub run_checks() {
+ ($submit_extension) = ($submit_filename =~ /\.([^.]+)$/);
+ if (!$submit_extension) {
+ checks_failed("The filename does not have a valid extension");
+ return;
+ }
+ sleep 1;
+ #checks_failed("One\nTwo\nThree...\n");
+ checks_ok();
+}
+
+sub do_submit() {
+ $submit_filename = $chooser->get_filename;
+ $submit_fn_cache{$selected_task} = $submit_filename;
+ msg "Selected $submit_filename";
+ defined $submit_filename or return;
+ -f $submit_filename or return;
+
+ $chooser->destroy;
+ $bbutton_box->destroy;
+
+ $status_label->set_markup("<span size='large'>Checking</span>");
+
+ $submitting_label = Gtk2::Label->new("Please wait...");
+ $subwin_vbox->pack_start_defaults($submitting_label);
+ $subwin->show_all;
+ $subwin->window->set_cursor($busy_cursor);
+
+ # Continue when everything is displayed
+ Glib::Idle->add(sub {
+ $window->Gtk2::Gdk::flush;
+ run_checks();
+ return 0;
+ });
+}
+
+sub submit($) {
+ $check_only = shift @_;
+
+ stop_refresh_timer();
+