Initial commit master 5999.000_001
authorMarius Gavrilescu <marius@ieval.ro>
Sat, 31 May 2014 22:40:11 +0000 (01:40 +0300)
committerMarius Gavrilescu <marius@ieval.ro>
Sat, 31 May 2014 22:40:11 +0000 (01:40 +0300)
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
gruntmaster-gui [new file with mode: 0755]
lib/Gruntmaster/GUI.pm [new file with mode: 0644]
t/Gruntmaster-GUI.t [new file with mode: 0644]

diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..98e51ea
--- /dev/null
+++ b/Changes
@@ -0,0 +1,4 @@
+Revision history for Perl extension Gruntmaster::GUI.
+
+5999.000_001 2014-06-01T01:40+03:00
+ - Initial release
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..43c3eb1
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,6 @@
+Changes
+Makefile.PL
+MANIFEST
+README
+t/Gruntmaster-GUI.t
+lib/Gruntmaster/GUI.pm
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..51ef4d9
--- /dev/null
@@ -0,0 +1,26 @@
+use 5.014000;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME              => 'Gruntmaster::GUI',
+       VERSION_FROM      => 'lib/Gruntmaster/GUI.pm',
+       ABSTRACT_FROM     => 'lib/Gruntmaster/GUI.pm',
+       AUTHOR            => 'Marius Gavrilescu <marius@ieval.ro>',
+       EXE_FILES         => [qw/gruntmaster-gui/],
+       MIN_PERL_VERSION  => '5.14.0',
+       LICENSE           => 'perl',
+       SIGN              => 1,
+       PREREQ_PM         => {
+               qw/Gruntmaster::Data 0
+                  Sub::Name 0
+                  Try::Tiny 0
+                  Wx 0
+                  Wx::Event 0/,
+       },
+       META_MERGE        => {
+               dynamic_config => 0,
+               resources      => {
+                       repository => 'https://git.ieval.ro/?p=gruntmaster-gui.git',
+               }
+       }
+);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..07be6bb
--- /dev/null
+++ b/README
@@ -0,0 +1,30 @@
+Gruntmaster-GUI version 5999.000_001
+====================================
+
+INSTALLATION
+
+To install this module type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+* Gruntmaster::Data
+* Sub::Name
+* Try::Tiny
+* Wx
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.18.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
diff --git a/gruntmaster-gui b/gruntmaster-gui
new file mode 100755 (executable)
index 0000000..3284301
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl -w
+use v5.14;
+
+use Gruntmaster::GUI;
+
+Gruntmaster::GUI->new->MainLoop;
+
+__END__
+
+=head1 NAME
+
+gruntmaster-gui - Gruntmaster 6000 Online Judge -- GUI database editor
+
+=head1 SYNOPSIS
+
+  gruntmaster-gui
+
+=head1 DESCRIPTION
+
+gruntmaster-gui is a GUI viewer and editor for the Gruntmaster 6000 database.
+
+CLI tools with the same purpose are distributed with Gruntmaster::Data. See L<gruntmaster-contest(1)>, L<gruntmaster-job(1)>, L<gruntmaster-problem(1)>.
+
+=head1 AUTHOR
+
+Marius Gavrilescu E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.18.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/lib/Gruntmaster/GUI.pm b/lib/Gruntmaster/GUI.pm
new file mode 100644 (file)
index 0000000..60cac04
--- /dev/null
@@ -0,0 +1,230 @@
+package Gruntmaster::GUI;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Wx::App/;
+our $VERSION = '5999.000_001';
+$VERSION = eval $VERSION;
+
+use constant FORMATS => [qw/C CPP GO HASKELL JAVA PASCAL PERL PYTHON/];
+
+use Gruntmaster::Data;
+use Sub::Name qw/subname/;
+use Try::Tiny;
+use Wx qw/wxVERTICAL wxHORIZONTAL wxEXPAND wxALL wxTOP wxBOTTOM wxTE_MULTILINE wxTE_PROCESS_ENTER wxDefaultPosition wxDefaultSize wxLC_ICON/;
+use Wx::Event qw/EVT_BUTTON EVT_COMBOBOX EVT_LISTBOX EVT_TEXT EVT_TEXT_ENTER/;
+
+my ($db, $pb, $ct);
+my ($problem_list, $contest_list, $job_list);
+my (%problem, %contest);
+
+sub problem_enable_relevant{
+       $problem{genformat}->Enable($problem{generator}->GetValue eq 'Run');
+       $problem{gensource}->Enable($problem{generator}->GetValue eq 'Run');
+       $problem{verformat}->Enable($problem{runner}->GetValue ne 'File');
+       $problem{versource}->Enable($problem{runner}->GetValue ne 'File');
+       $problem{tests}->Enable($problem{runner}->GetValue eq 'File');
+}
+
+sub select_problem {
+       my $id = $problem_list->GetClientData($problem_list->GetSelection);
+       $pb = $db->problem($id);
+       $problem{id}->SetLabel("ID: $id");
+       $problem{$_}->SetValue($pb->get_column($_) // '') for qw/name author writer owner tests timeout olimit level generator runner judge testcnt value statement genformat gensource verformat versource/;
+       $problem{private}->SetValue($pb->private);
+       problem_enable_relevant;
+}
+
+sub select_contest {
+       my $id = $contest_list->GetClientData($contest_list->GetSelection);
+       $ct = $db->contest($id);
+       $contest{id}->SetLabel("ID: $id");
+       $contest{$_}->SetValue($ct->get_column($_)) for qw/name start stop owner/;
+}
+
+sub connect_or_disconnect {
+       my ($dsn, $button, $nb) = @_;
+       subname 'connect_or_disconnect', sub {
+               if (defined $db) {
+                       undef $db;
+                       $dsn->Enable;
+                       $nb->Disable;
+                       $button->SetLabel('Connect');
+                       $problem_list->Clear;
+               } else {
+                       try {
+                               $db = Gruntmaster::Data->connect($dsn->GetValue);
+                               $db->problems->count({}); # Trigger database connection
+                       } catch {
+                               Wx::MessageBox("Cannot connect to database: $_");
+                               undef $db;
+                       };
+                       return unless defined $db;
+                       $dsn->Disable;
+                       $nb->Enable;
+                       $button->SetLabel('Disconnect');
+                       $problem_list->Append($_->name, $_->id) for $db->problems->search({}, {order_by => 'name'});
+                       $problem_list->GetParent->GetSizer->Layout;
+                       $contest_list->Append($_->name, $_->id) for $db->contests->search({}, {order_by => 'name'});
+                       $contest_list->GetParent->GetSizer->Layout;
+                       $problem_list->SetSelection(0);
+                       $contest_list->SetSelection(0);
+                       select_problem;
+                       select_contest;
+               }
+               $button->GetParent->GetSizer->Layout;
+       }
+}
+
+sub OnInit {
+       my $frame = Wx::Frame->new(undef, -1, 'Gruntmaster 6000', [-1, -1], [500, 700]);
+       my ($nb, $problems, $contests, $jobs);
+
+       {
+               my $panel = Wx::Panel->new($frame);
+               my $subpanel = Wx::Panel->new($panel);
+               my $panel_sizer = Wx::BoxSizer->new(wxVERTICAL);
+               my $subpanel_sizer = Wx::BoxSizer->new(wxHORIZONTAL);
+
+               my $dsn = Wx::TextCtrl->new($subpanel, -1, '', wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
+               my $db_button = Wx::Button->new($subpanel, -1, 'Connect');
+               $nb = Wx::Notebook->new($panel);
+               $nb->Disable;
+               EVT_BUTTON($db_button, $db_button, connect_or_disconnect $dsn, $db_button, $nb);
+               EVT_TEXT_ENTER($dsn, $dsn, connect_or_disconnect $dsn, $db_button, $nb);
+
+               $panel_sizer->Add($subpanel, 0, wxEXPAND | wxALL, 10);
+               $panel_sizer->Add($nb, 1, wxEXPAND | wxALL, 10);
+               $subpanel_sizer->Add($dsn, 1, wxEXPAND | wxALL, 10);
+               $subpanel_sizer->Add($db_button, 0, wxEXPAND | wxALL, 10);
+               $panel->SetSizer($panel_sizer);
+               $subpanel->SetSizer($subpanel_sizer);
+       }
+
+       sub label {
+               my ($parent, $sizer, $content) = @_;
+               my $temp = Wx::StaticText->new($parent, -1, $content);
+               $sizer->Add($temp, wxEXPAND);
+               $temp
+       }
+       sub formsize {
+               my ($sizer, $item) = @_;
+               $sizer->Add($item, 0, wxEXPAND | wxTOP | wxBOTTOM, 5);
+       }
+
+       {
+               $problems = Wx::Panel->new($nb);
+               my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
+               $problem_list = Wx::ListBox->new($problems);
+               EVT_LISTBOX($problem_list, $problem_list, \&select_problem);
+               my $form1 = Wx::ScrolledWindow->new($problems);
+               my $form2 = Wx::ScrolledWindow->new($problems);
+               my $f1sizer = Wx::BoxSizer->new(wxVERTICAL);
+               my $f2sizer = Wx::BoxSizer->new(wxVERTICAL);
+               $problem{id} = label $form1, $f1sizer, 'ID';
+               my %id_to_label = (timeout => 'Time limit', olimit => 'Output limit');
+               for (qw/name author writer owner tests timeout olimit/) {
+                       label $form1, $f1sizer, $id_to_label{$_} // ucfirst;
+                       formsize $f1sizer, $problem{$_} = Wx::TextCtrl->new($form1, -1, '');
+               }
+               $problem{private} = Wx::CheckBox->new($form2, -1, 'Private');
+               $f2sizer->Add($problem{private});
+               label $form2, $f2sizer, 'Level';
+               formsize $f2sizer, $problem{level} = Wx::ComboBox->new($form2);
+               $problem{level}->Append([qw/beginner easy medium hard/]);
+               label $form2, $f2sizer, 'Generator';
+               formsize $f2sizer, $problem{generator} = Wx::ComboBox->new($form2);
+               $problem{generator}->Append([qw/File Run Undef/]);
+               label $form2, $f2sizer, 'Runner';
+               formsize $f2sizer, $problem{runner} = Wx::ComboBox->new($form2);
+               $problem{runner}->Append([qw/File Verifier Interactive/]);
+               label $form2, $f2sizer, 'Judge';
+               formsize $f2sizer, $problem{judge} = Wx::ComboBox->new($form2);
+               $problem{judge}->Append([qw/Absolute Points/]);
+               label $form2, $f2sizer, 'Test count';
+               formsize $f2sizer, $problem{testcnt} = Wx::SpinCtrl->new($form2);
+               label $form2, $f2sizer, 'Value';
+               formsize $f2sizer, $problem{value} = Wx::SpinCtrl->new($form2);
+               label $form1, $f1sizer, 'Statement';
+               formsize $f1sizer, $problem{statement} = Wx::TextCtrl->new($form1, -1, '', wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
+               #$f1sizer->Add($problem{statement}, 2, wxEXPAND | wxTOP | wxBOTTOM, 5);
+               label $form2, $f2sizer, 'Generator program';
+               formsize $f2sizer, $problem{genformat} = Wx::ComboBox->new($form2);
+               $problem{genformat}->Append(FORMATS);
+               formsize $f2sizer, $problem{gensource} = Wx::TextCtrl->new($form2, -1, '', wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
+               label $form2, $f2sizer, 'Verifier program';
+               formsize $f2sizer, $problem{verformat} = Wx::ComboBox->new($form2);
+               $problem{verformat}->Append(FORMATS);
+               formsize $f2sizer, $problem{versource} = Wx::TextCtrl->new($form2, -1, '', wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
+               EVT_COMBOBOX($problem{$_}, $problem{$_}, \&problem_enable_relevant) for qw/generator runner/;
+               EVT_TEXT($problem{$_}, $problem{$_}, \&problem_enable_relevant) for qw/generator runner/;
+
+               $sizer->Add($problem_list, 0, wxEXPAND | wxALL, 10);
+               $sizer->Add($form1, 1, wxALL, 10);
+               $sizer->Add($form2, 1, wxALL, 10);
+               $form1->SetSizer($f1sizer);
+               $form2->SetSizer($f2sizer);
+               $problems->SetSizer($sizer);
+       }
+
+       {
+               $contests = Wx::Panel->new($nb);
+               my $sizer = Wx::BoxSizer->new(wxHORIZONTAL);
+               $contest_list = Wx::ListBox->new($contests);
+               EVT_LISTBOX($contest_list, $contest_list, \&select_contest);
+               my $form = Wx::ScrolledWindow->new($contests);
+               my $fsizer = Wx::BoxSizer->new(wxVERTICAL);
+               $contest{id} = label $form, $fsizer, 'ID';
+               label $form, $fsizer, 'Name';
+               formsize $fsizer, $contest{name} = Wx::TextCtrl->new($form, -1, '');
+               label $form, $fsizer, 'Start';
+               formsize $fsizer, $contest{start} = Wx::TextCtrl->new($form, -1, '');
+               label $form, $fsizer, 'Stop';
+               formsize $fsizer, $contest{stop} = Wx::TextCtrl->new($form, -1, '');
+               label $form, $fsizer, 'owner';
+               formsize $fsizer, $contest{owner} = Wx::TextCtrl->new($form, -1, '');
+
+               $sizer->Add($contest_list, 0, wxEXPAND | wxALL, 10);
+               $sizer->Add($form, 1, wxALL, 10);
+               $form->SetSizer($fsizer);
+               $contests->SetSizer($sizer);
+       }
+
+       $nb->AddPage($problems, 'Problems');
+       $nb->AddPage($contests, 'Contests');
+       $frame->Show(1)
+}
+
+1;
+__END__
+
+=head1 NAME
+
+Gruntmaster::GUI - Gruntmaster 6000 Online Judge -- GUI database editor
+
+=head1 SYNOPSIS
+
+  use Gruntmaster::GUI;
+  Gruntmaster::GUI->new->MainLoop;
+
+=head1 DESCRIPTION
+
+Gruntmaster::GUI is a GUI viewer and editor for the Gruntmaster 6000 database.
+
+CLI tools with the same purpose are distributed with Gruntmaster::Data. See L<gruntmaster-contest(1)>, L<gruntmaster-job(1)>, L<gruntmaster-problem(1)>.
+
+=head1 AUTHOR
+
+Marius Gavrilescu E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.18.2 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/t/Gruntmaster-GUI.t b/t/Gruntmaster-GUI.t
new file mode 100644 (file)
index 0000000..a6dcd68
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/perl -w
+use v5.14;
+
+use Test::More tests => 1;
+BEGIN { use_ok('Gruntmaster::GUI') };
This page took 0.019127 seconds and 4 git commands to generate.