4 * Copyright (C) 1998 Luca Montecchiani <m.luca@usa.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include <sys/types.h>
29 #include <QtGui/QGroupBox>
30 #include <QPushButton>
37 #include <QPaintEvent>
38 #include <QGridLayout>
39 #include <QHBoxLayout>
40 #include <QVBoxLayout>
41 #include <QApplication>
46 #include <kstandarddirs.h>
47 #include <kmessagebox.h>
50 #include <kcolorscheme.h>
56 HMSTimeWidget::HMSTimeWidget(QWidget
*parent
) :
61 QString
HMSTimeWidget::mapValueToText(int value
)
63 QString s
= QString::number(value
);
70 Dtime::Dtime(QWidget
* parent
)
73 // *************************************************************
75 // *************************************************************
79 privateLayoutWidget
= new QWidget( this );
80 QHBoxLayout
*layout1
= new QHBoxLayout( privateLayoutWidget
);
81 layout1
->setObjectName( "ntplayout" );
82 layout1
->setSpacing( 0 );
83 layout1
->setMargin( 0 );
85 setDateTimeAuto
= new QCheckBox( privateLayoutWidget
);
86 setDateTimeAuto
->setObjectName( "setDateTimeAuto" );
87 setDateTimeAuto
->setText(i18n("Set date and time &automatically:"));
88 connect(setDateTimeAuto
, SIGNAL(toggled(bool)), this, SLOT(serverTimeCheck()));
89 connect(setDateTimeAuto
, SIGNAL(toggled(bool)), SLOT(configChanged()));
90 layout1
->addWidget( setDateTimeAuto
);
92 timeServerList
= new QComboBox( privateLayoutWidget
);
93 timeServerList
->setObjectName( "timeServerList" );
94 timeServerList
->setEditable(false);
95 connect(timeServerList
, SIGNAL(activated(int)), SLOT(configChanged()));
96 connect(timeServerList
, SIGNAL(editTextChanged(const QString
&)), SLOT(configChanged()));
97 connect(setDateTimeAuto
, SIGNAL(toggled(bool)), timeServerList
, SLOT(setEnabled(bool)));
98 timeServerList
->setEnabled(false);
99 timeServerList
->setEditable(true);
100 layout1
->addWidget( timeServerList
);
104 QGroupBox
* dateBox
= new QGroupBox( this );
105 dateBox
->setObjectName( QLatin1String( "dateBox" ) );
107 QVBoxLayout
*l1
= new QVBoxLayout( dateBox
);
109 l1
->setSpacing( KDialog::spacingHint() );
111 cal
= new KDatePicker( dateBox
);
112 cal
->setMinimumSize(cal
->sizeHint());
113 l1
->addWidget( cal
);
114 cal
->setWhatsThis( i18n("Here you can change the system date's day of the month, month and year.") );
117 QGroupBox
* timeBox
= new QGroupBox( this );
118 timeBox
->setObjectName( QLatin1String( "timeBox" ) );
120 QVBoxLayout
*v2
= new QVBoxLayout( timeBox
);
122 v2
->setSpacing( KDialog::spacingHint() );
124 kclock
= new Kclock( timeBox
);
125 kclock
->setObjectName("Kclock");
126 kclock
->setMinimumSize(150,150);
127 v2
->addWidget( kclock
);
129 QGridLayout
*v3
= new QGridLayout( );
132 // Even if the module's widgets are reversed (usually when using RTL
133 // languages), the placing of the time fields must always be H:M:S, from
135 bool isRTL
= QApplication::isRightToLeft();
137 QSpacerItem
*spacer1
= new QSpacerItem( 20, 20, QSizePolicy::Expanding
, QSizePolicy::Minimum
);
138 v3
->addItem(spacer1
, 0, 1, 2, 1);
140 hour
= new HMSTimeWidget( timeBox
);
141 hour
->setWrapping(true);
142 hour
->setMaximum(23);
144 #warning fixme hour->setValidator(new KStrictIntValidator(0, 23, hour));
146 v3
->addWidget(hour
, 0, isRTL
? 6 : 2, 2, 1);
148 QLabel
*dots1
= new QLabel(":", timeBox
);
149 dots1
->setMinimumWidth( 7 );
150 dots1
->setAlignment( Qt::AlignCenter
);
151 v3
->addWidget(dots1
, 0, 3, 2, 1);
153 minute
= new HMSTimeWidget( timeBox
);
154 minute
->setWrapping(true);
155 minute
->setMinimum(0);
156 minute
->setMaximum(59);
158 #warning fixme minute->setValidator(new KStrictIntValidator(0, 59, minute));
160 v3
->addWidget(minute
, 0, 4, 2, 1);
162 QLabel
*dots2
= new QLabel(":", timeBox
);
163 dots2
->setMinimumWidth( 7 );
164 dots2
->setAlignment( Qt::AlignCenter
);
165 v3
->addWidget(dots2
, 0, 5, 2, 1);
167 second
= new HMSTimeWidget( timeBox
);
168 second
->setWrapping(true);
169 second
->setMinimum(0);
170 second
->setMaximum(59);
172 #warning fixme second->setValidator(new KStrictIntValidator(0, 59, second));
174 v3
->addWidget(second
, 0, isRTL
? 2 : 6, 2, 1);
176 v3
->addItem(new QSpacerItem(7, 0), 0, 7);
178 QString wtstr
= i18n("Here you can change the system time. Click into the"
179 " hours, minutes or seconds field to change the relevant value, either"
180 " using the up and down buttons to the right or by entering a new value.");
181 hour
->setWhatsThis( wtstr
);
182 minute
->setWhatsThis( wtstr
);
183 second
->setWhatsThis( wtstr
);
185 QSpacerItem
*spacer3
= new QSpacerItem( 20, 20, QSizePolicy::Expanding
, QSizePolicy::Minimum
);
186 v3
->addItem(spacer3
, 0, 9, 2, 1);
188 QGridLayout
*top
= new QGridLayout( this );
190 top
->setSpacing( KDialog::spacingHint() );
192 top
->addWidget(dateBox
, 1,0);
193 top
->addWidget(timeBox
, 1,1);
194 top
->addWidget(privateLayoutWidget
, 0, 0, 1, 2 );
196 // *************************************************************
198 // *************************************************************
200 connect( hour
, SIGNAL(valueChanged(int)), SLOT(set_time()) );
201 connect( minute
, SIGNAL(valueChanged(int)), SLOT(set_time()) );
202 connect( second
, SIGNAL(valueChanged(int)), SLOT(set_time()) );
203 connect( cal
, SIGNAL(dateChanged(QDate
)), SLOT(changeDate(QDate
)));
205 connect( &internalTimer
, SIGNAL(timeout()), SLOT(timeout()) );
209 kclock
->setEnabled(false);
212 void Dtime::serverTimeCheck() {
213 bool enabled
= !setDateTimeAuto
->isChecked();
214 cal
->setEnabled(enabled
);
215 hour
->setEnabled(enabled
);
216 minute
->setEnabled(enabled
);
217 second
->setEnabled(enabled
);
218 //kclock->setEnabled(enabled);
221 void Dtime::findNTPutility(){
222 if(!KStandardDirs::findExe("ntpdate").isEmpty()) {
223 ntpUtility
= "ntpdate";
224 kDebug() << "ntpUtility = " << ntpUtility
;
227 if(!KStandardDirs::findExe("rdate").isEmpty()) {
228 ntpUtility
= "rdate";
229 kDebug() << "ntpUtility = " << ntpUtility
;
232 privateLayoutWidget
->hide();
233 kDebug() << "ntpUtility not found!";
236 void Dtime::set_time()
241 internalTimer
.stop();
243 time
.setHMS( hour
->value(), minute
->value(), second
->value() );
244 kclock
->setTime( time
);
246 emit
timeChanged( true );
249 void Dtime::changeDate(const QDate
&d
)
252 emit
timeChanged( true );
255 void Dtime::configChanged(){
256 emit
timeChanged( true );
261 // The config is actually written to the system config, but the user does not have any local config,
262 // since there is nothing writing it.
263 KConfig
_config( "kcmclockrc", KConfig::NoGlobals
);
264 KConfigGroup
config(&_config
, "NTP");
265 timeServerList
->addItems(config
.readEntry("servers",
266 i18n("Public Time Server (pool.ntp.org),\
268 europe.pool.ntp.org,\
269 north-america.pool.ntp.org,\
270 oceania.pool.ntp.org")).split(',', QString::SkipEmptyParts
));
271 setDateTimeAuto
->setChecked(config
.readEntry("enabled", false));
273 // Reset to the current date and time
274 time
= QTime::currentTime();
275 date
= QDate::currentDate();
278 // start internal timer
279 internalTimer
.start( 1000 );
284 void Dtime::save( QStringList
& helperargs
)
286 // Save the order, but don't duplicate!
288 if( timeServerList
->count() != 0)
289 list
.append(timeServerList
->currentText());
290 for ( int i
=0; i
<timeServerList
->count();i
++ ) {
291 QString text
= timeServerList
->itemText(i
);
292 if( !list
.contains(text
) )
294 // Limit so errors can go away and not stored forever
295 if( list
.count() == 10)
298 helperargs
<< "ntp" << QString::number( list
.count()) << list
299 << ( setDateTimeAuto
->isChecked() ? "enabled" : "disabled" );
301 if(setDateTimeAuto
->isChecked() && !ntpUtility
.isEmpty()){
302 // NTP Time setting - done in helper
303 timeServer
= timeServerList
->currentText();
304 kDebug() << "Setting date from time server " << timeServer
;
309 QTime(hour
->value(), minute
->value(), second
->value()));
311 kDebug() << "Set date " << dt
;
313 helperargs
<< "date" << QString::number(dt
.toTime_t())
314 << QString::number(::time(0));
318 internalTimer
.start( 1000 );
321 void Dtime::processHelperErrors( int code
)
323 if( code
& ERROR_DTIME_NTP
) {
324 KMessageBox::error( this, i18n("Unable to contact time server: %1.", timeServer
) );
325 setDateTimeAuto
->setChecked( false );
327 if( code
& ERROR_DTIME_DATE
) {
328 KMessageBox::error( this, i18n("Can not set date."));
332 void Dtime::timeout()
335 time
= QTime::currentTime();
338 second
->setValue(time
.second());
339 minute
->setValue(time
.minute());
340 hour
->setValue(time
.hour());
343 kclock
->setTime( time
);
346 QString
Dtime::quickHelp() const
348 return i18n("<h1>Date & Time</h1> This control module can be used to set the system date and"
349 " time. As these settings do not only affect you as a user, but rather the whole system, you"
350 " can only change these settings when you start the Control Center as root. If you do not have"
351 " the root password, but feel the system time should be corrected, please contact your system"
355 void Kclock::setTime(const QTime
&time
)
361 void Kclock::paintEvent( QPaintEvent
* )
369 paint
.setRenderHint(QPainter::Antialiasing
);
372 QPoint cp
= rect().center();
373 int d
= qMin(width(),height());
375 KColorScheme
colorScheme( QPalette::Normal
);
376 QColor hands
= colorScheme
.foreground(KColorScheme::NormalText
).color();
378 paint
.setPen( hands
);
379 paint
.setBrush( hands
);
380 paint
.setViewport(4,4,width(),height());
383 matrix
.translate( cp
.x(), cp
.y() );
384 matrix
.scale( d
/1000.0F
, d
/1000.0F
);
387 float h_angle
= 30*(time
.hour()%12-3) + time
.minute()/2;
388 matrix
.rotate( h_angle
);
389 paint
.setWorldTransform( matrix
);
390 pts
.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
391 paint
.drawPolygon( pts
);
392 matrix
.rotate( -h_angle
);
395 float m_angle
= (time
.minute()-15)*6;
396 matrix
.rotate( m_angle
);
397 paint
.setWorldTransform( matrix
);
398 pts
.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
399 paint
.drawPolygon( pts
);
400 matrix
.rotate( -m_angle
);
403 float s_angle
= (time
.second()-15)*6;
404 matrix
.rotate( s_angle
);
405 paint
.setWorldTransform( matrix
);
406 pts
.setPoints(4,0,0,0,0,400,0,0,0);
407 paint
.drawPolygon( pts
);
408 matrix
.rotate( -s_angle
);
411 for ( int i
=0 ; i
< 60 ; i
++ ) {
412 paint
.setWorldTransform( matrix
);
414 paint
.drawLine( 450,0, 500,0 ); // draw hour lines
415 else paint
.drawPoint( 480,0 ); // draw second lines
422 QValidator::State
KStrictIntValidator::validate( QString
& input
, int & d
) const
424 if( input
.isEmpty() )
427 State st
= QIntValidator::validate( input
, d
);
429 if( st
== Intermediate
)