00001
00002 #include "portable.h"
00003
00004 #if defined( KDE2_PORT )
00005 #include <kapp.h>
00006 #include <klocale.h>
00007 #include <kstddirs.h>
00008 #include <status.h>
00009 #include <status.moc>
00010 #elif defined( QPE_PORT )
00011 #include <qpe/qpeapplication.h>
00012 #include <qpe/config.h>
00013 #include "status.h"
00014 #endif
00015
00016 #include <opie2/odebug.h>
00017 using namespace Opie::Core;
00018
00019 #include <qbitmap.h>
00020 #include <qmsgbox.h>
00021 #include <qfileinfo.h>
00022
00023 Status::Status( QWidget *parent, const char *name, int Scheme, int Mode ) :
00024 QWidget( parent, name )
00025 {
00026 owarn << "Status::Status" << oendl;
00027 actualLifes = 0;
00028 actualLevel = 0;
00029
00030 lifesPix = NULL;
00031 levelPix = NULL;
00032
00033 scheme = Scheme;
00034 mode = Mode;
00035 level = 0;
00036
00037 confScheme();
00038 }
00039
00040 QList<QPixmap> *Status::loadPixmap(QWidget *parent, QString pixmapName,
00041 QList<QPixmap> *pixmaps)
00042 {
00043 if (pixmaps == NULL) {
00044 pixmaps = new QList<QPixmap>;
00045 pixmaps->setAutoDelete(TRUE);
00046 }
00047
00048 if (!pixmaps->isEmpty())
00049 pixmaps->clear();
00050
00051 QPixmap PIXMAP(pixmapName);
00052 if (PIXMAP.isNull() || PIXMAP.mask() == NULL) {
00053 QString msg = tr("The pixmap could not be contructed.\n\n"
00054 "The file '@PIXMAPNAME@' does not exist,\n"
00055 "or is of an unknown format.");
00056 msg.replace(QRegExp("@PIXMAPNAME@"), pixmapName);
00057 QMessageBox::information(parent, tr("Initialization Error"),
00058 (const char *) msg);
00059 return 0;
00060 }
00061
00062 int height = PIXMAP.height();
00063 int width = (height == 0) ? 0 : PIXMAP.width()/(PIXMAP.width()/height);
00064
00065 QBitmap BITMAP;
00066 QBitmap MASK;
00067
00068 BITMAP = *PIXMAP.mask();
00069 MASK.resize(width, height);
00070
00071 for (int x = 0; x < PIXMAP.width()/width; x++) {
00072 QPixmap *pixmap = new QPixmap(width, height);
00073 pixmaps->append(pixmap);
00074 bitBlt(pixmap, 0, 0, &PIXMAP, x*width, 0, width, height, CopyROP, TRUE);
00075 bitBlt(&MASK, 0, 0, &BITMAP, x*width, 0, width, height, CopyROP, TRUE);
00076 pixmap->setMask(MASK);
00077 }
00078
00079 return pixmaps;
00080 }
00081
00082 void Status::paintEvent( QPaintEvent *)
00083 {
00084 for (int x = 0; x < actualLifes && !lifesPix->isEmpty(); x++)
00085 bitBlt(this, lifesPix->at(0)->width()+(lifesPix->at(0)->width()*x),
00086 (height()-lifesPix->at(0)->height())/2,
00087 lifesPix->at(0), 0, 0,
00088 lifesPix->at(0)->width(), lifesPix->at(0)->height());
00089
00090 for (int x = 0; x < actualLevel && !levelPix->isEmpty(); x++) {
00091 erase((width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
00092 (height()-levelPix->at(x)->height())/2,
00093 levelPix->at(x)->width(), levelPix->at(x)->height());
00094 bitBlt(this, (width()-levelPix->at(x)->width()*2)-(levelPix->at(x)->width()*levelPos[x]),
00095 (height()-levelPix->at(x)->height())/2,
00096 levelPix->at(x), 0, 0,
00097 levelPix->at(x)->width(), levelPix->at(x)->height());
00098 }
00099 }
00100
00101 void Status::initPixmaps()
00102 {
00103 if (lastLifesPixmapName != lifesPixmapName.at(level)) {
00104 lifesPix = loadPixmap(this, lifesPixmapName.at(level), lifesPix);
00105 lastLifesPixmapName = lifesPixmapName.at(level);
00106 }
00107 if (lastLevelPixmapName != levelPixmapName.at(level)) {
00108 levelPix = loadPixmap(this, levelPixmapName.at(level), levelPix);
00109 lastLevelPixmapName = levelPixmapName.at(level);
00110 }
00111 }
00112
00113 QString Status::decodeHexOctString(QString s)
00114 {
00115 QString value;
00116 QString valids;
00117 int pos, xpos = 0, opos = 0;
00118 int v, len, leadin;
00119 const char *ptr;
00120 uchar c;
00121
00122 while (((xpos = s.find(QRegExp("\\\\x[0-9a-fA-F]+"), xpos)) != -1) ||
00123 ((opos = s.find(QRegExp("\\\\[0-7]+"), opos)) != -1)) {
00124 if (xpos != -1) {
00125 valids = "0123456789abcdef";
00126 leadin = 2;
00127 pos = xpos;
00128 } else {
00129 valids = "01234567";
00130 leadin = 1;
00131 pos = opos;
00132 }
00133
00134 c = '\0';
00135 len = 0;
00136 value = s.mid(pos+leadin, 3);
00137 ptr = (const char *) value;
00138
00139 while (*ptr != '\0' && (v = valids.find(*ptr++, 0, FALSE)) != -1) {
00140 c = (c * valids.length()) + v;
00141 len++;
00142 }
00143
00144 value.fill(c, 1);
00145 s.replace(pos, len+leadin, value);
00146 }
00147
00148 return s;
00149 }
00150
00151 void Status::fillArray(QArray<int> &array, QString values, int max)
00152 {
00153 array.resize(max);
00154 int last = 0;
00155 bool ok;
00156 QString value;
00157
00158 for (uint i = 0; i < array.size(); i++) {
00159 if (values.find(',') < 0 && values.length() > 0) {
00160 value = values;
00161 values = "";
00162 }
00163 if (values.find(',') >= 0) {
00164 value = values.left(values.find(','));
00165 values.remove(0,values.find(',')+1);
00166 }
00167 array[i] = value.toInt(&ok);
00168 if (ok)
00169 last = array[i];
00170 else
00171 array[i] = last;
00172 }
00173 }
00174
00175 void Status::fillStrList(QStrList &list, QString values, int max)
00176 {
00177 if (!list.isEmpty())
00178 list.clear();
00179
00180 QString last = "";
00181 QString value;
00182
00183 for (uint i = 0; i < (uint) max; i++) {
00184 if (values.find(',') < 0 && values.length() > 0) {
00185 value = values;
00186 values = "";
00187 }
00188 if (values.find(',') >= 0) {
00189 value = values.left(values.find(','));
00190 values.remove(0,values.find(',')+1);
00191 }
00192 if (!value.isEmpty())
00193 last = decodeHexOctString(value);
00194 list.append(last);
00195 }
00196 }
00197
00198 void Status::fillPixmapName(QStrList &pixmapName)
00199 {
00200 QStrList list = pixmapName;
00201
00202 if (!pixmapName.isEmpty())
00203 pixmapName.clear();
00204
00205 QString pixmap;
00206
00207 QFileInfo fileInfo;
00208
00209 for (uint i = 0; i < list.count(); i++) {
00210 pixmap = list.at(i);
00211
00212 if (pixmap.left(1) != "/" && pixmap.left(1) != "~")
00213 pixmap = FIND_APP_DATA( pixmapDirectory+pixmap );
00214
00215 fileInfo.setFile(pixmap);
00216 if (!fileInfo.isReadable() || !fileInfo.isFile())
00217 pixmap = "";
00218
00219 pixmapName.append(pixmap);
00220 }
00221 }
00222
00223 void Status::confLevels(bool defGroup)
00224 {
00225 APP_CONFIG_BEGIN( cfg );
00226 if (defGroup || cfg->hasKey("Levels"))
00227 maxLevel = cfg->readNumEntry("Levels", 13);
00228 APP_CONFIG_END( cfg );
00229 }
00230
00231 void Status::confMisc(bool defGroup)
00232 {
00233 APP_CONFIG_BEGIN( cfg );
00234 if (defGroup || cfg->hasKey("LevelPosition"))
00235 fillArray(levelPos, cfg->readEntry("LevelPosition", "0,1,2,3,,4,,5,,6,,7"), maxLevel);
00236
00237 if (defGroup || cfg->hasKey("PixmapDirectory")) {
00238 pixmapDirectory = cfg->readEntry("PixmapDirectory");
00239
00240 if (pixmapDirectory.left(1) != "/" && pixmapDirectory.left(1) != "~")
00241 pixmapDirectory.insert(0, "pics/");
00242 if (pixmapDirectory.right(1) != "/")
00243 pixmapDirectory.append("/");
00244 }
00245
00246 if (defGroup || cfg->hasKey("LifesPixmapName"))
00247 fillStrList(lifesPixmapName,
00248 cfg->readEntry("LifesPixmapName", "lifes.xpm"), maxLevel+1);
00249 if (defGroup || cfg->hasKey("LevelPixmapName"))
00250 fillStrList(levelPixmapName,
00251 cfg->readEntry("LevelPixmapName", "fruit.xpm"), maxLevel+1);
00252 APP_CONFIG_END( cfg );
00253 }
00254
00255 void Status::confScheme()
00256 {
00257 APP_CONFIG_BEGIN( cfg );
00258 SAVE_CONFIG_GROUP( cfg, oldgroup );
00259 QString newgroup;
00260
00261
00262 if (mode == -1 && scheme == -1) {
00263 scheme = cfg->readNumEntry("Scheme", -1);
00264 mode = cfg->readNumEntry("Mode", -1);
00265
00266
00267 if (scheme != -1 || mode == -1) {
00268 newgroup.sprintf("Scheme %d", scheme);
00269 cfg->setGroup(newgroup);
00270
00271 mode = cfg->readNumEntry("Mode", -1);
00272 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00273 }
00274 }
00275
00276 confLevels();
00277
00278 if (mode != -1) {
00279 newgroup.sprintf("Mode %d", mode);
00280 cfg->setGroup(newgroup);
00281
00282 confLevels(FALSE);
00283 }
00284
00285 if (scheme != -1) {
00286 newgroup.sprintf("Scheme %d", scheme);
00287 cfg->setGroup(newgroup);
00288
00289 confLevels(FALSE);
00290 }
00291
00292 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00293
00294 confMisc();
00295
00296 if (mode != -1) {
00297 newgroup.sprintf("Mode %d", mode);
00298 cfg->setGroup(newgroup);
00299
00300 confMisc(FALSE);
00301 }
00302
00303 if (scheme != -1) {
00304 newgroup.sprintf("Scheme %d", scheme);
00305 cfg->setGroup(newgroup);
00306
00307 confMisc(FALSE);
00308 }
00309
00310 fillPixmapName(lifesPixmapName);
00311 fillPixmapName(levelPixmapName);
00312
00313 initPixmaps();
00314
00315 setFixedHeight(minHeight());
00316
00317 RESTORE_CONFIG_GROUP( cfg, oldgroup );
00318 APP_CONFIG_END( cfg );
00319 }
00320
00321 void Status::setScheme(int Scheme, int Mode)
00322 {
00323 mode = Mode;
00324 scheme = Scheme;
00325
00326 confScheme();
00327
00328 repaint();
00329 }
00330
00331 int Status::minHeight()
00332 {
00333 if (lifesPix->isEmpty() && levelPix->isEmpty())
00334 return 0;
00335 if (levelPix->isEmpty())
00336 return lifesPix->at(0)->height();
00337 if (lifesPix->isEmpty())
00338 return levelPix->at(0)->height();
00339 return (lifesPix->at(0)->height() > levelPix->at(0)->height()) ?
00340 lifesPix->at(0)->height() : levelPix->at(0)->height();
00341 }
00342
00343 int Status::minWidth()
00344 {
00345 if (lifesPix->isEmpty() && levelPix->isEmpty())
00346 return 0;
00347 if (levelPix->isEmpty())
00348 return lifesPix->at(0)->width();
00349 if (lifesPix->isEmpty())
00350 return levelPix->at(0)->width();
00351 return (lifesPix->at(0)->width() > levelPix->at(0)->width()) ?
00352 lifesPix->at(0)->width() : levelPix->at(0)->width();
00353 }
00354
00355 void Status::setLifes(int lifes)
00356 {
00357 actualLifes = lifes;
00358 repaint();
00359 }
00360
00361 void Status::setLevel(int Level)
00362 {
00363 level = Level;
00364
00365 initPixmaps();
00366
00367 actualLevel = (level > (int) levelPix->count()) ? (int) levelPix->count() : level;
00368 repaint();
00369 }