00001
00002 #include "batterystatus.h"
00003
00004
00005 #include <opie2/odevice.h>
00006 #include <qpe/power.h>
00007
00008
00009 #include <qpushbutton.h>
00010 #include <qdrawutil.h>
00011 #include <qfile.h>
00012 #include <qtextstream.h>
00013 #include <qmessagebox.h>
00014
00015 using namespace Opie::Core;
00016
00017 BatteryStatus::BatteryStatus( const PowerStatus *p, QWidget *parent, WFlags f )
00018 : QFrame( parent, 0, f), ps(p), bat2(false) {
00019
00020 UpdateBatteryStatus();
00021 }
00022
00023 BatteryStatus::~BatteryStatus() {}
00024
00025 void BatteryStatus::UpdateBatteryStatus() {
00026
00027 jackPercent = 0;
00028
00029 if ( ODevice::inst ( )-> series ( ) == Model_iPAQ ) {
00030 getProcApmStatusIpaq();
00031 }
00032 percent = ps->batteryPercentRemaining();
00033 }
00034
00035
00036
00037
00038 bool BatteryStatus::getProcApmStatusIpaq() {
00039
00040 bat2 = false;
00041
00042 QFile procApmIpaq("/proc/hal/battery");
00043
00044 if (procApmIpaq.open(IO_ReadOnly) ) {
00045 QStringList list;
00046
00047 QTextStream stream ( &procApmIpaq);
00048 QString streamIn;
00049 streamIn = stream.read();
00050 list = QStringList::split("\n", streamIn);
00051
00052 sec2 = sec1 = "";
00053
00054 for(QStringList::Iterator line=list.begin(); line!=list.end(); line++) {
00055
00056 if( (*line).startsWith(" Percentage") ) {
00057 if (bat2 == true) {
00058 perc2 = (*line).mid(((*line).find('(')) +1,(*line).find(')')-(*line).find('(')-2);
00059 } else {
00060 perc1 = (*line).mid(((*line).find('('))+1,(*line).find(')')-(*line).find('(')-2);
00061 }
00062 } else if( (*line).startsWith(" Life") ) {
00063 if (bat2 == true) {
00064 sec2 = (*line).mid(((*line).find(':')+2), 5 );
00065 } else {
00066 sec1 = (*line).mid(((*line).find(':')+2), 5 );
00067 }
00068 } else if( (*line).startsWith("Battery #1") ) {
00069 bat2 = true;
00070 } else if( (*line).startsWith(" Status") ) {
00071 if (bat2 == true) {
00072 jackStatus = (*line).mid((*line).find('(')+1, (*line).find(')')-(*line).find('(')-1);
00073 } else {
00074 ipaqStatus = (*line).mid((*line).find('(')+1, (*line).find(')')-(*line).find('(')-1);
00075 }
00076 } else if( (*line).startsWith(" Chemistry") ) {
00077 if (bat2 == true) {
00078 jackChem = (*line).mid((*line).find('('), (*line).find(')')-(*line).find('(')+1);
00079 } else {
00080 ipaqChem = (*line).mid((*line).find('('), (*line).find(')')-(*line).find('(')+1);
00081 }
00082 }
00083 }
00084 } else {
00085 QMessageBox::warning(this, tr("Failure"),tr("could not open file"));
00086 }
00087
00088 procApmIpaq.close();
00089 jackPercent = perc2.toInt();
00090 ipaqPercent = perc1.toInt();
00091
00092 if (perc2.isEmpty() || perc2 == "unknow" ) {
00093 perc2 = tr("no data");
00094 } else {
00095 perc2 += " %";
00096 }
00097
00098 if (sec2 == "0" || sec2 == "" || sec2.isEmpty()) {
00099 sec2 = tr("no data");
00100 } else {
00101 sec2 += " min";
00102 }
00103
00104 jackStatus.prepend( " ( " );
00105 jackStatus.append( " )" );
00106 return true;
00107 }
00108
00109
00110 void BatteryStatus::updatePercent( int pc ) {
00111 percent = pc;
00112 repaint(FALSE);
00113 }
00114
00115 void BatteryStatus::drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height ) {
00116 int h1, h2, s1, s2, v1, v2, ng = r.height(), hy = ng*30/100, hh = hightlight_height;
00117 topgrad.hsv( &h1, &s1, &v1 );
00118 botgrad.hsv( &h2, &s2, &v2 );
00119 for ( int j = 0; j < hy-2; j++ ) {
00120 p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
00121 v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
00122 p->drawLine( r.x(), r.top()+hy-2-j, r.x()+r.width(), r.top()+hy-2-j );
00123 }
00124 for ( int j = 0; j < hh; j++ ) {
00125 p->setPen( highlight );
00126 p->drawLine( r.x(), r.top()+hy-2+j, r.x()+r.width(), r.top()+hy-2+j );
00127 }
00128 for ( int j = 0; j < ng-hy-hh; j++ ) {
00129 p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
00130 v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
00131 p->drawLine( r.x(), r.top()+hy+hh-2+j, r.x()+r.width(), r.top()+hy+hh-2+j );
00132 }
00133 }
00134
00135 QString BatteryStatus::statusText() const {
00136 QString text;
00137
00138 if ( ps->batteryStatus() == PowerStatus::Charging ) {
00139 if (bat2) {
00140 text = tr("Charging both devices");
00141 } else {
00142 text = tr("Charging");
00143 }
00144 } else if ( ps->batteryPercentAccurate() ) {
00145 text = tr( "Remaining Power: %1%" ).arg( percent );
00146
00147 } else {
00148 text = tr( "Battery status: " );
00149 switch ( ps->batteryStatus() ) {
00150 case PowerStatus::High:
00151 text.append( tr( "Good" ) );
00152 break;
00153 case PowerStatus::Low:
00154 text.append( tr( "Low" ) );
00155 break;
00156 case PowerStatus::VeryLow:
00157 text.append( tr( "Very Low" ) );
00158 break;
00159 case PowerStatus::Critical:
00160 text.append( tr( "Critical" ) );
00161 break;
00162 default:
00163 text.append( tr( "Unknown" ) );
00164 }
00165 }
00166
00167 if ( ps->acStatus() == PowerStatus::Backup )
00168 {
00169 text.append( '\n' );
00170 text.append( tr( "On backup power" ) );
00171 }
00172 else if ( ps->acStatus() == PowerStatus::Online )
00173 {
00174 text.append( '\n' );
00175 text.append( tr( "Power on-line" ) );
00176 }
00177 else if ( ps->acStatus() == PowerStatus::Offline )
00178 {
00179 text.append( '\n' );
00180 text.append( tr( "External power disconnected" ) );
00181 }
00182
00183 if ( ps->batteryTimeRemaining() >= 0 )
00184 {
00185 text.append( '\n' );
00186 text.append( tr("Remaining Time: %1m %2s" ).arg( ps->batteryTimeRemaining() / 60 )
00187 .arg( ps->batteryTimeRemaining() % 60, 2 ) );
00188
00189
00190 }
00191 return text;
00192 }
00193
00194 QString BatteryStatus::statusTextIpaq() const {
00195 QString text = tr( "Remaining Power: %1 \n%2\nRemaining Time: %3" ).arg( perc2 )
00196 .arg( jackStatus )
00197 .arg( sec2 );
00198
00199
00200 return text;
00201 }
00202
00203 void BatteryStatus::paintEvent( QPaintEvent * ev ) {
00204
00205 QPainter p( this );
00206
00207 QString text = statusText();
00208 p.eraseRect( p.boundingRect( 10, 50, width() - 20, 40 , AlignVCenter, text ) );
00209 p.drawText( 10, 50, width() - 20, 40 , AlignVCenter, text );
00210
00211 QColor c;
00212 QColor darkc;
00213 QColor lightc;
00214 if ( ps->acStatus() == PowerStatus::Offline ) {
00215 c = blue.light(120);
00216 darkc = c.dark(280);
00217 lightc = c.light(145);
00218 } else if ( ps->acStatus() == PowerStatus::Online ) {
00219 c = green.dark(130);
00220 darkc = c.dark(200);
00221 lightc = c.light(220);
00222 } else {
00223 c = red;
00224 darkc = c.dark(280);
00225 lightc = c.light(140);
00226 }
00227 if ( percent < 0 )
00228 return;
00229
00230 int rightEnd1 = width() - 47;
00231 int rightEnd2 = width() - 35;
00232 int percent2 = (percent * rightEnd1) / 100;
00233 p.setPen( black );
00234 qDrawShadePanel( &p, 9, 10, rightEnd1 , 39, colorGroup(), TRUE, 1, NULL);
00235 qDrawShadePanel( &p, rightEnd2, 17, 12, 24, colorGroup(), TRUE, 1, NULL);
00236 drawSegment( &p, QRect( 10, 10, percent2, 40 ), lightc, darkc, lightc.light(115), 6 );
00237 drawSegment( &p, QRect( 11 + percent2, 10, rightEnd1 - percent2, 40 ), white.light(80), black, white.light(90), 6 );
00238 drawSegment( &p, QRect( rightEnd2, 17, 10, 25 ), white.light(80), black, white.light(90), 2 );
00239 p.setPen( black);
00240
00241 if ( ODevice::inst ( )-> series ( ) == Model_iPAQ && bat2 ) {
00242
00243 p.drawText( 15, 30, tr("Ipaq %1").arg( ipaqChem ) );
00244
00245 QString jacketMsg;
00246 if (bat2) {
00247 p.setPen(black);
00248 QString text = statusTextIpaq();
00249 p.eraseRect( p.boundingRect( 10, 130, width() - 20, 40 , AlignVCenter, text ) );
00250 p.drawText( 10, 130, width() - 20, 40 , AlignVCenter, text );
00251 jacketMsg = tr("Jacket ").arg( jackChem );
00252 } else {
00253 jackPercent = 0;
00254 jacketMsg = tr("No jacket with battery inserted");
00255 }
00256
00257 int jackPerc = ( jackPercent * ( width() - 47 ) ) / 100;
00258
00259 qDrawShadePanel( &p, 9, 90, rightEnd1, 39, colorGroup(), TRUE, 1, NULL);
00260 qDrawShadePanel( &p, rightEnd2, 97, 12, 24, colorGroup(), TRUE, 1, NULL);
00261 drawSegment( &p, QRect( 10, 90, jackPerc, 40 ), lightc, darkc, lightc.light(115), 6 );
00262 drawSegment( &p, QRect( 11 + jackPerc, 90, rightEnd1 - jackPerc, 40 ), white.light(80), black, white.light(90), 6 );
00263 drawSegment( &p, QRect( rightEnd2, 97, 10, 25 ), white.light(80), black, white.light(90), 2 );
00264 p.setPen( black );
00265 p.drawText(15, 100, width() - 20, 20 , AlignVCenter, jacketMsg);
00266 }
00267 QFrame::paintEvent(ev);
00268 }
00269
00270 QSize BatteryStatus::sizeHint() const {
00271 QString text = statusText();
00272 QString text2 = statusTextIpaq();
00273 QFontMetrics fm = fontMetrics();
00274 QRect r=fm.boundingRect( 10, 0, width(), height(), AlignVCenter, text );
00275 QRect r2=fm.boundingRect( 10, 0, width(), height(), AlignVCenter, text2 );
00276
00277 if ( bat2 ) {
00278 return QSize( QMAX( QMIN( 200, qApp->desktop()->width() ),
00279 r.width()+2*10 ), 2 * 10 + 100 + r.height() + r2.height() );
00280 }
00281 return QSize( QMAX( QMIN( 200, qApp->desktop()->width() ),
00282 r.width()+2*10 ), 2 * 10 + 40 + r.height() );
00283 }