summaryrefslogtreecommitdiffstats
path: root/kcontrol/clock/dtime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/clock/dtime.cpp')
-rw-r--r--kcontrol/clock/dtime.cpp449
1 files changed, 449 insertions, 0 deletions
diff --git a/kcontrol/clock/dtime.cpp b/kcontrol/clock/dtime.cpp
new file mode 100644
index 000000000..ba8330c7a
--- /dev/null
+++ b/kcontrol/clock/dtime.cpp
@@ -0,0 +1,449 @@
+/*
+ * dtime.cpp
+ *
+ * Copyright (C) 1998 Luca Montecchiani <m.luca@usa.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qpushbutton.h>
+#include <qpainter.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qwhatsthis.h>
+#include <qcheckbox.h>
+#include <qregexp.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+#include <kdialog.h>
+#include <kconfig.h>
+
+#include "dtime.h"
+#include "dtime.moc"
+
+HMSTimeWidget::HMSTimeWidget(QWidget *parent, const char *name) :
+ KIntSpinBox(parent, name)
+{
+}
+
+QString HMSTimeWidget::mapValueToText(int value)
+{
+ QString s = QString::number(value);
+ if( value < 10 ) {
+ s = "0" + s;
+ }
+ return s;
+}
+
+Dtime::Dtime(QWidget * parent, const char *name)
+ : QWidget(parent, name)
+{
+ // *************************************************************
+ // Start Dialog
+ // *************************************************************
+
+ // Time Server
+
+ privateLayoutWidget = new QWidget( this, "layout1" );
+ QHBoxLayout *layout1 = new QHBoxLayout( privateLayoutWidget, 0, 0, "ntplayout");
+
+ setDateTimeAuto = new QCheckBox( privateLayoutWidget, "setDateTimeAuto" );
+ setDateTimeAuto->setText(i18n("Set date and time &automatically:"));
+ connect(setDateTimeAuto, SIGNAL(toggled(bool)), this, SLOT(serverTimeCheck()));
+ connect(setDateTimeAuto, SIGNAL(toggled(bool)), SLOT(configChanged()));
+ layout1->addWidget( setDateTimeAuto );
+
+ timeServerList = new QComboBox( false, privateLayoutWidget, "timeServerList" );
+ connect(timeServerList, SIGNAL(activated(int)), SLOT(configChanged()));
+ connect(timeServerList, SIGNAL(textChanged(const QString &)), SLOT(configChanged()));
+ connect(setDateTimeAuto, SIGNAL(toggled(bool)), timeServerList, SLOT(setEnabled(bool)));
+ timeServerList->setEnabled(false);
+ timeServerList->setEditable(true);
+ layout1->addWidget( timeServerList );
+ findNTPutility();
+
+ // Date box
+ QGroupBox* dateBox = new QGroupBox( this, "dateBox" );
+
+ QVBoxLayout *l1 = new QVBoxLayout( dateBox, KDialog::spacingHint() );
+
+ cal = new KDatePicker( dateBox );
+ cal->setMinimumSize(cal->sizeHint());
+ l1->addWidget( cal );
+ QWhatsThis::add( cal, i18n("Here you can change the system date's day of the month, month and year.") );
+
+ // Time frame
+ QGroupBox* timeBox = new QGroupBox( this, "timeBox" );
+
+ QVBoxLayout *v2 = new QVBoxLayout( timeBox, KDialog::spacingHint() );
+
+ kclock = new Kclock( timeBox, "kclock" );
+ kclock->setMinimumSize(150,150);
+ v2->addWidget( kclock );
+
+ QGridLayout *v3 = new QGridLayout( v2, 2, 9 );
+
+ // Even if the module's widgets are reversed (usually when using RTL
+ // languages), the placing of the time fields must always be H:M:S, from
+ // left to right.
+ bool isRTL = QApplication::reverseLayout();
+
+ QSpacerItem *spacer1 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ v3->addMultiCell(spacer1, 0, 1, 1, 1);
+
+ hour = new HMSTimeWidget( timeBox );
+ hour->setWrapping(true);
+ hour->setMaxValue(23);
+ hour->setValidator(new KStrictIntValidator(0, 23, hour));
+ v3->addMultiCellWidget(hour, 0, 1, isRTL ? 6 : 2, isRTL ? 6 : 2 );
+
+ QLabel *dots1 = new QLabel(":", timeBox);
+ dots1->setMinimumWidth( 7 );
+ dots1->setAlignment( QLabel::AlignCenter );
+ v3->addMultiCellWidget(dots1, 0, 1, 3, 3 );
+
+ minute = new HMSTimeWidget( timeBox );
+ minute->setWrapping(true);
+ minute->setMinValue(0);
+ minute->setMaxValue(59);
+ minute->setValidator(new KStrictIntValidator(0, 59, minute));
+ v3->addMultiCellWidget(minute, 0, 1, 4, 4 );
+
+ QLabel *dots2 = new QLabel(":", timeBox);
+ dots2->setMinimumWidth( 7 );
+ dots2->setAlignment( QLabel::AlignCenter );
+ v3->addMultiCellWidget(dots2, 0, 1, 5, 5 );
+
+ second = new HMSTimeWidget( timeBox );
+ second->setWrapping(true);
+ second->setMinValue(0);
+ second->setMaxValue(59);
+ second->setValidator(new KStrictIntValidator(0, 59, second));
+ v3->addMultiCellWidget(second, 0, 1, isRTL ? 2 : 6, isRTL ? 2 : 6 );
+
+ v3->addColSpacing(7, 7);
+
+ QString wtstr = i18n("Here you can change the system time. Click into the"
+ " hours, minutes or seconds field to change the relevant value, either"
+ " using the up and down buttons to the right or by entering a new value.");
+ QWhatsThis::add( hour, wtstr );
+ QWhatsThis::add( minute, wtstr );
+ QWhatsThis::add( second, wtstr );
+
+ QSpacerItem *spacer3 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
+ v3->addMultiCell(spacer3, 0, 1, 9, 9);
+
+ QGridLayout *top = new QGridLayout( this, 2,2, KDialog::spacingHint() );
+
+ top->addWidget(dateBox, 1,0);
+ top->addWidget(timeBox, 1,1);
+ top->addMultiCellWidget(privateLayoutWidget, 0,0, 0,1);
+
+ // *************************************************************
+ // End Dialog
+ // *************************************************************
+
+ connect( hour, SIGNAL(valueChanged(int)), SLOT(set_time()) );
+ connect( minute, SIGNAL(valueChanged(int)), SLOT(set_time()) );
+ connect( second, SIGNAL(valueChanged(int)), SLOT(set_time()) );
+ connect( cal, SIGNAL(dateChanged(QDate)), SLOT(changeDate(QDate)));
+
+ connect( &internalTimer, SIGNAL(timeout()), SLOT(timeout()) );
+
+ load();
+
+ if (getuid() != 0)
+ {
+ cal->setEnabled(false);
+ hour->setEnabled(false);
+ minute->setEnabled(false);
+ second->setEnabled(false);
+ timeServerList->setEnabled(false);
+ setDateTimeAuto->setEnabled(false);
+ }
+ kclock->setEnabled(false);
+}
+
+void Dtime::serverTimeCheck() {
+ bool enabled = !setDateTimeAuto->isChecked();
+ cal->setEnabled(enabled);
+ hour->setEnabled(enabled);
+ minute->setEnabled(enabled);
+ second->setEnabled(enabled);
+ //kclock->setEnabled(enabled);
+}
+
+void Dtime::findNTPutility(){
+ KProcess proc;
+ proc << "which" << "ntpdate";
+ proc.start(KProcess::Block);
+ if(proc.exitStatus() == 0) {
+ ntpUtility = "ntpdate";
+ kdDebug() << "ntpUtility = " << ntpUtility.latin1() << endl;
+ return;
+ }
+ proc.clearArguments();
+ proc << "which" << "rdate";
+ proc.start(KProcess::Block);
+ if(proc.exitStatus() == 0) {
+ ntpUtility = "rdate";
+ kdDebug() << "ntpUtility = " << ntpUtility.latin1() << endl;
+ return;
+ }
+ privateLayoutWidget->hide();
+ kdDebug() << "ntpUtility not found!" << endl;
+}
+
+void Dtime::set_time()
+{
+ if( ontimeout )
+ return;
+
+ internalTimer.stop();
+
+ time.setHMS( hour->value(), minute->value(), second->value() );
+ kclock->setTime( time );
+
+ emit timeChanged( TRUE );
+}
+
+void Dtime::changeDate(QDate d)
+{
+ date = d;
+ emit timeChanged( TRUE );
+}
+
+void Dtime::configChanged(){
+ emit timeChanged( TRUE );
+}
+
+void Dtime::load()
+{
+ KConfig config("kcmclockrc", true, false);
+ config.setGroup("NTP");
+ timeServerList->insertStringList(QStringList::split(',', config.readEntry("servers",
+ i18n("Public Time Server (pool.ntp.org),\
+asia.pool.ntp.org,\
+europe.pool.ntp.org,\
+north-america.pool.ntp.org,\
+oceania.pool.ntp.org"))));
+ setDateTimeAuto->setChecked(config.readBoolEntry("enabled", false));
+
+ // Reset to the current date and time
+ time = QTime::currentTime();
+ date = QDate::currentDate();
+ cal->setDate(date);
+
+ // start internal timer
+ internalTimer.start( 1000 );
+
+ timeout();
+}
+
+void Dtime::save()
+{
+ KConfig config("kcmclockrc", false, false);
+ config.setGroup("NTP");
+
+ // Save the order, but don't duplicate!
+ QStringList list;
+ if( timeServerList->count() != 0)
+ list.append(timeServerList->currentText());
+ for ( int i=0; i<timeServerList->count();i++ ) {
+ QString text = timeServerList->text(i);
+ if( list.find(text) == list.end())
+ list.append(text);
+ // Limit so errors can go away and not stored forever
+ if( list.count() == 10)
+ break;
+ }
+ config.writeEntry("servers", list.join(","));
+ config.writeEntry("enabled", setDateTimeAuto->isChecked());
+
+ if(setDateTimeAuto->isChecked() && !ntpUtility.isEmpty()){
+ // NTP Time setting
+ QString timeServer = timeServerList->currentText();
+ if( timeServer.find( QRegExp(".*\\(.*\\)$") ) != -1 ) {
+ timeServer.replace( QRegExp(".*\\("), "" );
+ timeServer.replace( QRegExp("\\).*"), "" );
+ // Would this be better?: s/^.*\(([^)]*)\).*$/\1/
+ }
+ KProcess proc;
+ proc << ntpUtility << timeServer;
+ proc.start( KProcess::Block );
+ if( proc.exitStatus() != 0 ){
+ KMessageBox::error( this, i18n(QString("Unable to contact time server: %1.").arg(timeServer).latin1()));
+ setDateTimeAuto->setChecked( false );
+ }
+ else {
+ // success
+ kdDebug() << "Set date from time server " << timeServer.latin1() << " success!" << endl;
+ }
+ }
+ else {
+ // User time setting
+ KProcess c_proc;
+
+ // BSD systems reverse year compared to Susv3
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+ BufS.sprintf("%04d%02d%02d%02d%02d.%02d",
+ date.year(),
+ date.month(), date.day(),
+ hour->value(), minute->value(), second->value());
+#else
+ BufS.sprintf("%02d%02d%02d%02d%04d.%02d",
+ date.month(), date.day(),
+ hour->value(), minute->value(),
+ date.year(), second->value());
+#endif
+
+ kdDebug() << "Set date " << BufS << endl;
+
+ c_proc << "date" << BufS;
+ c_proc.start( KProcess::Block );
+ int result = c_proc.exitStatus();
+ if (result != 0
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+ && result != 2 // can only set local date, which is okay
+#endif
+ ) {
+ KMessageBox::error( this, i18n("Can not set date."));
+ return;
+ }
+
+ // try to set hardware clock. We do not care if it fails
+ KProcess hwc_proc;
+ hwc_proc << "hwclock" << "--systohc";
+ hwc_proc.start(KProcess::Block);
+ }
+
+ // restart time
+ internalTimer.start( 1000 );
+}
+
+void Dtime::timeout()
+{
+ // get current time
+ time = QTime::currentTime();
+
+ ontimeout = TRUE;
+ second->setValue(time.second());
+ minute->setValue(time.minute());
+ hour->setValue(time.hour());
+ ontimeout = FALSE;
+
+ kclock->setTime( time );
+}
+
+QString Dtime::quickHelp() const
+{
+ return i18n("<h1>Date & Time</h1> This control module can be used to set the system date and"
+ " time. As these settings do not only affect you as a user, but rather the whole system, you"
+ " can only change these settings when you start the Control Center as root. If you do not have"
+ " the root password, but feel the system time should be corrected, please contact your system"
+ " administrator.");
+}
+
+void Kclock::setTime(const QTime &time)
+{
+ this->time = time;
+ repaint();
+}
+
+void Kclock::paintEvent( QPaintEvent * )
+{
+ if ( !isVisible() )
+ return;
+
+ QPainter paint;
+ paint.begin( this );
+
+ QPointArray pts;
+ QPoint cp = rect().center();
+ int d = QMIN(width(),height());
+ QColor hands = colorGroup().dark();
+ QColor shadow = colorGroup().text();
+ paint.setPen( shadow );
+ paint.setBrush( shadow );
+ paint.setViewport(4,4,width(),height());
+
+ for ( int c=0 ; c < 2 ; c++ )
+ {
+ QWMatrix matrix;
+ matrix.translate( cp.x(), cp.y() );
+ matrix.scale( d/1000.0F, d/1000.0F );
+
+ // lancetta delle ore
+ float h_angle = 30*(time.hour()%12-3) + time.minute()/2;
+ matrix.rotate( h_angle );
+ paint.setWorldMatrix( matrix );
+ pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
+ paint.drawPolygon( pts );
+ matrix.rotate( -h_angle );
+
+ // lancetta dei minuti
+ float m_angle = (time.minute()-15)*6;
+ matrix.rotate( m_angle );
+ paint.setWorldMatrix( matrix );
+ pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
+ paint.drawPolygon( pts );
+ matrix.rotate( -m_angle );
+
+ // lancetta dei secondi
+ float s_angle = (time.second()-15)*6;
+ matrix.rotate( s_angle );
+ paint.setWorldMatrix( matrix );
+ pts.setPoints(4,0,0,0,0,400,0,0,0);
+ paint.drawPolygon( pts );
+ matrix.rotate( -s_angle );
+
+ // quadrante
+ for ( int i=0 ; i < 60 ; i++ )
+ {
+ paint.setWorldMatrix( matrix );
+ if ( (i % 5) == 0 )
+ paint.drawLine( 450,0, 500,0 ); // draw hour lines
+ else paint.drawPoint( 480,0 ); // draw second lines
+ matrix.rotate( 6 );
+ }
+
+ paint.setPen( hands );
+ paint.setBrush( hands );
+ paint.setViewport(0,0,width(),height());
+ }
+ paint.end();
+}
+
+QValidator::State KStrictIntValidator::validate( QString & input, int & d ) const
+{
+ if( input.isEmpty() )
+ return Valid;
+
+ State st = QIntValidator::validate( input, d );
+
+ if( st == Intermediate )
+ return Invalid;
+
+ return st;
+}