aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ManaTools/Module/Clock.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ManaTools/Module/Clock.pm')
-rw-r--r--lib/ManaTools/Module/Clock.pm518
1 files changed, 518 insertions, 0 deletions
diff --git a/lib/ManaTools/Module/Clock.pm b/lib/ManaTools/Module/Clock.pm
new file mode 100644
index 0000000..f2bb5c0
--- /dev/null
+++ b/lib/ManaTools/Module/Clock.pm
@@ -0,0 +1,518 @@
+# vim: set et ts=4 sw=4:
+package ManaTools::Module::Clock;
+#============================================================= -*-perl-*-
+
+=head1 NAME
+
+ManaTools::Module::Clock - This module aims to configure system clock and time
+
+=head1 SYNOPSIS
+
+ my $clockSettings = ManaTools::Module::Clock->new();
+ $clockSettings->start();
+
+=head1 DESCRIPTION
+
+Long_description
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command:
+
+perldoc ManaTools::Module::Clock
+
+=head1 SEE ALSO
+
+SEE_ALSO
+
+=head1 AUTHOR
+
+Angelo Naselli <anaselli@linux.it>
+
+=head1 COPYRIGHT and LICENSE
+
+Copyright (C) 2014-2015, Angelo Naselli.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2, as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+=head1 FUNCTIONS
+
+=cut
+
+use Moose;
+
+use diagnostics;
+
+use ManaTools::Shared::GUI;
+use ManaTools::Shared::Locales;
+use ManaTools::Shared::TimeZone;
+
+use Time::Piece;
+
+use yui;
+
+extends qw( ManaTools::Module );
+
+### TODO icon
+has '+icon' => (
+ default => "/usr/share/mcc/themes/default/time-mdk.png",
+);
+
+has 'loc' => (
+ is => 'rw',
+ init_arg => undef,
+ builder => '_localeInitialize'
+);
+
+sub _localeInitialize {
+ my $self = shift;
+
+ # TODO fix domain binding for translation
+ $self->loc(ManaTools::Shared::Locales->new(domain_name => 'libDrakX-standalone') );
+ # TODO if we want to give the opportunity to test locally add dir_name => 'path'
+}
+
+has 'sh_gui' => (
+ is => 'rw',
+ lazy => 1,
+ init_arg => undef,
+ builder => '_SharedGUIInitialize'
+);
+
+sub _SharedGUIInitialize {
+ my $self = shift;
+
+ $self->sh_gui(ManaTools::Shared::GUI->new() );
+}
+
+has 'sh_tz' => (
+ is => 'rw',
+ lazy => 1,
+ builder => '_SharedTimeZoneInitialize'
+);
+
+sub _SharedTimeZoneInitialize {
+ my $self = shift;
+
+ $self->sh_tz(ManaTools::Shared::TimeZone->new() );
+}
+
+
+=head1 VERSION
+
+Version 1.0.0
+
+=cut
+
+our $VERSION = '1.0.0';
+
+#=============================================================
+
+=head2 BUILD
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ The BUILD method is called after a Moose object is created,
+ in this methods Services loads all the service information.
+
+=cut
+
+#=============================================================
+sub BUILD {
+ my $self = shift;
+
+ if (! $self->name) {
+ $self->name ($self->loc->N("Date, Clock & Time Zone Settings"));
+ }
+}
+
+#=============================================================
+
+=head2 start
+
+=head3 INPUT
+
+ $self: this object
+
+=head3 DESCRIPTION
+
+ This method extends Module::start and is invoked to
+ start admin clock
+
+=cut
+
+#=============================================================
+sub start {
+ my $self = shift;
+
+ $self->_adminClockPanel();
+};
+
+### _get_NTPservers
+## returns ntp servers in the format
+## Zone|Nation: server
+#
+sub _get_NTPservers {
+ my $self = shift;
+
+ my $servs = $self->sh_tz->ntpServers();
+ [ map { "$servs->{$_}|$_" } sort { $servs->{$a} cmp $servs->{$b} || $a cmp $b } keys %$servs ];
+}
+
+### _restoreValues
+## restore NTP server and Time Zone from configuration files
+#
+## input '$datetime_only' restore date and time only
+#
+## returns 'info', a HASH references containing:
+## time_zone => time zone hash reference to be restored
+## ntp_server => ntp server address
+## date => date string
+## time => time string
+## ntp_running => is NTP running?
+#
+sub _restoreValues {
+ my ($self, $datetime_only) = @_;
+
+ my $info;
+ if (!$datetime_only) {
+ $info->{time_zone} = $self->sh_tz->readConfiguration();
+ $info->{ntp_server} = $self->sh_tz->ntpCurrentServer();
+ #- strip digits from \d+.foo.pool.ntp.org
+ $info->{ntp_server} =~ s/^\d+\.// if $info->{ntp_server};
+ $info->{ntp_running} = $self->sh_tz->isNTPRunning();
+ }
+ my $t = localtime;
+ my $day = $t->strftime("%F");
+ my $time = $t->strftime("%H:%M:%S");
+ $info->{date} = $day;
+ $info->{time} = $time;
+
+ return $info;
+}
+
+sub _adminClockPanel {
+ my $self = shift;
+
+ my $appTitle = yui::YUI::app()->applicationTitle();
+
+ ## set new title to get it in dialog
+ yui::YUI::app()->setApplicationTitle($self->name);
+ ## set icon if not already set by external launcher
+ yui::YUI::app()->setApplicationIcon($self->icon);
+
+ my $factory = yui::YUI::widgetFactory;
+ my $optFactory = yui::YUI::optionalWidgetFactory;
+ die "calendar widgets missing" if (!$optFactory->hasDateField() || !$optFactory->hasTimeField());
+
+ # Create Dialog
+ my $dialog = $factory->createMainDialog;
+# my $minSize = $factory->createMinSize($dialog, 40, 15);
+
+ # Start Dialog layout:
+ my $layout = $factory->createVBox($dialog);
+ my $align = $factory->createLeft($layout);
+
+ my $frame = $factory->createFrame($align, $self->loc->N("Setting date and time"));
+ my $hbox = $factory->createHBox($frame);
+
+ my $dateField = $optFactory->createDateField($hbox, "");
+ $factory->createHSpacing($hbox, 3.0);
+ my $timeField = $optFactory->createTimeField($hbox, "");
+ $factory->createHSpacing($hbox, 1.0);
+ $factory->createVSpacing($hbox, 1.0);
+ $factory->createVSpacing($layout, 1.0);
+
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ my $ntpFrame = $factory->createCheckBoxFrame($hbox, $self->loc->N("Enable Network Time Protocol"), 0);
+
+ my $hbox1 = $factory->createHBox($ntpFrame);
+ my $changeNTPButton = $factory->createPushButton($hbox1, $self->loc->N("Change &NTP server"));
+ $factory->createHSpacing($hbox1, 1.0);
+ $factory->createLabel($hbox1,$self->loc->N("Current:"));
+ $factory->createHSpacing($hbox1, 1.0);
+ my $ntpLabel = $factory->createLabel($hbox1, $self->loc->N("not defined"));
+ $factory->createHSpacing($hbox1, 1.0);
+ $ntpLabel->setWeight($yui::YD_HORIZ, 2);
+ $changeNTPButton->setWeight($yui::YD_HORIZ, 1);
+ $factory->createHSpacing($hbox, 1.0);
+
+ $factory->createVSpacing($layout, 1.0);
+ $align = $factory->createLeft($layout);
+ $hbox = $factory->createHBox($align);
+ $frame = $factory->createFrame ($hbox, $self->loc->N("TimeZone"));
+ $hbox1 = $factory->createHBox( $frame );
+ my $changeTZButton = $factory->createPushButton($hbox1, $self->loc->N("Change &Time Zone"));
+ $factory->createHSpacing($hbox1, 1.0);
+ $factory->createLabel($hbox1,$self->loc->N("Current:"));
+ $factory->createHSpacing($hbox1, 1.0);
+ my $timeZoneLbl = $factory->createLabel($hbox1, $self->loc->N("not defined"));
+ $factory->createHSpacing($hbox1, 1.0);
+ $timeZoneLbl->setWeight($yui::YD_HORIZ, 2);
+ $changeTZButton->setWeight($yui::YD_HORIZ, 1);
+
+ $factory->createHSpacing($hbox, 1.0);
+
+ # buttons on the last line
+ $factory->createVSpacing($layout, 1.0);
+ $hbox = $factory->createHBox($layout);
+
+ $align = $factory->createLeft($hbox);
+ $hbox = $factory->createHBox($align);
+ my $aboutButton = $factory->createPushButton($hbox, $self->loc->N("&About") );
+ my $resetButton = $factory->createPushButton($hbox, $self->loc->N("&Reset") );
+
+ $align = $factory->createRight($hbox);
+ $hbox = $factory->createHBox($align);
+ my $cancelButton = $factory->createPushButton($hbox, $self->loc->N("&Cancel"));
+ my $okButton = $factory->createPushButton($hbox, $self->loc->N("&Ok"));
+ $factory->createHSpacing($hbox, 1.0);
+
+ ## no changes by default
+ $dialog->setDefaultButton($cancelButton);
+
+ # End Dialof layout
+
+ ## default value
+ my $info = $self->_restoreValues();
+
+ $dateField->setValue($info->{date});
+ $timeField->setValue($info->{time});
+
+ if (exists $info->{time_zone} && $info->{time_zone}->{ZONE}) {
+ $timeZoneLbl->setValue($info->{time_zone}->{ZONE});
+ }
+
+ if ($info->{ntp_server}) {
+ $ntpLabel->setValue($info->{ntp_server});
+ }
+ $ntpFrame->setValue($info->{ntp_running});
+
+
+ # get only once
+ my $NTPservers = $self->_get_NTPservers();
+
+ while(1) {
+ my $event = $dialog->waitForEvent(1000);
+ my $eventType = $event->eventType();
+
+ #event type checking
+ if ($eventType == $yui::YEvent::CancelEvent) {
+ last;
+ }
+ elsif ($eventType == $yui::YEvent::TimeoutEvent) {
+ my $t = Time::Piece->strptime($timeField->value(), "%H:%M:%S") + 1;
+ $timeField->setValue($t->strftime("%H:%M:%S"));
+ }
+ elsif ($eventType == $yui::YEvent::WidgetEvent) {
+ # widget selected
+ my $widget = $event->widget();
+ if ($widget == $cancelButton) {
+ last;
+ }
+ elsif ($widget == $okButton) {
+ yui::YUI::app()->busyCursor();
+ my $finished = 1;
+ # (1) write new TZ settings
+ # (2) write new NTP settigs if checked
+ # (3) use date time fields if NTP is not checked
+
+ my $old_conf = $self->sh_tz->readConfiguration();
+ if ($info->{time_zone}->{UTC} != $old_conf->{UTC} ||
+ $info->{time_zone}->{ZONE} ne $old_conf->{ZONE}) {
+ # (1)
+ eval { $self->sh_tz->writeConfiguration($info->{time_zone}) };
+ my $errors = $@;
+ if ($errors) {
+ $finished = 0;
+ $self->sh_gui->warningMsgBox({
+ title => $self->loc->N("Write configuration failed"),
+ text => "$errors",
+ richtext => 1,
+ });
+ }
+ }
+ if ($ntpFrame->value()) {
+ # (2)
+ if ($info->{ntp_server}) {
+ eval { $self->sh_tz->setNTPServer($info->{ntp_server}) };
+ my $errors = $@;
+ if ($errors) {
+ $finished = 0;
+ $self->sh_gui->warningMsgBox({
+ title => $self->loc->N("Set NTP failed"),
+ text => "$errors",
+ richtext => 1,
+ });
+ }
+ }
+ else {
+ $self->sh_gui->warningMsgBox({text => $self->loc->N("Please enter a valid NTP server address.")});
+ $finished = 0;
+ }
+ }
+ else {
+ my $t = Time::Piece->strptime($dateField->value()."T".$timeField->value(),
+ "%Y-%m-%dT%H:%M:%S"
+ );
+ eval {
+ $self->sh_tz->disableAndStopNTP();
+ # (3)
+ $self->sh_tz->setTime($t->epoch());
+ };
+ my $errors = $@;
+ if ($errors) {
+ $finished = 0;
+ $self->sh_gui->warningMsgBox({
+ title => $self->loc->N("Set system time failed"),
+ text => "$errors",
+ richtext => 1,
+ });
+ }
+ }
+ yui::YUI::app()->normalCursor();
+
+ last if ($finished);
+ }
+ elsif ($widget == $changeNTPButton) {
+ # get time to calculate elapsed
+ my $t0 = localtime;
+ my $item = $self->sh_gui->ask_fromTreeList({title => $self->loc->N("NTP server - DrakClock"),
+ header => $self->loc->N("Choose your NTP server"),
+ default_button => 1,
+ item_separator => '|',
+ default_item => $info->{ntp_server},
+ skip_path => 1,
+ list => $NTPservers});
+ if ($item) {
+ $ntpLabel->setValue($item);
+ $info->{ntp_server} = $item;
+ }
+ # fixing elapsed time (dialog is modal)
+ my $t1 = localtime;
+ my $elapsed = $t1->epoch - $t0->epoch;
+
+ my $t = Time::Piece->strptime($dateField->value() . "T" . $timeField->value(),
+ '%Y-%m-%dT%H:%M:%S') + $elapsed;
+ $timeField->setValue($t->strftime("%H:%M:%S"));
+ $dateField->setValue($t->strftime("%F"));
+ }
+ elsif ($widget == $changeTZButton) {
+ # get time to calculate elapsed
+ my $t0 = localtime;
+ my $timezones = $self->sh_tz->getTimeZones();
+ if (!$timezones || scalar (@{$timezones}) == 0) {
+ $self->sh_gui->warningMsgBox({title => $self->loc->N("Timezone - DrakClock"),
+ text => $self->loc->N("Failed to retrieve timezone list"),
+ });
+ $changeTZButton->setDisabled();
+ }
+ else {
+ my $item = $self->sh_gui->ask_fromTreeList({title => $self->loc->N("Timezone - DrakClock"),
+ header => $self->loc->N("Which is your timezone?"),
+ default_button => 1,
+ item_separator => '/',
+ default_item => $info->{time_zone}->{ZONE},
+ list => $timezones});
+ if ($item) {
+ my $utc = 0;
+ if ($info->{time_zone}->{UTC} ) {
+ $utc = $info->{time_zone}->{UTC};
+ }
+ $utc = $self->sh_gui->ask_YesOrNo({
+ title => $self->loc->N("GMT - manaclock"),
+ text => $self->loc->N("Is your hardware clock set to GMT?"),
+ default_button => 1,
+ });
+ $info->{time_zone}->{UTC} = $utc;
+ $info->{time_zone}->{ZONE} = $item;
+ $timeZoneLbl->setValue($info->{time_zone}->{ZONE});
+ }
+ }
+ # fixing elapsed time (dialog is modal)
+ my $t1 = localtime;
+ my $elapsed = $t1->epoch - $t0->epoch;
+
+ my $t = Time::Piece->strptime($dateField->value() . "T" . $timeField->value(),
+ '%Y-%m-%dT%H:%M:%S') + $elapsed;
+ $timeField->setValue($t->strftime("%H:%M:%S"));
+ $dateField->setValue($t->strftime("%F"));
+ }
+ elsif ($widget == $resetButton) {
+ my $datetime_only = $self->sh_gui->ask_YesOrNo({
+ title => $self->loc->N("Restore data"),
+ text => $self->loc->N("Restore date and time only?"),
+ default_button => 1, #Yes
+ });
+ my $newInfo = $self->_restoreValues($datetime_only);
+ if ($datetime_only) {
+ $info->{date} = $newInfo->{date};
+ $info->{time} = $newInfo->{time};
+ }
+ else{
+ $info = $newInfo;
+ }
+
+ $dateField->setValue($info->{date});
+ $timeField->setValue($info->{time});
+ if (exists $info->{time_zone} && $info->{time_zone}->{ZONE}) {
+ $timeZoneLbl->setValue($info->{time_zone}->{ZONE});
+ }
+ else {
+ $timeZoneLbl->setValue($self->loc->N("not defined"));
+ }
+ if ($info->{ntp_server}) {
+ $ntpLabel->setValue($info->{ntp_server});
+ }
+ else {
+ $ntpLabel->setValue($self->loc->N("not defined"));
+ }
+ $ntpFrame->setValue($info->{ntp_running});
+ }
+ elsif($widget == $aboutButton) {
+ my $translators = $self->loc->N("_: Translator(s) name(s) & email(s)\n");
+ $translators =~ s/\</\&lt\;/g;
+ $translators =~ s/\>/\&gt\;/g;
+ $self->sh_gui->AboutDialog({ name => $self->name,
+ version => $self->VERSION,
+ credits => $self->loc->N("Copyright (C) %s Mageia community", '2014-2015'),
+ license => $self->loc->N("GPLv2"),
+ description => $self->loc->N("Date, Clock & Time Zone Settings allows to setup time zone and adjust date and time"),
+ authors => $self->loc->N("<h3>Developers</h3>
+ <ul><li>%s</li>
+ <li>%s</li>
+ </ul>
+ <h3>Translators</h3>
+ <ul><li>%s</li></ul>",
+ "Angelo Naselli &lt;anaselli\@linux.it&gt;",
+ $translators
+ ),
+ }
+ );
+ }
+ }
+ }
+ $dialog->destroy();
+
+ #restore old application title
+ yui::YUI::app()->setApplicationTitle($appTitle) if $appTitle;
+}
+
+
+