Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

mainwindow.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003 
00004                              Copyright (C) Opie Team <opie-devel@handhelds.org>
00005               =.
00006             .=l.
00007            .>+-=
00008  _;:,     .>    :=|.         This program is free software; you can
00009 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00010 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00011 .="- .-=="i,     .._         License as published by the Free Software
00012  - .   .-<_>     .<>         Foundation; either version 2 of the License,
00013      ._= =}       :          or (at your option) any later version.
00014     .%`+i>       _;_.
00015     .i_,=:_.      -<s.       This program is distributed in the hope that
00016      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00017     : ..    .:,     . . .    without even the implied warranty of
00018     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00019   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00020 ..}^=.=       =       ;      Library General Public License for more
00021 ++=   -.     .`     .:       details.
00022 :     =  ...= . :.=-
00023  -.   .:....=;==+<;          You should have received a copy of the GNU
00024   -_. . .   )=.  =           Library General Public License along with
00025     --        :-=`           this library; see the file COPYING.LIB.
00026                              If not, write to the Free Software Foundation,
00027                              Inc., 59 Temple Place - Suite 330,
00028                              Boston, MA 02111-1307, USA.
00029 */
00030 
00031 #include "mainwindow.h"
00032 #include "timetabwidget.h"
00033 #include "formattabwidget.h"
00034 #include "settingstabwidget.h"
00035 #include "ntptabwidget.h"
00036 #include "predicttabwidget.h"
00037 
00038 #include <qpe/config.h>
00039 #include <qpe/datebookdb.h>
00040 #include <qpe/qpeapplication.h>
00041 #include <qpe/qpedialog.h>
00042 
00043 #if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
00044 #include <qpe/qcopenvelope_qws.h>
00045 #endif
00046 
00047 #include <qlayout.h>
00048 #include <qmessagebox.h>
00049 #include <qsocket.h>
00050 #include <qstring.h>
00051 #include <qtimer.h>
00052 
00053 using namespace Opie::Ui;
00054 using namespace Opie::Core;
00055 MainWindow::MainWindow( QWidget *parent , const char *name,  bool modal, WFlags f )
00056     : QDialog( parent, name, modal, f )
00057 {
00058     setCaption( tr( "SystemTime" ) );
00059 
00060     QVBoxLayout *layout = new QVBoxLayout( this );
00061     layout->setMargin( 2 );
00062     layout->setSpacing( 4 );
00063 
00064     // Create main tabbed control
00065     mainWidget = new OTabWidget( this );
00066 
00067     // Default object pointers to null
00068     ntpProcess = 0x0;
00069     ntpTab = 0x0;
00070     predictTab = 0x0;
00071 
00072     // Add tab widgets
00073     mainWidget->addTab( timeTab = new TimeTabWidget( mainWidget ), "netsystemtime/DateTime", tr( "Time" ) );
00074     mainWidget->addTab( formatTab = new FormatTabWidget( mainWidget ), "netsystemtime/formattab", tr( "Format" ) );
00075     mainWidget->addTab( settingsTab = new SettingsTabWidget( mainWidget ), "SettingsIcon", tr( "Settings" ) );
00076     Config config( "ntp" );
00077     config.setGroup( "settings" );
00078     slotDisplayNTPTab( config.readBoolEntry( "displayNtpTab", false ) );
00079     slotDisplayPredictTab( config.readBoolEntry( "displayPredictTab", false ) );
00080 
00081     mainWidget->setCurrentTab( tr( "Time" ) );
00082     layout->addWidget( mainWidget );
00083 
00084     connect( qApp, SIGNAL(appMessage(const QCString&,const QByteArray&)),
00085         this, SLOT(slotQCopReceive(const QCString&,const QByteArray&)) );
00086 
00087 
00088     // Create NTP socket
00089     ntpSock = new QSocket( this );
00090     connect( ntpSock, SIGNAL(error(int)),SLOT(slotCheckNtp(int)) );
00091     slotProbeNTPServer();
00092 
00093     // Create timer for automatic time lookups
00094     ntpTimer = new QTimer( this );
00095 
00096     // Connect everything together
00097     connect( timeTab, SIGNAL(getNTPTime()), this, SLOT(slotGetNTPTime()) );
00098     connect( timeTab, SIGNAL(tzChanged(const QString&)), predictTab, SLOT(slotTZChanged(const QString&)) );
00099     connect( timeTab, SIGNAL(getPredictedTime()), predictTab, SLOT(slotSetPredictedTime()) );
00100     connect( formatTab, SIGNAL(show12HourTime(int)), timeTab, SLOT(slotUse12HourTime(int)) );
00101     connect( formatTab, SIGNAL(dateFormatChanged(const DateFormat&)),
00102              timeTab, SLOT(slotDateFormatChanged(const DateFormat&)) );
00103     connect( formatTab, SIGNAL(weekStartChanged(int)), timeTab, SLOT(slotWeekStartChanged(int)) );
00104     connect( settingsTab, SIGNAL(ntpDelayChanged(int)), this, SLOT(slotNTPDelayChanged(int)) );
00105     connect( settingsTab, SIGNAL(displayNTPTab(bool)), this, SLOT(slotDisplayNTPTab(bool)) );
00106     connect( settingsTab, SIGNAL(displayPredictTab(bool)), this, SLOT(slotDisplayPredictTab(bool)) );
00107     connect( predictTab, SIGNAL(setTime(const QDateTime&)), this, SLOT(slotSetTime(const QDateTime&)) );
00108 
00109     // Do initial time server check
00110     slotNTPDelayChanged( config.readNumEntry( "ntpRefreshFreq", 1440 ) );
00111     slotCheckNtp( -1 );
00112 
00113     // Display app
00114     //showMaximized();
00115     (void)new QPEDialogListener(this);
00116 }
00117 
00118 MainWindow::~MainWindow()
00119 {
00120     if ( ntpProcess )
00121         delete ntpProcess;
00122 }
00123 
00124 void MainWindow::accept()
00125 {
00126     // Turn off the screensaver (Note: needs to be encased in { } so that it deconstructs and sends)
00127     {
00128         QCopEnvelope disableScreenSaver( "QPE/System", "setScreenSaverIntervals(int,int,int)" );
00129         disableScreenSaver << 0 << 0 << 0;
00130     }
00131 
00132     // Update the systemtime
00133     timeTab->saveSettings( true );
00134 
00135     // Save format options
00136     formatTab->saveSettings( true );
00137 
00138     // Save settings options
00139     settingsTab->saveSettings();
00140 
00141     // Since time has changed quickly load in the DateBookDB to allow the alarm server to get a better
00142     // grip on itself (example re-trigger alarms for when we travel back in time).
00143     DateBookDB db;
00144 
00145     // Turn back on the screensaver
00146     QCopEnvelope enableScreenSaver( "QPE/System", "setScreenSaverIntervals(int,int,int)" );
00147     enableScreenSaver << -1 << -1 << -1;
00148 
00149     // Exit app
00150     qApp->quit();
00151 }
00152 
00153 void MainWindow::reject()
00154 {
00155     // Reset time settings
00156     timeTab->saveSettings( false );
00157 
00158     // Send notifications but do not save settings
00159     formatTab->saveSettings( false );
00160 
00161     // Exit app
00162     qApp->quit();
00163 }
00164 
00165 void MainWindow::runNTP()
00166 {
00167     if ( !ntpDelayElapsed() && ntpInteractive )
00168     {
00169         QString msg = tr( "You asked for a delay of %1 minutes, but only %2 minutes elapsed since last lookup.<br>Continue?" ).arg( QString::number( ntpDelay ) ).arg( QString::number( _lookupDiff / 60 ) );
00170 
00171         switch (
00172             QMessageBox::warning( this, tr( "Continue?" ), msg, QMessageBox::Yes, QMessageBox::No )
00173             )
00174         {
00175             case QMessageBox::Yes: break;
00176             case QMessageBox::No:  return;
00177             default: return;
00178         }
00179     }
00180 
00181     QString srv = settingsTab->ntpServer();
00182 
00183     // Send information to time server tab if enabled
00184     if ( ntpTabEnabled )
00185     {
00186         ntpTab->setStartTime( QDateTime::currentDateTime().toString() );
00187         QString output = tr( "Running:\nntpdate " );
00188         output.append( srv );
00189         ntpTab->addNtpOutput( output );
00190         ntpTab->setNTPBtnEnabled( false );
00191     }
00192 
00193     // Disable set time buttons & change app caption to indicate time update is happening
00194     timeTab->setNTPBtnEnabled( false );
00195     setCaption( tr( "Retrieving time from network..." ) );
00196 
00197     if ( !ntpProcess )
00198     {
00199         ntpProcess = new OProcess();
00200         connect( ntpProcess, SIGNAL(receivedStdout(Opie::Core::OProcess*,char*,int)),
00201                  this, SLOT(slotNtpOutput(Opie::Core::OProcess*,char*,int)) );
00202         connect( ntpProcess, SIGNAL(processExited(Opie::Core::OProcess*)),
00203                  this, SLOT(slotNtpFinished(Opie::Core::OProcess*)) );
00204     }
00205 
00206     else
00207         ntpProcess->clearArguments();
00208 
00209     *ntpProcess << "ntpdate"  << srv;
00210     bool ret = ntpProcess->start( OProcess::NotifyOnExit, OProcess::AllOutput );
00211     if ( !ret )
00212     {
00213         QMessageBox::critical( this, tr( "Error" ), tr( "Error while getting time from network." ) );
00214         if ( ntpTabEnabled )
00215         {
00216             ntpTab->addNtpOutput( tr( "Error while executing ntpdate" ) );
00217             ntpTab->setNTPBtnEnabled( true );
00218         }
00219 
00220         // Re-enable set time buttons & change app caption to indicate time update is happening
00221         timeTab->setNTPBtnEnabled( true );
00222         setCaption( tr( "SystemTime" ) );
00223     }
00224 }
00225 
00226 bool MainWindow::ntpDelayElapsed()
00227 {
00228     // Determine if time elapsed is greater than time delay
00229     Config config( "ntp" );
00230     config.setGroup( "lookups" );
00231     _lookupDiff = TimeConversion::toUTC( QDateTime::currentDateTime() ) - config.readNumEntry( "time", 0 );
00232     if ( _lookupDiff < 0 )
00233         return true;
00234     return ( _lookupDiff - ( ntpDelay * 60) ) > 0;
00235 }
00236 
00237 void MainWindow::slotSetTime( const QDateTime &dt )
00238 {
00239     timeTab->setDateTime( dt );
00240 }
00241 
00242 void MainWindow::slotQCopReceive( const QCString &msg, const QByteArray & )
00243 {
00244     if ( msg == "ntpLookup(QString)" )
00245     {
00246         ntpInteractive = false;
00247         runNTP();
00248     }
00249     if ( msg == "setPredictedTime(QString)" )
00250     {
00251         //setPredictTime();
00252     }
00253 }
00254 
00255 void MainWindow::slotDisplayNTPTab( bool display )
00256 {
00257     ntpTabEnabled = display;
00258 
00259     // Create widget if it hasn't needed
00260     if ( display && !ntpTab )
00261     {
00262         ntpTab = new NTPTabWidget( mainWidget );
00263         connect( ntpTab, SIGNAL(getNTPTime()), this, SLOT(slotGetNTPTime()) );
00264     }
00265 
00266     // Display/hide tab
00267     display ? mainWidget->addTab( ntpTab, "netsystemtime/ntptab", tr( "Time Server" ) )
00268             : mainWidget->removePage( ntpTab );
00269 }
00270 
00271 void MainWindow::slotDisplayPredictTab( bool display )
00272 {
00273     predictTabEnabled = display;
00274 
00275     // Create widget if it hasn't needed
00276     if ( display && !predictTab )
00277     {
00278         predictTab = new PredictTabWidget( mainWidget );
00279     }
00280     // Display/hide tab
00281     display ? mainWidget->addTab( predictTab, "netsystemtime/predicttab", tr( "Predict" ) )
00282             : mainWidget->removePage( predictTab );
00283 }
00284 
00285 void MainWindow::slotGetNTPTime()
00286 {
00287     ntpInteractive = true;
00288     runNTP();
00289 }
00290 
00291 void MainWindow::slotTimerGetNTPTime()
00292 {
00293     ntpInteractive = false;
00294     runNTP();
00295 }
00296 
00297 void MainWindow::slotProbeNTPServer()
00298 {
00299     ntpSock->connectToHost( settingsTab->ntpServer(), 123 );
00300 }
00301 
00302 void MainWindow::slotNtpOutput( OProcess *, char *buffer, int buflen )
00303 {
00304     QString output = QString( buffer ).left( buflen );
00305     ntpOutput.append( output );
00306 
00307     if ( ntpTabEnabled )
00308         ntpTab->addNtpOutput( output );
00309 }
00310 
00311 void MainWindow::slotNtpFinished( OProcess *p )
00312 {
00313     QString output;
00314     QDateTime dt = QDateTime::currentDateTime();
00315 
00316     // Re-enable set time buttons & change app caption to indicate time update is happening
00317     if ( ntpTabEnabled )
00318         ntpTab->setNTPBtnEnabled( true );
00319     timeTab->setNTPBtnEnabled( true );
00320     setCaption( tr( "SystemTime" ) );
00321 
00322     //  Verify run was successful
00323     if ( p->exitStatus() != 0 )
00324     {
00325         if ( isVisible() && ntpInteractive )
00326         {
00327             output = tr( "Error while getting time from\n server: " );
00328             output.append( settingsTab->ntpServer() );
00329             QMessageBox::critical(this, tr( "Error" ), output );
00330         }
00331     //      slotCheckNtp(-1);
00332         return;
00333     }
00334 
00335     // Set controls on time tab to new time value
00336     timeTab->setDateTime( dt );
00337 
00338     // Write out lookup information
00339     Config config( "ntp" );
00340     config.setGroup( "lookups" );
00341     int lastLookup = config.readNumEntry( "time", 0 );
00342     int lookupCount = config.readNumEntry( "count", 0 );
00343     bool lastNtp = config.readBoolEntry( "lastNtp", false );
00344     int time = TimeConversion::toUTC( QDateTime::currentDateTime() );
00345     config.writeEntry( "time", time );
00346 
00347     // Calculate new time/time shift
00348     QString _offset = "offset";
00349     QString _sec = "sec";
00350     QRegExp _reOffset = QRegExp( _offset );
00351     QRegExp _reEndOffset = QRegExp( _sec );
00352     int posOffset = _reOffset.match(  ntpOutput );
00353     int posEndOffset = _reEndOffset.match(  ntpOutput, posOffset );
00354     posOffset += _offset.length() + 1;
00355     QString diff =  ntpOutput.mid( posOffset, posEndOffset - posOffset - 1 );
00356 
00357     float timeShift = diff.toFloat();
00358     if ( timeShift == 0.0 )
00359         return;
00360     int secsSinceLast = time - lastLookup;
00361     output = tr( "%1 seconds").arg(QString::number( timeShift ));
00362 
00363     // Display information on time server tab
00364     if ( ntpTabEnabled )
00365     {
00366         ntpTab->setTimeShift( output );
00367         ntpTab->setNewTime( dt.toString() );
00368     }
00369 
00370     if ( lastNtp && lastLookup > 0 && secsSinceLast > 60 * ntpDelay )
00371     {
00372         QString grpname = QString( "lookup_" ).append( QString::number( lookupCount ) );
00373         config.setGroup( grpname );
00374         lookupCount++;
00375         
00376         if(predictTab)
00377         {
00378             predictTab->setShiftPerSec( (int)(timeShift / secsSinceLast) );
00379         }
00380 
00381         config.writeEntry( "secsSinceLast", secsSinceLast );
00382         config.writeEntry( "timeShift", QString::number( timeShift ) );
00383         config.setGroup( "lookups" );
00384         config.writeEntry( "count", lookupCount );
00385         config.writeEntry( "lastNtp", true );
00386     }
00387 }
00388 
00389 void MainWindow::slotNTPDelayChanged( int delay )
00390 {
00391     ntpTimer->changeInterval( delay * 1000 * 60 );
00392     ntpDelay = delay;
00393 }
00394 
00395 void MainWindow::slotCheckNtp( int i )
00396 {
00397     if ( i == 0 )
00398     {
00399         if ( ntpDelayElapsed() )
00400         {
00401             runNTP();
00402             disconnect( ntpTimer, SIGNAL(timeout()), this, SLOT(slotProbeNTPServer()) );
00403             connect( ntpTimer, SIGNAL(timeout()), SLOT(slotTimerGetNTPTime()) );
00404         }
00405         else
00406         {
00407             disconnect(ntpTimer, SIGNAL(timeout()), this, SLOT(slotTimerGetNTPTime()) );
00408             connect(ntpTimer, SIGNAL(timeout()), SLOT(slotProbeNTPServer()) );
00409         }
00410     }
00411     else
00412     {
00413         if(predictTab)
00414         {
00415             predictTab->slotPredictTime();
00416         }
00417 
00418         if ( i > 0 )
00419         {
00420             QString output = tr( "Could not connect to server " );
00421             output.append( settingsTab->ntpServer() );
00422             ntpOutput.append( output );
00423             if ( ntpTabEnabled )
00424                 ntpTab->addNtpOutput( output );
00425         }
00426         connect( ntpTimer, SIGNAL(timeout()), SLOT(slotProbeNTPServer()) );
00427     }
00428 }

Generated on Sat Nov 5 16:15:52 2005 for OPIE by  doxygen 1.4.2