コード例 #1
0
ファイル: mhi.cpp プロジェクト: Olti/mythtv
// Called by the video player to redraw the image.
void MHIContext::UpdateOSD(InteractiveScreen *osdWindow,
                           MythPainter *osdPainter)
{
    if (!osdWindow || !osdPainter)
        return;

    QMutexLocker locker(&m_display_lock);
    m_updated = false;
    osdWindow->DeleteAllChildren();
    // Copy all the display items into the display.
    list<MHIImageData*>::iterator it = m_display.begin();
    for (int count = 0; it != m_display.end(); ++it, count++)
    {
        MHIImageData *data = *it;
        MythImage* image = osdPainter->GetFormatImage();
        if (!image)
            continue;

        image->Assign(data->m_image);
        MythUIImage *uiimage = new MythUIImage(osdWindow, QString("itv%1")
                                               .arg(count));
        if (uiimage)
        {
            uiimage->SetImage(image);
            uiimage->SetArea(MythRect(data->m_x, data->m_y,
                             data->m_image.width(), data->m_image.height()));
        }
        image->DecrRef();
    }
    osdWindow->OptimiseDisplayedArea();
    // N.B. bypasses OSD class hence no expiry set
    osdWindow->SetVisible(true);
}
コード例 #2
0
MythUIType *MythUIEditBar::GetNew(MythUIShape *shape, MythUIImage *image)
{
    QString name = QString("editbarimage_%1").arg(m_images.size());

    if (shape)
    {
        MythUIShape *newshape = new MythUIShape(this, name);

        if (newshape)
        {
            newshape->CopyFrom(shape);
            newshape->SetVisible(true);
            m_images.append(newshape);
            return newshape;
        }
    }
    else if (image)
    {
        MythUIImage *newimage = new MythUIImage(this, name);

        if (newimage)
        {
            newimage->CopyFrom(image);
            newimage->SetVisible(true);
            m_images.append(newimage);
            return newimage;
        }
    }

    return NULL;
}
コード例 #3
0
ファイル: example.cpp プロジェクト: adicarlo/mythtv
void AirPlayPictureScreen::Init(void)
{
    if (m_airplayImage)
    {
        if (!m_imageFilename.isEmpty())
        {
            m_airplayImage->SetFilename(m_imageFilename); // Absolute path, http or SG url
            m_airplayImage->Load(); // By default the image is loaded in a background thread, use LoadNow() to load in foreground
        }
        else
        {
            // Will default to displaying whatever placeholder image is defined
            // in the xml by the themer, means we can show _something_ rather than
            // a big empty hole. Generally you always want to call Reset() in
            // these circumstances
            m_airplayImage->Reset();
        }
    }

    if (m_airplayText)
    {
        if (!m_imageDescription.isEmpty())
        {
            m_airplayText->SetText(m_imageDescription);
        }
        else
        {
            // Same as above, calling Reset() allows for a sane, themer defined
            //default to be displayed
            m_airplayText->Reset();
        }
    }
}
コード例 #4
0
ファイル: subtitlescreen.cpp プロジェクト: Openivo/mythtv
void SubtitleScreen::AddScaledImage(QImage &img, QRect &pos)
{
    VideoOutput *vo = m_player->GetVideoOutput();
    if (!vo)
        return;

    QRect scaled = vo->GetImageRect(pos);
    if (scaled.size() != pos.size())
    {
        img = img.scaled(scaled.width(), scaled.height(),
                         Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    }

    MythPainter *osd_painter = vo->GetOSDPainter();
    MythImage* image = NULL;
    if (osd_painter)
         image = osd_painter->GetFormatImage();

    if (image)
    {
        image->Assign(img);
        MythUIImage *uiimage = new MythUIImage(this, "dvd_button");
        if (uiimage)
        {
            m_refreshArea = true;
            uiimage->SetImage(image);
            uiimage->SetArea(MythRect(scaled));
        }
    }
}
コード例 #5
0
bool MythUIStateType::AddImage(StateType type, MythImage *image)
{
    if (m_ObjectsByState.contains((int)type) || !image)
        return false;

    MythUIImage *imType = new MythUIImage(this, "stateimage");
    imType->SetImage(image);

    return AddObject(type, imType);
}
コード例 #6
0
bool MythUIStateType::AddImage(const QString &name, MythImage *image)
{
    QString key = name.lower();
    if (m_ObjectsByName.contains(key) || !image)
        return false;

    MythUIImage *imType = new MythUIImage(this, key);
    imType->SetImage(image);

    return AddObject(name, imType);
}
コード例 #7
0
void TeletextScreen::OptimiseDisplayedArea(void)
{
    VideoOutput *vo = m_player->GetVideoOutput();
    if (!vo)
        return;
    MythPainter *osd_painter = vo->GetOSDPainter();
    if (!osd_painter)
        return;

    QHashIterator<int, QImage*> it(m_rowImages);
    while (it.hasNext())
    {
        it.next();
        MythImage* image = osd_painter->GetFormatImage();
        if (!image || !it.value())
            continue;

        int row = it.key();
        image->Assign(*(it.value()));
        MythUIImage *uiimage = new MythUIImage(this, QString("ttrow%1")
                                                        .arg(row));
        if (uiimage)
        {
            uiimage->SetImage(image);
            uiimage->SetArea(MythRect(0, row * m_rowHeight,
                                      m_safeArea.width(), m_rowHeight * 2));
        }
    }

    QRegion visible;
    QListIterator<MythUIType *> i(m_ChildrenList);
    while (i.hasNext())
    {
        MythUIType *img = i.next();
        visible = visible.united(img->GetArea());
    }

    if (visible.isEmpty())
        return;

    QRect bounding  = visible.boundingRect();
    bounding = bounding.translated(m_safeArea.topLeft());
    bounding = m_safeArea.intersected(bounding);
    int left = m_safeArea.left() - bounding.left();
    int top  = m_safeArea.top()  - bounding.top();
    SetArea(MythRect(bounding));

    i.toFront();;
    while (i.hasNext())
    {
        MythUIType *img = i.next();
        img->SetArea(img->GetArea().translated(left, top));
    }
}
コード例 #8
0
ファイル: mythuistatetype.cpp プロジェクト: DaveDaCoda/mythtv
bool MythUIStateType::AddImage(StateType type, MythImage *image)
{
    if (m_ObjectsByState.contains((int)type) || !image)
        return false;

    QString name = QString("stateimage%1").arg(type);

    MythUIImage *imType = new MythUIImage(this, name);
    imType->SetImage(image);

    return AddObject(type, imType);
}
コード例 #9
0
void WeatherScreen::prepareWidget(MythUIType *widget)
{
    MythUIImage *img;
    /*
     * Basically so we don't do it twice since some screens (Static Map) mess
     * with image dimensions
     */
    if ((img = dynamic_cast<MythUIImage *>(widget)))
    {
        img->Load();
    }
}
コード例 #10
0
ファイル: mythuistatetype.cpp プロジェクト: DaveDaCoda/mythtv
bool MythUIStateType::AddImage(const QString &name, MythImage *image)
{
    QString key = name.toLower();

    if (m_ObjectsByName.contains(key) || !image)
        return false;

    // Uses name, not key which is lower case otherwise we break
    // inheritance
    MythUIImage *imType = new MythUIImage(this, name);
    imType->SetImage(image);

    return AddObject(key, imType);
}
コード例 #11
0
ファイル: osd.cpp プロジェクト: jshattoc/mythtv
void OSD::SetGraph(const QString &window, const QString &graph, int64_t timecode)
{
    MythScreenType *win = GetWindow(window);
    if (!win)
        return;

    MythUIImage *image = dynamic_cast<MythUIImage* >(win->GetChild(graph));
    if (!image)
        return;

    MythImage* mi = m_parent->GetAudioGraph().GetImage(timecode);
    if (mi)
        image->SetImage(mi);
}
コード例 #12
0
ファイル: mythuieditbar.cpp プロジェクト: DocOnDev/mythtv
void MythUIEditBar::AddBar(MythUIShape *shape, MythUIImage *image,
                           const QRect &area)
{
    MythUIType *add = GetNew(shape, image);
    if (add)
    {
        MythUIShape *shape = dynamic_cast<MythUIShape*>(add);
        MythUIImage *image = dynamic_cast<MythUIImage*>(add);
        if (shape)
            shape->SetCropRect(area.left(), area.top(), area.width(), area.height());
        if (image)
            image->SetCropRect(area.left(), area.top(), area.width(), area.height());
        add->SetPosition(area.left(), area.top());
    }
}
コード例 #13
0
bool TrackInfoPopup::Create(void)
{
    bool err = false;

    err = LoadWindowFromXML("music-ui.xml", "trackinfo_popup", this);

    if (!err)
        return false;

    // get map for current track
    MetadataMap metadataMap; 
    m_metadata->toMap(metadataMap); 

    // add the map from the next track
    MusicMetadata *nextMetadata = gPlayer->getNextMetadata();
    if (nextMetadata)
        nextMetadata->toMap(metadataMap, "next");

    SetTextFromMap(metadataMap);

    MythUIStateType *ratingState = dynamic_cast<MythUIStateType *>(GetChild("ratingstate"));
    if (ratingState)
        ratingState->DisplayState(QString("%1").arg(m_metadata->Rating()));

    MythUIImage *albumImage = dynamic_cast<MythUIImage *>(GetChild("coverart"));
    if (albumImage)
    {
        if (!m_metadata->getAlbumArtFile().isEmpty())
        {
            albumImage->SetFilename(m_metadata->getAlbumArtFile());
            albumImage->Load();
        }
    }

    m_displayTimer = new QTimer(this);
    connect(m_displayTimer, SIGNAL(timeout()), this, SLOT(Close()));
    m_displayTimer->setSingleShot(true);
    m_displayTimer->start(MUSICINFOPOPUPTIME);

    return true;
}
コード例 #14
0
void MythUIProgressBar::CalculatePosition(void)
{
    MythUIType *progressType = GetChild("progressimage");

    if (!progressType)
    {
        LOG(VB_GENERAL, LOG_ERR, "Progress image doesn't exist");
        return;
    }

    progressType->SetVisible(false);

    int total = m_total - m_start;
    int current = m_current - m_start;
    float percentage = 0.0;

    if (total <= 0 || current <= 0 || current > total)
        return;

    percentage = (float)current / (float)total;
    progressType->SetVisible(true);

    QRect fillArea = progressType->GetArea();

    int height = fillArea.height();
    int width = fillArea.width();
    int x = fillArea.x();
    int y = fillArea.y();

    switch (m_effect)
    {
        case EffectReveal :

            if (m_layout == LayoutHorizontal)
            {
                width = (int)((float)fillArea.width() * percentage);
            }
            else
            {
                height = (int)((float)fillArea.height() * percentage);
            }

            break;
        case EffectSlide :

            if (m_layout == LayoutHorizontal)
            {
                int newwidth = (int)((float)fillArea.width() * percentage);
                x = width - newwidth;
                width = newwidth;
            }
            else
            {
                int newheight = (int)((float)fillArea.height() * percentage);
                y = height - newheight;
                height = newheight;
            }

            break;
        case EffectAnimate :
            // Not implemented yet
            break;
    }

    MythUIImage *progressImage = dynamic_cast<MythUIImage *>(progressType);
    MythUIShape *progressShape = dynamic_cast<MythUIShape *>(progressType);

    if (width <= 0)
        width = 1;

    if (height <= 0)
        height = 1;

    if (progressImage)
        progressImage->SetCropRect(x, y, width, height);
    else if (progressShape)
        progressShape->SetCropRect(x, y, width, height);

    SetRedraw();
}
コード例 #15
0
ファイル: bdoverlayscreen.cpp プロジェクト: StefanRoss/mythtv
void BDOverlayScreen::DisplayBDOverlay(BDOverlay *overlay)
{
    if (!overlay || !m_player)
        return;

    if (!overlay->m_data)
    {
        m_overlayArea = overlay->m_position;
        SetArea(MythRect(m_overlayArea));
        DeleteAllChildren();
        m_overlayMap.clear();
        SetRedraw();
        LOG(VB_PLAYBACK, LOG_INFO, LOC +
            QString("Initialised Size: %1x%2 (%3+%4) Plane: %5 Pts: %6")
                .arg(overlay->m_position.width())
                .arg(overlay->m_position.height())
                .arg(overlay->m_position.left())
                .arg(overlay->m_position.top())
                .arg(overlay->m_plane)
                .arg(overlay->m_pts));
        BDOverlay::DeleteOverlay(overlay);
        return;
    }

    if (!m_overlayArea.isValid())
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "Error: Overlay image submitted before initialisation.");
    }

    VideoOutput *vo = m_player->GetVideoOutput();
    if (!vo)
        return;

    QRect   rect = overlay->m_position;
    QString hash = QString("%1+%2+%3x%4")
                    .arg(rect.left()).arg(rect.top())
                    .arg(rect.width()).arg(rect.height());

    // remove if we already have this overlay
    if (m_overlayMap.contains(hash))
    {
        LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Removing %1 (%2 left)")
            .arg(hash).arg(m_overlayMap.size()));
        MythUIImage *old = m_overlayMap.take(hash);
        DeleteChild(old);
    }

    // convert the overlay palette to ARGB
    uint32_t *origpalette = (uint32_t *)(overlay->m_palette);
    QVector<unsigned int> palette;
    for (int i = 0; i < 256; i++)
    {
        int y  = (origpalette[i] >> 0) & 0xff;
        int cr = (origpalette[i] >> 8) & 0xff;
        int cb = (origpalette[i] >> 16) & 0xff;
        int a  = (origpalette[i] >> 24) & 0xff;
        int r  = int(y + 1.4022 * (cr - 128));
        int b  = int(y + 1.7710 * (cb - 128));
        int g  = int(1.7047 * y - (0.1952 * b) - (0.5647 * r));
        if (r < 0) r = 0;
        if (g < 0) g = 0;
        if (b < 0) b = 0;
        if (r > 0xff) r = 0xff;
        if (g > 0xff) g = 0xff;
        if (b > 0xff) b = 0xff;
        palette.push_back((a << 24) | (r << 16) | (g << 8) | b);
    }

    // convert the image to QImage
    QImage img(rect.size(), QImage::Format_Indexed8);
    memcpy(img.bits(), overlay->m_data, rect.width() * rect.height());
    img.setColorTable(palette);
    img.convertToFormat(QImage::Format_ARGB32);

    // add to screen
    QRect scaled = vo->GetImageRect(rect);
    if (scaled.size() != rect.size())
    {
        img = img.scaled(scaled.width(), scaled.height(),
                         Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    }

    MythPainter *osd_painter = vo->GetOSDPainter();
    MythImage* image = NULL;
    if (osd_painter)
         image = osd_painter->GetFormatImage();

    if (image)
    {
        image->Assign(img);
        MythUIImage *uiimage = new MythUIImage(this, "bdoverlay");
        if (uiimage)
        {
            uiimage->SetImage(image);
            uiimage->SetArea(MythRect(scaled));
            m_overlayMap.insert(hash, uiimage);
            LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Added %1 (%2 tot)")
                .arg(hash).arg(m_overlayMap.size()));
        }
    }

    SetRedraw();
    BDOverlay::DeleteOverlay(overlay);
}
コード例 #16
0
ファイル: subtitlescreen.cpp プロジェクト: mdda/mythtv
void SubtitleScreen::DisplayAVSubtitles(void)
{
    if (!m_player || !m_subreader)
        return;

    AVSubtitles* subs = m_subreader->GetAVSubtitles();
    QMutexLocker lock(&(subs->lock));
    if (subs->buffers.empty() && (kDisplayAVSubtitle != m_subtitleType))
        return;

    VideoOutput    *videoOut = m_player->GetVideoOutput();
    VideoFrame *currentFrame = videoOut ? videoOut->GetLastShownFrame() : NULL;

    if (!currentFrame || !videoOut)
        return;

    float tmp = 0.0;
    QRect dummy;
    videoOut->GetOSDBounds(dummy, m_safeArea, tmp, tmp, tmp);

    while (!subs->buffers.empty())
    {
        const AVSubtitle subtitle = subs->buffers.front();
        if (subtitle.start_display_time > currentFrame->timecode)
            break;

        ClearDisplayedSubtitles();
        subs->buffers.pop_front();
        for (std::size_t i = 0; i < subtitle.num_rects; ++i)
        {
            AVSubtitleRect* rect = subtitle.rects[i];

            bool displaysub = true;
            if (subs->buffers.size() > 0 &&
                subs->buffers.front().end_display_time <
                currentFrame->timecode)
            {
                displaysub = false;
            }

            if (displaysub && rect->type == SUBTITLE_BITMAP)
            {
                // AVSubtitleRect's image data's not guaranteed to be 4 byte
                // aligned.

                QSize img_size(rect->w, rect->h);
                QRect img_rect(rect->x, rect->y, rect->w, rect->h);
                QRect display(rect->display_x, rect->display_y,
                              rect->display_w, rect->display_h);

                // XSUB and some DVD/DVB subs are based on the original video
                // size before the video was converted. We need to guess the
                // original size and allow for the difference

                int right  = rect->x + rect->w;
                int bottom = rect->y + rect->h;
                if (subs->fixPosition || (currentFrame->height < bottom) ||
                   (currentFrame->width  < right))
                {
                    int sd_height = 576;
                    if ((m_player->GetFrameRate() > 26.0f) && bottom <= 480)
                        sd_height = 480;
                    int height = ((currentFrame->height <= sd_height) &&
                                  (bottom <= sd_height)) ? sd_height :
                                 ((currentFrame->height <= 720) && bottom <= 720)
                                   ? 720 : 1080;
                    int width  = ((currentFrame->width  <= 720) &&
                                  (right <= 720)) ? 720 :
                                 ((currentFrame->width  <= 1280) &&
                                  (right <= 1280)) ? 1280 : 1920;
                    display = QRect(0, 0, width, height);
                }

                QRect scaled = videoOut->GetImageRect(img_rect, &display);
                QImage qImage(img_size, QImage::Format_ARGB32);
                for (int y = 0; y < rect->h; ++y)
                {
                    for (int x = 0; x < rect->w; ++x)
                    {
                        const uint8_t color = rect->pict.data[0][y*rect->pict.linesize[0] + x];
                        const uint32_t pixel = *((uint32_t*)rect->pict.data[1]+color);
                        qImage.setPixel(x, y, pixel);
                    }
                }

                if (scaled.size() != img_size)
                {
                    qImage = qImage.scaled(scaled.width(), scaled.height(),
                             Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
                }

                MythPainter *osd_painter = videoOut->GetOSDPainter();
                MythImage* image = NULL;
                if (osd_painter)
                   image = osd_painter->GetFormatImage();

                long long displayfor = subtitle.end_display_time -
                                       subtitle.start_display_time;
                if (displayfor == 0)
                    displayfor = 60000;
                displayfor = (displayfor < 50) ? 50 : displayfor;
                long long late = currentFrame->timecode -
                                 subtitle.start_display_time;
                MythUIImage *uiimage = NULL;
                if (image)
                {
                    image->Assign(qImage);
                    QString name = QString("avsub%1").arg(i);
                    uiimage = new MythUIImage(this, name);
                    if (uiimage)
                    {
                        m_refreshArea = true;
                        uiimage->SetImage(image);
                        uiimage->SetArea(MythRect(scaled));
                        m_expireTimes.insert(uiimage,
                                     currentFrame->timecode + displayfor);
                    }
                }
                if (uiimage)
                {
                    LOG(VB_PLAYBACK, LOG_INFO, LOC +
                        QString("Display %1AV subtitle for %2ms")
                        .arg(subtitle.forced ? "FORCED " : "")
                        .arg(displayfor));
                    if (late > 50)
                        LOG(VB_PLAYBACK, LOG_INFO, LOC +
                            QString("AV Sub was %1ms late").arg(late));
                }
            }
#ifdef USING_LIBASS
            else if (displaysub && rect->type == SUBTITLE_ASS)
            {
                InitialiseAssTrack(m_player->GetDecoder()->GetTrack(kTrackTypeSubtitle));
                AddAssEvent(rect->ass);
            }
#endif
        }
        m_subreader->FreeAVSubtitle(subtitle);
    }
#ifdef USING_LIBASS
    RenderAssTrack(currentFrame->timecode);
#endif
}
コード例 #17
0
ファイル: mythuiimage.cpp プロジェクト: tgm4883/lr-rpi2
/**
 *  \copydoc MythUIType::CreateCopy()
 */
void MythUIImage::CreateCopy(MythUIType *parent)
{
    QReadLocker updateLocker(&d->m_UpdateLock);
    MythUIImage *im = new MythUIImage(parent, objectName());
    im->CopyFrom(this);
}
コード例 #18
0
ファイル: osd.cpp プロジェクト: jshattoc/mythtv
void OSD::SetText(const QString &window, const InfoMap &map,
                  OSDTimeout timeout)
{
    MythScreenType *win = GetWindow(window);
    if (!win)
        return;

    if (map.contains("numstars"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("ratingstate"));
        if (state)
            state->DisplayState(map["numstars"]);
    }
    if (map.contains("tvstate"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("tvstate"));
        if (state)
            state->DisplayState(map["tvstate"]);
    }
    if (map.contains("videocodec"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("videocodec"));
        if (state)
            state->DisplayState(map["videocodec"]);
    }
    if (map.contains("videodescrip"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("videodescrip"));
        if (state)
            state->DisplayState(map["videodescrip"]);
    }
    if (map.contains("audiocodec"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("audiocodec"));
        if (state)
            state->DisplayState(map["audiocodec"]);
    }
    if (map.contains("audiochannels"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("audiochannels"));
        if (state)
            state->DisplayState(map["audiochannels"]);
    }
    if (map.contains("chanid"))
    {
        MythUIImage *icon = dynamic_cast<MythUIImage *> (win->GetChild("iconpath"));
        if (icon)
        {
            icon->Reset();

            uint chanid = map["chanid"].toUInt();
            QString iconpath;
            if (map.contains("iconpath"))
                iconpath = map["iconpath"];
            else
                iconpath = ChannelUtil::GetIcon(chanid);

            if (!iconpath.isEmpty())
            {
                QString iconurl =
                                gCoreContext->GetMasterHostPrefix("ChannelIcons",
                                                                  iconpath);

                icon->SetFilename(iconurl);
                icon->Load(false);
            }
        }
    }
    if (map.contains("inetref"))
    {
        MythUIImage *cover = dynamic_cast<MythUIImage *> (win->GetChild("coverart"));
        if (cover && map.contains("coverartpath"))
        {
            QString coverpath = map["coverartpath"];
            cover->SetFilename(coverpath);
            cover->Load(false);
        }
        MythUIImage *fanart = dynamic_cast<MythUIImage *> (win->GetChild("fanart"));
        if (fanart && map.contains("fanartpath"))
        {
            QString fanartpath = map["fanartpath"];
            fanart->SetFilename(fanartpath);
            fanart->Load(false);
        }
        MythUIImage *banner = dynamic_cast<MythUIImage *> (win->GetChild("banner"));
        if (banner && map.contains("bannerpath"))
        {
            QString bannerpath = map["bannerpath"];
            banner->SetFilename(bannerpath);
            banner->Load(false);
        }
        MythUIImage *screenshot = dynamic_cast<MythUIImage *> (win->GetChild("screenshot"));
        if (screenshot && map.contains("screenshotpath"))
        {
            QString screenshotpath = map["screenshotpath"];
            screenshot->SetFilename(screenshotpath);
            screenshot->Load(false);
        }
    }
    if (map.contains("nightmode"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("nightmode"));
        if (state)
            state->DisplayState(map["nightmode"]);
    }
    if (map.contains("mediatype"))
    {
        MythUIStateType *state = dynamic_cast<MythUIStateType *> (win->GetChild("mediatype"));
        if (state)
            state->DisplayState(map["mediatype"]);
    }

    MythUIProgressBar *bar =
        dynamic_cast<MythUIProgressBar *>(win->GetChild("elapsedpercent"));
    if (bar)
    {
        int startts = map["startts"].toInt();
        int endts   = map["endts"].toInt();
        int nowts   = MythDate::current().toTime_t();
        if (startts > nowts)
        {
            bar->SetUsed(0);
        }
        else if (endts < nowts)
        {
            bar->SetUsed(1000);
        }
        else
        {
            int duration = endts - startts;
            if (duration > 0)
                bar->SetUsed(1000 * (nowts - startts) / duration);
            else
                bar->SetUsed(0);
        }
        bar->SetVisible(startts > 0);
        bar->SetStart(0);
        bar->SetTotal(1000);
    }

    win->SetVisible(true);

    if (win == m_Dialog)
    {
        ChannelEditor *edit = dynamic_cast<ChannelEditor*>(m_Dialog);
        if (edit)
            edit->SetText(map);
    }
    else
        win->SetTextFromMap(map);

    SetExpiry(window, timeout);
}