• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files

uitypes.cpp

Go to the documentation of this file.
00001 
00002 #include <iostream>
00003 #include <math.h>
00004 
00005 #include <qapplication.h>
00006 #include <qsimplerichtext.h>
00007 #include <qbitmap.h>
00008 
00009 using namespace std;
00010 
00011 #include "uitypes.h"
00012 #include "mythdialogs.h"
00013 #include "mythcontext.h"
00014 #include "lcddevice.h"
00015 
00016 #ifdef USING_MINGW
00017 #undef LoadImage
00018 #endif
00019 
00020 LayerSet::LayerSet(const QString &name)
00021 {
00022     m_name = name;
00023     m_context = -1;
00024     m_debug = false;
00025     numb_layers = -1;
00026     allTypes = new vector<UIType *>;
00027 }
00028 
00029 LayerSet::~LayerSet()
00030 {
00031     vector<UIType *>::iterator i = allTypes->begin();
00032     for (; i != allTypes->end(); i++)
00033     {
00034         UIType *type = (*i);
00035         if (type)
00036             delete type;
00037     }
00038     delete allTypes;
00039 }
00040 
00041 void LayerSet::AddType(UIType *type)
00042 {
00043     type->SetDebug(m_debug);
00044     typeList[type->Name()] = type;
00045     allTypes->push_back(type);
00046     type->SetParent(this);
00047     bumpUpLayers(type->getOrder());
00048 }
00049 
00050 UIType *LayerSet::GetType(const QString &name)
00051 {
00052     UIType *ret = NULL;
00053     if (typeList.contains(name))
00054         ret = typeList[name];
00055 
00056     return ret;
00057 }
00058 
00059 void LayerSet::bumpUpLayers(int a_number)
00060 {
00061     if (a_number > numb_layers)
00062     {
00063         numb_layers = a_number;
00064     }
00065 }
00066 
00067 void LayerSet::Draw(QPainter *dr, int drawlayer, int context)
00068 {
00069   if (m_context == context || m_context == -1)
00070   {
00071     vector<UIType *>::iterator i = allTypes->begin();
00072     for (; i != allTypes->end(); i++)
00073     {
00074         if (m_debug == true)
00075             cerr << "-LayerSet::Draw\n";
00076         UIType *type = (*i);
00077         type->Draw(dr, drawlayer, context);
00078     }
00079   }
00080 }
00081 
00082 void LayerSet::DrawRegion(QPainter *dr, QRect &area, int drawlayer, int context)
00083 {
00084   if (m_context == context || m_context == -1)
00085   {
00086     vector<UIType *>::iterator i = allTypes->begin();
00087     for (; i != allTypes->end(); i++)
00088     {
00089         if (m_debug == true)
00090             cerr << "-LayerSet::Draw\n";
00091         UIType *type = (*i);
00092         type->DrawRegion(dr, area, drawlayer, context);
00093     }
00094   }
00095 }
00096 
00097 void LayerSet::ClearAllText(void)
00098 {
00099     vector<UIType *>::iterator i = allTypes->begin();
00100     for (; i != allTypes->end(); i++)
00101     {
00102         UIType *type = (*i);
00103         if (UITextType *item = dynamic_cast<UITextType *>(type))
00104         {
00105             QString defText = item->GetDefaultText();
00106             if ((defText == "" ) ||
00107                 (defText.contains(QRegExp("%"))))
00108                 item->SetText(QString(""));
00109         }
00110     }
00111 }
00112 
00113 void LayerSet::SetText(QMap<QString, QString> &infoMap)
00114 {
00115     vector<UIType *>::iterator i = allTypes->begin();
00116     for (; i != allTypes->end(); i++)
00117     {
00118         UIType *type = (*i);
00119         if (UITextType *item = dynamic_cast<UITextType *>(type))
00120         {
00121             QMap<QString, QString>::Iterator riter = infoMap.begin();
00122             QString new_text = item->GetDefaultText();
00123             QString full_regex;
00124 
00125             if ((new_text == "") &&
00126                 (infoMap.contains(item->Name())))
00127             {
00128                 new_text = infoMap[item->Name()];
00129             }
00130             else if (new_text.contains(QRegExp("%.*%")))
00131             {
00132                 for (; riter != infoMap.end(); riter++)
00133                 {
00134                     QString key = riter.key().upper();
00135                     QString data = riter.data();
00136 
00137                     if (new_text.contains(key))
00138                     {
00139                         full_regex = QString("%") + key + QString("(\\|([^%|]*))?") +
00140                                      QString("(\\|([^%|]*))?") + QString("(\\|([^%]*))?%");
00141                         if (riter.data() != "")
00142                             new_text.replace(QRegExp(full_regex),
00143                                              QString("\\2") + data + QString("\\4"));
00144                         else
00145                             new_text.replace(QRegExp(full_regex), QString("\\6"));
00146                     }
00147                 }
00148             }
00149 
00150             if (new_text != "")
00151                 item->SetText(new_text);
00152         }
00153     }
00154 }
00155 
00156 void LayerSet::UseAlternateArea(bool useAlt)
00157 {
00158     vector<UIType *>::iterator i = allTypes->begin();
00159     for (; i != allTypes->end(); i++)
00160     {
00161         UIType *type = (*i);
00162         if (UITextType *item = dynamic_cast<UITextType *>(type))
00163             item->UseAlternateArea(useAlt);
00164     }
00165 }
00166 
00167 void LayerSet::SetDrawFontShadow(bool state)
00168 {
00169     vector<UIType *>::iterator i = allTypes->begin();
00170     for (; i != allTypes->end(); i++)
00171     {
00172         UIType *type = (*i);
00173         type->SetDrawFontShadow(state);
00174     }
00175 }
00176 
00177 // **************************************************************
00178 
00179 UIType::UIType(const QString &name)
00180        : QObject(NULL, name)
00181 {
00182     m_parent = NULL;
00183     m_name = name;
00184     m_debug = false;
00185     m_context = -1;
00186     m_order = -1;
00187     has_focus = false;
00188     takes_focus = false;
00189     screen_area = QRect(0,0,0,0);
00190     drawFontShadow = true;
00191     hidden = false;
00192 }
00193 
00194 void UIType::SetOrder(int order)
00195 {
00196     m_order = order;
00197     if (m_parent)
00198     {
00199         m_parent->bumpUpLayers(order);
00200     }
00201 }
00202 
00203 UIType::~UIType()
00204 {
00205 }
00206 
00207 void UIType::Draw(QPainter *dr, int drawlayer, int context)
00208 {
00209     dr->end();
00210     drawlayer = 0;
00211     context = 0;
00212 }
00213 
00214 void UIType::DrawRegion(QPainter *dr, QRect &area, int drawlayer, int context)
00215 {
00216     (void)dr;
00217     (void)area;
00218     (void)drawlayer;
00219     (void)context;
00220 }
00221 
00222 void UIType::SetParent(LayerSet *parent)
00223 {
00224     m_parent = parent;
00225 }
00226 
00227 QString UIType::Name()
00228 {
00229     return m_name;
00230 }
00231 
00232 bool UIType::takeFocus()
00233 {
00234     if (takes_focus)
00235     {
00236         has_focus = true;
00237         refresh();
00238         emit takingFocus();
00239         return true;
00240     }
00241     has_focus = false;
00242     return false;
00243 }
00244 
00245 void UIType::looseFocus()
00246 {
00247     emit loosingFocus();
00248     has_focus = false;
00249     refresh();
00250 }
00251 
00252 void UIType::calculateScreenArea()
00253 {
00254     screen_area = QRect(0,0,0,0);
00255 }
00256 
00257 void UIType::refresh()
00258 {
00259     emit requestUpdate(screen_area);
00260 }
00261 
00262 void UIType::show()
00263 {
00264     //
00265     //  In this base class, this is pretty simple. The method is virtual
00266     //  though, and inherited fancy classes like UIListBttn can/will/should
00267     //  set a timer and fade things on a show()
00268     //
00269 
00270     hidden = false;
00271     refresh();
00272 }
00273 
00274 void UIType::hide()
00275 {
00276     hidden = true;
00277     refresh();
00278 }
00279 
00280 bool UIType::toggleShow()
00281 {
00282     if (hidden)
00283     {
00284         show();
00285     }
00286     else
00287     {
00288         hide();
00289     }
00290 
00291     return !hidden;
00292 }
00293 
00294 QString UIType::cutDown(const QString &data, QFont *testFont, bool multiline,
00295                         int overload_width, int overload_height)
00296 {
00297     int length = data.length();
00298     if (length == 0)
00299         return data;
00300 
00301     int maxwidth = screen_area.width();
00302     if (overload_width != -1)
00303         maxwidth = overload_width;
00304     int maxheight = screen_area.height();
00305     if (overload_height != -1)
00306         maxheight = overload_height;
00307 
00308     int justification = Qt::AlignLeft | Qt::WordBreak;
00309     QFontMetrics fm(*testFont);
00310 
00311     int margin = length - 1;
00312     int index = 0;
00313     int diff = 0;
00314 
00315     while (margin > 0)
00316     {
00317         if (multiline)
00318             diff = maxheight - fm.boundingRect(0, 0, maxwidth, maxheight,
00319                                                justification, data,
00320                                                index + margin).height();
00321         else
00322             diff = maxwidth - fm.width(data, index + margin);
00323         if (diff >= 0)
00324             index += margin;
00325 
00326         margin /= 2;
00327 
00328         if (index + margin >= length - 1)
00329             margin = (length - 1) - index;
00330     }
00331 
00332     if (index < length - 1)
00333     {
00334         QString tmpStr(data);
00335         tmpStr.truncate(index);
00336         if (index >= 3)
00337             tmpStr.replace(index - 3, 3, "...");
00338         return tmpStr;
00339     }
00340 
00341     return data;
00342 }
00343 
00344 
00345 // **************************************************************
00346 
00347 UIBarType::UIBarType(const QString &name, QString imgfile,
00348                      int dorder, QRect displayrect)
00349          : UIType(name)
00350 {
00351     m_name = name;
00352 
00353     m_filename = imgfile;
00354 
00355     m_displaysize = displayrect;
00356     m_order = dorder;
00357     m_justification = (Qt::AlignLeft | Qt::AlignVCenter);
00358 
00359     m_textoffset = QPoint(0, 0);
00360     m_iconoffset = QPoint(0, 0);
00361 
00362 }
00363 
00364 UIBarType::~UIBarType()
00365 {
00366 }
00367 
00368 void UIBarType::SetText(int num, QString myText)
00369 {
00370     textData[num] = myText;
00371 }
00372 
00373 void UIBarType::SetIcon(int num, QString myIcon)
00374 {
00375     LoadImage(num, myIcon);
00376 }
00377 
00378 void UIBarType::SetIcon(int num, QPixmap myIcon)
00379 {
00380     QImage sourceImg = myIcon.convertToImage();
00381     if (!sourceImg.isNull())
00382     {
00383         QImage scalerImg;
00384 
00385         scalerImg = sourceImg.smoothScale((int)(m_iconsize.x()),
00386                                                (int)(m_iconsize.y()));
00387         iconData[num].convertFromImage(scalerImg);
00388     }
00389     else
00390         iconData[num].resize(0, 0);
00391 }
00392 
00393 void UIBarType::LoadImage(int loc, QString myFile)
00394 {
00395     QImage sourceImg;
00396     int doX = 0;
00397     int doY = 0;
00398     QImage scalerImg;
00399 
00400     if (m_size == 0)
00401     {
00402         VERBOSE(VB_IMPORTANT, "uitypes.cpp:UIBarType:LoadImage:m_size == 0");
00403         return;
00404     }
00405     QString filename = m_filename;
00406     if (loc != -1)
00407         filename = myFile;
00408 
00409     QString file = filename;
00410     if (!gContext->FindThemeFile(file))
00411         goto error;
00412 
00413     if (!sourceImg.load(file))
00414         goto error;
00415 
00416     if (m_orientation == 1)
00417     {
00418         doX = m_displaysize.width() / m_size;
00419         doY = m_displaysize.height();
00420     }
00421     else if (m_orientation == 2)
00422     {
00423         doX = m_displaysize.width();
00424         doY = m_displaysize.height() / m_size;
00425     }
00426     if (loc != -1)
00427     {
00428         doX = m_iconsize.x();
00429         doY = m_iconsize.y();
00430     }
00431 
00432     scalerImg = sourceImg.smoothScale(doX, doY);
00433     if (loc == -1)
00434         m_image.convertFromImage(scalerImg);
00435     else
00436         iconData[loc].convertFromImage(scalerImg);
00437 
00438     if (m_debug == true)
00439         VERBOSE(VB_IMPORTANT, "     -Image: " << file << " loaded.");
00440     return;
00441 
00442 error:
00443     if (m_debug == true)
00444         VERBOSE(VB_IMPORTANT, "     -Image: " << file << " failed to load.");
00445     iconData[loc].resize(0, 0);
00446 }
00447 
00448 void UIBarType::Draw(QPainter *dr, int drawlayer, int context)
00449 {
00450     if (hidden)
00451         return;
00452   
00453   if (m_context == context || m_context == -1)
00454   {
00455     if (drawlayer == m_order)
00456     {
00457       if (m_debug == true)
00458          cerr << "    +UIBarType::Size is " << m_size << endl;
00459 
00460       if (m_size < 0)
00461          cerr << "uitypes.cpp:UIBarType:Size is < 0!\n";
00462 
00463       int xdrop = 0;
00464       int ydrop = 0;
00465       int drawx = 0;
00466       int drawy = 0;
00467 
00468       if (m_orientation == 1)
00469       {
00470          xdrop = (int)(m_displaysize.width() / m_size);
00471          ydrop = m_displaysize.height();
00472       }
00473       else
00474       {
00475          xdrop = m_displaysize.width();
00476          ydrop = (int)(m_displaysize.height() / m_size);
00477       }
00478 
00479       for (int i = 0; i < m_size; i++)
00480       {
00481         if (m_debug == true)
00482             cerr << "    +UIBarType::Drawing Item # " << i << endl;
00483         QPoint fontdrop = m_font->shadowOffset;
00484         QString msg = textData[i];
00485 
00486         if (m_orientation == 1)
00487         {
00488             drawx = m_displaysize.left() + (int)(i * xdrop);
00489             drawy = m_displaysize.top();
00490         }
00491         else
00492         {
00493             drawx = m_displaysize.left();
00494             drawy = m_displaysize.top() + (int)(i * ydrop);
00495         }
00496         dr->drawPixmap(drawx, drawy, m_image);
00497         if (!iconData[i].isNull() && iconData[i].width() > 0)
00498         {
00499             dr->drawPixmap(drawx + m_iconoffset.x(),
00500                            drawy + (int)(ydrop / 2) - (int)(m_iconsize.y() / 2),
00501                            iconData[i]);
00502         }
00503 
00504         QColor clr = m_font->color;
00505         int h,s,v;
00506 
00507         int fav = msg.find("<MARK:fav>");
00508         if (fav >= 0)
00509         {
00510             msg = msg.left(fav) + msg.mid(fav + 10);
00511             clr.getHsv(&h, &s, &v);
00512             clr.setHsv(60, 200, v);
00513         }
00514 
00515         int unavail = msg.find("<MARK:unavail>");
00516         if (unavail >= 0)
00517         {
00518             msg = msg.left(unavail) + msg.mid(unavail + 14);
00519             clr.getHsv(&h, &s, &v);
00520             clr = (v >= 128) ? clr.dark() : clr.light();
00521         }
00522 
00523 
00524         dr->setFont(m_font->face);
00525         if (drawFontShadow && (fontdrop.x() != 0 || fontdrop.y() != 0))
00526         {
00527             dr->setBrush(m_font->dropColor);
00528             dr->setPen(QPen(m_font->dropColor, (int)(2 * m_wmult)));
00529             if (m_orientation == 1)
00530             {
00531                 drawx = m_displaysize.left() + fontdrop.x() + (int)(i * xdrop);
00532                 drawy = m_displaysize.top();
00533             }
00534             else
00535             {
00536                 drawx = m_displaysize.left();
00537                 drawy = m_displaysize.top() + fontdrop.y() + (int)(i * ydrop);
00538             }
00539             if (m_debug == true)
00540                 cerr << "    +UIBarType::Drawing Shadow @ (" << drawx
00541                      << ", " << drawy << ")" << endl;
00542             dr->drawText(drawx + m_textoffset.x(), drawy + m_textoffset.y(),
00543                            xdrop - m_textoffset.x(), ydrop - (int)(2 * m_textoffset.y()),
00544                            m_justification, msg);
00545         }
00546 
00547         dr->setBrush(clr);
00548         dr->setPen(QPen(clr, (int)(2 * m_wmult)));
00549         if (m_orientation == 1)
00550         {
00551             drawx = m_displaysize.left() + (int)(i * xdrop);
00552             drawy = m_displaysize.top();
00553         }
00554         else
00555         {
00556             drawx = m_displaysize.left();
00557             drawy = m_displaysize.top() + (int)(i * ydrop);
00558         }
00559         if (m_debug == true)
00560         {
00561             cerr << "    +UIBarType::Drawing @ (" << drawx << ", " << drawy << ")" << endl;
00562             cerr << "     +UIBarType::Data = " << msg << endl;
00563         }
00564         dr->drawText(drawx + m_textoffset.x(), drawy + m_textoffset.y(),
00565                      xdrop - m_textoffset.x(), ydrop - (int)(2 * m_textoffset.y()),
00566                      m_justification, msg);
00567 
00568         if (m_debug == true)
00569             cerr << "   +UIBarType::Draw() <- inside Layer\n";
00570       }
00571     }
00572     else
00573         if (m_debug == true)
00574         {
00575              cerr << "   +UIBarType::Draw() <- outside (layer = " << drawlayer
00576                   << ", widget layer = " << m_order << "\n";
00577         }
00578   }
00579 }
00580 
00581 // **************************************************************
00582 
00583 UIGuideType::UIGuideType(const QString &name, int order)
00584            : UIType(name)
00585 {
00586     m_name = name;
00587     m_order = order;
00588 
00589     maxRows = 20;
00590     numRows = 0;
00591 
00592     SetJustification((Qt::AlignLeft | Qt::AlignTop));
00593     cutdown = true;
00594     drawCategoryColors = true;
00595     drawCategoryText = true;
00596 
00597     font = NULL;
00598     window = NULL;
00599     seltype = 1;
00600     filltype = Alpha;
00601 
00602     allData = new QPtrList<UIGTCon>[maxRows];
00603 
00604     for (int i = 0; i < maxRows; i++)
00605         allData[i].setAutoDelete(true);
00606 
00607     int alphalevel = 80;
00608     alphaBlender.init(alphalevel, 307);
00609     prog_past_col = 0;
00610 }
00611 
00612 UIGuideType::~UIGuideType()
00613 {
00614     delete [] allData;
00615 }
00616 
00617 void UIGuideType::SetJustification(int jst)
00618 {
00619     justification = jst;
00620     multilineText = (justification & Qt::WordBreak) > 0;
00621 }
00622 
00623 void UIGuideType::Draw(QPainter *dr, int drawlayer, int context)
00624 {
00625     if (hidden)
00626         return;
00627 
00628     if ((m_context != context && m_context != -1) || drawlayer != m_order)
00629         return;
00630 
00631     UIGTCon *data;
00632     for (int i = 0; i < numRows; i++)
00633     {
00634         for (data = allData[i].first(); data; data = allData[i].next())
00635         {
00636             if (data->recStat == 0)
00637                 drawBackground(dr, data);
00638             else if (data->recStat == 1)
00639                 drawBox(dr, data, reccolor);
00640             else
00641                 drawBox(dr, data, concolor);
00642         }
00643     }
00644 
00645     drawCurrent(dr, &selectedItem);
00646 
00647     for (int i = 0; i < numRows; i++)
00648     {
00649         for (data = allData[i].first(); data; data = allData[i].next())
00650         {
00651             drawText(dr, data);
00652 
00653             if (data->recType != 0 || data->arrow != 0)
00654                 drawRecType(dr, data);
00655         }
00656     }
00657 }
00658 
00659 void UIGuideType::drawCurrent(QPainter *dr, UIGTCon *data)
00660 {
00661     int breakin = 2;
00662     QRect area = data->drawArea;
00663     area.addCoords(breakin, breakin, -breakin, -breakin);
00664 
00665     dr->setBrush(QBrush(Qt::NoBrush));
00666     dr->setPen(QPen(selcolor, 2));
00667 
00668     dr->drawRect(area);
00669     dr->drawLine(area.left(), area.top() - 1,
00670                  area.right(), area.top() - 1);
00671     dr->drawLine(area.left() - 1, area.top(),
00672                  area.left() - 1, area.bottom());
00673     dr->drawLine(area.left(), area.bottom() + 1,
00674                  area.right(), area.bottom() + 1);
00675     dr->drawLine(area.right() + 1, area.top(),
00676                  area.right() + 1, area.bottom());
00677 }
00678 
00679 void UIGuideType::drawRecType(QPainter *dr, UIGTCon *data)
00680 {
00681     int breakin = 1;
00682     QRect area = data->drawArea;
00683     area.addCoords(breakin, breakin, -breakin, -breakin);
00684 
00685     int recTypeOffset = 0;
00686 
00687     if (data->arrow != 0)
00688     {
00689         QPixmap *arrowImg;
00690         if (data->arrow == 1 || data->arrow == 3)
00691         {
00692             arrowImg = &arrowImages[0];
00693             dr->drawPixmap(area.left(), area.top() + (area.height() / 2) -
00694                            (arrowImg->height() / 2), *arrowImg);
00695         }
00696         if (data->arrow == 2 || data->arrow == 3)
00697         {
00698             arrowImg = &arrowImages[1];
00699             recTypeOffset = arrowImg->width();
00700             dr->drawPixmap(area.right() - arrowImg->width(),
00701                            area.top() + (area.height() / 2) -
00702                            (arrowImg->height() / 2), *arrowImg);
00703         }
00704     }
00705 
00706     if (data->recType != 0)
00707     {
00708         QPixmap *recImg = &recImages[data->recType];
00709         dr->drawPixmap(area.right() - recImg->width() - recTypeOffset,
00710                        area.bottom() - recImg->height(), *recImg);
00711     }
00712 }
00713 
00714 void UIGuideType::drawBox(QPainter *dr, UIGTCon *data, const QColor &color)
00715 {
00716     int breakin = 1;
00717     QRect area = data->drawArea;
00718     area.addCoords(breakin, breakin, -breakin, -breakin);
00719 
00720     if (filltype == Alpha)
00721     {
00722         QPixmap orig(area.width(), area.height());
00723         orig.fill(window, screenloc.x() + area.left(),
00724                             screenloc.y() + area.top());
00725         QImage tmpimg = orig.convertToImage();
00726 
00727         alphaBlender.blendImage(tmpimg, color);
00728         dr->drawImage(area.left(), area.top(), tmpimg);
00729     }
00730     else if (filltype == Dense)
00731     {
00732         dr->fillRect(area, QBrush(color, Qt::Dense4Pattern));
00733     }
00734     else if (filltype == Eco)
00735     {
00736         dr->fillRect(area, QBrush(color, Qt::Dense4Pattern));
00737     }
00738     else if (filltype == Solid)
00739     {
00740         dr->fillRect(area, QBrush(color, Qt::SolidPattern));
00741     }
00742 }
00743 
00744 void UIGuideType::drawBackground(QPainter *dr, UIGTCon *data)
00745 {
00746     QColor overColor;
00747     QRect overArea;
00748 
00749     int breakin = 1;
00750     QRect area = data->drawArea;
00751 
00752     QColor fillColor = solidcolor;
00753     if (drawCategoryColors && data->categoryColor.isValid())
00754         fillColor = data->categoryColor;
00755 
00756     if (prog_past_col && area.left() < prog_past_col)
00757     {
00758         if (area.right() < prog_past_col)
00759         {
00760             fillColor = fillColor.dark();
00761             area.addCoords(breakin, breakin, -breakin, -breakin);
00762         }
00763         else
00764         {
00765             overColor = fillColor.dark();
00766             int first = prog_past_col - area.left();
00767             int second = area.width() - first;
00768             overArea = area;
00769             overArea.setWidth(first);
00770             area.moveBy(first, 0);
00771             area.setWidth(second);
00772 
00773             area.addCoords(0, breakin, -breakin, -breakin);
00774             overArea.addCoords(breakin, breakin, 0, -breakin);
00775         }
00776     }
00777     else
00778         area.addCoords(breakin, breakin, -breakin, -breakin);
00779 
00780     if (area.width() <= 1)
00781         area.setWidth(2);
00782     if (area.height() <= 1)
00783         area.setHeight(2);
00784 
00785     if (filltype == Alpha)
00786     {
00787         QPixmap orig(area.width(), area.height());
00788         orig.fill(window, screenloc.x() + area.left(),
00789                           screenloc.y() + area.top());
00790         QImage tmpimg = orig.convertToImage();
00791 
00792         alphaBlender.blendImage(tmpimg, fillColor);
00793         dr->drawImage(area.left(), area.top(), tmpimg);
00794 
00795         if (overArea.width() > 0)
00796         {
00797             orig = QPixmap(overArea.width(), overArea.height());
00798             orig.fill(window, screenloc.x() + overArea.left(),
00799                               screenloc.y() + overArea.top());
00800             tmpimg = orig.convertToImage();
00801 
00802             alphaBlender.blendImage(tmpimg, overColor);
00803             dr->drawImage(overArea.left(), overArea.top(), tmpimg);
00804         }
00805     }
00806     else if (filltype == Dense)
00807     {
00808         dr->fillRect(area, QBrush(fillColor, Qt::Dense4Pattern));
00809         if (overArea.width() > 0)
00810             dr->fillRect(overArea, QBrush(overColor, Qt::Dense4Pattern));
00811     }
00812     else if (filltype == Eco)
00813     {
00814         dr->fillRect(area, QBrush(fillColor, Qt::Dense4Pattern));
00815         if (overArea.width() > 0)
00816             dr->fillRect(overArea, QBrush(overColor, Qt::Dense4Pattern));
00817     }
00818     else if (filltype == Solid)
00819     {
00820         dr->fillRect(area, QBrush(fillColor, Qt::SolidPattern));
00821         if (overArea.width() > 0)
00822             dr->fillRect(overArea, QBrush(overColor, Qt::SolidPattern));
00823     }
00824 }
00825 
00826 void UIGuideType::drawText(QPainter *dr, UIGTCon *data)
00827 {
00828     QString msg = data->title;
00829 
00830     if (drawCategoryText && data->category.length() > 0)
00831         msg += " (" + data->category + ")";
00832 
00833     QRect area = data->drawArea;
00834     area.addCoords(textoffset.x(), textoffset.y(),
00835                    -textoffset.x(), -textoffset.y());
00836 
00837     if (data->arrow == 1 || data->arrow == 3)
00838         area.setLeft(area.left() + arrowImages[0].width());
00839     if (data->arrow == 2 || data->arrow == 3)
00840         area.setRight(area.right() - arrowImages[1].width());
00841 
00842     if (cutdown)
00843         msg = cutDown(msg, &font->face, multilineText,
00844                       area.width(), area.height());
00845 
00846     dr->setFont(font->face);
00847 
00848     if (drawFontShadow &&
00849         (font->shadowOffset.x() != 0 || font->shadowOffset.y() != 0))
00850     {
00851         dr->setBrush(font->dropColor);
00852         dr->setPen(QPen(font->dropColor, (int)(2 * m_wmult)));
00853         dr->drawText(area.left() + font->shadowOffset.x(),
00854                      area.top() + font->shadowOffset.y(),
00855                      area.width(), area.height(), justification, msg);
00856     }
00857 
00858     dr->setBrush(font->color);
00859     dr->setPen(QPen(font->color, (int)(2 * m_wmult)));
00860     dr->drawText(area, justification, msg);
00861 }
00862 
00863 void UIGuideType::SetProgramInfo(int row, int col, const QRect &area,
00864                                  const QString &title, const QString &genre,
00865                                  int arrow, int recType, int recStat,
00866                                  bool selected)
00867 {
00868     (void)col;
00869     UIGTCon *data = new UIGTCon(area, title, genre, arrow, recType, recStat);
00870 
00871     allData[row].append(data);
00872 
00873     if (drawCategoryColors)
00874     {
00875         data->categoryColor = categoryColors[data->category.lower()];
00876         if (!data->categoryColor.isValid())
00877             data->categoryColor = categoryColors["none"];
00878     }
00879 
00880     if (selected)
00881         selectedItem = *data;
00882 }
00883 
00884 void UIGuideType::SetCategoryColors(const QMap<QString, QString> &catC)
00885 {
00886     for (QMap<QString, QString>::const_iterator it = catC.begin();
00887          it != catC.end(); ++it)
00888     {
00889         QColor tmp(it.data());
00890         categoryColors[it.key()] = tmp;
00891     }
00892 }
00893 
00894 void UIGuideType::LoadImage(int recType, const QString &file)
00895 {
00896     QString themeDir = gContext->GetThemeDir();
00897     QString filename = themeDir + file;
00898 
00899     QPixmap *pix = gContext->LoadScalePixmap(filename);
00900 
00901     if (pix)
00902     {
00903         recImages[recType] = *pix;
00904         delete pix;
00905     }
00906 }
00907 
00908 void UIGuideType::SetArrow(int direction, const QString &file)
00909 {
00910     QString themeDir = gContext->GetThemeDir();
00911     QString filename = themeDir + file;
00912 
00913     QPixmap *pix = gContext->LoadScalePixmap(filename);
00914 
00915     if (pix)
00916     {
00917         arrowImages[direction] = *pix;
00918         delete pix;
00919     }
00920 }
00921 
00922 void UIGuideType::ResetData()
00923 {
00924     for (int i = 0; i < numRows; i++)
00925         allData[i].clear();
00926 }
00927 
00928 void UIGuideType::ResetRow(int row)
00929 {
00930     allData[row].clear();
00931 }
00932 
00933 void UIGuideType::SetProgPast(int ppast)
00934 {
00935     prog_past_col = area.width() * ppast / 100;
00936 }
00937 
00938 
00939 // **************************************************************
00940 
00941 AlphaTable::AlphaTable(const QColor &color, int alpha)
00942 {
00943     maketable(r, color.red(), alpha);
00944     maketable(g, color.green(), alpha);
00945     maketable(b, color.blue(), alpha);
00946 }
00947 
00948 AlphaTable::~AlphaTable()
00949 {
00950 }
00951 
00952 void AlphaTable::maketable(unsigned char* data, int channel, int alpha)
00953 {
00954     for (int i = 0; i <= 255; i++)
00955         data[i] = (unsigned char)(i + (((channel - i) * alpha) >> 8));
00956 }
00957 
00958 AlphaBlender::AlphaBlender()
00959 {
00960     init();
00961 }
00962 
00963 AlphaBlender::~AlphaBlender()
00964 {
00965 }
00966 
00967 void AlphaBlender::init(int alpha, int cacheSize)
00968 {
00969     this->alpha = alpha;
00970     alphaTables.setAutoDelete(true);
00971     alphaTables.clear();
00972     alphaTables.resize(cacheSize);
00973 }
00974 
00975 void AlphaBlender::addColor(const QColor &color)
00976 {
00977     if (!alphaTables[color.name()])
00978         alphaTables.insert(color.name(), new AlphaTable(color, alpha));
00979 }
00980 
00981 void AlphaBlender::blendImage(const QImage &image, const QColor &color)
00982 {
00983     AlphaTable *table = alphaTables.find(color.name());
00984     if (!table)
00985     {
00986         addColor(color);
00987         table = alphaTables.find(color.name());
00988     }
00989 
00990     unsigned char *r = table->r;
00991     unsigned char *g = table->g;
00992     unsigned char *b = table->b;
00993 
00994     int size = image.height() * image.width();
00995     unsigned char *data = *image.jumpTable();
00996 
00997     for (int i = 0; i < size; i++)
00998     {
00999         *data = b[*data]; data++;
01000         *data = g[*data]; data++;
01001         *data = r[*data]; data++;
01002         data++;
01003     }
01004 }
01005 
01006 // **************************************************************
01007 
01008 UIListType::UIListType(const QString &name, QRect area, int dorder)
01009           : UIType(name)
01010 {
01011     m_name = name;
01012     m_area = area;
01013     m_order = dorder;
01014     m_active = false;
01015     m_columns = 0;
01016     m_current = -1;
01017     m_count = 0;
01018     m_justification = 0;
01019     m_uarrow = false;
01020     m_darrow = false;
01021     m_fill_type = -1;
01022     m_showSelAlways = true;
01023     has_focus = false;
01024     takes_focus = true;
01025 }
01026 
01027 UIListType::~UIListType()
01028 {
01029 }
01030 
01031 void UIListType::Draw(QPainter *dr, int drawlayer, int context)
01032 {
01033   if (hidden)
01034      return;
01035 
01036   if (m_context == context || m_context == -1)
01037   {
01038     if (drawlayer == m_order)
01039     {
01040         if (m_fill_type == 1 && m_active == true)
01041             dr->fillRect(m_fill_area, QBrush(m_fill_color, Qt::Dense4Pattern));
01042 
01043         QString tempWrite;
01044             int left = 0;
01045         fontProp *tmpfont = NULL;
01046         bool lastShown = true;
01047         QPoint fontdrop = QPoint(0, 0);
01048         int tempArrows = 0;
01049 
01050         if (m_debug == true)
01051             cerr << "   +UIListType::Draw() <- within Layer\n";
01052 
01053         for (int i = 0; i < m_count; i++)
01054         {
01055             if (m_active == true)
01056                 tmpfont = &m_fontfcns[m_fonts["active"]];
01057             else
01058                 tmpfont = &m_fontfcns[m_fonts["inactive"]];
01059 
01060             if (forceFonts[i] != "")
01061                 tmpfont = &m_fontfcns[forceFonts[i]];
01062 
01063             fontdrop = tmpfont->shadowOffset;
01064 
01065             dr->setFont(tmpfont->face);
01066 
01067             left = m_area.left();
01068             for (int j = 1; j <= m_columns; j++)
01069             {
01070                 int offsetRight = 0;
01071                 int offsetLeft = 0;
01072                 int caw = columnWidth[j];
01073 
01074                 if (caw == 0)
01075                     caw = m_area.width();
01076 
01077                 if (j > 1 && lastShown == true)
01078                     left = left + columnWidth[j - 1] + m_pad;
01079 
01080                 if (m_debug == true)
01081                 {
01082                     cerr << "      -Column #" << j
01083                          << ", Column Context: " << columnContext[j]
01084                          << ", Draw Context: " << context << endl;
01085                 }
01086 
01087                 if (columnContext[j] != context && columnContext[j] != -1)
01088                 {
01089                     lastShown = false;
01090                 }
01091                 else
01092                 {
01093                     tempWrite = listData[i + (int)(100*j)];
01094                     tempArrows = listArrows[i + 100];
01095 
01096                     if (j == 1)
01097                     {
01098                         offsetLeft = m_leftarrow.width() + m_leftarrow_loc.x();
01099                         if (tempArrows & ARROW_LEFT)
01100                             dr->drawPixmap(left + m_leftarrow_loc.x(),
01101                                        m_area.top() + (int)(i * m_selheight) + m_leftarrow_loc.y(),
01102                                        m_leftarrow);
01103 
01104                     }
01105 
01106                     if (j == m_columns)
01107                     {
01108                         offsetRight = m_rightarrow.width()  - m_rightarrow_loc.x();
01109                         if (tempArrows & ARROW_RIGHT)
01110                             dr->drawPixmap(m_area.right() - offsetRight + m_rightarrow_loc.x(),
01111                                        m_area.top() + (int)(i * m_selheight) + m_rightarrow_loc.y(),
01112                                        m_rightarrow);
01113                     }
01114 
01115                     if (tempWrite != "***FILLER***")
01116                     {
01117                         if (columnWidth[j] > 0)
01118                             tempWrite = cutDown(tempWrite, &(tmpfont->face),
01119                                                 false, columnWidth[j] - offsetRight - offsetLeft);
01120                     }
01121                     else
01122                         tempWrite = "";
01123 
01124 
01125                     if (drawFontShadow &&
01126                         (fontdrop.x() != 0 || fontdrop.y() != 0))
01127                     {
01128                         dr->setBrush(tmpfont->dropColor);
01129                         dr->setPen(QPen(tmpfont->dropColor,
01130                                         (int)(2 * m_wmult)));
01131                         dr->drawText((int)(left + fontdrop.x()) + offsetLeft,
01132                                      (int)(m_area.top() + (int)(i*m_selheight) +
01133                                      fontdrop.y()), caw - offsetRight, m_selheight,
01134                                      m_justification, tempWrite);
01135                     }
01136                     dr->setBrush(tmpfont->color);
01137                     dr->setPen(QPen(tmpfont->color, (int)(2 * m_wmult)));
01138 
01139                     dr->drawText(left + offsetLeft, m_area.top() + (int)(i*m_selheight),
01140                                  caw - offsetRight, m_selheight, m_justification,
01141                                  tempWrite);
01142                     dr->setFont(tmpfont->face);
01143                     if (m_debug == true)
01144                         cerr << "   +UIListType::Draw() Data: "
01145                              << tempWrite << "\n";
01146                     lastShown = true;
01147                  }
01148               }
01149           }
01150 
01151           if (m_uarrow == true)
01152               dr->drawPixmap(m_uparrow_loc, m_uparrow);
01153           if (m_darrow == true)
01154               dr->drawPixmap(m_downarrow_loc, m_downarrow);
01155     }
01156     else if (drawlayer == 8 && m_current >= 0)
01157     {
01158         QString tempWrite;
01159         int left = 0;
01160         int i = m_current;
01161         fontProp *tmpfont = NULL;
01162         int tempArrows;
01163 
01164         if (m_active == true)
01165             tmpfont = &m_fontfcns[m_fonts["selected"]];
01166         else
01167             tmpfont = &m_fontfcns[m_fonts["inactive"]];
01168 
01169         if (forceFonts[i] != "")
01170             tmpfont = &m_fontfcns[forceFonts[i]];
01171 
01172         bool lastShown = true;
01173         QPoint fontdrop = tmpfont->shadowOffset;
01174 
01175         dr->setFont(tmpfont->face);
01176 
01177         if (m_active == true || m_showSelAlways)
01178             dr->drawPixmap(m_area.left() + m_selection_loc.x(),
01179                            m_area.top() + m_selection_loc.y() +
01180                            (int)(m_current * m_selheight),
01181                            m_selection);
01182 
01183         left = m_area.left();
01184         for (int j = 1; j <= m_columns; j++)
01185         {
01186             int offsetRight = 0;
01187             int offsetLeft = 0;
01188             int caw = columnWidth[j];
01189 
01190             if (caw == 0)
01191                 caw = m_area.width();
01192 
01193             if (j > 1 && lastShown == true)
01194                 left = left + columnWidth[j - 1] + m_pad;
01195 
01196             if (m_debug == true)
01197             {
01198                 cerr << "      -Column #" << j
01199                      << ", Column Context: " << columnContext[j]
01200                      << ", Draw Context: " << context << endl;
01201             }
01202             if (columnContext[j] != context && columnContext[j] != -1)
01203             {
01204                 lastShown = false;
01205             }
01206             else
01207             {
01208                 tempWrite = listData[i + (int)(100*j)];
01209                 tempArrows = listArrows[i + 100];
01210 
01211                 if (j == 1)
01212                 {
01213                     offsetLeft = m_leftarrow.width() + m_leftarrow_loc.x();
01214                     if (tempArrows & ARROW_LEFT)
01215                     {
01216                         dr->drawPixmap(left + m_leftarrow_loc.x(),
01217                                        m_area.top() + (int)(i * m_selheight) + m_leftarrow_loc.y(),
01218                                        m_leftarrow);
01219                     }
01220                 }
01221 
01222                 if (j == m_columns)
01223                 {
01224                     offsetRight = m_rightarrow.width() - m_rightarrow_loc.x();
01225                     if (tempArrows & ARROW_RIGHT)
01226                     {
01227                         dr->drawPixmap(m_area.right() - offsetRight + m_rightarrow_loc.x(),
01228                                        m_area.top() + (int)(i * m_selheight) + m_rightarrow_loc.y(),
01229                                        m_rightarrow);
01230                     }
01231                 }
01232 
01233                  if (columnWidth[j] > 0)
01234                      tempWrite = cutDown(tempWrite, &(tmpfont->face), false,
01235                                          columnWidth[j] - offsetLeft - offsetRight);
01236 
01237                  if (drawFontShadow &&
01238                      (fontdrop.x() != 0 || fontdrop.y() != 0))
01239                  {
01240                      dr->setBrush(tmpfont->dropColor);
01241                      dr->setPen(QPen(tmpfont->dropColor, (int)(2 * m_wmult)));
01242                      dr->drawText((int)(left + fontdrop.x()) + offsetLeft,
01243                                   (int)(m_area.top() + (int)(i*m_selheight) +
01244                                   fontdrop.y()), caw - offsetRight, m_selheight,
01245                                   m_justification, tempWrite);
01246                  }
01247                  dr->setBrush(tmpfont->color);
01248                  dr->setPen(QPen(tmpfont->color, (int)(2 * m_wmult)));
01249 
01250                  dr->drawText(left + offsetLeft, m_area.top() + (int)(i*m_selheight),
01251                               caw - offsetRight, m_selheight, m_justification,
01252                               tempWrite);
01253 
01254                  dr->setFont(tmpfont->face);
01255              }
01256         }
01257     }
01258     else
01259     {
01260         if (m_debug == true)
01261             cerr << "   +UIListType::Draw() <- outside (layer = " << drawlayer
01262                  << ", widget layer = " << m_order << "\n";
01263     }
01264   }
01265 }
01266 
01267 void UIListType::SetItemText(int num, int column, QString data)
01268 {
01269     if (column > m_columns)
01270         m_columns = column;
01271     listData[(int)(num + (int)(column * 100))] = data;
01272 }
01273 
01274 QString UIListType::GetItemText(int num, int column)
01275 {
01276     QString ret;
01277     ret = listData[(int)(num + (int)(column * 100))];
01278     return ret;
01279 }
01280 
01281 void UIListType::SetItemText(int num, QString data)
01282 {
01283     m_columns = 1;
01284     listData[num + 100] = data;
01285 }
01286 
01287 void UIListType::SetItemArrow(int num, int which)
01288 {
01289     m_columns = 1;
01290     listArrows[num + 100] = which;
01291 }
01292 
01293 void UIListType::calculateScreenArea()
01294 {
01295     QRect r2, r = m_area;
01296 
01297     // take the selection image position into account
01298     r2.setRect(r.x() + m_selection_loc.x(), r.y() + m_selection_loc.y(),
01299                m_selection.width(), m_selection.height()); 
01300     r = r.unite(r2);
01301 
01302     // take the up arrow image position into account
01303     r2.setRect(m_uparrow_loc.x(), m_uparrow_loc.y(),
01304               m_uparrow.width(), m_uparrow.height()); 
01305     r = r.unite(r2);
01306 
01307     // take the down arrow image position into account
01308     r2.setRect(m_downarrow_loc.x(), m_downarrow_loc.y(),
01309                m_downarrow.width(), m_downarrow.height()); 
01310     r = r.unite(r2);
01311 
01312     r.moveBy(m_parent->GetAreaRect().left(),
01313              m_parent->GetAreaRect().top());
01314     screen_area = r;
01315 }
01316 
01317 
01318 bool UIListType::takeFocus()
01319 {
01320     SetActive(true);
01321     return UIType::takeFocus();
01322 }
01323 
01324 void UIListType::looseFocus()
01325 {
01326     SetActive(false);
01327     UIType::looseFocus();
01328 }
01329 
01330 // *****************************************************************
01331 
01332 UIImageType::UIImageType(const QString &name, const QString &filename, int dorder, QPoint displaypos)
01333            : UIType(name)
01334 {
01335     m_isvalid = false;
01336     m_flex = false;
01337     img = QPixmap();
01338 
01339     m_filename = filename;
01340     orig_filename = filename;
01341     m_displaypos = displaypos;
01342     m_order = dorder;
01343     m_force_x = -1;
01344     m_force_y = -1;
01345     m_drop_x = 0;
01346     m_drop_y = 0;
01347     m_show = false;
01348     m_transparent = gContext->GetNumSetting("PlayBoxTransparency", 1);
01349 }
01350 
01351 UIImageType::~UIImageType()
01352 {
01353 }
01354 
01355 void UIImageType::LoadImage()
01356 {
01357     if (m_filename == "none")
01358     {
01359         m_show = false;
01360         return;
01361     }
01362 
01363     QString file;
01364     if (m_flex == true)
01365     {
01366         QString flexprefix = m_transparent ? "trans-" : "solid-";
01367         int pathStart = m_filename.findRev('/');
01368         if (pathStart < 0 )
01369             m_filename = flexprefix + m_filename;
01370         else
01371             m_filename.replace(pathStart, 1, "/" + flexprefix);
01372     }
01373 
01374     QString filename = gContext->GetThemeDir() + m_filename;
01375 
01376     if (m_force_x == -1 && m_force_y == -1)
01377     {
01378         QPixmap *tmppix = gContext->LoadScalePixmap(filename);
01379         if (tmppix)
01380         {
01381             img = *tmppix;
01382             m_show = true;
01383 
01384             delete tmppix;
01385             refresh();
01386 
01387             return;
01388         }
01389     }
01390 
01391     file = m_filename;
01392 
01393     if (!gContext->FindThemeFile(file))
01394     {
01395         VERBOSE(VB_IMPORTANT, "UIImageType::LoadImage() - Cannot find image: "
01396                 << m_filename);
01397         m_show = false;
01398         return;
01399     }
01400 
01401     if (m_debug == true)
01402         VERBOSE(VB_GENERAL, "     -Filename: " << file);
01403 
01404     if (m_hmult == 1 && m_wmult == 1 && m_force_x == -1 && m_force_y == -1)
01405     {
01406         if (img.load(file))
01407             m_show = true;
01408     }
01409     else
01410     {
01411         QImage *sourceImg = new QImage();
01412         if (sourceImg->load(file))
01413         {
01414             QImage scalerImg;
01415             int doX = sourceImg->width();
01416             int doY = sourceImg->height();
01417             if (m_force_x != -1)
01418             {
01419                 doX = m_force_x;
01420                 if (m_debug == true)
01421                     VERBOSE(VB_GENERAL, "         +Force X: " << doX);
01422             }
01423             if (m_force_y != -1)
01424             {
01425                 doY = m_force_y;
01426                 if (m_debug == true)
01427                     VERBOSE(VB_GENERAL, "         +Force Y: " << doY);
01428             }
01429 
01430             scalerImg = sourceImg->smoothScale((int)(doX * m_wmult),
01431                                                (int)(doY * m_hmult));
01432             m_show = true;
01433             img.convertFromImage(scalerImg);
01434             if (m_debug == true)
01435                 VERBOSE(VB_GENERAL, "     -Image: " << file << " loaded.");
01436         }
01437         else
01438         {
01439             m_show = false;
01440             if (m_debug == true)
01441                 VERBOSE(VB_GENERAL, "     -Image: " << file << " failed to load.");
01442         }
01443         delete sourceImg;
01444     }
01445 
01446     //
01447     //  On the odd chance we are owned by a
01448     //  MythThemedDialog, ask to be re-painted
01449     //
01450 
01451     refresh();
01452 }
01453 
01454 void UIImageType::Draw(QPainter *dr, int drawlayer, int context)
01455 {
01456     if (hidden)
01457     {
01458         return;
01459     }
01460     if (m_context == context || m_context == -1)
01461     {
01462         if (drawlayer == m_order)
01463         {
01464             if (!img.isNull() && m_show == true)
01465             {
01466                 if (m_debug == true)
01467                 {
01468                     cerr << "   +UIImageType::Draw() <- inside Layer\n";
01469                     cerr << "       -Drawing @ (" << m_displaypos.x() << ", " << m_displaypos.y() << ")" << endl;
01470                     cerr << "       -Skip Section: (" << m_drop_x << ", " << m_drop_y << ")\n";
01471                 }
01472                 dr->drawPixmap(m_displaypos.x(), m_displaypos.y(), img, m_drop_x, m_drop_y);
01473             }
01474             else if (m_debug == true)
01475             {
01476                 cerr << "   +UIImageType::Draw() <= Image is null\n";
01477             }
01478         }
01479     }
01480     else if (m_debug == true)
01481     {
01482             cerr << "   +UIImageType::Draw() <- outside (layer = " << drawlayer
01483                  << ", widget layer = " << m_order << "\n";
01484     }
01485 }
01486 
01487 void UIImageType::refresh()
01488 {
01489     //
01490     //  Figure out how big we are
01491     //  and where we are in screen
01492     //  coordinates
01493     //
01494 
01495     QRect r = QRect(m_displaypos.x(),
01496                     m_displaypos.y(),
01497                     img.width(),
01498                     img.height());
01499 
01500     if (m_parent)
01501     {
01502         r.moveBy(m_parent->GetAreaRect().left(),
01503                  m_parent->GetAreaRect().top());
01504 
01505         //
01506         //  Tell someone who cares
01507         //
01508 
01509         emit requestUpdate(r);
01510     }
01511     else
01512     {
01513         //
01514         //  This happens when parent isn't set,
01515         //  usually during initial parsing.
01516         //
01517         emit requestUpdate();
01518     }
01519 }
01520 
01521 // *****************************************************************
01522 
01523 UIAnimatedImageType::UIAnimatedImageType(const QString &name, const QString &filename,
01524            int imagecount, int interval, int startinterval, int dorder, QPoint displaypos)
01525            : UIType(name)
01526 {
01527     m_isvalid = false;
01528     m_flex = false;
01529 
01530     m_filename = filename;
01531     orig_filename = filename;
01532     m_displaypos = displaypos;
01533     m_order = dorder;
01534     m_force_x = -1;
01535     m_force_y = -1;
01536     m_drop_x = 0;
01537     m_drop_y = 0;
01538     m_show = false;
01539     m_imagecount = imagecount;
01540     m_interval = interval;
01541     m_startinterval = startinterval;
01542     m_currentimage = 0;
01543 
01544     // create the image cache
01545     imageList = NULL;
01546     InitImageCache();
01547 
01548     m_window = NULL;
01549     connect( &timer, SIGNAL(timeout()), this, SLOT(IntervalTimeout()));
01550     timer.start(m_interval);
01551 }
01552 
01553 UIAnimatedImageType::~UIAnimatedImageType()
01554 {
01555     ClearImages();
01556     delete imageList;
01557 }
01558 
01559 void UIAnimatedImageType::InitImageCache()
01560 {
01561     if (imageList)
01562     {
01563         ClearImages();
01564         delete imageList;
01565     }
01566 
01567     // create the image cache
01568     imageList = new vector<QPixmap*>;
01569 }
01570 
01571 void UIAnimatedImageType::ClearImages()
01572 {
01573     if (imageList)
01574     {
01575     vector<QPixmap *>::iterator i = imageList->begin();
01576     for (; i != imageList->end(); i++)
01577     {
01578         QPixmap *pixmap = (*i);
01579         if (pixmap)
01580         {
01581             delete pixmap;
01582             (*i) = NULL;
01583         }
01584     }
01585     }
01586 }
01587 
01588 void UIAnimatedImageType::LoadImages()
01589 {
01590     InitImageCache();
01591 
01592     for (int x = 0; x < m_imagecount; x++)
01593     {
01594         if (!LoadImage(x))
01595             cerr << "UIAnimatedImage: LoadImages() Failed to load image No.: " << x << endl;
01596     }
01597 
01598     refresh();
01599 }
01600 
01601 bool UIAnimatedImageType::LoadImage(int imageNo)
01602 {
01603     if (imageNo >= m_imagecount)
01604         return false;
01605 
01606     QString filename = m_filename.arg(imageNo);
01607     if (!gContext->FindThemeFile(filename))
01608          return true;
01609 
01610     bool bSuccess = false;
01611     if (m_force_x == -1 && m_force_y == -1)
01612     {
01613         QPixmap *tmppix = gContext->LoadScalePixmap(filename);
01614         if (tmppix)
01615         {
01616             imageList->push_back(tmppix);
01617             bSuccess = true;
01618         }
01619     }
01620 
01621     if (m_hmult == 1 && m_wmult == 1 && m_force_x == -1 && m_force_y == -1)
01622     {
01623         QPixmap *img = new QPixmap();
01624         if (img->load(filename))
01625         {
01626             imageList->push_back(img);
01627             bSuccess = true;
01628         }
01629         else
01630         {
01631            delete img;
01632         }
01633     }
01634     else
01635     {
01636         QImage sourceImg(filename);
01637         if (!sourceImg.isNull())
01638         {
01639             int doX = sourceImg.width();
01640             int doY = sourceImg.height();
01641             if (m_force_x != -1)
01642             {
01643                 doX = m_force_x;
01644             }
01645             if (m_force_y != -1)
01646             {
01647                 doY = m_force_y;
01648             }
01649 
01650             QImage scalerImg = sourceImg.smoothScale((int)(doX * m_wmult),
01651                                                (int)(doY * m_hmult));
01652 
01653             QPixmap *img = new QPixmap();
01654             img->convertFromImage(scalerImg);
01655             imageList->push_back(img);
01656 
01657             bSuccess = true;
01658         }
01659     }
01660 
01661     return bSuccess;
01662 }
01663 
01664 void UIAnimatedImageType::Draw(QPainter *dr, int drawlayer, int context)
01665 {
01666     if (hidden)
01667     {
01668         return;
01669     }
01670 
01671     if (m_context == context || m_context == -1)
01672     {
01673         if (drawlayer == m_order)
01674         {
01675             // sanity check
01676             if ( !imageList || m_currentimage < 0 || m_currentimage >= (int) imageList->size() )
01677                     return;
01678 
01679             if (!((*imageList)[m_currentimage])->isNull())
01680             {
01681                 dr->drawPixmap(m_displaypos.x(), m_displaypos.y(), *(*imageList)[m_currentimage], m_drop_x, m_drop_y);
01682             }
01683         }
01684     }
01685 }
01686 
01687 void UIAnimatedImageType::refresh()
01688 {
01689     if (m_parent && imageList->size() > 0 && !((*imageList)[0])->isNull())
01690     {
01691         QRect r = QRect(m_displaypos.x(),  m_displaypos.y(),
01692                         (*imageList)[0]->width(), (*imageList)[0]->height());
01693 
01694         r.moveBy(m_parent->GetAreaRect().left(),
01695                  m_parent->GetAreaRect().top());
01696 
01697         if (m_window)
01698             m_window->update(r);
01699         else
01700             emit requestUpdate(r);
01701     }
01702     else
01703     {
01704         if (m_window)
01705             m_window->update();
01706         else
01707             emit requestUpdate();
01708     }
01709 }
01710 
01711 void UIAnimatedImageType::IntervalTimeout()
01712 {
01713     timer.stop();
01714     m_currentimage++;
01715     if (m_currentimage >= (int)imageList->size())
01716         m_currentimage = 0;
01717 
01718     refresh();
01719 
01720     if (m_currentimage == (int)(imageList->size() - 1))
01721         timer.start(m_startinterval, true);
01722     else
01723         timer.start(m_interval, true);
01724 }
01725 
01726 void UIAnimatedImageType::Pause()
01727 {
01728     timer.stop();
01729 }
01730 
01731 void UIAnimatedImageType::UnPause()
01732 {
01733     if (!timer.isActive())
01734         timer.start(m_interval);
01735 }
01736 
01737 void UIAnimatedImageType::NextImage()
01738 {
01739     if (!timer.isActive())
01740     {
01741         m_currentimage++;
01742         if (m_currentimage >= (int)imageList->size())
01743             m_currentimage = 0;
01744 
01745         refresh();
01746     }
01747 }
01748 
01749 void UIAnimatedImageType::PreviousImage()
01750 {
01751     if (!timer.isActive())
01752     {
01753         m_currentimage--;
01754         if (m_currentimage < 0)
01755             m_currentimage = (int)imageList->size() - 1;
01756 
01757         refresh();
01758     }
01759 }
01760 
01761 void UIAnimatedImageType::SetImageCount(int count)
01762 {
01763     m_imagecount = count;
01764     InitImageCache();
01765     LoadImages();
01766 }
01767 
01768 // ******************************************************************
01769 
01770 UIRepeatedImageType::UIRepeatedImageType(const QString &name, const QString &filename, int dorder, QPoint displaypos)
01771         : UIImageType(name, filename, dorder, displaypos)
01772 {
01773     m_repeat = 0;
01774     m_highest_repeat = 1;
01775     m_orientation = 0;
01776 }
01777 
01778 void UIRepeatedImageType::Draw(QPainter *p, int drawlayer, int context)
01779 {
01780     if (hidden)
01781         return;
01782 
01783     if (m_context == context || m_context == -1)
01784     {
01785         if (drawlayer == m_order)
01786         {
01787             if (!img.isNull() && m_show == true)
01788             {
01789                 if (m_debug == true)
01790                 {
01791                     cerr << "   +UIRepeatedImageType::Draw() <- inside Layer\n";
01792                     cerr << "       -Drawing @ (" << m_displaypos.x() << ", " << m_displaypos.y() << ")" << endl;
01793                     cerr << "       -Skip Section: (" << m_drop_x << ", " << m_drop_y << ")\n";
01794                 }
01795                 if (m_orientation == 0)
01796                 {
01797                     for(int i = 0; i < m_repeat; i++)
01798                     {
01799                         p->drawPixmap(m_displaypos.x() + (i * img.width()), m_displaypos.y(), img, m_drop_x, m_drop_y);
01800                     }
01801                 }
01802                 else if (m_orientation == 1)
01803                 {
01804                     for(int i = 0; i < m_repeat; i++)
01805                     {
01806                         p->drawPixmap(m_displaypos.x() - (i * img.width()), m_displaypos.y(), img, m_drop_x, m_drop_y);
01807                     }
01808                 }
01809                 else if (m_orientation == 2)
01810                 {
01811                     for(int i = 0; i < m_repeat; i++)
01812                     {
01813                         p->drawPixmap(m_displaypos.x(),  m_displaypos.y() - (i * img.height()), img, m_drop_x, m_drop_y);
01814                     }
01815                 }
01816                 else if (m_orientation == 3)
01817                 {
01818                     for(int i = 0; i < m_repeat; i++)
01819                     {
01820                         p->drawPixmap(m_displaypos.x(),  m_displaypos.y() + (i * img.height()), img, m_drop_x, m_drop_y);
01821                     }
01822                 }
01823             }
01824             else if (m_debug == true)
01825             {
01826                 cerr << "   +UIImageType::Draw() <= Image is null\n";
01827             }
01828         }
01829 
01830     }
01831     else
01832     {
01833         if (m_debug == true)
01834         {
01835             cerr << "   +UIImageType::Draw() <- outside (layer = " << drawlayer
01836                  << ", widget layer = " << m_order << "\n";
01837         }
01838     }
01839 }
01840 
01841 void UIRepeatedImageType::setRepeat(int how_many)
01842 {
01843     if (how_many >= 0)
01844     {
01845         m_repeat = how_many;
01846         if (how_many > m_highest_repeat)
01847         {
01848             m_highest_repeat = how_many;
01849         }
01850         refresh();
01851     }
01852 }
01853 
01854 void UIRepeatedImageType::setOrientation(int x)
01855 {
01856     if (x < 0 || x > 3)
01857     {
01858         cerr << "uitypes.o: UIRepeatedImageType received an invalid request to set orientation to " << x << endl;
01859         return;
01860     }
01861     m_orientation = x ;
01862 }
01863 
01864 void UIRepeatedImageType::refresh()
01865 {
01866     //
01867     //  Figure out how big we are
01868     //  and where we are in screen
01869     //  coordinates
01870     //
01871 
01872     QRect r = QRect(0,0,0,0);
01873 
01874     if (m_orientation == 0)
01875     {
01876         r = QRect(m_displaypos.x(),
01877                   m_displaypos.y(),
01878                   img.width() * m_highest_repeat,
01879                   img.height());
01880     }
01881     else if (m_orientation == 1)
01882     {
01883         r = QRect(m_displaypos.x() - (m_highest_repeat * img.width()),
01884                   m_displaypos.y(),
01885                   img.width() * (m_highest_repeat + 1),
01886                   img.height());
01887     }
01888     else if (m_orientation == 2)
01889     {
01890         r = QRect(m_displaypos.x(),
01891                   m_displaypos.y() - (m_highest_repeat * img.height()),
01892                   img.width(),
01893                   img.height() * (m_highest_repeat + 1));
01894     }
01895     else if (m_orientation == 3)
01896     {
01897         r = QRect(m_displaypos.x(),
01898                   m_displaypos.y(),
01899                   img.width(),
01900                   img.height() * m_highest_repeat);
01901     }
01902     if (m_parent)
01903     {
01904         r.moveBy(m_parent->GetAreaRect().left(),
01905                  m_parent->GetAreaRect().top());
01906 
01907         //
01908         //  Tell someone who cares
01909         //
01910 
01911         emit requestUpdate(r);
01912     }
01913     else
01914     {
01915         //
01916         //  This happens when parent isn't set,
01917         //  usually during initial parsing.
01918         //
01919         emit requestUpdate();
01920     }
01921 }
01922 
01923 // **************************************************************
01924 
01925 UIImageGridType::UIImageGridType(const QString &name, int order)
01926     : UIType(name)
01927 {
01928     m_name = name;
01929     m_order = order;
01930 
01931     activeFont = inactiveFont = selectedFont = NULL;
01932     window = NULL;
01933     defaultPixmap = normalPixmap = selectedPixmap = highlightedPixmap = NULL;
01934 
01935     topRow = rowCount = columnCount = itemCount = currentItem =
01936             borderWidth = padding = topRow = cellWidth = cellHeight =
01937             lastRow = lastColumn = curColumn = curRow = 0;
01938 
01939     textPos = UIImageGridType::textPosBottom;
01940     textHeight = 20;
01941     cutdown = true;
01942     setJustification((Qt::AlignLeft | Qt::AlignVCenter));
01943     allowFocus(true);
01944     showCheck = false;
01945     showSelected = false;
01946 
01947     allData = new QPtrList<ImageGridItem>;
01948     allData->setAutoDelete(true);
01949 }
01950 
01951 UIImageGridType::~UIImageGridType(void)
01952 {
01953     if (normalPixmap)
01954         delete normalPixmap;
01955     if (highlightedPixmap)
01956         delete highlightedPixmap;
01957     if (selectedPixmap)
01958         delete selectedPixmap;
01959     if (defaultPixmap)
01960         delete defaultPixmap;
01961 
01962     if (checkNonPixmap)
01963         delete checkNonPixmap;
01964     if (checkHalfPixmap)
01965         delete checkHalfPixmap;
01966     if (checkFullPixmap)
01967         delete checkFullPixmap;
01968 
01969     if (upArrowRegPixmap)
01970         delete upArrowRegPixmap;
01971     if (upArrowActPixmap)
01972         delete upArrowActPixmap;
01973     if (dnArrowRegPixmap)
01974         delete dnArrowRegPixmap;
01975     if (upArrowActPixmap)
01976         delete dnArrowActPixmap;
01977 
01978     delete allData;
01979 }
01980 
01981 void UIImageGridType::reset(void)
01982 {
01983     allData->clear();
01984     topRow = itemCount = currentItem = topRow = lastRow =
01985             lastColumn = curColumn = curRow = 0;
01986 }
01987 
01988 void  UIImageGridType::setCurrentPos(int pos)
01989 {
01990     if (pos < 0 || pos > (int) allData->count() - 1)
01991         return;
01992 
01993     currentItem = pos;
01994 
01995     // make sure the selected item is visible
01996     if ((currentItem < topRow * columnCount) || 
01997             (currentItem >= (topRow + rowCount) * columnCount))
01998     {
01999         topRow = QMAX(QMIN(currentItem / columnCount, lastRow - rowCount + 1), 0);
02000         curRow = topRow;
02001     }
02002 
02003     curColumn = currentItem % columnCount;
02004     refresh();
02005 }
02006 
02007 void  UIImageGridType::setCurrentPos(QString value)
02008 {
02009     ImageGridItem *item;
02010     for (item = allData->first(); item; item = allData->next())
02011     {
02012         if (item->text == value)
02013         {
02014             setCurrentPos(allData->at());
02015             return;
02016         }
02017     }
02018 }
02019 
02020 ImageGridItem *UIImageGridType::getCurrentItem(void)
02021 {
02022     return getItemAt(currentItem);
02023 }
02024 
02025 ImageGridItem *UIImageGridType::getItemAt(int pos)
02026 {
02027     if (pos < 0 || pos > (int) allData->count() - 1)
02028         return NULL;
02029 
02030     return allData->at(pos);
02031 }
02032 
02033 void UIImageGridType::appendItem(ImageGridItem *item)
02034 {
02035     allData->append(item);
02036     itemCount = allData->count();
02037 }
02038 
02039 void UIImageGridType::updateItem(ImageGridItem *item)
02040 {
02041     int itemNo = allData->find(item);
02042 
02043     updateItem(itemNo, item);
02044 }
02045 
02046 void UIImageGridType::updateItem(int itemNo, ImageGridItem *item)
02047 {
02048     if (itemNo < 0 || itemNo > (int) allData->count() - 1)
02049         return;
02050 
02051     ImageGridItem *gridItem = allData->at(itemNo);
02052 
02053     if (gridItem)
02054     {
02055         gridItem = item;
02056     }
02057 
02058     // if this item is visible update the imagegrid
02059     if ((itemNo >= topRow * columnCount) && (itemNo < (topRow + rowCount) * columnCount))
02060         refresh();
02061 }
02062 
02063 void UIImageGridType::removeItem(ImageGridItem *item)
02064 {
02065     int itemNo = allData->find(item);
02066 
02067     removeItem(itemNo);
02068 }
02069 
02070 void UIImageGridType::removeItem(int itemNo)
02071 {
02072     if (itemNo < 0 || itemNo > (int) allData->count() - 1)
02073         return;
02074 
02075     allData->remove(itemNo);
02076 
02077     itemCount--;
02078     lastRow = QMAX((int) ceilf((float) itemCount/columnCount) - 1, 0);
02079     lastColumn = QMAX(itemCount - lastRow * columnCount - 1, 0);
02080 
02081     // make sure the selected item is still visible
02082     if (topRow + rowCount > lastRow) 
02083         topRow = QMAX(QMIN(currentItem / columnCount, lastRow - rowCount + 1), 0);
02084 
02085     if (curRow > lastRow)
02086         curRow = topRow;
02087 
02088     refresh();
02089 }
02090 
02091 void UIImageGridType::setJustification(int jst)
02092 {
02093     justification = jst;
02094     multilineText = (justification & Qt::WordBreak) > 0;
02095 }
02096 
02097 bool UIImageGridType::handleKeyPress(QString action)
02098 {
02099     if (!has_focus)
02100         return false;
02101 
02102     if (action == "LEFT")
02103     {
02104         if (curRow == 0 && curColumn == 0)
02105             return true;
02106 
02107         curColumn--;
02108         if (curColumn < 0)
02109         {
02110             curColumn = columnCount - 1;
02111             curRow--;
02112             if (curRow < topRow)
02113                 topRow = curRow;
02114         }
02115     }
02116     else if (action == "RIGHT")
02117     {
02118         if (curRow * columnCount + curColumn >= itemCount - 1)
02119             return true;
02120 
02121         curColumn++;
02122         if (curColumn >= columnCount)
02123         {
02124             curColumn = 0;
02125             curRow++;
02126             if (curRow >= topRow + rowCount)
02127                 topRow++;
02128         }
02129     }
02130     else if (action == "UP")
02131     {
02132         if (curRow == 0)
02133         {
02134             curRow = lastRow;
02135             curColumn = QMIN(curColumn, lastColumn);
02136             topRow  = QMAX(curRow - rowCount + 1,0);
02137         }
02138         else
02139         {
02140             curRow--;
02141             if (curRow < topRow)
02142                 topRow = curRow;
02143         }
02144     }
02145     else if (action == "DOWN")
02146     {
02147         if (curRow == lastRow)
02148         {
02149             curRow = 0;
02150             topRow = 0;
02151         }
02152         else
02153         {
02154             curRow++;
02155 
02156             if (curRow == lastRow)
02157                 curColumn = QMIN(curColumn, lastColumn);
02158 
02159             if (curRow >= topRow + rowCount)
02160                 topRow++;
02161         }
02162     }
02163     else if (action == "PAGEUP")
02164     {
02165         if (curRow == 0)
02166             return true;
02167         else
02168             curRow = QMAX(curRow - rowCount, 0);
02169 
02170         topRow = curRow;
02171     }
02172     else if (action == "PAGEDOWN")
02173     {
02174         if (curRow == lastRow)
02175             return true;
02176         else
02177             curRow += rowCount;
02178 
02179         if (curRow >= lastRow)
02180         {
02181             curRow = lastRow;
02182             curColumn = QMIN(curColumn, lastColumn);
02183         }
02184 
02185         topRow = QMAX(curRow - rowCount + 1,0);
02186     }
02187     else if (action == "SELECT" && showSelected)
02188     {
02189         ImageGridItem *item = allData->at(currentItem);
02190         if (item)
02191             item->selected = !item->selected;
02192     }
02193     else
02194         return false;
02195 
02196 
02197     currentItem = curRow * columnCount + curColumn;
02198 
02199     showUpArrow = (topRow != 0);
02200     showDnArrow = (topRow + rowCount <= lastRow);
02201 
02202     refresh();
02203 
02204     emit itemChanged(allData->at(currentItem));
02205 
02206     return true;
02207 }
02208 
02209 void UIImageGridType::Draw(QPainter *p, int drawlayer, int context)
02210 {
02211     if (hidden)
02212         return;
02213 
02214     if ((m_context != context && m_context != -1) || drawlayer != m_order)
02215         return;
02216 
02217     // redraw the complete view rectangle
02218     QRect pr = displayRect;
02219 
02220     if (m_debug == true)
02221     {
02222         p->setPen(Qt::red);
02223         p->drawRect(QRect(displayRect.x(), displayRect.y(),
02224                     displayRect.width(), displayRect.height()));
02225     }
02226 
02227     int curPos = topRow * columnCount;
02228 
02229     for (int y = 0; y < rowCount; y++)
02230     {
02231         int ypos = displayRect.y() + y * (padding + cellHeight);
02232 
02233         for (int x = 0; x < columnCount; x++)
02234         {
02235             if (curPos >= itemCount)
02236                 continue;
02237 
02238             int xpos = displayRect.x() + x * (padding + cellWidth);
02239             drawCell(p, curPos, xpos, ypos);
02240 
02241             curPos++;
02242         }
02243     }
02244 
02245     if (showScrollArrows)
02246     {
02247         if (showUpArrow)
02248             p->drawPixmap(displayRect.x(),
02249                           displayRect.bottom() - upArrowActPixmap->height(),
02250                           *upArrowActPixmap);
02251         else
02252             p->drawPixmap(displayRect.x(),
02253                           displayRect.bottom() - upArrowRegPixmap->height(),
02254                           *upArrowRegPixmap);
02255         if (showDnArrow)
02256             p->drawPixmap(displayRect.x() + upArrowRegPixmap->width() +
02257                     (int)(5 * m_wmult),
02258         displayRect.bottom() - dnArrowActPixmap->height(),
02259         *dnArrowActPixmap);
02260         else
02261             p->drawPixmap(displayRect.x() + upArrowRegPixmap->width() +
02262                     (int)(5 * m_wmult),
02263         displayRect.bottom() - dnArrowRegPixmap->height(),
02264         *dnArrowRegPixmap);
02265     }
02266 }
02267 
02268 void UIImageGridType::drawCell(QPainter *p, int curPos, int xpos, int ypos)
02269 {
02270     QRect r(xpos, ypos, cellWidth, cellHeight);
02271 
02272     if (curPos == currentItem)
02273     {
02274         // highlighted
02275         if (m_debug == true)
02276             p->setPen(Qt::yellow);
02277         if (highlightedPixmap)
02278             p->drawPixmap(xpos, ypos, *highlightedPixmap);
02279     }
02280     else
02281     {
02282         if (m_debug == true)
02283             p->setPen(Qt::green);
02284         if (normalPixmap)
02285             p->drawPixmap(xpos, ypos, *normalPixmap);
02286     }
02287 
02288     // draw item image
02289     QPixmap *pixmap = NULL;
02290     QString filename = "";
02291     ImageGridItem *item = allData->at(curPos);
02292 
02293     // use pixmap stored in item
02294     if (item)
02295         pixmap = item->pixmap;
02296 
02297     // use default pixmap if non found
02298     if (!pixmap)
02299         pixmap = defaultPixmap;
02300 
02301     if (pixmap && !pixmap->isNull())
02302         p->drawPixmap(xpos + imageRect.x() + ( (imageRect.width() - pixmap->width()) / 2 ),
02303                       ypos + imageRect.y() + ( (imageRect.height() - pixmap->height()) / 2 ),
02304                       *pixmap, 0, 0, -1, -1);
02305 
02306     if (m_debug == true)
02307     {
02308       p->setBrush(Qt::NoBrush);
02309       p->drawRect(r);
02310     }
02311 
02312     // draw text area
02313     drawText(p, curPos, xpos, ypos);
02314 }
02315 
02316 void UIImageGridType::drawText(QPainter *p, int curPos, int xpos, int ypos)
02317 {
02318     QRect textRect(xpos, ypos, cellWidth, textHeight);
02319     if (textPos == UIImageGridType::textPosBottom)
02320         textRect.moveTop(ypos + cellHeight - textHeight);
02321 
02322     if (m_debug == true)
02323     {
02324         p->setBrush(Qt::NoBrush);
02325         p->setPen(Qt::blue);
02326         p->drawRect(textRect);
02327     }
02328 
02329     QString msg = "Invalid Item!!";
02330     ImageGridItem * item = allData->at(curPos);
02331     if (item)
02332     {
02333         msg = item->text;
02334 
02335         if (showCheck)
02336         {
02337             QRect cr(checkRect);
02338             cr.moveBy(textRect.x(), textRect.y());
02339             if (item->selected)
02340                 p->drawPixmap(cr, *checkFullPixmap);
02341             else
02342                 p->drawPixmap(cr, *checkNonPixmap);
02343 
02344             textRect.setX(textRect.x() + cr.width() + (int)(5 * m_wmult));
02345         }
02346     }
02347 
02348     if (m_debug == true)
02349     {
02350         p->setBrush(Qt::NoBrush);
02351         p->setPen(Qt::blue);
02352         p->drawRect(textRect);
02353     }
02354 
02355     fontProp *font = has_focus ? activeFont : inactiveFont;
02356 
02357     if (item && item->selected && showSelected)
02358         font = selectedFont;
02359 
02360     if (cutdown)
02361         msg = cutDown(msg, &font->face, multilineText,
02362                       textRect.width(), textRect.height());
02363 
02364     p->setFont(font->face);
02365 
02366     if (font->shadowOffset.x() != 0 || font->shadowOffset.y() != 0)
02367     {
02368         p->setBrush(font->dropColor);
02369         p->setPen(QPen(font->dropColor, (int)(2 * m_wmult)));
02370         p->drawText(textRect.left() + font->shadowOffset.x(),
02371                     textRect.top() + font->shadowOffset.y(),
02372                     textRect.width(), textRect.height(), justification, msg);
02373     }
02374 
02375     p->setBrush(font->color);
02376     p->setPen(QPen(font->color, (int)(2 * m_wmult)));
02377     p->drawText(textRect, justification, msg);
02378 }
02379 
02380 void UIImageGridType::recalculateLayout(void)
02381 {
02382     loadImages();
02383 
02384     int arrowHeight = 0;
02385     if (showScrollArrows)
02386         arrowHeight = upArrowRegPixmap->height() + (int)(5 * m_hmult);
02387 
02388     cellWidth = (displayRect.width() - (padding * (columnCount -1))) / columnCount;
02389     cellHeight = (displayRect.height() - arrowHeight -
02390             (padding * (rowCount -1))) / rowCount;
02391     lastRow = QMAX((int) ceilf((float) itemCount/columnCount) - 1, 0);
02392     lastColumn = QMAX(itemCount - lastRow * columnCount - 1, 0);
02393 
02394 
02395     // calc image item bounding rect
02396     int yoffset = 0;
02397     int bw = cellWidth;
02398     int bh = cellHeight - textHeight;
02399     int sw = (int) (7 * m_wmult);
02400     int sh = (int) (7 * m_hmult);
02401 
02402     imageRect.setX(sw);
02403     imageRect.setY(sh + yoffset);
02404     imageRect.setWidth((int) (bw - 2 * sw));
02405     imageRect.setHeight((int) (bh - 2 * sw));
02406 
02407     // centre check pixmap in text area
02408     int cw = checkFullPixmap->width();
02409     int ch = checkFullPixmap->height();
02410     checkRect = QRect(0, (textHeight - ch) / 2, cw, ch);
02411 
02412     loadCellImages();
02413 }
02414 
02415 QPixmap *UIImageGridType::createScaledPixmap(QString filename,
02416                                              int width, int height, QImage::ScaleMode mode)
02417 {
02418     QPixmap *pixmap = NULL;
02419 
02420     if (filename != "")
02421     {
02422         QImage *img = gContext->LoadScaleImage(filename);
02423         if (!img)
02424         {
02425             cout << "Failed to load image" << filename << endl;
02426             return NULL;
02427         }
02428         else
02429         {
02430             pixmap = new QPixmap(img->smoothScale(width, height, mode));
02431             delete img;
02432         }
02433     }
02434 
02435     return pixmap;
02436 }
02437 
02438 void UIImageGridType::loadImages(void)
02439 {
02440     checkNonPixmap = gContext->LoadScalePixmap("lb-check-empty.png");
02441     checkHalfPixmap = gContext->LoadScalePixmap("lb-check-half.png");
02442     checkFullPixmap = gContext->LoadScalePixmap("lb-check-full.png");
02443     upArrowRegPixmap = gContext->LoadScalePixmap("lb-uparrow-reg.png");
02444     upArrowActPixmap = gContext->LoadScalePixmap("lb-uparrow-sel.png");
02445     dnArrowRegPixmap = gContext->LoadScalePixmap("lb-dnarrow-reg.png");
02446     dnArrowActPixmap = gContext->LoadScalePixmap("lb-dnarrow-sel.png");
02447 }
02448 
02449 void UIImageGridType::loadCellImages(void)
02450 {
02451     int imgHeight = cellHeight - textHeight;
02452     int imgWidth = cellWidth;
02453     int sw = (int) (7 * m_wmult);
02454     int sh = (int) (7 * m_hmult);
02455 
02456     normalPixmap = createScaledPixmap(normalImage, imgWidth, imgHeight,
02457                                       QImage::ScaleFree);
02458     highlightedPixmap = createScaledPixmap(highlightedImage, imgWidth, imgHeight,
02459                                            QImage::ScaleFree);
02460     selectedPixmap = createScaledPixmap(selectedImage, imgWidth, imgHeight,
02461                                         QImage::ScaleFree);
02462     defaultPixmap = createScaledPixmap(defaultImage, imgWidth - 2 * sw,
02463                                        imgHeight - 2 * sh,
02464                                        QImage::ScaleMin);
02465 }
02466 
02467 void UIImageGridType::calculateScreenArea(void)
02468 {
02469     QRect r = displayRect;
02470     r.moveBy(m_parent->GetAreaRect().left(),
02471              m_parent->GetAreaRect().top());
02472     screen_area = r;
02473 }
02474 
02475 QSize UIImageGridType::getImageItemSize(void)
02476 {
02477     return QSize(imageRect.width(), imageRect.height());
02478 }
02479 
02480 // ******************************************************************
02481 
02482 UITextType::UITextType(const QString &name, fontProp *font,
02483                        const QString &text, int dorder, QRect displayrect,
02484                        QRect altdisplayrect)
02485            : UIType(name)
02486 {
02487 
02488     m_name = name;
02489     if (text.length())
02490         m_message = text;
02491     else
02492         m_message = " ";
02493 
02494     m_default_msg = text;
02495     m_font = font;
02496     m_displaysize = displayrect;
02497     m_origdisplaysize = displayrect;
02498     m_altdisplaysize = altdisplayrect;
02499     m_cutdown = true;
02500     m_order = dorder;
02501     m_justification = (Qt::AlignLeft | Qt::AlignTop);
02502 }
02503 
02504 UITextType::~UITextType()
02505 {
02506 }
02507 
02508 void UITextType::UseAlternateArea(bool useAlt)
02509 {
02510     if (useAlt && (m_altdisplaysize.width() > 1))
02511         m_displaysize = m_altdisplaysize;
02512     else
02513         m_displaysize = m_origdisplaysize;
02514 }
02515 
02516 void UITextType::SetText(const QString &text)
02517 {
02518     m_message = text;
02519     refresh();
02520 }
02521 
02522 void UITextType::SetFont(fontProp *font)
02523 {
02524     m_font = font;
02525     refresh();
02526 }
02527 
02528 void UITextType::Draw(QPainter *dr, int drawlayer, int context)
02529 {
02530     if (hidden)
02531     {
02532         return;
02533     }
02534   if (m_context == context || m_context == -1)
02535     if (drawlayer == m_order)
02536     {
02537         bool m_multi = false;
02538         if ((m_justification & Qt::WordBreak) > 0)
02539             m_multi = true;
02540         QPoint fontdrop = m_font->shadowOffset;
02541         QString msg = m_message;
02542         dr->setFont(m_font->face);
02543         if (m_cutdown == true)
02544             msg = cutDown(msg, &(m_font->face), m_multi, m_displaysize.width(), m_displaysize.height());
02545         if (m_cutdown == true && m_debug == true)
02546             cerr << "    +UITextType::CutDown Called.\n";
02547 
02548         if (drawFontShadow && (fontdrop.x() != 0 || fontdrop.y() != 0))
02549         {
02550             if (m_debug == true)
02551                 cerr << "    +UITextType::Drawing shadow @ ("
02552                      << (int)(m_displaysize.left() + fontdrop.x()) << ", "
02553                      << (int)(m_displaysize.top() + fontdrop.y()) << ")" << endl;
02554             dr->setBrush(m_font->dropColor);
02555             dr->setPen(QPen(m_font->dropColor, (int)(2 * m_wmult)));
02556             dr->drawText((int)(m_displaysize.left() + fontdrop.x()),
02557                            (int)(m_displaysize.top() + fontdrop.y()),
02558                            m_displaysize.width(),
02559                            m_displaysize.height(), m_justification, msg);
02560         }
02561 
02562         dr->setBrush(m_font->color);
02563         dr->setPen(QPen(m_font->color, (int)(2 * m_wmult)));
02564         if (m_debug == true)
02565                 cerr << "    +UITextType::Drawing @ ("
02566                      << (int)(m_displaysize.left()) << ", " << (int)(m_displaysize.top())
02567                      << ")" << endl;
02568         dr->drawText(m_displaysize.left(), m_displaysize.top(),
02569                       m_displaysize.width(), m_displaysize.height(), m_justification, msg);
02570         if (m_debug == true)
02571         {
02572             cerr << "   +UITextType::Draw() <- inside Layer\n";
02573             cerr << "       -Message: " << m_message << " (cut: " << msg << ")" <<  endl;
02574         }
02575     }
02576     else
02577         if (m_debug == true)
02578         {
02579              cerr << "   +UITextType::Draw() <- outside (layer = " << drawlayer
02580                   << ", widget layer = " << m_order << "\n";
02581         }
02582 }
02583 
02584 void UITextType::calculateScreenArea()
02585 {
02586     QRect r = m_displaysize;
02587     r.moveBy(m_parent->GetAreaRect().left(),
02588              m_parent->GetAreaRect().top());
02589     screen_area = r;
02590 }
02591 
02592 // ******************************************************************
02593 
02594 UIRichTextType::UIRichTextType(const QString &name, fontProp *font,
02595                        const QString &text, int dorder, QRect displayrect,
02596                        QRect textrect)
02597     : UIType(name)
02598 {
02599 
02600     m_name = name;
02601     takes_focus = true;
02602 
02603     if (QStyleSheet::mightBeRichText(text))
02604         m_message = text;
02605     else
02606         m_message = QStyleSheet::convertFromPlainText(text, QStyleSheetItem::WhiteSpaceNormal);
02607 
02608     m_font = font;
02609     m_displayArea = displayrect;
02610     m_yPos = 0;
02611     m_textArea = textrect;
02612     m_order = dorder;
02613     m_image = new QPixmap(m_displayArea.width(), m_displayArea.height(), -1);
02614     m_background = new QPixmap(m_displayArea.width(), m_displayArea.height(), -1);
02615     m_compBackground = new QPixmap(m_displayArea.width(), m_displayArea.height(), -1);
02616     m_backgroundImage = NULL;
02617     m_backgroundFile = "";
02618 
02619     m_bgImageReg = m_bgImageSel = "";
02620     m_showScrollArrows = true;
02621 }
02622 
02623 UIRichTextType::~UIRichTextType()
02624 {
02625     if (m_image)
02626         delete m_image;
02627 
02628     if (m_background)
02629         delete m_background;
02630 
02631     if (m_backgroundImage)
02632         delete m_backgroundImage;
02633 
02634     if (m_compBackground)
02635         delete m_compBackground;
02636 }
02637 
02638 void UIRichTextType::SetText(const QString &text)
02639 {
02640     if (QStyleSheet::mightBeRichText(text))
02641         m_message = text;
02642     else
02643         m_message = QStyleSheet::convertFromPlainText(text, QStyleSheetItem::WhiteSpaceNormal);
02644 
02645     m_yPos = 0;
02646     m_showUpArrow = false;
02647     refreshImage();
02648 }
02649 
02650 void UIRichTextType::SetBackgroundImages(QString bgImageReg, QString bgImageSel)
02651 {
02652     m_bgImageReg = bgImageReg;
02653     m_bgImageSel = bgImageSel;
02654 
02655     bool needreload = false;
02656     loadBackgroundImg(needreload);
02657     if (needreload) updateBackground();
02658 }
02659 
02660 void UIRichTextType::SetBackground(QPixmap *background)
02661 {
02662     copyBlt(m_background, 0, 0, background, m_displayArea.x(), m_displayArea.y(),
02663             m_displayArea.width(), m_displayArea.height());
02664 
02665     updateBackground();
02666 }
02667 
02668 void UIRichTextType::loadBackgroundImg(bool &changed)
02669 {
02670     QString file = "";
02671     changed = false;
02672 
02673     file = isFocused() ? m_bgImageSel : m_bgImageReg;
02674 
02675     // paint our background image over the window background
02676     if (file != "")
02677     {
02678         if (file != m_backgroundFile)
02679         {
02680             if (m_backgroundImage) 
02681                 delete m_backgroundImage;
02682 
02683             m_backgroundImage = gContext->LoadScaleImage(file, true);
02684             m_backgroundFile = file;
02685             changed = true;
02686         }
02687     }
02688 }
02689 
02690 void UIRichTextType::updateBackground(void)
02691 {
02692     // paint our background image over the window background
02693     QPainter p(m_compBackground);
02694     if (m_background) p.drawPixmap(QPoint(0, 0), *m_background);
02695     if (m_backgroundImage)
02696         p.drawImage(QPoint(0, 0), *m_backgroundImage);
02697     refreshImage();
02698 }
02699 
02700 void UIRichTextType::refreshImage()
02701 {
02702     if (!m_background)
02703         return;
02704 
02705     QRect clipRect(0, 0, m_textArea.width(), m_textArea.height());
02706 
02707     QPainter p(m_image);
02708     QBrush brush;
02709 
02710     brush.setPixmap(*m_compBackground);
02711     p.fillRect(0, 0, m_displayArea.width(), m_displayArea.height() , brush);
02712     p.translate(m_textArea.x() - m_displayArea.x() , m_textArea.y() - m_displayArea.y());
02713     QSimpleRichText richText(m_message, m_font->face);
02714     richText.setWidth(m_textArea.width());
02715     richText.draw(&p, 0, -m_yPos, clipRect, gContext->GetMainWindow()->colorGroup(), 0);
02716     m_textHeight = richText.height();
02717 
02718     // do we need to show scroll arrows
02719     if (m_showScrollArrows)
02720     {
02721         if (m_textHeight <= m_textArea.height())
02722         {
02723             m_showUpArrow = false;
02724             m_showDnArrow = false;
02725         }
02726         else
02727         {
02728             m_showUpArrow = (m_yPos > 0);
02729             m_showDnArrow = (m_yPos != m_textHeight - m_textArea.height());
02730         }
02731     }
02732 
02733     refresh();
02734 }
02735 
02736 void UIRichTextType::Draw(QPainter *dr, int drawlayer, int context)
02737 {
02738     if (hidden)
02739         return;
02740 
02741     if ((m_context == context || m_context == -1) && drawlayer == m_order)
02742     {
02743         // draw text image 
02744         dr->drawPixmap(m_displayArea, *m_image);
02745 
02746         // draw scroll arrows
02747         if (m_showScrollArrows) 
02748         {
02749             if (m_showUpArrow)
02750                 dr->drawPixmap(m_upArrowSelPos, m_upArrowSel);
02751             else
02752                 dr->drawPixmap(m_upArrowRegPos, m_upArrowReg);
02753 
02754             if (m_showDnArrow)
02755                 dr->drawPixmap(m_dnArrowSelPos, m_dnArrowSel);
02756             else
02757                 dr->drawPixmap(m_dnArrowRegPos, m_dnArrowReg);
02758         }
02759     }
02760 }
02761 
02762 void UIRichTextType::calculateScreenArea()
02763 {
02764     QRect r = m_displayArea;
02765     r.moveBy(m_parent->GetAreaRect().left(),
02766              m_parent->GetAreaRect().top());
02767     screen_area = r;
02768 }
02769 
02770 void UIRichTextType::ScrollUp()
02771 {
02772     if (m_textHeight <= m_textArea.height())
02773         return;
02774 
02775     m_yPos -= m_textArea.height() / 10;
02776     if (m_yPos < 0)
02777         m_yPos = 0;
02778 
02779     refreshImage();
02780 }
02781 
02782 void UIRichTextType::ScrollDown()
02783 {
02784     if (m_textHeight <= m_textArea.height())
02785         return;
02786 
02787     m_yPos += m_textArea.height() / 10;
02788 
02789     if (m_yPos > m_textHeight - m_textArea.height())
02790         m_yPos = m_textHeight - m_textArea.height();
02791 
02792     refreshImage();
02793 }
02794 
02795 void UIRichTextType::ScrollPageUp()
02796 {
02797     if (m_textHeight <= m_textArea.height())
02798         return;
02799 
02800     m_yPos -= m_textArea.height();
02801     if (m_yPos < 0)
02802         m_yPos = 0;
02803 
02804     refreshImage();
02805 }
02806 
02807 void UIRichTextType::ScrollPageDown()
02808 {
02809     if (m_textHeight <= m_textArea.height())
02810         return;
02811 
02812     m_yPos += m_textArea.height();
02813     if (m_yPos > m_textHeight - m_textArea.height())
02814         m_yPos = m_textHeight - m_textArea.height();
02815 
02816     refreshImage();
02817 }
02818 
02819 bool UIRichTextType::takeFocus()
02820 {
02821     bool res = UIType::takeFocus();
02822     bool needreload = false;
02823     loadBackgroundImg(needreload);
02824     if (needreload) updateBackground();
02825 
02826     return res;
02827 }
02828 
02829 void UIRichTextType::looseFocus()
02830 {
02831     UIType::looseFocus();
02832     bool needreload = false;
02833     loadBackgroundImg(needreload);
02834     if (needreload) updateBackground();
02835 }
02836 
02837 // ******************************************************************
02838 
02839 UIRemoteEditType::UIRemoteEditType(const QString &name, fontProp *font,
02840                        const QString &text, int dorder, QRect displayrect)
02841            : UIType(name)
02842 {
02843     m_font = font;
02844     m_text = text;
02845     m_displaysize = displayrect;
02846     m_order = dorder;
02847     edit = NULL;
02848     takes_focus = true;
02849 }
02850 
02851 void UIRemoteEditType::createEdit(MythThemedDialog* parent)
02852 {
02853     m_parentDialog = parent;
02854     edit = new MythRemoteLineEdit(parent);
02855      
02856     edit->setFocusPolicy(QWidget::NoFocus);
02857     edit->setText(m_text);
02858     edit->setCurrentFont(m_font->face);
02859     edit->setMinimumHeight(getScreenArea().height());
02860     edit->setMaximumHeight(getScreenArea().height());
02861     edit->setGeometry(getScreenArea());
02862     edit->setCharacterColors(m_unselected, m_selected, m_special);
02863         
02864     connect(edit, SIGNAL(tryingToLooseFocus(bool)), 
02865             this, SLOT(takeFocusAwayFromEditor(bool)));
02866     connect(edit, SIGNAL(textChanged(QString)), 
02867             this, SLOT(editorChanged(QString)));
02868 
02869     edit->show();
02870 }
02871 
02872 UIRemoteEditType::~UIRemoteEditType()
02873 {
02874     if (edit)
02875     {
02876         edit->hide();
02877         edit->deleteLater();
02878         edit = NULL;
02879     }    
02880 }
02881 
02882 void UIRemoteEditType::setText(const QString text)
02883 {
02884     m_text = text;
02885     if (edit)
02886         edit->setText(text);
02887     //refresh();
02888 }
02889 
02890 QString UIRemoteEditType::getText()
02891 {
02892     if (edit)
02893         return edit->text();
02894     else
02895         return QString::null;    
02896 }
02897 
02898 void  UIRemoteEditType::setFont(fontProp *font)
02899 { 
02900     m_font = font;
02901     if (edit)
02902         edit->setCurrentFont(font->face);
02903 }
02904  
02905 void UIRemoteEditType::setCharacterColors(QColor unselected, QColor selected, QColor special)
02906 {
02907     m_unselected = unselected; 
02908     m_selected = selected; 
02909     m_special = special;
02910     
02911     if (edit)
02912         edit->setCharacterColors(unselected, selected, special);
02913 }
02914 
02915 void UIRemoteEditType::show(void)
02916 {
02917     if (edit)
02918         edit->show();
02919     
02920     UIType::show();    
02921 }
02922 
02923 void UIRemoteEditType::hide(void)
02924 {
02925     if (edit)
02926         edit->hide();
02927     
02928     UIType::hide();    
02929 }
02930 
02931 void UIRemoteEditType::Draw(QPainter *dr, int drawlayer, int context)
02932 {
02933     if (hidden)
02934     {
02935         if (edit && edit->isVisible())
02936             edit->hide();
02937 
02938         return;
02939     }
02940 
02941     if (m_context == context || m_context == -1)
02942     {
02943         if (drawlayer == m_order)
02944         {
02945             if (edit && !edit->isVisible())
02946                 edit->show();
02947 
02948             dr = dr;
02949         }
02950     }
02951     else
02952     {
02953         // not in this context so hide the edit
02954         if (edit && edit->isVisible())
02955             edit->hide();
02956     }
02957 }
02958 
02959 void UIRemoteEditType::calculateScreenArea()
02960 {
02961     QRect r = m_displaysize;
02962     r.moveBy(m_parent->GetAreaRect().left(),
02963              m_parent->GetAreaRect().top());
02964     screen_area = r;
02965 }
02966 
02967 void UIRemoteEditType::takeFocusAwayFromEditor(bool up_or_down)
02968 {
02969     if (m_parentDialog) 
02970         m_parentDialog->nextPrevWidgetFocus(up_or_down);
02971     
02972     looseFocus();
02973 }
02974 
02975 bool UIRemoteEditType::takeFocus()
02976 {
02977     if (edit)
02978     {
02979         edit->setCursorPosition(0, edit->text().length());
02980         edit->setFocus();
02981     }
02982     
02983     return UIType::takeFocus();
02984 }
02985 
02986 void UIRemoteEditType::looseFocus()
02987 {
02988     if (edit)
02989     {
02990         edit->clearFocus();
02991     }
02992     
02993     UIType::looseFocus();
02994 }
02995 
02996 void UIRemoteEditType::editorChanged(QString value)
02997 {
02998     emit textChanged(value);
02999 }
03000 
03001 // ******************************************************************
03002 
03003 UIMultiTextType::UIMultiTextType(
03004                                     const QString &name,
03005                                     fontProp *font,
03006                                     int dorder,
03007                                     QRect displayrect,
03008                                     QRect altdisplayrect
03009                                 )
03010            : UITextType(name, font, "", dorder, displayrect, altdisplayrect)
03011 {
03012     connect(&transition_timer, SIGNAL(timeout()),
03013             this, SLOT(animate()));
03014 
03015     m_justification = (Qt::AlignCenter | Qt::AlignBottom);
03016 
03017     vertical_transform = 0;
03018     horizontal_transform = 0;
03019     m_cutdown = false;
03020 
03021 
03022     drop_timing_length = 10;
03023     drop_timing_pause = 500;
03024     scroll_timing_length = 40;
03025     scroll_timing_pause = 4000;
03026     message_space_padding = 0;
03027 
03028     current_text_index = -1;
03029 }
03030 
03031 void UIMultiTextType::setTexts(QStringList new_messages)
03032 {
03033     messages = new_messages;
03034     for(int i = 0; i < (int) messages.count(); i++)
03035     {
03036         for(int j = 0; j < message_space_padding; j++)
03037         {
03038             messages[i].prepend(" ");
03039             messages[i].append(" ");
03040         }
03041     }
03042     if (messages.count() > 0)
03043     {
03044         m_message = messages[0];
03045         current_text_index = 0;
03046         if (drop_timing_length > 0)
03047         {
03048             transition_timer.start(drop_timing_length);
03049             animation_stage = Animation_Drop;
03050             vertical_transform = m_displaysize.height();
03051         }
03052         else
03053         {
03054             transition_timer.start(drop_timing_pause);
03055             animation_stage = Animation_DropPause;
03056             vertical_transform = 0;
03057         }
03058 
03059         horizontal_transform = 0;
03060         QFontMetrics fm(m_font->face);
03061         max_horizontal_transform = fm.width(m_message) - m_displaysize.width();
03062         if (max_horizontal_transform < 0)
03063         {
03064             max_horizontal_transform = 0;
03065             m_justification = (Qt::AlignCenter | Qt::AlignBottom);
03066         }
03067         else
03068         {
03069             m_justification = (Qt::AlignLeft | Qt::AlignBottom);
03070         }
03071     }
03072     else
03073     {
03074         //
03075         //  No need to have a timer as there is nothing to cycle through
03076         //
03077 
03078         transition_timer.stop();
03079     }
03080 }
03081 
03082 void UIMultiTextType::clearTexts()
03083 {
03084     m_message = "";
03085     messages.clear();
03086     current_text_index = -1;
03087     transition_timer.stop();
03088     vertical_transform = 0;
03089     horizontal_transform = 0;
03090     refresh();
03091 }
03092 
03093 void UIMultiTextType::Draw(QPainter *dr, int drawlayer, int context)
03094 {
03095     if (hidden)
03096         return;
03097 
03098     if (m_context == context || m_context == -1)
03099     {
03100 
03101         if (drawlayer == m_order)
03102         {
03103             dr->save();
03104             dr->translate(-1.0 * horizontal_transform, -1.0 * vertical_transform);
03105             bool m_multi = false;
03106             if ((m_justification & Qt::WordBreak) > 0)
03107             m_multi = true;
03108             QPoint fontdrop = m_font->shadowOffset;
03109             QString msg = m_message;
03110             dr->setFont(m_font->face);
03111             if (m_cutdown == true)
03112             {
03113                 msg = cutDown(msg, &(m_font->face), m_multi, m_displaysize.width(), m_displaysize.height());
03114             }
03115             if (m_cutdown == true && m_debug == true)
03116             {
03117                 cerr << "    +UITextType::CutDown Called.\n";
03118             }
03119 
03120             if (drawFontShadow && (fontdrop.x() != 0 || fontdrop.y() != 0))
03121             {
03122                 if (m_debug == true)
03123                 {
03124                     cerr << "    +UITextType::Drawing shadow @ ("
03125                          << (int)(m_displaysize.left() + fontdrop.x()) << ", "
03126                          << (int)(m_displaysize.top() + fontdrop.y()) << ")" << endl;
03127                 }
03128                 dr->setBrush(m_font->dropColor);
03129                 dr->setPen(QPen(m_font->dropColor, (int)(2 * m_wmult)));
03130                 dr->drawText((int)(m_displaysize.left() + fontdrop.x()),
03131                                (int)(m_displaysize.top() + fontdrop.y()),
03132                                m_displaysize.width(),
03133                                m_displaysize.height(), m_justification, msg);
03134             }
03135 
03136             dr->setBrush(m_font->color);
03137             dr->setPen(QPen(m_font->color, (int)(2 * m_wmult)));
03138             if (m_debug == true)
03139                     cerr << "    +UITextType::Drawing @ ("
03140                          << (int)(m_displaysize.left()) << ", " << (int)(m_displaysize.top())
03141                          << ")" << endl;
03142             dr->drawText(m_displaysize.left(), m_displaysize.top(),
03143                           m_displaysize.width() + horizontal_transform, m_displaysize.height(), m_justification, msg);
03144             if (m_debug == true)
03145             {
03146                 cerr << "   +UITextType::Draw() <- inside Layer\n";
03147                 cerr << "       -Message: " << m_message << " (cut: " << msg << ")" <<  endl;
03148             }
03149             dr->restore();
03150             //dr->translate(horizontal_transform, vertical_transform);
03151         }
03152         else
03153         {
03154             if (m_debug == true)
03155             {
03156                  cerr << "   +UITextType::Draw() <- outside (layer = " << drawlayer
03157                       << ", widget layer = " << m_order << "\n";
03158             }
03159         }
03160     }
03161 }
03162 
03163 
03164 void UIMultiTextType::animate()
03165 {
03166     //
03167     //  Check which animation stage we're in and move things along appropriately
03168     //
03169 
03170     if (animation_stage == Animation_Drop)
03171     {
03172         if (vertical_transform > 0)
03173         {
03174             vertical_transform--;
03175             refresh();
03176         }
03177         else
03178         {
03179 
03180             //
03181             //  The drop down is finished.
03182             //
03183 
03184             animation_stage = Animation_DropPause;
03185             transition_timer.changeInterval(drop_timing_pause);
03186         }
03187         return;
03188     }
03189     else if (animation_stage == Animation_DropPause)
03190     {
03191         //
03192         //  Done pausing after drop
03193         //
03194 
03195         animation_stage = Animation_Scroll;
03196         transition_timer.changeInterval(scroll_timing_length);
03197         return;
03198     }
03199     else if (animation_stage == Animation_Scroll)
03200     {
03201         if (horizontal_transform < max_horizontal_transform)
03202         {
03203             horizontal_transform++;
03204             refresh();
03205         }
03206         else
03207         {
03208             animation_stage = Animation_ScrollPause;
03209             transition_timer.changeInterval(scroll_timing_pause);
03210         }
03211         return;
03212     }
03213     else if (animation_stage == Animation_ScrollPause)
03214     {
03215         if (messages.count() > 1)
03216         {
03217             current_text_index++;
03218             if (current_text_index >= (int) messages.count())
03219             {
03220                 current_text_index = 0;
03221             }
03222             m_message = messages[current_text_index];
03223             if (drop_timing_length > 0)
03224             {
03225                 transition_timer.start(drop_timing_length);
03226                 animation_stage = Animation_Drop;
03227                 vertical_transform = m_displaysize.height();
03228             }
03229             else
03230             {
03231                 transition_timer.start(drop_timing_pause);
03232                 animation_stage = Animation_DropPause;
03233                 vertical_transform = 0;
03234             }
03235 
03236             horizontal_transform = 0;
03237             QFontMetrics fm(m_font->face);
03238             max_horizontal_transform = fm.width(m_message) - m_displaysize.width();
03239             if (max_horizontal_transform < 0)
03240             {
03241                 max_horizontal_transform = 0;
03242                 m_justification = (Qt::AlignCenter | Qt::AlignBottom);
03243             }
03244             else
03245             {
03246                 m_justification = (Qt::AlignLeft | Qt::AlignBottom);
03247             }
03248             refresh();
03249         }
03250         else
03251         {
03252             transition_timer.stop();
03253         }
03254 
03255     }
03256     else
03257     {
03258         cerr << "uitypes.o: animation_stage is set to unknown "
03259              << "value in UIMutliTextType object"
03260              << endl;
03261     }
03262 }
03263 
03264 
03265 // ******************************************************************
03266 
03267 UIStatusBarType::UIStatusBarType(QString &name, QPoint loc, int dorder)
03268                : UIType(name)
03269 {
03270     m_location = loc;
03271     m_order = dorder;
03272     m_orientation = 0;
03273     m_used = 0;
03274     m_total = 100;
03275 }
03276 
03277 UIStatusBarType::~UIStatusBarType()
03278 {
03279 }
03280 
03281 void UIStatusBarType::Draw(QPainter *dr, int drawlayer, int context)
03282 {
03283     if (hidden)
03284         return;
03285 
03286     if (m_context == context || m_context == -1)
03287     {
03288         if (drawlayer == m_order)
03289         {
03290             if (m_debug == true)
03291             {
03292                 cerr << "   +UIStatusBarType::Draw() <- within Layer\n";
03293             }
03294             int width = (int)((double)((double)m_container.width() - (double)(2*m_fillerSpace))
03295                     * (double)((double)m_used / (double)m_total));
03296 
03297             int height = (int)((double)((double)m_container.height() - (double)(2*m_fillerSpace))
03298                     * (double)((double)m_used / (double)m_total));
03299 
03300             if (m_debug == true)
03301             {
03302                 cerr << "       -Width  = " << width << "\n";
03303                 cerr << "       -Height = " << height << endl;
03304             }
03305 
03306             if (m_orientation == 0)
03307             {
03308                 dr->drawPixmap(m_location.x(), m_location.y(), m_container);
03309                 dr->drawPixmap(m_location.x(), m_location.y(), m_filler, 0, 0, width + m_fillerSpace);
03310             }
03311             else if (m_orientation == 1)
03312             {
03313                 dr->drawPixmap(m_location.x(), m_location.y(), m_container);
03314                 dr->drawPixmap(m_location.x() + width, m_location.y(), m_filler, width - m_fillerSpace, 0);
03315             }
03316             else if (m_orientation == 2)
03317             {
03318                 dr->drawPixmap(m_location.x(), m_location.y(), m_container);
03319                 dr->drawPixmap( m_location.x(),
03320                                 (m_location.y() + m_container.height()) - height,
03321                                 m_filler,
03322                                 0,
03323                                 (m_filler.height() - height) - m_fillerSpace);
03324             }
03325             else if (m_orientation == 3)
03326             {
03327                 dr->drawPixmap(m_location.x(), m_location.y(), m_container);
03328                 dr->drawPixmap(m_location.x(), m_location.y(), m_filler, 0, 0, -1, height + m_fillerSpace);
03329             }
03330         }
03331     }
03332 }
03333 
03334 void UIStatusBarType::calculateScreenArea()
03335 {
03336     QRect r = QRect(m_location.x(),
03337                     m_location.y(),
03338                     m_container.width(),
03339                     m_container.height());
03340     r.moveBy(m_parent->GetAreaRect().left(),
03341              m_parent->GetAreaRect().top());
03342     screen_area = r;
03343 }
03344 
03345 void UIStatusBarType::setOrientation(int x)
03346 {
03347     if (x < 0 || x > 3)
03348     {
03349         cerr << "uitypes.o: UIStatusBarType received an invalid request to set orientation to " << x << endl;
03350         return;
03351     }
03352     m_orientation = x ;
03353 }
03354 
03355 // *********************************************************************
03356 
03357 UIManagedTreeListType::UIManagedTreeListType(const QString & name)
03358                      : UIType(name)
03359 {
03360     bins = 0;
03361     bin_corners.clear();
03362     screen_corners.clear();
03363     route_to_active.clear();
03364     resized_highlight_images.setAutoDelete(true);
03365     my_tree_data = NULL;
03366     current_node = NULL;
03367     active_node = NULL;
03368     active_parent = NULL;
03369     m_justification = (Qt::AlignLeft | Qt::AlignVCenter);
03370     active_bin = 0;
03371     tree_order = -1;
03372     visual_order = -1;
03373     iconAttr = -1;
03374     show_whole_tree = false;
03375     scrambled_parents = false;
03376     color_selectables = false;
03377     selectPadding = 0;
03378     selectScale = false;
03379     selectPoint.setX(0);
03380     selectPoint.setY(0);
03381     upArrowOffset.setX(0);
03382     upArrowOffset.setY(0);
03383     downArrowOffset.setX(0);
03384     downArrowOffset.setY(0);
03385     leftArrowOffset.setX(0);
03386     leftArrowOffset.setY(0);
03387     rightArrowOffset.setX(0);
03388     rightArrowOffset.setY(0);
03389     incSearch = "";
03390 }
03391 
03392 UIManagedTreeListType::~UIManagedTreeListType()
03393 {
03394 }
03395 
03396 void UIManagedTreeListType::drawText(QPainter *p,
03397                                     QString the_text,
03398                                     QString font_name,
03399                                     int x, int y,
03400                                     int bin_number,
03401                                     int icon_number)
03402 {
03403     fontProp *temp_font = NULL;
03404     QString a_string = QString("bin%1-%2").arg(bin_number).arg(font_name);
03405     temp_font = &m_fontfcns[m_fonts[a_string]];
03406     p->setFont(temp_font->face);
03407     p->setPen(QPen(temp_font->color, (int)(2 * m_wmult)));
03408 
03409     if (!show_whole_tree)
03410     {
03411         the_text = cutDown(the_text, &(temp_font->face), false, area.width() - 80, area.height());
03412         p->drawText(x, y, the_text);
03413     }
03414     else if (bin_number == bins)
03415     {
03416         // See if we should leave room for an icon to the left of the text
03417         int iconDim = 0;
03418         if (iconAttr >= 0)
03419             iconDim = QFontMetrics(temp_font->face).height(); 
03420     
03421         the_text = cutDown(the_text, &(temp_font->face), false, bin_corners[bin_number].width() - right_arrow_image.width()-iconDim, bin_corners[bin_number].height());
03422         p->drawText(x+iconDim, y, the_text);
03423         if ((icon_number >= 0) && (iconMap.contains(icon_number)))
03424             p->drawPixmap(x, y-iconDim+QFontMetrics(temp_font->face).descent(),
03425                           *iconMap[icon_number]);
03426     }
03427     else if (bin_number == 1)
03428     {
03429         the_text = cutDown(the_text, &(temp_font->face), false, bin_corners[bin_number].width() - left_arrow_image.width(), bin_corners[bin_number].height());
03430         p->drawText(x + left_arrow_image.width(), y, the_text);
03431     }
03432     else
03433     {
03434         the_text = cutDown(the_text, &(temp_font->face), false, bin_corners[bin_number].width(), bin_corners[bin_number].height());
03435         p->drawText(x, y, the_text);
03436     }
03437 }
03438 
03439 void UIManagedTreeListType::Draw(QPainter *p, int drawlayer, int context)
03440 {
03441     if (hidden)
03442         return;
03443 
03444     //  Do nothing if context is wrong;
03445 
03446     if (m_context != context)
03447     {
03448         if (m_context != -1)
03449         {
03450             return;
03451         }
03452     }
03453 
03454     if (drawlayer != m_order)
03455     {
03456         // not my turn
03457         return;
03458     }
03459 
03460     if (!current_node)
03461     {
03462         // no data (yet?)
03463         return;
03464     }
03465 
03466     //
03467     //  Put something on the LCD device (if one exists)
03468     //
03469 
03470     if (class LCD *lcddev = LCD::Get())
03471     {
03472         QString msg = current_node->getString();
03473         GenericTree *parent = current_node->getParent();
03474         if (parent == NULL)
03475         {
03476             VERBOSE(VB_IMPORTANT, "UIManagedTreeListType: LCD sees no "
03477                  "parent to current_node" );
03478         }
03479         else
03480         {
03481             // add max of lcd height menu items either side of the selected node
03482             // let the lcdserver figure out which ones to display
03483             GenericTree *lnode;
03484             int pos = parent->getChildPosition(current_node, visual_order);
03485             bool selected;
03486 
03487             QPtrList<GenericTree> *nodes = parent->getAllChildren(visual_order);
03488             QPtrList<LCDMenuItem> menuItems;
03489             menuItems.setAutoDelete(true);
03490 
03491             if (pos > (int)lcddev->getLCDHeight())
03492                 lnode = nodes->at(pos - lcddev->getLCDHeight());
03493             else
03494                 lnode = nodes->first();
03495 
03496             uint count = 0;
03497 
03498             while ((lnode = nodes->current()) != 0 && count < lcddev->getLCDHeight() * 2)
03499             {
03500                 if (lnode == current_node)
03501                     selected = true;
03502                 else
03503                     selected = false;
03504 
03505                 menuItems.append(new LCDMenuItem(selected, NOTCHECKABLE,
03506                                                     lnode->getString()));
03507                 nodes->next();
03508                 ++count;
03509             }
03510 
03511             QString title;
03512             title = (parent->getParent()) ? "<< " : "   ";
03513             title += (current_node->childCount () > 0) ? " >> " : "  ";
03514             if (!menuItems.isEmpty())
03515             {
03516                 lcddev->switchToMenu(&menuItems, title);
03517             }
03518         }
03519     }
03520 
03521     bool draw_up_arrow = false;
03522     bool draw_down_arrow = false;
03523 
03524     //
03525     //  Draw each bin, using current_node and working up
03526     //  and/or down to tell us what to draw in each bin.
03527     //
03528 
03529     int starting_bin = 0;
03530     int ending_bin = 0;
03531 
03532     if (show_whole_tree)
03533     {
03534         starting_bin = bins;
03535         ending_bin = 0;
03536     }
03537     else
03538     {
03539         starting_bin = bins;
03540         ending_bin = bins - 1;
03541     }
03542 
03543     for(int i = starting_bin; i > ending_bin; --i)
03544     {
03545         GenericTree *hotspot_node = current_node;
03546 
03547         if (i < active_bin)
03548         {
03549             for(int j = 0; j < active_bin - i; j++)
03550             {
03551                 if (hotspot_node)
03552                 {
03553                     if (hotspot_node->getParent())
03554                     {
03555                         hotspot_node = hotspot_node->getParent();
03556                     }
03557                 }
03558             }
03559         }
03560         if (i > active_bin)
03561         {
03562             for(int j = 0; j < i - active_bin; j++)
03563             {
03564                 if (hotspot_node)
03565                 {
03566                     if (hotspot_node->childCount() > 0)
03567                     {
03568                         hotspot_node = hotspot_node->getSelectedChild(visual_order);
03569                     }
03570                     else
03571                     {
03572                         hotspot_node = NULL;
03573                     }
03574                 }
03575             }
03576         }
03577 
03578         //
03579         //  OK, we have the starting node for this bin (if it exists)
03580         //
03581 
03582         if (hotspot_node)
03583         {
03584             QString a_string = QString("bin%1-active").arg(i);
03585             fontProp *tmpfont = &m_fontfcns[m_fonts[a_string]];
03586             int x_location = bin_corners[i].left();
03587             int y_location = bin_corners[i].top() + (bin_corners[i].height() / 2)
03588                              + (QFontMetrics(tmpfont->face).height() / 2);
03589 
03590             if (!show_whole_tree)
03591             {
03592                 x_location = area.left();
03593                 y_location = area.top() + (area.height() / 2) + (QFontMetrics(tmpfont->face).height() / 2);
03594             }
03595 
03596             if (i == bins)
03597             {
03598                 draw_up_arrow = true;
03599                 draw_down_arrow = true;
03600 
03601                 //
03602                 //  if required, move the hotspot up or down
03603                 //  (beginning of list, end of list, etc.)
03604                 //
03605 
03606                 int position_in_list = hotspot_node->getPosition(visual_order);
03607                 int number_in_list = hotspot_node->siblingCount();
03608 
03609                 int number_of_slots = 0;
03610                 int another_y_location = y_location - QFontMetrics(tmpfont->face).height();
03611                 int a_limit = bin_corners[i].top();
03612                 if (!show_whole_tree)
03613                 {
03614                     a_limit = area.top();
03615                 }
03616                 while (another_y_location - QFontMetrics(tmpfont->face).height() > a_limit)
03617                 {
03618                     another_y_location -= QFontMetrics(tmpfont->face).height();
03619                     ++number_of_slots;
03620                 }
03621 
03622                 if (position_in_list <= number_of_slots)
03623                 {
03624                     draw_up_arrow = false;
03625                 }
03626                 if (position_in_list < number_of_slots)
03627                 {
03628                     for(int j = 0; j < number_of_slots - position_in_list; j++)
03629                     {
03630                         y_location -= QFontMetrics(tmpfont->face).height();
03631                     }
03632                 }
03633                 if ((number_in_list - position_in_list) <= number_of_slots &&
03634                    position_in_list > number_of_slots)
03635                 {
03636                     draw_down_arrow = false;
03637                     if (number_in_list >= number_of_slots * 2 + 1)
03638                     {
03639                         for(int j = 0; j <= number_of_slots - (number_in_list - position_in_list); j++)
03640                         {
03641                             y_location += QFontMetrics(tmpfont->face).height();
03642                         }
03643                     }
03644                     else
03645                     {
03646                         for(int j = 0; j <= position_in_list - (number_of_slots + 1); j++)
03647                         {
03648                             y_location += QFontMetrics(tmpfont->face).height();
03649                         }
03650                     }
03651                 }
03652                 if ((number_in_list - position_in_list) == number_of_slots + 1)
03653                 {
03654                     draw_down_arrow = false;
03655                 }
03656                 if (number_in_list <  (number_of_slots * 2) + 2)
03657                 {
03658                     draw_down_arrow = false;
03659                     draw_up_arrow = false;
03660                 }
03661             }
03662 
03663             QString font_name = "active";
03664             if (i > active_bin)
03665             {
03666                 font_name = "inactive";
03667             }
03668             if (hotspot_node == active_node)
03669             {
03670                 font_name = "selected";
03671             }
03672             if (i == active_bin && color_selectables && hotspot_node->isSelectable())
03673             {
03674                 font_name = "selectable";
03675             }
03676 
03677 
03678 
03679             if (i == active_bin)
03680             {
03681                 //
03682                 //  Draw the highlight pixmap for this bin
03683                 //
03684 
03685                 if (show_whole_tree)
03686                 {
03687                     p->drawPixmap(x_location + selectPoint.x(), y_location - QFontMetrics(tmpfont->face).height() + QFontMetrics(tmpfont->face).descent() + selectPoint.y(), (*highlight_map[i]));
03688                     //p->drawPixmap(x_location, y_location - QFontMetrics(tmpfont->face).height() + QFontMetrics(tmpfont->face).descent(), (*highlight_map[i]));
03689 
03690                     //
03691                     //  Left or right arrows
03692                     //
03693                     if (i == bins && hotspot_node->childCount() > 0)
03694                     {
03695                         p->drawPixmap(x_location + (*highlight_map[i]).width() - right_arrow_image.width() + rightArrowOffset.x(),
03696                                       y_location + rightArrowOffset.y() - QFontMetrics(tmpfont->face).height() + right_arrow_image.height() / 2,
03697                                       right_arrow_image);
03698                     }
03699                     if (i == 1 && hotspot_node->getParent()->getParent())
03700                     {
03701                         p->drawPixmap(x_location + leftArrowOffset.x(),
03702                                       y_location + leftArrowOffset.y() - QFontMetrics(tmpfont->face).height() + left_arrow_image.height() / 2,
03703                                       left_arrow_image);
03704                     }
03705                 }
03706                 else
03707                 {
03708                     p->drawPixmap(x_location + selectPoint.x(), y_location - QFontMetrics(tmpfont->face).height() + QFontMetrics(tmpfont->face).descent() + selectPoint.y(), (*highlight_map[0]));
03709                 }
03710             }
03711 
03712             //
03713             //  Move this down for people with (slightly) broken fonts
03714             //
03715 
03716             QString msg = hotspot_node->getString();
03717             int icn = -1;
03718             if (iconAttr >= 0)
03719                 icn = hotspot_node->getAttribute(iconAttr);
03720             drawText(p, msg, font_name, x_location, y_location, i, icn);
03721 
03722             if (i == bins)
03723             {
03724                 //
03725                 //  Draw up/down arrows
03726                 //
03727 
03728                 if (draw_up_arrow)
03729                 {
03730                     if (show_whole_tree)
03731                     {
03732                         p->drawPixmap((bin_corners[i].right() - up_arrow_image.width()) + upArrowOffset.x(),
03733                                       bin_corners[i].top()  + upArrowOffset.y(),
03734                                       up_arrow_image);
03735                     }
03736                     else
03737                     {
03738                         p->drawPixmap((area.right() - up_arrow_image.width())+ upArrowOffset.x(),
03739                                       area.top() + upArrowOffset.y(),
03740                                       up_arrow_image);
03741                     }
03742                 }
03743                 if (draw_down_arrow)
03744                 {
03745                     if (show_whole_tree)
03746                     {
03747                         p->drawPixmap((bin_corners[i].right() - down_arrow_image.width()) + downArrowOffset.x(),
03748                                       (bin_corners[i].bottom() - down_arrow_image.height())  + downArrowOffset.y(),
03749                                       down_arrow_image);
03750                     }
03751                     else
03752                     {
03753                         p->drawPixmap((area.right() - down_arrow_image.width()) + downArrowOffset.x(),
03754                                       (area.bottom() - down_arrow_image.height())  + downArrowOffset.y(),
03755                                       down_arrow_image);
03756                     }
03757                 }
03758             }
03759 
03760             //
03761             //  Do the ones above
03762             //
03763 
03764             int numb_above = 1;
03765             int still_yet_another_y_location = y_location - QFontMetrics(tmpfont->face).height();
03766             int a_limit = bin_corners[i].top();
03767             if (!show_whole_tree)
03768             {
03769                 a_limit = area.top();
03770             }
03771             while (still_yet_another_y_location - QFontMetrics(tmpfont->face).height() > a_limit)
03772             {
03773                 GenericTree *above = hotspot_node->prevSibling(numb_above, visual_order);
03774                 if (above)
03775                 {
03776                     if (i == active_bin && color_selectables && above->isSelectable())
03777                     {
03778                         font_name = "selectable";
03779                     }
03780                     else if (above == active_node)
03781                     {
03782                         font_name = "selected";
03783                     }
03784                     else if (i == active_bin)
03785                     {
03786                         font_name = "active";
03787                     }
03788                     else
03789                     {
03790                         font_name = "inactive";
03791                     }
03792                     msg = above->getString();
03793                     int icn = -1;
03794                     if (iconAttr >= 0)
03795                         icn = above->getAttribute(iconAttr);
03796                     drawText(p, msg, font_name, x_location, still_yet_another_y_location, i, icn);
03797                 }
03798                 still_yet_another_y_location -= QFontMetrics(tmpfont->face).height();
03799                 numb_above++;
03800             }
03801 
03802 
03803             //
03804             //  Do the ones below
03805             //
03806 
03807             int numb_below = 1;
03808             y_location += QFontMetrics(tmpfont->face).height();
03809             a_limit = bin_corners[i].bottom();
03810             if (!show_whole_tree)
03811             {
03812                 a_limit = area.bottom();
03813             }
03814             while (y_location < a_limit)
03815             {
03816                 GenericTree *below = hotspot_node->nextSibling(numb_below, visual_order);
03817                 if (below)
03818                 {
03819                     if (i == active_bin && color_selectables && below->isSelectable())
03820                     {
03821                         font_name = "selectable";
03822                     }
03823                     else if (below == active_node)
03824                     {
03825                         font_name = "selected";
03826                     }
03827                     else if (i == active_bin)
03828                     {
03829                         font_name = "active";
03830                     }
03831                     else
03832                     {
03833                         font_name = "inactive";
03834                     }
03835                     msg = below->getString();
03836                     int icn = -1;
03837                     if (iconAttr >= 0)
03838                         icn = below->getAttribute(iconAttr);
03839                     drawText(p, msg, font_name, x_location, y_location, i, icn);
03840                 }
03841                 y_location += QFontMetrics(tmpfont->face).height();
03842                 numb_below++;
03843             }
03844 
03845         }
03846         else
03847         {
03848             //
03849             //  This bin is empty
03850             //
03851             // p->eraseRect(bin_corners[i]);
03852         }
03853     }
03854 
03855 
03856     //
03857     //  Debugging, draw edges around bins
03858     //
03859 
03860     /*
03861     p->setPen(QColor(255,0,0));
03862     CornerMap::Iterator it;
03863     for ( it = bin_corners.begin(); it != bin_corners.end(); ++it )
03864     {
03865         p->drawRect(it.data());
03866     }
03867     */
03868 
03869 }
03870 
03871 void UIManagedTreeListType::moveToNode(QValueList<int> route_of_branches)
03872 {
03873     current_node = my_tree_data->findNode(route_of_branches);
03874     if (!current_node)
03875     {
03876         current_node = my_tree_data->findLeaf();
03877     }
03878     active_node = current_node;
03879     active_parent = active_node->getParent();
03880     emit nodeSelected(current_node->getInt(), current_node->getAttributes());
03881 }
03882 
03883 void UIManagedTreeListType::moveToNodesFirstChild(QValueList<int> route_of_branches)
03884 {
03885     GenericTree *finder = my_tree_data->findNode(route_of_branches);
03886 
03887     if (finder)
03888     {
03889         if (finder->childCount() > 0)
03890         {
03891             current_node = finder->getChildAt(0, tree_order);
03892             active_node = current_node;
03893             active_parent = active_node->getParent();
03894             emit nodeSelected(current_node->getInt(), current_node->getAttributes());
03895         }
03896         else
03897         {
03898             current_node = finder;
03899             active_node = NULL;
03900             active_parent = NULL;
03901             emit nodeSelected(current_node->getInt(), current_node->getAttributes());
03902         }
03903     }
03904     else
03905     {
03906         current_node = my_tree_data->findLeaf();
03907         active_node = NULL;
03908     }
03909 }
03910 
03911 QValueList <int> * UIManagedTreeListType::getRouteToActive()
03912 {
03913     if (active_node)
03914     {
03915         route_to_active.clear();
03916         GenericTree *climber = active_node;
03917 
03918         route_to_active.push_front(climber->getInt());
03919         while( (climber = climber->getParent()) )
03920         {
03921             route_to_active.push_front(climber->getInt());
03922         }
03923         return &route_to_active;
03924     }
03925     return NULL;
03926 }
03927 
03928 QStringList UIManagedTreeListType::getRouteToCurrent()
03929 {
03930     QStringList route_to_current;
03931     if (current_node)
03932     {
03933         GenericTree *climber = current_node;
03934         route_to_current.push_front(climber->getString());
03935         while( (climber = climber->getParent()) )
03936         {
03937             route_to_current.push_front(climber->getString());
03938         }
03939         return route_to_current;
03940     }
03941     return route_to_current;
03942 }
03943 
03944 bool UIManagedTreeListType::tryToSetActive(QValueList <int> route)
03945 {
03946     GenericTree *a_node = my_tree_data->findNode(route);
03947     if (a_node && a_node->isSelectable())
03948     {
03949         active_node = a_node;
03950         current_node = a_node;
03951         active_parent = active_node->getParent();
03952         return true;
03953     }
03954     return false;
03955 }
03956 
03957 bool UIManagedTreeListType::tryToSetCurrent(QStringList route)
03958 {
03959     if (!my_tree_data)
03960     {
03961         current_node = NULL;
03962         return false;
03963     }
03964 
03965     current_node = my_tree_data;
03966 
03967     //
03968     //
03969     //
03970 
03971     if (route.count() > 0)
03972     {
03973         if (route[0] == my_tree_data->getString())
03974         {
03975             for(uint i = 1; i < route.count(); i ++)
03976             {
03977                 GenericTree *descender = current_node->getChildByName(route[i]);
03978                 if (descender)
03979                 {
03980                     current_node = descender;
03981                 }
03982                 else
03983                 {
03984                     return false;
03985                 }
03986             }
03987             return true;
03988         }
03989         else
03990         {
03991             return false;
03992         }
03993     }
03994     return false;
03995 
03996 }
03997 
03998 void UIManagedTreeListType::assignTreeData(GenericTree *a_tree)
03999 {
04000     if (a_tree)
04001     {
04002         my_tree_data = a_tree;
04003 
04004         //
04005         //  By default, current_node is first branch at every
04006         //  level down till we hit a leaf node.
04007         //
04008 
04009         current_node = my_tree_data->findLeaf();
04010         active_bin = bins;
04011     }
04012     else
04013     {
04014         cerr << "uitypes.o: somebody just assigned me to assign tree data, but they gave me no data" << endl;
04015     }
04016 
04017 }
04018 
04019 void UIManagedTreeListType::setCurrentNode(GenericTree *a_node)
04020 {
04021     //
04022     //  We should really do a recursive check of the tree
04023     //  to see if this node exists somewhere...
04024     //
04025 
04026     if (a_node)
04027     {
04028         current_node = a_node;
04029     }
04030 }
04031 
04032 int UIManagedTreeListType::getActiveBin()
04033 {
04034     return active_bin;
04035 }
04036 
04037 void UIManagedTreeListType::setActiveBin(int a_bin)
04038 {
04039     if (a_bin > bins)
04040     {
04041         active_bin = bins;
04042     }
04043     else
04044     {
04045         active_bin = a_bin;
04046     }
04047 }
04048 
04049 void UIManagedTreeListType::makeHighlights()
04050 {
04051     resized_highlight_images.clear();
04052     highlight_map.clear();
04053 
04054     //
04055     //  (pre-)Draw the highlight pixmaps
04056     //
04057 
04058     for(int i = 1; i <= bins; i++)
04059     {
04060         if (selectScale)
04061         {
04062             QImage temp_image = highlight_image.convertToImage();
04063             QPixmap *temp_pixmap = new QPixmap();
04064             fontProp *tmpfont = NULL;
04065             QString a_string = QString("bin%1-active").arg(i);
04066             tmpfont = &m_fontfcns[m_fonts[a_string]];
04067             temp_pixmap->convertFromImage(temp_image.smoothScale(bin_corners[i].width(), QFontMetrics(tmpfont->face).height() + selectPadding));
04068             resized_highlight_images.append(temp_pixmap);
04069             highlight_map[i] = temp_pixmap;
04070         }
04071         else
04072         {
04073             highlight_map[i] = &highlight_image;
04074         }
04075     }
04076 
04077     //
04078     //  Make no tree version
04079     //
04080 
04081     if (selectScale)
04082     {
04083         QImage temp_image = highlight_image.convertToImage();
04084         QPixmap *temp_pixmap = new QPixmap();
04085         fontProp *tmpfont = NULL;
04086         QString a_string = QString("bin%1-active").arg(bins);
04087         tmpfont = &m_fontfcns[m_fonts[a_string]];
04088         temp_pixmap->convertFromImage(temp_image.smoothScale(area.width(), QFontMetrics(tmpfont->face).height() + selectPadding ));
04089         resized_highlight_images.append(temp_pixmap);
04090         highlight_map[0] = temp_pixmap;
04091     }
04092     else
04093     {
04094         highlight_map[0] = &highlight_image;
04095     }
04096 
04097 }
04098 
04099 bool UIManagedTreeListType::popUp()
04100 {
04101     //
04102     //  Move the active node to the
04103     //  current active node's parent
04104     //
04105 
04106     if (!current_node)
04107     {
04108         return false;
04109     }
04110 
04111     if (!current_node->getParent())
04112     {
04113         return false;
04114     }
04115 
04116     if (!current_node->getParent()->