#!/usr/bin/perl use strict; use lib qw(/usr/lib/libDrakX); use POSIX; use common; use my_gtk qw(:helpers :wrappers :various);; use interactive; use standalone; use timezone; #------------------------------------------------------------- # i18n # IMPORTANT: next code is needed to get correct namespace # (drakconf instead of libDrakX) # (This version is now UTF8 compliant - Sg 2001-08-18) #------------------------------------------------------------- push @::textdomains, 'drakconf'; my $in = interactive->vnew('su'); my $pixmap; my $radius; my $dRadians_hour; my $dRadians_min; my $dRadians_sec; my $Radian; my $type; my $timer; my ($midx, $midy); my $first = 1; my $is24; my $h_old; my ($old_year, $old_month, $old_day); my $its_reset = 0; my $my_win = my_gtk->new('print_launcher'); $my_win->{rwindow}->set_title(N("DrakClock")) unless $::isEmbedded; my $vbox = new Gtk::VBox(0,0); $my_win->{window}->add($vbox); $my_win->{window}->signal_connect (delete_event => sub { my_gtk->exit(0) }); my $hbox = new Gtk::HBox(0,0); $vbox->pack_start($hbox, 1, 1, 0); my $vbox1 = new Gtk::VBox(0,0); $hbox->pack_start($vbox1, 1, 1, 0); my $calendar = new Gtk::Calendar; $vbox1->pack_start($calendar, 1, 1, 0); $calendar->signal_connect ($_ => \&cal_changed) foreach ('month-changed', 'day-selected', 'day-selected-double-click', 'prev-month', 'next-month', 'prev-year', 'next-year'); my $button_time = new Gtk::Button N("Time Zone"); $vbox1->pack_start($button_time, 0, 1, 10); $button_time->signal_connect (clicked => sub { local $::isEmbedded = 0; # to prevent sub window embedding $in->{timezone} = {}; add2hash($in->{timezone}, timezone::read('')); my $timezone = $in->{timezone}{timezone}; $in->{timezone}{timezone} = $in->ask_from_treelist(N("Timezone - DrakClock"), N("Which is your timezone?"), '/', [ timezone::getTimeZones('') ], $timezone); if (defined($in->{timezone}{timezone})) { $in->{timezone}{UTC} = $in->ask_yesorno(N("GMT - DrakClock"), N("Is your hardware clock set to GMT?"), $in->{timezone}{UTC}); timezone::write('', $in->{timezone}); } else { $in->{timezone}{timezone} = $timezone; } }); my $vbox2 = new Gtk::VBox(0,0); my $pressed; $hbox->pack_start($vbox2, 1, 1, 0); my $drawing_area = new Gtk::DrawingArea; $drawing_area->size(300,300); $vbox2->pack_start($drawing_area, 1, 1, 0); $drawing_area->set_events(['button_press_mask', 'button_release_mask', "pointer_motion_mask" ]); $drawing_area->signal_connect (expose_event => \&expose_event); $drawing_area->signal_connect (configure_event => \&configure_event); $drawing_area->signal_connect (button_press_event => sub { $pressed = 1 }); $drawing_area->signal_connect (button_release_event => sub { $first = 1; $pressed = 0 }); $drawing_area->signal_connect (motion_notify_event => \&motion_event); my $hbox11 = new Gtk::HBox(1,0); $vbox2->pack_start($hbox11, 0, 0, 10); my $hbox2 = new Gtk::HBox(1,0); $hbox11->pack_start($hbox2, 0, 0, 0); my $adj_h = new Gtk::Adjustment 0.0, 0.0, 23.0, 1.0, 5.0, 0.0; my $spinner_h = new Gtk::SpinButton $adj_h, 0, 0; $hbox2->pack_start($spinner_h, 0, 0, 0); $spinner_h->set_wrap(1); $spinner_h->signal_connect (activate => \&spinned); $spinner_h->signal_connect (button_release_event => \&spinned); $spinner_h->signal_connect (changed => \&changed); my $adj_m = new Gtk::Adjustment 0.0, 0.0, 59.0, 1.0, 5.0, 0.0; my $spinner_m = new Gtk::SpinButton $adj_m, 0, 0; $hbox2->pack_start($spinner_m, 0, 0, 0); $spinner_m->set_wrap(1); $spinner_m->signal_connect (activate => \&spinned); $spinner_m->signal_connect (button_release_event => \&spinned); my $adj_s = new Gtk::Adjustment 0.0, 0.0, 59.0, 1.0, 5.0, 0.0; my $spinner_s = new Gtk::SpinButton $adj_s, 0, 0; $hbox2->pack_start($spinner_s, 0, 0, 0); $spinner_s->set_wrap(1); $spinner_s->signal_connect (activate => \&spinned); $spinner_s->signal_connect (button_release_event => \&spinned); my $bbox = new Gtk::HButtonBox; $bbox->set_layout(-end); $vbox->pack_start($bbox, 0, 0, 5); $bbox->add(gtksignal_connect(new Gtk::Button(N("OK")), clicked => sub { my ($year, $month, $day) = $calendar->get_date; $month++; my ($hour, $min, $sec) = ($adj_h->get_value, $adj_m->get_value, $adj_s->get_value); system("date " . join('', map { print_it0($_) } ($month, $day, $hour, $min, $year)) . '.' . print_it0($sec)); -e '/sbin/hwclock' and system('/sbin/hwclock --systohc'); my_gtk->exit(0); } )); $bbox->add(gtksignal_connect(new Gtk::Button(N("Cancel")), clicked => sub { my_gtk->exit(0) })); my $button_reset; $button_reset = gtksignal_connect(new Gtk::Button(N("Reset")), clicked => sub { $its_reset = 1; $timer = Gtk->timeout_add(120, sub { time_to_rad(localtime(time)); Repaint($drawing_area) }); time_to_rad(localtime(time)); Repaint($drawing_area); $calendar->select_month($old_month, $old_year); $calendar->select_day($old_day); $button_reset->set_sensitive(0); $its_reset = 0; }); $bbox->add($button_reset); $my_win->{window}->show_all; Gtk->main_iteration while Gtk->events_pending; $calendar->realize; (undef,undef,$h_old,$old_day,$old_month,$old_year) = localtime(time); $is24 = $h_old>12; $old_year += 1900; $calendar->select_month($old_month, $old_year); $calendar->select_day($old_day); $button_reset->set_sensitive(0); $timer = Gtk->timeout_add(120, sub { time_to_rad(localtime(time)); Repaint($drawing_area) }); $my_win->main; my_gtk->exit(0); sub cal_changed { !$its_reset and $timer and Gtk->timeout_remove($timer); $button_reset->set_sensitive(1); } sub changed { if ($h_old > $adj_h->get_value && $adj_h->get_value < ($is24 ? 18 : 6) && $h_old > ($is24 ? 18 : 6) && $h_old < ($is24 ? 24 : 12)) { $is24 = !$is24; } elsif ($h_old < $adj_h->get_value && $adj_h->get_value > ($is24 ? 18 : 6) && $h_old < ($is24 ? 18 : 6) && ($adj_h->get_value-$h_old != 12)) { $is24 = !$is24; } $h_old = $adj_h->get_value; } sub spinned { Gtk->timeout_remove($timer); $button_reset->set_sensitive(1); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); time_to_rad($adj_s->get_value,$adj_m->get_value,$adj_h->get_value,$mday,$mon,$year,$wday,$yday,$isdst); Repaint($drawing_area); } sub motion_event { my ($widget, $event) = @_; $pressed or return; if ($first) { Gtk->timeout_remove($timer); ($Radian, $type) = determine_radian($event->{'x'}, $event->{'y'}); $button_reset->set_sensitive(1); } $$Radian = -atan2(($event->{'x'}-$midx),($event->{'y'}-$midy)) + $PI; Repaint($widget); rad_to_time(); $first = 0; } sub determine_radian { my ($x, $y) = @_; my $res; my $r; my $i = 0; foreach (\$dRadians_hour, \$dRadians_min, \$dRadians_sec) { my $d = sqrt ( ($x - ($midx + 7/10 * $radius * sin ($$_)))**2 + ($y - ($midy - 7/10 * $radius * cos ($$_)))**2); $res or $res = $d, $r = $_; $d<$res and $res = $d, $r = $_, $i++; } ($r, $i); } sub expose_event { my ($widget) = @_; $widget->window->draw_pixmap ( $widget->style->fg_gc('normal'), $pixmap, 0, 0, 0, 0, $widget->allocation->[2], $widget->allocation->[3]); } sub configure_event { my ($widget) = @_; $pixmap = new Gtk::Gdk::Pixmap ($widget->window, $widget->allocation->[2], $widget->allocation->[3], -1); Repaint($widget); } sub rad_to_time { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $adj_h->set_value(POSIX::floor($dRadians_hour * 6 / $PI) + ($is24 ? 12 : 0)); $adj_m->set_value(POSIX::floor($dRadians_min*30/$PI)); $adj_s->set_value(POSIX::floor($dRadians_sec*30/$PI)); } sub time_to_rad { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @_; $dRadians_hour = $hour % 12 * $PI / 6; $dRadians_min = $min * $PI / 30; $dRadians_sec = $sec * $PI / 30; $adj_h->set_value($hour); $adj_m->set_value($min); $adj_s->set_value($sec); } sub Repaint { my ($drawing_area) = @_; my $dRadians_hour_real = POSIX::floor($dRadians_hour / $PI*6) * $PI/6.0 + $dRadians_min / 12; my $dRadians_min_real = POSIX::floor($dRadians_min / $PI * 30) * $PI / 30; my $dRadians_sec_real = $dRadians_sec; $pixmap->draw_rectangle($drawing_area->style->white_gc, 1, 0, 0, $drawing_area->allocation->[2], $drawing_area->allocation->[3]); $midx = $drawing_area->allocation->[2] / 2; $midy = $drawing_area->allocation->[3] / 2; $radius = $midx < $midy ? $midx -10 : $midy - 10; my $nHour; my $gray_gc = $drawing_area->style->bg_gc('normal'); my $black_gc = $drawing_area->style->black_gc; foreach my $i ([\&DrawTickAt, 12], [\&DrawPointAt, 60]) { $i->[0]($pixmap, $black_gc, $gray_gc, $_, $midx, $midy) foreach (1..$i->[1]) } my $now = time; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); my $dRadians; foreach ([$gray_gc, 5], [$black_gc, 0]) { DrawHour ($pixmap, $_->[0], $midx, $midy, $dRadians_hour_real, $_->[1]); DrawMin ($pixmap, $_->[0], $midx, $midy, $dRadians_min_real, $_->[1]); DrawSec ($pixmap, $_->[0], $midx, $midy, $dRadians_sec_real, $_->[1]); } $drawing_area->draw(undef); 1; } sub DrawSec { my ($pixmap, $gc, $midx, $midy, $dRadians, $dec) = @_; $pixmap->draw_line ($gc, $midx+$dec, $midy+$dec, $midx+$dec + (8/10 * $radius * sin ($dRadians)), $midy+$dec - (8/10 * $radius * cos ($dRadians))) } sub DrawMin { my ($pixmap, $gc, $midx, $midy, $dRadians, $dec) = @_; $pixmap->draw_polygon ($gc, 1, $midx+$dec - 3/100 * $radius * sin ($dRadians), $midy+$dec + 3/100 * $radius * cos ($dRadians), $midx+$dec - 3/100 * $radius * sin ($dRadians+$PI/2), $midy+$dec + 3/100 * $radius * cos ($dRadians+$PI/2), $midx+$dec + 8/10 * $radius * sin ($dRadians), $midy+$dec - 8/10 * $radius * cos ($dRadians), $midx+$dec + 3/100 * $radius * sin ($dRadians+$PI/2), $midy+$dec - 3/100 * $radius * cos ($dRadians+$PI/2)); } sub DrawHour { my ($pixmap, $gc, $midx, $midy, $dRadians, $dec) = @_; $pixmap->draw_polygon ($gc, 1, $midx+$dec - 5/100 * $radius * sin ($dRadians), $midy+$dec + 5/100 * $radius * cos ($dRadians), $midx+$dec - 5/100 * $radius * sin ($dRadians+$PI/2), $midy+$dec + 5/100 * $radius * cos ($dRadians+$PI/2), $midx+$dec + 7/10 * $radius * sin ($dRadians), $midy+$dec - 7/10 * $radius * cos ($dRadians), $midx+$dec + 5/100 * $radius * sin ($dRadians+$PI/2), $midy+$dec - 5/100 * $radius * cos ($dRadians+$PI/2)); } sub DrawTickAt { my ($pixmap, $black_gc, $gray_gc, $nHour, $cx, $cy) = @_; my $dRadians = $nHour * $PI / 6.0; $pixmap->draw_line ($_->[0], $cx+$_->[1] + 9/10 * $radius * sin ($dRadians), $cy+$_->[1] - 9/10 * $radius * cos ($dRadians), $cx+$_->[1] + 1 * $radius * sin ($dRadians), $cy+$_->[1] - 1 * $radius * cos ($dRadians)) foreach ([$gray_gc, 5], [$black_gc, 0]); } sub DrawPointAt { my ($pixmap, $black_gc, $gray_gc, $nHour, $cx, $cy) = @_; my $dRadians = $nHour * $PI / 30; $pixmap->draw_point ($black_gc, $cx + 95/100 * $radius * sin ($dRadians), $cy - 95/100 * $radius * cos ($dRadians)) } sub print_it0 { sprintf("%02d", @_[0]) }