Beispiel #1
0
void LookerUpper::HandleAllRecordings()
{
    QMap< QString, ProgramInfo* > recMap;
    QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
    QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);

    ProgramList progList;

    LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 );

    for( int n = 0; n < (int)progList.size(); n++)
    {
        ProgramInfo *pginfo = new ProgramInfo(*(progList[n]));
        if (pginfo->GetInetRef().isEmpty() ||
            (!pginfo->GetSubtitle().isEmpty() &&
              (pginfo->GetSeason() == 0) &&
              (pginfo->GetEpisode() == 0)))
        {
            QString msg = QString("Looking up: %1 %2").arg(pginfo->GetTitle())
                                           .arg(pginfo->GetSubtitle());
            VERBOSE(VB_IMPORTANT, msg);

            m_busyRecList.append(pginfo);
            m_metadataFactory->Lookup(pginfo, false, false);
        }
    }
}
void ProgramRecPriority::countMatches()
{
    m_listMatch.clear();
    m_conMatch.clear();
    m_nowMatch.clear();
    m_recMatch.clear();
    ProgramList schedList;
    LoadFromScheduler(schedList);
    QDateTime now = MythDate::current();

    ProgramList::const_iterator it = schedList.begin();
    for (; it != schedList.end(); ++it)
    {
        const RecStatus::Type recstatus = (**it).GetRecordingStatus();
        const uint          recordid  = (**it).GetRecordingRuleID();
        if ((**it).GetRecordingEndTime() > now && recstatus != RecStatus::NotListed)
        {
            m_listMatch[recordid]++;
            if (recstatus == RecStatus::Conflict || recstatus == RecStatus::Offline)
                m_conMatch[recordid]++;
            else if (recstatus == RecStatus::WillRecord)
                m_recMatch[recordid]++;
            else if (recstatus == RecStatus::Recording)
            {
                m_nowMatch[recordid]++;
                m_recMatch[recordid]++;
            }
        }
    }
}
Beispiel #3
0
void Bank::createFromXml( istringstream& is, ProgramList& list )
{
    Document doc;
    try
    {
	    doc.Parse( is.str(), true );

        Node* moduleNode = doc.FirstChild( "Module", false );
        if( moduleNode != NULL )
        {
            Program* program = new Program();
            createFromXml( is, *program );
            list.push_back( program );
        }
        else {

	        Iterator< Element > it( "Program" );
	        for( it = it.begin( &doc ); it != it.end(); it++ )
	        {
		        Program* program = new Program();
		        Element* programElement = it.Get();
		        readProgram( programElement, program );

		        list.push_back( program );
	        }
        }
    }
    catch( const exception& e ) {
        TRACE( e.what() );
    }
}
Beispiel #4
0
void LookerUpper::CopyRuleInetrefsToRecordings()
{
    QMap< QString, ProgramInfo* > recMap;
    QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
    QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);

    ProgramList progList;

    LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 );

    for( int n = 0; n < (int)progList.size(); n++)
    {
        ProgramInfo *pginfo = new ProgramInfo(*(progList[n]));
        if (pginfo && pginfo->GetInetRef().isEmpty())
        {
            RecordingRule *rule = new RecordingRule();
            rule->m_recordID = pginfo->GetRecordingRuleID();
            rule->Load();
            if (!rule->m_inetref.isEmpty())
            {
                QString msg = QString("%1").arg(pginfo->GetTitle());
                if (!pginfo->GetSubtitle().isEmpty())
                    msg += QString(": %1").arg(pginfo->GetSubtitle());
                msg += " has no inetref, but its recording rule does. Copying...";
                LOG(VB_GENERAL, LOG_INFO, msg);
                pginfo->SaveInetRef(rule->m_inetref);
            }
            delete rule;
        }
        delete pginfo;
    }
}
Beispiel #5
0
void LookerUpper::HandleAllRecordings(bool updaterules)
{
    QMap< QString, ProgramInfo* > recMap;
    QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
    QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);

    m_updaterules = updaterules;

    ProgramList progList;

    LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 );

    for( int n = 0; n < (int)progList.size(); n++)
    {
        ProgramInfo *pginfo = new ProgramInfo(*(progList[n]));
        if ((pginfo->GetRecordingGroup() != "Deleted") &&
            (pginfo->GetRecordingGroup() != "LiveTV") &&
            (pginfo->GetInetRef().isEmpty() ||
            (!pginfo->GetSubtitle().isEmpty() &&
            (pginfo->GetSeason() == 0) &&
            (pginfo->GetEpisode() == 0))))
        {
            QString msg = QString("Looking up: %1 %2").arg(pginfo->GetTitle())
                                           .arg(pginfo->GetSubtitle());
            LOG(VB_GENERAL, LOG_INFO, msg);

            m_busyRecList.append(pginfo);
            m_metadataFactory->Lookup(pginfo, true, false, false);
        }
        else
            delete pginfo;
    }
}
Beispiel #6
0
OnsetDetector::ProgramList
OnsetDetector::getPrograms() const
{
    ProgramList programs;
    programs.push_back("");
    programs.push_back("General purpose");
    programs.push_back("Soft onsets");
    programs.push_back("Percussive onsets");
    return programs;
}
Beispiel #7
0
TemplateDetector::ProgramList TemplateDetector::getPrograms() const {
    ProgramList list;
    list.push_back("blow1");
    list.push_back("blow2");

    // If you have no programs, return an empty list (or simply don't
    // implement this function or getCurrentProgram/selectProgram)

    return list;
}
PluginHostAdapter::ProgramList
PluginHostAdapter::getPrograms() const
{
    ProgramList list;
    
    for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
        list.push_back(m_descriptor->programs[i]);
    }
    
    return list;
}
Beispiel #9
0
ProgramList
MidiDevice::getPrograms(const MidiBank &bank) const
{
    ProgramList programs;

    for (ProgramList::const_iterator it = m_programList.begin();
         it != m_programList.end(); ++it) {
        if (it->getBank() == bank) programs.push_back(*it);
    }

    return programs;
}
ProgramList
MidiProgramsEditor::getBankSubset(const MidiBank &bank)
{
    ProgramList program;
    ProgramList::iterator it;

    for (it = m_programList.begin(); it != m_programList.end(); ++it) {
        if (it->getBank() == bank)
            program.push_back(*it);
    }

    return program;
}
Beispiel #11
0
bool GetProgramDetailList(
    QDateTime &nextRecordingStart, bool *hasConflicts, ProgramDetailList *list)
{
    nextRecordingStart = QDateTime();

    bool dummy;
    bool *conflicts = (hasConflicts) ? hasConflicts : &dummy;

    ProgramList progList;
    if (!LoadFromScheduler(progList, *conflicts))
        return false;

    // find the earliest scheduled recording
    ProgramList::const_iterator it = progList.begin();
    for (; it != progList.end(); ++it)
    {
        if (((*it)->GetRecordingStatus() == rsWillRecord) &&
            (nextRecordingStart.isNull() ||
             nextRecordingStart > (*it)->GetRecordingStartTime()))
        {
            nextRecordingStart = (*it)->GetRecordingStartTime();
        }
    }

    if (!list)
        return true;

    // save the details of the earliest recording(s)
    for (it = progList.begin(); it != progList.end(); ++it)
    {
        if (((*it)->GetRecordingStatus()    == rsWillRecord) &&
            ((*it)->GetRecordingStartTime() == nextRecordingStart))
        {
            ProgramDetail prog;
            prog.channame  = (*it)->GetChannelName();
            prog.title     = (*it)->GetTitle();
            prog.subtitle  = (*it)->GetSubtitle();
            prog.startTime = (*it)->GetRecordingStartTime();
            prog.endTime   = (*it)->GetRecordingEndTime();
            list->push_back(prog);
        }
    }

    return true;
}
Beispiel #12
0
DTC::Program* Guide::GetProgramDetails( int              nChanId,
                                        const QDateTime &dtStartTime )
                                          
{
    if (!dtStartTime.isValid())
        throw( "StartTime is invalid" );

    // ----------------------------------------------------------------------
    // -=>TODO: Add support for getting Recorded Program Info
    // ----------------------------------------------------------------------

    // Build add'l SQL statement for Program Listing

    MSqlBindings bindings;
    QString      sSQL = "WHERE program.chanid = :ChanId "
                          "AND program.starttime = :StartTime ";

    bindings[":ChanId"   ] = nChanId;
    bindings[":StartTime"] = dtStartTime;

    // Get all Pending Scheduled Programs

    ProgramList  schedList;
    bool hasConflicts;
    LoadFromScheduler(schedList, hasConflicts);

    // ----------------------------------------------------------------------

    ProgramList progList;

    LoadFromProgram( progList, sSQL, bindings, schedList, false );

    if ( progList.size() == 0)
        throw( "Error Reading Program Info" );

    // Build Response

    DTC::Program *pProgram = new DTC::Program();
    ProgramInfo  *pInfo    = progList[ 0 ];

    FillProgramInfo( pProgram, pInfo, true );

    return pProgram;
}
Beispiel #13
0
void
MidiDevice::mergeProgramList(const ProgramList &programList)
{
    ProgramList::const_iterator it;
    ProgramList::iterator oIt;
    bool clash = false;

    for (it = programList.begin(); it != programList.end(); ++it)
    {
        for (oIt = m_programList.begin(); oIt != m_programList.end(); ++oIt)
        {
            if (*it == *oIt)
            {
                clash = true;
                break;
            }
        }

        if (clash == false)
            addProgram(*it);
        else
            clash = false;
    }
}
Beispiel #14
0
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &rawStartTime ,
                                           const QDateTime &rawEndTime   ,
                                           bool             bDetails,
                                           int              nChannelGroupId,
                                           int              nStartIndex,
                                           int              nCount)
{     
    if (!rawStartTime.isValid())
        throw( "StartTime is invalid" );

    if (!rawEndTime.isValid())
        throw( "EndTime is invalid" );

    QDateTime dtStartTime = rawStartTime.toUTC();
    QDateTime dtEndTime = rawEndTime.toUTC();

    if (dtEndTime < dtStartTime)
        throw( "EndTime is before StartTime");

    if (nStartIndex <= 0)
        nStartIndex = 0;

    if (nCount <= 0)
        nCount = 20000;

    // ----------------------------------------------------------------------
    // Load the channel list
    // ----------------------------------------------------------------------

    uint nTotalAvailable = 0;
    ChannelInfoList chanList = ChannelUtil::LoadChannels(nStartIndex, nCount,
                                                         nTotalAvailable, true,
                                                         ChannelUtil::kChanOrderByChanNum,
                                                         ChannelUtil::kChanGroupByCallsign,
                                                         0,
                                                         nChannelGroupId);

    // ----------------------------------------------------------------------
    // Build SQL statement for Program Listing
    // ----------------------------------------------------------------------

    ProgramList  schedList;
    MSqlBindings bindings;

    QString sWhere   = "program.chanid = :CHANID "
                       "AND program.endtime >= :STARTDATE "
                       "AND program.starttime < :ENDDATE "
                       "AND program.starttime >= :STARTDATELIMIT "
                       "AND program.manualid = 0"; // Omit 'manual' recordings scheds

    QString sGroupBy = "program.starttime, channel.channum,"
                       "channel.callsign, program.title";

    QString sOrderBy = "program.starttime";

    bindings[":STARTDATE"     ] = dtStartTime;
    bindings[":STARTDATELIMIT"] = dtStartTime.addDays(-1);
    bindings[":ENDDATE"       ] = dtEndTime;

    // ----------------------------------------------------------------------
    // Get all Pending Scheduled Programs
    // ----------------------------------------------------------------------

    // NOTE: Fetching this information directly from the schedule is
    //       significantly faster than using ProgramInfo::LoadFromScheduler()
    Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
    if (scheduler)
        scheduler->GetAllPending(schedList);

    // ----------------------------------------------------------------------
    // Build Response
    // ----------------------------------------------------------------------

    DTC::ProgramGuide *pGuide = new DTC::ProgramGuide();

    ChannelInfoList::iterator chan_it;
    for (chan_it = chanList.begin(); chan_it != chanList.end(); ++chan_it)
    {
        // Create ChannelInfo Object
        DTC::ChannelInfo *pChannel   = NULL;
        pChannel = pGuide->AddNewChannel();
        FillChannelInfo( pChannel, (*chan_it), bDetails );

        // Load the list of programmes for this channel
        ProgramList  progList;
        bindings[":CHANID"] = (*chan_it).chanid;
        LoadFromProgram( progList, sWhere, sOrderBy, sOrderBy, bindings,
                         schedList );

        // Create Program objects and add them to the channel object
        ProgramList::iterator progIt;
        for( progIt = progList.begin(); progIt != progList.end(); ++progIt)
        {
            DTC::Program *pProgram = pChannel->AddNewProgram();
            FillProgramInfo( pProgram, *progIt, false, bDetails, false ); // No cast info
        }
    }

    // ----------------------------------------------------------------------

    pGuide->setStartTime    ( dtStartTime   );
    pGuide->setEndTime      ( dtEndTime     );
    pGuide->setDetails      ( bDetails      );
    
    pGuide->setStartIndex    ( nStartIndex     );
    pGuide->setCount         ( chanList.size() );
    pGuide->setTotalAvailable( nTotalAvailable );
    pGuide->setAsOf          ( MythDate::current() );
    
    pGuide->setVersion      ( MYTH_BINARY_VERSION );
    pGuide->setProtoVer     ( MYTH_PROTO_VERSION  );
    
    return pGuide;
}
void
MIDIInstrumentParameterPanel::updateProgramComboBox()
{
    RG_DEBUG << "updateProgramComboBox()";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md) {
        std::cerr << "WARNING: MIDIInstrumentParameterPanel::updateProgramComboBox(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n';
        return;
    }

    RG_DEBUG << "updateProgramComboBox(): variation type is " << md->getVariationType();

    MidiBank bank = getSelectedInstrument()->getProgram().getBank();

    ProgramList programs =
            md->getPrograms0thVariation(getSelectedInstrument()->isPercussion(), bank);

    // Remove the programs that have no name.
    programs.erase(std::remove_if(programs.begin(), programs.end(),
                                  MIDIInstrumentParameterPanel::hasNoName),
                   programs.end());

    // If we've got programs, show the Program widgets.
    // Why not "show = (programs.size()>1)"?  Because that would hide the
    // program checkbox which would take away the user's ability to
    // enable/disable program changes.  If we do away with the checkbox
    // in the future, we should re-evaluate this decision.
    bool show = !programs.empty();
    m_programLabel->setVisible(show);
    m_programCheckBox->setVisible(show);
    m_programComboBox->setVisible(show);

    int currentProgram = -1;

    // Compute the current program.
    for (unsigned i = 0; i < programs.size(); ++i) {
        // If the program change is the same...
        if (getSelectedInstrument()->getProgram().getProgram() == programs[i].getProgram()) {
            currentProgram = i;
            break;
        }
    }

    // If the programs have changed, we need to repopulate the combobox.
    if (!partialCompareWithName(programs, m_programs))
    {
        // Update the cache.
        m_programs = programs;

        // Copy from m_programs to m_programComboBox.
        m_programComboBox->clear();
        for (unsigned i = 0; i < m_programs.size(); ++i) {
            m_programComboBox->addItem(QObject::tr("%1. %2")
                                       .arg(m_programs[i].getProgram() + 1)
                                       .arg(QObject::tr(m_programs[i].getName().c_str())));
        }
    }

    m_programComboBox->setEnabled(getSelectedInstrument()->sendsProgramChange());

#if 0
// ??? This is a pretty nifty idea, but unfortunately, it requires
//     that we maintain a bogus combobox entry.  For now, we'll go
//     with the simpler "unselected" approach.

    // If the current program was not found...
    if (currentProgram < 0  &&  !m_programs.empty()) {
        // Format program change and add to combobox.
        MidiByte programChange = getSelectedInstrument()->getProgram().getProgram();
        m_programComboBox.addItem(QString::number(programChange + 1));
        currentProgram = programs.size();
    }
#endif

    // Display the current program.
    m_programComboBox->setCurrentIndex(currentProgram);
}
void
MIDIInstrumentParameterPanel::updateVariationComboBox()
{
    RG_DEBUG << "updateVariationComboBox() begin...";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md) {
        std::cerr << "WARNING: MIDIInstrumentParameterPanel::updateVariationComboBox(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n';
        return;
    }

    RG_DEBUG << "updateVariationComboBox(): Variation type is " << md->getVariationType();

    if (md->getVariationType() == MidiDevice::NoVariations) {
        showVariation(false);
        return;
    }

    // Get the variations.

    bool useMSB = (md->getVariationType() == MidiDevice::VariationFromMSB);
    MidiByteList variationBanks;

    if (useMSB) {
        MidiByte lsb = getSelectedInstrument()->getLSB();
        variationBanks = md->getDistinctMSBs(getSelectedInstrument()->isPercussion(),
                                         lsb);
        RG_DEBUG << "updateVariationComboBox(): Have " << variationBanks.size() << " variations for LSB " << lsb;

    } else {
        MidiByte msb = getSelectedInstrument()->getMSB();
        variationBanks = md->getDistinctLSBs(getSelectedInstrument()->isPercussion(),
                                         msb);

        RG_DEBUG << "updateVariationComboBox(): Have " << variationBanks.size() << " variations for MSB " << msb;
    }

    // Convert variationBanks to a ProgramList.

    ProgramList variations;

    // For each variation
    for (size_t i = 0; i < variationBanks.size(); ++i) {
        // Assemble the program for the variation.
        MidiBank bank;
        if (useMSB) {
            bank = MidiBank(getSelectedInstrument()->isPercussion(),
                            variationBanks[i],
                            getSelectedInstrument()->getLSB());
        } else {
            bank = MidiBank(getSelectedInstrument()->isPercussion(),
                            getSelectedInstrument()->getMSB(),
                            variationBanks[i]);
        }
        MidiProgram program(bank, getSelectedInstrument()->getProgramChange());

        // Skip any programs without names.
        if (md->getProgramName(program) == "")
            continue;

        variations.push_back(program);
    }

    // Compute the current variation.
    // ??? This might be combined into the previous for loop.

    int currentVariation = -1;

    // For each variation
    for (size_t i = 0; i < variations.size(); ++i) {
        if (getSelectedInstrument()->getProgram().partialCompare(variations[i])) {
            currentVariation = i;
            break;
        }
    }

    // If the variations have changed, repopulate the combobox.
    if (!partialCompareWithName(variations, m_variations)) {
        RG_DEBUG << "updateVariationComboBox(): Repopulating the combobox";

        // Update the cache.
        m_variations = variations;

        // Copy from m_variations to m_variationComboBox.
        m_variationComboBox->clear();
        for (size_t i = 0; i < m_variations.size(); ++i) {
            std::string programName = md->getProgramName(m_variations[i]);

            // Pick the correct bank number.
            MidiBank bank = m_variations[i].getBank();
            MidiByte variationBank = useMSB ? bank.getMSB() : bank.getLSB();

            m_variationComboBox->addItem(QObject::tr("%1. %2")
                                         .arg(variationBank)
                                         .arg(QObject::tr(programName.c_str())));
        }
    }

    // Display the current variation.
    m_variationComboBox->setCurrentIndex(currentVariation);

    // Show the variation widgets in either of two cases:
    //   1. More than one variation is available for this program.
    //   2. The variation was not in the Device and there is a variation
    //      to choose from.
    showVariation(m_variations.size() > 1  ||
                  (currentVariation == -1  &&  !m_variations.empty()));

    m_variationComboBox->setEnabled(getSelectedInstrument()->sendsBankSelect());
}
Beispiel #17
0
void LookerUpper::HandleAllArtwork(bool aggressive)
{
    m_updateartwork = true;

    if (aggressive)
        m_updaterules = true;

    // First, handle all recording rules w/ inetrefs
    vector<ProgramInfo *> recordingList;

    RemoteGetAllScheduledRecordings(recordingList);
    int maxartnum = 3;

    for( int n = 0; n < (int)recordingList.size(); n++)
    {
        ProgramInfo *pginfo = new ProgramInfo(*(recordingList[n]));
        bool dolookup = true;

        if (pginfo->GetInetRef().isEmpty())
            dolookup = false;
        if (dolookup || aggressive)
        {
            ArtworkMap map = GetArtwork(pginfo->GetInetRef(), pginfo->GetSeason(), true);
            if (map.isEmpty() || (aggressive && map.count() < maxartnum))
            {
                QString msg = QString("Looking up artwork for recording rule: %1 %2")
                                               .arg(pginfo->GetTitle())
                                               .arg(pginfo->GetSubtitle());
                LOG(VB_GENERAL, LOG_INFO, msg);

                m_busyRecList.append(pginfo);
                m_metadataFactory->Lookup(pginfo, true, true, true);
                continue;
            }
        }
        delete pginfo;
    }

    // Now, Attempt to fill in the gaps for recordings
    QMap< QString, ProgramInfo* > recMap;
    QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap();
    QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);

    ProgramList progList;

    LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 );

    for( int n = 0; n < (int)progList.size(); n++)
    {
        ProgramInfo *pginfo = new ProgramInfo(*(progList[n]));

        bool dolookup = true;

        LookupType type = GuessLookupType(pginfo);

        if (type == kProbableMovie)
           maxartnum = 2;

        if ((!aggressive && type == kProbableGenericTelevision) ||
             pginfo->GetRecordingGroup() == "Deleted" ||
             pginfo->GetRecordingGroup() == "LiveTV")
            dolookup = false;
        if (dolookup || aggressive)
        {
            ArtworkMap map = GetArtwork(pginfo->GetInetRef(), pginfo->GetSeason(), true);
            if (map.isEmpty() || (aggressive && map.count() < maxartnum))
            {
               QString msg = QString("Looking up artwork for recording: %1 %2")
                                           .arg(pginfo->GetTitle())
                                           .arg(pginfo->GetSubtitle());
                LOG(VB_GENERAL, LOG_INFO, msg);

                m_busyRecList.append(pginfo);
                m_metadataFactory->Lookup(pginfo, true, true, aggressive);
                continue;
            }
        }
        delete pginfo;
    }

}
void
MIDIInstrumentParameterPanel::slotSelectBank(int index)
{
    RG_DEBUG << "slotSelectBank() begin...";

    if (!getSelectedInstrument())
        return;

    MidiDevice *md =
            dynamic_cast<MidiDevice *>(getSelectedInstrument()->getDevice());
    if (!md) {
        std::cerr << "WARNING: MIDIInstrumentParameterPanel::slotSelectBank(): No MidiDevice for Instrument " << getSelectedInstrument()->getId() << '\n';
        return;
    }

    const MidiBank &bank = m_banks[index];

    bool change = false;

    if (md->getVariationType() != MidiDevice::VariationFromLSB) {
        if (getSelectedInstrument()->getLSB() != bank.getLSB()) {
            getSelectedInstrument()->setLSB(bank.getLSB());
            change = true;
        }
    }
    if (md->getVariationType() != MidiDevice::VariationFromMSB) {
        if (getSelectedInstrument()->getMSB() != bank.getMSB()) {
            getSelectedInstrument()->setMSB(bank.getMSB());
            change = true;
        }
    }

    // If no change, bail.
    if (!change)
        return;

    // Make sure the Instrument is valid WRT the Device.

    // If the current bank/program is not valid for this device, fix it.
    if (!getSelectedInstrument()->isProgramValid()) {

        // If we're not in variations mode...
        if (md->getVariationType() == MidiDevice::NoVariations) {

            // ...go with the first program
            ProgramList programList = md->getPrograms(bank);
            if (!programList.empty()) {
                // Switch to the first program in this bank.
                getSelectedInstrument()->setProgram(programList.front());
            } else {
                // No programs for this bank.  Just go with 0.
                getSelectedInstrument()->setProgramChange(0);
            }

        } else {  // We're in variations mode...

            // This is the three-comboboxes (bank/program/variation) case.
            // It's an extremely difficult case to handle, so we're just
            // going to punt and give them the first program/variation in
            // the bank they just selected.

            // Get the variation bank list for this bank
            BankList bankList;
            if (md->getVariationType() == MidiDevice::VariationFromMSB) {
                bankList = md->getBanksByLSB(
                        getSelectedInstrument()->isPercussion(), bank.getLSB());
            } else {
                bankList = md->getBanksByMSB(
                        getSelectedInstrument()->isPercussion(), bank.getMSB());
            }
            if (!bankList.empty()) {
                // Pick the first bank
                MidiBank firstBank = bankList.front();
                // Get the program list
                ProgramList programList = md->getPrograms(firstBank);
                if (!programList.empty()) {
                    // Pick the first program
                    getSelectedInstrument()->setProgram(programList.front());
                }
            }

            // To make the above more complex, we could consider the
            // case where the Program Change happens to be valid for
            // some variation bank in the newly selected bank.  Then
            // go with the 0th variation bank that has that program
            // change.  But I think this is complicated enough.

        }
    }

    getSelectedInstrument()->sendChannelSetup();

    // This is why changed() isn't called within
    // the setters.  If it were, then each of the above changes would
    // result in a change notification going out.  Worst case, that
    // would be three change notifications and the first two would be
    // sent when the Instrument was in an inconsistent state.
    // Rule: Avoid sending change notifications from setters.
    // Why?  It reduces the number of notifications which improves
    // performance.  It avoids sending notifications when an object's
    // state is inconsistent.  It avoids endless loops.
    getSelectedInstrument()->changed();
}
void
MidiProgramsEditor::populate(QTreeWidgetItem* item)
{
    RG_DEBUG << "MidiProgramsEditor::populate\n";

    MidiBankTreeWidgetItem* bankItem = dynamic_cast<MidiBankTreeWidgetItem*>(item);
    if (!bankItem) {
        RG_DEBUG << "MidiProgramsEditor::populate : not a bank item - returning\n";
        return ;
    }

    DeviceId deviceId = bankItem->getDeviceId();
    m_device = m_bankEditor->getMidiDevice(deviceId);
    if (!m_device)
        return ;

    setEnabled(true);

    setBankName(item->text(0));

    RG_DEBUG << "MidiProgramsEditor::populate : bankItem->getBank = "
    << bankItem->getBank() << endl;

    m_currentBank = &(m_bankList[bankItem->getBank()]); // m_device->getBankByIndex(bankItem->getBank());

    blockAllSignals(true);

    // set the bank values
    m_percussion->setChecked(m_currentBank->isPercussion());
    m_msb->setValue(m_currentBank->getMSB());
    m_lsb->setValue(m_currentBank->getLSB());

    m_oldBank = *m_currentBank;

    // Librarian details
    //
    m_librarian->setText(strtoqstr(m_device->getLibrarianName()));
    m_librarianEmail->setText(strtoqstr(m_device->getLibrarianEmail()));

    ProgramList programSubset = getBankSubset(*m_currentBank);
    ProgramList::iterator it;

    QPixmap noKeyPixmap, keyPixmap;

    IconLoader il;
    noKeyPixmap = il.loadPixmap("key-white");
    keyPixmap = il.loadPixmap("key-green");

    bool haveKeyMappings = m_device->getKeyMappings().size() > 0;

    for (unsigned int i = 0; i < (unsigned int)m_names.size(); i++) {

        m_names[i]->clear();
        getKeyMapButton(i)->setEnabled(haveKeyMappings);
        getKeyMapButton(i)->setIcon(QIcon(noKeyPixmap));
        // QToolTip::remove
        //    ( getKeyMapButton(i) );
        getKeyMapButton(i)->setToolTip(QString(""));  //@@@ Usefull ?
        getKeyMapButton(i)->setMaximumHeight( 12 );

        for (it = programSubset.begin(); it != programSubset.end(); ++it) {
            if (it->getProgram() == i) {

                // zero in on "Harpsichord" vs. "Coupled Harpsichord to cut down
                // on noise (0-based)
//                if (i == 6) std::cout << "it->getName(): " << it->getName() << std::endl;
                QString programName = strtoqstr(it->getName());
                m_completions << programName;
                m_names[i]->setText(programName);

                if (m_device->getKeyMappingForProgram(*it)) {
                    getKeyMapButton(i)->setIcon(QIcon(keyPixmap));
                    getKeyMapButton(i)->setToolTip
                        (tr("Key Mapping: %1") 
                              .arg(strtoqstr(m_device->getKeyMappingForProgram(*it)->getName())));
                }

                break;
            }
        }

        // show start of label
        m_names[i]->setCursorPosition(0);
    }

    blockAllSignals(false);
}
Beispiel #20
0
void StatusBox::doScheduleStatus()
{
    if (m_iconState)
        m_iconState->DisplayState("schedule");
    m_logList->Reset();

    QString helpmsg(tr("Schedule Status shows current statistics "
                       "from the scheduler."));
    if (m_helpText)
        m_helpText->SetText(helpmsg);
    if (m_justHelpText)
        m_justHelpText->SetText(helpmsg);

    MSqlQuery query(MSqlQuery::InitCon());

    query.prepare("SELECT COUNT(*) FROM record WHERE search = 0");
    if (query.exec() && query.next())
    {
        QString rules = tr("%n standard rule(s) (is) defined", "",
                            query.value(0).toInt());
        AddLogLine(rules, helpmsg);
    }
    else
    {
        MythDB::DBError("StatusBox::doScheduleStatus()", query);
        return;
    }

    query.prepare("SELECT COUNT(*) FROM record WHERE search > 0");
    if (query.exec() && query.next())
    {
        QString rules = tr("%n search rule(s) are defined", "",
                            query.value(0).toInt());
        AddLogLine(rules, helpmsg);
    }
    else
    {
        MythDB::DBError("StatusBox::doScheduleStatus()", query);
        return;
    }

    QMap<RecStatusType, int> statusMatch;
    QMap<RecStatusType, QString> statusText;
    QMap<int, int> sourceMatch;
    QMap<int, QString> sourceText;
    QMap<int, int> inputMatch;
    QMap<int, QString> inputText;
    QString tmpstr;
    int maxSource = 0;
    int maxInput = 0;
    int lowerpriority = 0;
    int hdflag = 0;

    query.prepare("SELECT MAX(sourceid) FROM videosource");
    if (query.exec())
    {
        if (query.next())
            maxSource = query.value(0).toInt();
    }

    query.prepare("SELECT sourceid,name FROM videosource");
    if (query.exec())
    {
        while (query.next())
            sourceText[query.value(0).toInt()] = query.value(1).toString();
    }

    query.prepare("SELECT MAX(cardinputid) FROM cardinput");
    if (query.exec())
    {
        if (query.next())
            maxInput = query.value(0).toInt();
    }

    query.prepare("SELECT cardinputid,cardid,inputname,displayname "
                  "FROM cardinput");
    if (query.exec())
    {
        while (query.next())
        {
            if (!query.value(3).toString().isEmpty())
                inputText[query.value(0).toInt()] = query.value(3).toString();
            else
                inputText[query.value(0).toInt()] = QString("%1: %2")
                                              .arg(query.value(1).toInt())
                                              .arg(query.value(2).toString());
        }
    }

    ProgramList schedList;
    LoadFromScheduler(schedList);

    tmpstr = tr("%n matching showing(s)", "", schedList.size());
    AddLogLine(tmpstr, helpmsg);

    ProgramList::const_iterator it = schedList.begin();
    for (; it != schedList.end(); ++it)
    {
        const ProgramInfo *s = *it;
        const RecStatusType recstatus = s->GetRecordingStatus();

        if (statusMatch[recstatus] < 1)
        {
            statusText[recstatus] = toString(
                recstatus, s->GetRecordingRuleType());
        }

        ++statusMatch[recstatus];

        if (recstatus == rsWillRecord || recstatus == rsRecording)
        {
            ++sourceMatch[s->GetSourceID()];
            ++inputMatch[s->GetInputID()];
            if (s->GetRecordingPriority2() < 0)
                ++lowerpriority;
            if (s->GetVideoProperties() & VID_HDTV)
                ++hdflag;
        }
    }

#define ADD_STATUS_LOG_LINE(rtype, fstate)                      \
    do {                                                        \
        if (statusMatch[rtype] > 0)                             \
        {                                                       \
            tmpstr = QString("%1 %2").arg(statusMatch[rtype])   \
                                     .arg(statusText[rtype]);   \
            AddLogLine(tmpstr, helpmsg, tmpstr, tmpstr, fstate);\
        }                                                       \
    } while (0)
    ADD_STATUS_LOG_LINE(rsRecording, "");
    ADD_STATUS_LOG_LINE(rsWillRecord, "");
    ADD_STATUS_LOG_LINE(rsConflict, "error");
    ADD_STATUS_LOG_LINE(rsTooManyRecordings, "warning");
    ADD_STATUS_LOG_LINE(rsLowDiskSpace, "warning");
    ADD_STATUS_LOG_LINE(rsLaterShowing, "warning");
    ADD_STATUS_LOG_LINE(rsNotListed, "warning");

    QString willrec = statusText[rsWillRecord];

    if (lowerpriority > 0)
    {
        tmpstr = QString("%1 %2 %3").arg(lowerpriority).arg(willrec)
                                    .arg(tr("with lower priority"));
        AddLogLine(tmpstr, helpmsg, tmpstr, tmpstr, "warning");
    }
    if (hdflag > 0)
    {
        tmpstr = QString("%1 %2 %3").arg(hdflag).arg(willrec)
                                    .arg(tr("marked as HDTV"));
        AddLogLine(tmpstr, helpmsg);
    }
    int i;
    for (i = 1; i <= maxSource; ++i)
    {
        if (sourceMatch[i] > 0)
        {
            tmpstr = QString("%1 %2 %3 %4 \"%5\"")
                             .arg(sourceMatch[i]).arg(willrec)
                             .arg(tr("from source")).arg(i).arg(sourceText[i]);
            AddLogLine(tmpstr, helpmsg);
        }
    }
    for (i = 1; i <= maxInput; ++i)
    {
        if (inputMatch[i] > 0)
        {
            tmpstr = QString("%1 %2 %3 %4 \"%5\"")
                             .arg(inputMatch[i]).arg(willrec)
                             .arg(tr("on input")).arg(i).arg(inputText[i]);
            AddLogLine(tmpstr, helpmsg);
        }
    }
}
Beispiel #21
0
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &rawStartTime ,
                                           const QDateTime &rawEndTime   ,
                                           int              nStartChanId,
                                           int              nNumChannels,
                                           bool             bDetails,
                                           int              nChannelGroupId )
{     
    if (!rawStartTime.isValid())
        throw( "StartTime is invalid" );

    if (!rawEndTime.isValid())
        throw( "EndTime is invalid" );

    QDateTime dtStartTime = rawStartTime.toUTC();
    QDateTime dtEndTime = rawEndTime.toUTC();

    if (dtEndTime < dtStartTime)
        throw( "EndTime is before StartTime");

    if (nNumChannels == 0)
        nNumChannels = SHRT_MAX;

    // ----------------------------------------------------------------------
    // Find the ending channel Id
    // ----------------------------------------------------------------------

    int nEndChanId = nStartChanId;

    MSqlQuery query(MSqlQuery::InitCon());

    query.prepare( "SELECT chanid FROM channel WHERE (chanid >= :STARTCHANID )"
                   " ORDER BY chanid LIMIT :NUMCHAN" );

    query.bindValue(":STARTCHANID", nStartChanId );
    query.bindValue(":NUMCHAN"    , nNumChannels );

    if (!query.exec())
        MythDB::DBError("Select ChanId", query);

    query.first();  nStartChanId = query.value(0).toInt();
    query.last();   nEndChanId   = query.value(0).toInt();

    // ----------------------------------------------------------------------
    // Build SQL statement for Program Listing
    // ----------------------------------------------------------------------

    ProgramList  progList;
    ProgramList  schedList;
    MSqlBindings bindings;

    // lpad is to allow natural sorting of numbers
    QString      sSQL;

    if (nChannelGroupId > 0)
    {
        sSQL = "LEFT JOIN channelgroup ON program.chanid = channelgroup.chanid "
                         "WHERE channelgroup.grpid = :CHANGRPID AND ";
        bindings[":CHANGRPID"  ] = nChannelGroupId;
    }
    else
        sSQL = "WHERE ";

    sSQL +=     "visible != 0 "
                "AND program.chanid >= :StartChanId "
                "AND program.chanid <= :EndChanId "
                "AND program.endtime >= :StartDate "
                "AND program.starttime <= :EndDate "
                "AND program.manualid = 0 " // Exclude programmes created purely for 'manual' recording schedules
                "ORDER BY LPAD(CAST(channum AS UNSIGNED), 10, 0), "
                "         LPAD(channum,  10, 0),             "
                "         callsign,                          "
                "         LPAD(program.chanid, 10, 0),       "
                "         program.starttime ";

    bindings[":StartChanId"] = nStartChanId;
    bindings[":EndChanId"  ] = nEndChanId;
    bindings[":StartDate"  ] = dtStartTime;
    bindings[":EndDate"    ] = dtEndTime;

    // ----------------------------------------------------------------------
    // Get all Pending Scheduled Programs
    // ----------------------------------------------------------------------

    bool hasConflicts;
    LoadFromScheduler(schedList, hasConflicts);

    // ----------------------------------------------------------------------

    LoadFromProgram( progList, sSQL, bindings, schedList );

    // ----------------------------------------------------------------------
    // Build Response
    // ----------------------------------------------------------------------

    DTC::ProgramGuide *pGuide = new DTC::ProgramGuide();

    int               nChanCount = 0;
    uint              nCurChanId = 0;
    DTC::ChannelInfo *pChannel   = NULL;
    QString           sCurCallsign;
    uint              nSkipChanId = 0;

    for( uint n = 0; n < progList.size(); n++)
    {
        ProgramInfo *pInfo = progList[ n ];

        if ( nSkipChanId == pInfo->GetChanID())
            continue;

        if ( nCurChanId != pInfo->GetChanID() )
        {
            nChanCount++;

            nCurChanId = pInfo->GetChanID();

            // Filter out channels with the same callsign, keeping just the
            // first seen
            if (sCurCallsign == pInfo->GetChannelSchedulingID())
            {
                nSkipChanId = pInfo->GetChanID();
                continue;
            }

            pChannel = pGuide->AddNewChannel();

            FillChannelInfo( pChannel, pInfo->GetChanID(), bDetails );

            sCurCallsign = pChannel->CallSign();
        }
        
        DTC::Program *pProgram = pChannel->AddNewProgram();

        FillProgramInfo( pProgram, pInfo, false, bDetails, false ); // No cast info
    }

    // ----------------------------------------------------------------------

    pGuide->setStartTime    ( dtStartTime   );
    pGuide->setEndTime      ( dtEndTime     );
    pGuide->setStartChanId  ( nStartChanId  );
    pGuide->setEndChanId    ( nEndChanId    );
    pGuide->setNumOfChannels( nChanCount    );
    pGuide->setDetails      ( bDetails      );
    
    pGuide->setCount        ( progList.size());
    pGuide->setAsOf         ( MythDate::current() );
    
    pGuide->setVersion      ( MYTH_BINARY_VERSION );
    pGuide->setProtoVer     ( MYTH_PROTO_VERSION  );
    
    return pGuide;
}
Beispiel #22
0
DTC::ProgramList* Guide::GetProgramList(int              nStartIndex,
                                        int              nCount,
                                        const QDateTime& rawStartTime,
                                        const QDateTime& rawEndTime,
                                        int nChanId,
                                        const QString& sTitleFilter,
                                        const QString& sCategoryFilter,
                                        const QString& sPersonFilter,
                                        const QString& sKeywordFilter,
                                        bool bOnlyNew,
                                        bool bDetails,
                                        const QString   &sSort,
                                        bool             bDescending)
{
    if (!rawStartTime.isNull() && !rawStartTime.isValid())
        throw( "StartTime is invalid" );

    if (!rawEndTime.isNull() && !rawEndTime.isValid())
        throw( "EndTime is invalid" );

    QDateTime dtStartTime = rawStartTime;
    QDateTime dtEndTime = rawEndTime;

    if (!rawEndTime.isNull() && dtEndTime < dtStartTime)
        throw( "EndTime is before StartTime");

    MSqlQuery query(MSqlQuery::InitCon());


    // ----------------------------------------------------------------------
    // Build SQL statement for Program Listing
    // ----------------------------------------------------------------------

    ProgramList  progList;
    ProgramList  schedList;
    MSqlBindings bindings;

    QString      sSQL;

    if (!sPersonFilter.isEmpty())
    {
        sSQL = ", people, credits " // LEFT JOIN
               "WHERE people.name LIKE :PersonFilter "
               "AND credits.person = people.person "
               "AND program.chanid = credits.chanid "
               "AND program.starttime = credits.starttime AND ";
        bindings[":PersonFilter"] = QString("%%1%").arg(sPersonFilter);
    }
    else
        sSQL = "WHERE ";

    sSQL +=    "visible != 0 AND program.manualid = 0 "; // Exclude programmes created purely for 'manual' recording schedules

    if (nChanId < 0)
        nChanId = 0;

    if (nChanId > 0)
    {
        sSQL += "AND program.chanid = :ChanId ";
        bindings[":ChanId"]      = nChanId;
    }

    if (dtStartTime.isNull())
        dtStartTime = QDateTime::currentDateTimeUtc();

    sSQL += " AND program.endtime >= :StartDate ";
    bindings[":StartDate"] = dtStartTime;

    if (!dtEndTime.isNull())
    {
        sSQL += "AND program.starttime <= :EndDate ";
        bindings[":EndDate"] = dtEndTime;
    }

    if (!sTitleFilter.isEmpty())
    {
        sSQL += "AND program.title LIKE :Title ";
        bindings[":Title"] = QString("%%1%").arg(sTitleFilter);
    }

    if (!sCategoryFilter.isEmpty())
    {
        sSQL += "AND program.category LIKE :Category ";
        bindings[":Category"] = sCategoryFilter;
    }

    if (!sKeywordFilter.isEmpty())
    {
        sSQL += "AND (program.title LIKE :Keyword1 "
                "OR   program.subtitle LIKE :Keyword2 "
                "OR   program.description LIKE :Keyword3) ";

        QString filter = QString("%%1%").arg(sKeywordFilter);
        bindings[":Keyword1"] = filter;
        bindings[":Keyword2"] = filter;
        bindings[":Keyword3"] = filter;
    }

    if (sSort == "starttime")
        sSQL += "ORDER BY program.starttime ";
    else if (sSort == "title")
        sSQL += "ORDER BY program.title ";
    else if (sSort == "channel")
        sSQL += "ORDER BY channel.channum ";
    else if (sSort == "duration")
        sSQL += "ORDER BY (program.endtime - program.starttime) ";
    else
        sSQL += "ORDER BY program.starttime ";

    if (bDescending)
        sSQL += "DESC ";
    else
        sSQL += "ASC ";

    // ----------------------------------------------------------------------
    // Get all Pending Scheduled Programs
    // ----------------------------------------------------------------------

    bool hasConflicts;
    LoadFromScheduler(schedList, hasConflicts);

    // ----------------------------------------------------------------------

    uint nTotalAvailable = 0;
    LoadFromProgram( progList, sSQL, bindings, schedList,
                     (uint)nStartIndex, (uint)nCount, nTotalAvailable);

    // ----------------------------------------------------------------------
    // Build Response
    // ----------------------------------------------------------------------

    DTC::ProgramList *pPrograms = new DTC::ProgramList();

    nCount        = (int)progList.size();
    int nEndIndex = (int)progList.size();

    for( int n = 0; n < nEndIndex; n++)
    {
        ProgramInfo *pInfo = progList[ n ];

        DTC::Program *pProgram = pPrograms->AddNewProgram();

        FillProgramInfo( pProgram, pInfo, true, bDetails, false ); // No cast info, loading this takes far too long
    }

    // ----------------------------------------------------------------------

    pPrograms->setStartIndex    ( nStartIndex     );
    pPrograms->setCount         ( nCount          );
    pPrograms->setTotalAvailable( nTotalAvailable );
    pPrograms->setAsOf          ( MythDate::current() );
    pPrograms->setVersion       ( MYTH_BINARY_VERSION );
    pPrograms->setProtoVer      ( MYTH_PROTO_VERSION  );

    return pPrograms;
}
Beispiel #23
0
DTC::ProgramList* Dvr::GetRecordedList( bool           bDescending,
                                        int            nStartIndex,
                                        int            nCount,
                                        const QString &sTitleRegEx,
                                        const QString &sRecGroup,
                                        const QString &sStorageGroup )
{
    QMap< QString, ProgramInfo* > recMap;

    if (gCoreContext->GetScheduler())
        recMap = gCoreContext->GetScheduler()->GetRecording();

    QMap< QString, uint32_t > inUseMap    = ProgramInfo::QueryInUseMap();
    QMap< QString, bool >     isJobRunning= ProgramInfo::QueryJobsRunning(JOB_COMMFLAG);

    ProgramList progList;

    int desc = 1;
    if (bDescending)
        desc = -1;

    LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, desc );

    QMap< QString, ProgramInfo* >::iterator mit = recMap.begin();

    for (; mit != recMap.end(); mit = recMap.erase(mit))
        delete *mit;

    // ----------------------------------------------------------------------
    // Build Response
    // ----------------------------------------------------------------------

    DTC::ProgramList *pPrograms = new DTC::ProgramList();
    int nAvailable = 0;

    int nMax      = (nCount > 0) ? nCount : progList.size();

    nAvailable = 0;
    nCount = 0;

    QRegExp rTitleRegEx        = QRegExp(sTitleRegEx, Qt::CaseInsensitive);

    for( unsigned int n = 0; n < progList.size(); n++)
    {
        ProgramInfo *pInfo = progList[ n ];

        if (pInfo->IsDeletePending() ||
            (!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) ||
            (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) ||
            (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup()))
            continue;

        if ((nAvailable < nStartIndex) ||
            (nCount >= nMax))
        {
            ++nAvailable;
            continue;
        }

        ++nAvailable;
        ++nCount;

        DTC::Program *pProgram = pPrograms->AddNewProgram();

        FillProgramInfo( pProgram, pInfo, true );
    }

    // ----------------------------------------------------------------------

    pPrograms->setStartIndex    ( nStartIndex     );
    pPrograms->setCount         ( nCount          );
    pPrograms->setTotalAvailable( nAvailable      );
    pPrograms->setAsOf          ( MythDate::current() );
    pPrograms->setVersion       ( MYTH_BINARY_VERSION );
    pPrograms->setProtoVer      ( MYTH_PROTO_VERSION  );

    return pPrograms;
}
Beispiel #24
0
void ViewScheduled::FillList()
{
    m_schedulesList->Reset();

    MythUIText *norecordingText = dynamic_cast<MythUIText*>
                                                (GetChild("norecordings_info"));

    if (norecordingText)
        norecordingText->SetVisible(m_recList.empty());

    if (m_recList.empty())
        return;

    ProgramList plist;

    if (!m_recgroupList.contains(m_currentGroup))
        m_currentGroup = m_defaultGroup;

    plist = m_recgroupList[m_currentGroup];

    ProgramList::iterator pit = plist.begin();
    while (pit != plist.end())
    {
        ProgramInfo *pginfo = *pit;
        if (!pginfo)
        {
            ++pit;
            continue;
        }

        QString state;

        const RecStatusType recstatus = pginfo->GetRecordingStatus();
        if (recstatus == rsRecording)
            state = "running";
        else if (recstatus == rsConflict  ||
                 recstatus == rsOffLine   ||
                 recstatus == rsTunerBusy ||
                 recstatus == rsFailed    ||
                 recstatus == rsAborted   ||
                 recstatus == rsMissed)
            state = "error";
        else if (recstatus == rsWillRecord)
        {
            if ((m_curcard == 0 && m_curinput == 0) ||
                pginfo->GetCardID() == m_curcard ||
                pginfo->GetInputID() == m_curinput)
            {
                if (pginfo->GetRecordingPriority2() < 0)
                    state = "warning";
                else
                    state = "normal";
            }
        }
        else if (recstatus == rsRepeat ||
                 recstatus == rsOtherShowing ||
                 recstatus == rsNeverRecord ||
                 recstatus == rsDontRecord ||
                 (recstatus != rsDontRecord &&
                  recstatus <= rsEarlierShowing))
            state = "disabled";
        else
            state = "warning";

        MythUIButtonListItem *item =
                                new MythUIButtonListItem(m_schedulesList,"",
                                                    qVariantFromValue(pginfo));

        InfoMap infoMap;
        pginfo->ToMap(infoMap);
        item->SetTextFromMap(infoMap, state);

        QString rating = QString::number(pginfo->GetStars(10));
        item->DisplayState(rating, "ratingstate");
        item->DisplayState(state, "status");

        ++pit;
    }

    MythUIText *statusText = dynamic_cast<MythUIText*>(GetChild("status"));
    if (statusText)
    {
        if (m_conflictBool)
        {
            // Find first conflict and store in m_conflictDate field
            ProgramList::const_iterator it = plist.begin();
            for (; it != plist.end(); ++it)
            {
                ProgramInfo &p = **it;
                if (p.GetRecordingStatus() == rsConflict)
                {
                    m_conflictDate = p.GetRecordingStartTime().date();
                    break;
                }
            }

            // figure out caption based on m_conflictDate
            QString cstring = tr("Time Conflict");
            QDate now = QDate::currentDate();
            int daysToConflict = now.daysTo(m_conflictDate);

            if (daysToConflict == 0)
                cstring = tr("Conflict Today");
            else if (daysToConflict > 0)
                cstring = QString(tr("Conflict %1"))
                                .arg(m_conflictDate.toString(m_dateFormat));

            statusText->SetText(cstring);
        }
        else
            statusText->SetText(tr("No Conflicts"));
    }

    MythUIText *filterText = dynamic_cast<MythUIText*>(GetChild("filter"));
    if (filterText)
    {
        if (m_showAll)
            filterText->SetText(tr("All"));
        else
            filterText->SetText(tr("Important"));
    }
}
Beispiel #25
0
void ViewScheduled::LoadList(bool useExistingData)
{
    if (m_inFill)
        return;

    m_inFill = true;

    MythUIButtonListItem *currentItem = m_schedulesList->GetItemCurrent();

    QString callsign;
    QDateTime startts, recstartts;

    if (currentItem)
    {
        ProgramInfo *currentpginfo = qVariantValue<ProgramInfo*>
                                                    (currentItem->GetData());
        if (currentpginfo)
        {
            callsign   = currentpginfo->GetChannelSchedulingID();
            startts    = currentpginfo->GetScheduledStartTime();
            recstartts = currentpginfo->GetRecordingStartTime();
        }
    }

    QDateTime now = QDateTime::currentDateTime();

    QMap<int, int> toomanycounts;

    m_schedulesList->Reset();
    if (m_groupList)
        m_groupList->Reset();

    m_recgroupList.clear();

    if (!useExistingData)
        LoadFromScheduler(m_recList, m_conflictBool);

    ProgramList::iterator pit = m_recList.begin();
    QString currentDate;
    m_recgroupList[m_defaultGroup] = ProgramList(false);
    m_recgroupList[m_defaultGroup].setAutoDelete(false);
    while (pit != m_recList.end())
    {
        ProgramInfo *pginfo = *pit;
        const RecStatusType recstatus = pginfo->GetRecordingStatus();
        if ((pginfo->GetRecordingEndTime() >= now ||
             pginfo->GetScheduledEndTime() >= now) &&
            (m_showAll ||
             recstatus <= rsWillRecord ||
             recstatus == rsDontRecord ||
             (recstatus == rsTooManyRecordings &&
              ++toomanycounts[pginfo->GetRecordingRuleID()] <= 1) ||
             (recstatus > rsTooManyRecordings &&
              recstatus != rsRepeat &&
              recstatus != rsNeverRecord)))
        {
            m_cardref[pginfo->GetCardID()]++;
            if (pginfo->GetCardID() > m_maxcard)
                m_maxcard = pginfo->GetCardID();

            m_inputref[pginfo->GetInputID()]++;
            if (pginfo->GetInputID() > m_maxinput)
                m_maxinput = pginfo->GetInputID();

            QDate date = (pginfo->GetRecordingStartTime()).date();
            m_recgroupList[date].push_back(pginfo);
            m_recgroupList[date].setAutoDelete(false);

            m_recgroupList[m_defaultGroup].push_back(pginfo);

            ++pit;
        }
        else
        {
            pit = m_recList.erase(pit);
            continue;
        }
    }

    if (m_groupList)
    {
        QString label;
        QMap<QDate,ProgramList>::iterator dateit = m_recgroupList.begin();
        while (dateit != m_recgroupList.end())
        {
            if (dateit.key().isNull())
                label = tr("All");
            else
                label = dateit.key().toString(m_dateFormat);

            new MythUIButtonListItem(m_groupList, label,
                                     qVariantFromValue(dateit.key()));
            ++dateit;
        }
        if (!m_recgroupList.contains(m_currentGroup))
            m_groupList->SetValueByData(qVariantFromValue(m_currentGroup));
    }

    FillList();

    // Restore position after a list update
    if (!callsign.isEmpty())
    {
        ProgramList plist;

        if (!m_recgroupList.contains(m_currentGroup))
            m_currentGroup = m_defaultGroup;

        plist = m_recgroupList[m_currentGroup];

        int listPos = ((int) plist.size()) - 1;
        int i;
        for (i = listPos; i >= 0; --i)
        {
            ProgramInfo *pginfo = plist[i];
            if (callsign == pginfo->GetChannelSchedulingID() &&
                startts  == pginfo->GetScheduledStartTime())
            {
                listPos = i;
                break;
            }
            else if (recstartts <= pginfo->GetRecordingStartTime())
                listPos = i;
        }
        m_schedulesList->SetItemCurrent(listPos);
    }

    m_inFill = false;
    m_needFill = false;
}
Beispiel #26
0
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &dtStartTime ,
                                           const QDateTime &dtEndTime   ,
                                           int              nStartChanId,
                                           int              nNumChannels,
                                           bool             bDetails      )
{     

    if (!dtStartTime.isValid())
        throw( "StartTime is invalid" );

    if (!dtEndTime.isValid())
        throw( "EndTime is invalid" );

    if (dtEndTime < dtStartTime)
        throw( "EndTime is before StartTime");

    if (nNumChannels == 0)
        nNumChannels = 1;

    if (nNumChannels == -1)
        nNumChannels = SHRT_MAX;

    // ----------------------------------------------------------------------
    // Find the ending channel Id
    // ----------------------------------------------------------------------

    int nEndChanId = nStartChanId;

    MSqlQuery query(MSqlQuery::InitCon());

    query.prepare( "SELECT chanid FROM channel WHERE (chanid >= :STARTCHANID )"
                   " ORDER BY chanid LIMIT :NUMCHAN" );

    query.bindValue(":STARTCHANID", nStartChanId );
    query.bindValue(":NUMCHAN"    , nNumChannels );

    if (!query.exec())
        MythDB::DBError("Select ChanId", query);

    query.first();  nStartChanId = query.value(0).toInt();
    query.last();   nEndChanId   = query.value(0).toInt();

    // ----------------------------------------------------------------------
    // Build SQL statement for Program Listing
    // ----------------------------------------------------------------------

    ProgramList  progList;
    ProgramList  schedList;
    MSqlBindings bindings;

    QString      sSQL = "WHERE program.chanid >= :StartChanId "
                         "AND program.chanid <= :EndChanId "
                         "AND program.endtime >= :StartDate "
                         "AND program.starttime <= :EndDate "
                        "GROUP BY program.starttime, channel.channum, "
                         "channel.callsign, program.title "
                        "ORDER BY program.chanid ";

    bindings[":StartChanId"] = nStartChanId;
    bindings[":EndChanId"  ] = nEndChanId;
    bindings[":StartDate"  ] = dtStartTime;
    bindings[":EndDate"    ] = dtEndTime;

    // ----------------------------------------------------------------------
    // Get all Pending Scheduled Programs
    // ----------------------------------------------------------------------

    bool hasConflicts;
    LoadFromScheduler(schedList, hasConflicts);

    // ----------------------------------------------------------------------

    LoadFromProgram( progList, sSQL, bindings, schedList, false );

    // ----------------------------------------------------------------------
    // Build Response
    // ----------------------------------------------------------------------

    DTC::ProgramGuide *pGuide = new DTC::ProgramGuide();

    int               nChanCount = 0;
    uint              nCurChanId = 0;
    DTC::ChannelInfo *pChannel   = NULL;

    for( uint n = 0; n < progList.size(); n++)
    {
        ProgramInfo *pInfo = progList[ n ];

        if ( nCurChanId != pInfo->GetChanID() )
        {
            nChanCount++;

            nCurChanId = pInfo->GetChanID();

            pChannel = pGuide->AddNewChannel();

            FillChannelInfo( pChannel, pInfo, bDetails );
        }

        
        DTC::Program *pProgram = pChannel->AddNewProgram();

        FillProgramInfo( pProgram, pInfo, false, bDetails );
    }

    // ----------------------------------------------------------------------

    pGuide->setStartTime    ( dtStartTime   );
    pGuide->setEndTime      ( dtEndTime     );
    pGuide->setStartChanId  ( nStartChanId  );
    pGuide->setEndChanId    ( nEndChanId    );
    pGuide->setNumOfChannels( nChanCount    );
    pGuide->setDetails      ( bDetails      );
    
    pGuide->setCount        ( progList.size());
    pGuide->setAsOf         ( QDateTime::currentDateTime() );
    
    pGuide->setVersion      ( MYTH_BINARY_VERSION );
    pGuide->setProtoVer     ( MYTH_PROTO_VERSION  );
    
    return pGuide;
}
Beispiel #27
0
/** \brief Fills RecordingInfo for the program that airs at
 *         "desiredts" on "chanid".
 *  \param chanid  %Channel ID on which to search for program.
 *  \param desiredts Date and Time for which we desire the program.
 *  \param genUnknown Generate a full entry for live-tv if unknown
 *  \param maxHours Clamp the maximum time to X hours from dtime.
 *  \return LoadStatus describing what happened.
 */
RecordingInfo::RecordingInfo(
    uint _chanid, const QDateTime &desiredts,
    bool genUnknown, uint maxHours, LoadStatus *status) :
    oldrecstatus(rsUnknown),
    savedrecstatus(rsUnknown),
    future(false),
    schedorder(0),
    mplexid(0),
    desiredrecstartts(),
    desiredrecendts(),
    record(NULL)
{
    ProgramList schedList;
    ProgramList progList;

    MSqlBindings bindings;
    QString querystr = "WHERE program.chanid    = :CHANID   AND "
                       "      program.starttime < :STARTTS1 AND "
                       "      program.endtime   > :STARTTS2 ";
    bindings[":CHANID"] = QString::number(_chanid);
    QDateTime query_startts = desiredts.addSecs(50 - desiredts.time().second());
    bindings[":STARTTS1"] = query_startts;
    bindings[":STARTTS2"] = query_startts;

    ::LoadFromScheduler(schedList);
    LoadFromProgram(progList, querystr, bindings, schedList);

    if (!progList.empty())
    {
        ProgramInfo *pginfo = progList[0];

        if (maxHours > 0)
        {
            if (desiredts.secsTo(
                    pginfo->GetScheduledEndTime()) > (int)maxHours * 3600)
            {
                pginfo->SetScheduledEndTime(desiredts.addSecs(maxHours * 3600));
                pginfo->SetRecordingEndTime(pginfo->GetScheduledEndTime());
            }
        }

        *this = *pginfo;
        if (status)
            *status = kFoundProgram;
        return;
    }

    recstartts = startts = desiredts;
    recendts   = endts   = desiredts;
    lastmodified         = desiredts;

    MSqlQuery query(MSqlQuery::InitCon());
    query.prepare("SELECT chanid, channum, callsign, name, "
                  "commmethod, outputfilters "
                  "FROM channel "
                  "WHERE chanid = :CHANID");
    query.bindValue(":CHANID", _chanid);

    if (!query.exec())
    {
        MythDB::DBError("Loading Program overlapping a datetime", query);
        if (status)
            *status = kNoProgram;
        return;
    }

    if (!query.next())
    {
        if (status)
            *status = kNoProgram;
        return;
    }

    chanid               = query.value(0).toUInt();
    chanstr              = query.value(1).toString();
    chansign             = query.value(2).toString();
    channame             = query.value(3).toString();
    programflags &= ~FL_CHANCOMMFREE;
    programflags |= (query.value(4).toInt() == COMM_DETECT_COMMFREE) ?
        FL_CHANCOMMFREE : 0;
    chanplaybackfilters  = query.value(5).toString();

    {
        QMutexLocker locker(&staticDataLock);
        if (unknownTitle.isEmpty())
            unknownTitle = gCoreContext->GetSetting("UnknownTitle");
        title = unknownTitle;
        title.detach();
    }

    if (!genUnknown)
    {
        if (status)
            *status = kFakedZeroMinProgram;
        return;
    }

    // Round endtime up to the next half-hour.
    endts = QDateTime(
        endts.date(),
        QTime(endts.time().hour(),
              endts.time().minute() / kUnknownProgramLength
              * kUnknownProgramLength), Qt::UTC);
    endts = endts.addSecs(kUnknownProgramLength * 60);

    // if under a minute, bump it up to the next half hour
    if (startts.secsTo(endts) < 60)
        endts = endts.addSecs(kUnknownProgramLength * 60);

    recendts = endts;

    // Find next program starttime
    bindings.clear();
    QDateTime nextstart = startts;
    querystr = "WHERE program.chanid    = :CHANID  AND "
               "      program.starttime > :STARTTS "
               "GROUP BY program.starttime ORDER BY program.starttime LIMIT 1 ";
    bindings[":CHANID"]  = QString::number(_chanid);
    bindings[":STARTTS"] = desiredts.addSecs(50 - desiredts.time().second());

    LoadFromProgram(progList, querystr, bindings, schedList);

    if (!progList.empty())
        nextstart = (*progList.begin())->GetScheduledStartTime();

    if (nextstart > startts && nextstart < recendts)
        recendts = endts = nextstart;

    if (status)
        *status = kFakedLiveTVProgram;

    desiredrecstartts = startts;
    desiredrecendts = endts;
}
Beispiel #28
0
void TVBrowseHelper::GetNextProgramDB(
    BrowseDirection direction, InfoMap &infoMap) const
{
    uint chanid = infoMap["chanid"].toUInt();
    if (!chanid)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC + "GetNextProgramDB() requires a chanid");
        return;
    }

    int chandir = -1;
    switch (direction)
    {
        case BROWSE_UP:       chandir = CHANNEL_DIRECTION_UP;       break;
        case BROWSE_DOWN:     chandir = CHANNEL_DIRECTION_DOWN;     break;
        case BROWSE_FAVORITE: chandir = CHANNEL_DIRECTION_FAVORITE; break;
    }
    if (chandir != -1)
    {
        chanid = ChannelUtil::GetNextChannel(
            db_all_visible_channels, chanid, 0 /*mplexid_restriction*/,
            chandir, true /*skip non visible*/, true /*skip same callsign*/);
    }

    infoMap["chanid"]  = QString::number(chanid);
    infoMap["channum"] = db_chanid_to_channum[chanid];

    QDateTime nowtime = QDateTime::currentDateTime();
    QDateTime latesttime = nowtime.addSecs(6*60*60);
    QDateTime browsetime = QDateTime::fromString(
        infoMap["dbstarttime"], Qt::ISODate);

    MSqlBindings bindings;
    bindings[":CHANID"] = chanid;
    bindings[":NOWTS"] = nowtime;
    bindings[":LATESTTS"] = latesttime;
    bindings[":BROWSETS"] = browsetime;
    bindings[":BROWSETS2"] = browsetime;

    QString querystr = " WHERE program.chanid = :CHANID ";
    switch (direction)
    {
        case BROWSE_LEFT:
            querystr += " AND program.endtime <= :BROWSETS "
                " AND program.endtime > :NOWTS ";
            break;

        case BROWSE_RIGHT:
            querystr += " AND program.starttime > :BROWSETS "
                " AND program.starttime < :LATESTTS ";
            break;

        default:
            querystr += " AND program.starttime <= :BROWSETS "
                " AND program.endtime > :BROWSETS2 ";
    };

    ProgramList progList;
    ProgramList dummySched;
    LoadFromProgram(progList, querystr, bindings, dummySched);

    if (progList.empty())
    {
        infoMap["dbstarttime"] = "";
        return;
    }

    const ProgramInfo *prog = (direction == BROWSE_LEFT) ?
        progList[progList.size() - 1] : progList[0];

    infoMap["dbstarttime"] = prog->GetScheduledStartTime(ISODate);
}
Beispiel #29
0
void ViewScheduled::FillList()
{
    m_schedulesList->Reset();

    MythUIText *norecordingText = dynamic_cast<MythUIText*>
                                                (GetChild("norecordings_info"));

    if (norecordingText)
        norecordingText->SetVisible(m_recList.empty());

    if (m_recList.empty())
        return;

    ProgramList plist;

    if (!m_recgroupList.contains(m_currentGroup))
        m_currentGroup = m_defaultGroup;

    plist = m_recgroupList[m_currentGroup];

    ProgramList::iterator pit = plist.begin();
    while (pit != plist.end())
    {
        ProgramInfo *pginfo = *pit;
        if (!pginfo)
        {
            ++pit;
            continue;
        }

        QString state;

        const RecStatus::Type recstatus = pginfo->GetRecordingStatus();
        if (recstatus == RecStatus::Recording      ||
            recstatus == RecStatus::Tuning)
            state = "running";
        else if (recstatus == RecStatus::Conflict  ||
                 recstatus == RecStatus::Offline   ||
                 recstatus == RecStatus::TunerBusy ||
                 recstatus == RecStatus::Failed    ||
                 recstatus == RecStatus::Failing   ||
                 recstatus == RecStatus::Aborted   ||
                 recstatus == RecStatus::Missed)
            state = "error";
        else if (recstatus == RecStatus::WillRecord ||
                 recstatus == RecStatus::Pending)
        {
            if (m_curinput == 0 || pginfo->GetInputID() == m_curinput)
            {
                if (pginfo->GetRecordingPriority2() < 0)
                    state = "warning";
                else
                    state = "normal";
            }
        }
        else if (recstatus == RecStatus::Repeat ||
                 recstatus == RecStatus::NeverRecord ||
                 recstatus == RecStatus::DontRecord ||
                 (recstatus != RecStatus::DontRecord &&
                  recstatus <= RecStatus::EarlierShowing))
            state = "disabled";
        else
            state = "warning";

        MythUIButtonListItem *item =
                                new MythUIButtonListItem(m_schedulesList,"",
                                                    qVariantFromValue(pginfo));

        InfoMap infoMap;
        pginfo->ToMap(infoMap);
        item->SetTextFromMap(infoMap, state);

        QString rating = QString::number(pginfo->GetStars(10));
        item->DisplayState(rating, "ratingstate");
        item->DisplayState(state, "status");

        ++pit;
    }

    MythUIText *statusText = dynamic_cast<MythUIText*>(GetChild("status"));
    if (statusText)
    {
        if (m_conflictBool)
        {
            // Find first conflict and store in m_conflictDate field
            ProgramList::const_iterator it = plist.begin();
            for (; it != plist.end(); ++it)
            {
                ProgramInfo &p = **it;
                if (p.GetRecordingStatus() == RecStatus::Conflict)
                {
                    m_conflictDate = p.GetRecordingStartTime()
                        .toLocalTime().date();
                    break;
                }
            }

            // TODO: This can be templated instead of hardcoding
            //       Conflict/No Conflict
            QString cstring = tr("Conflict %1")
                                .arg(MythDate::toString(m_conflictDate,
                                     MythDate::kDateFull | MythDate::kSimplify));

            statusText->SetText(cstring);
        }
        else
            statusText->SetText(tr("No Conflicts"));
    }

    MythUIText *filterText = dynamic_cast<MythUIText*>(GetChild("filter"));
    if (filterText)
    {
        if (m_showAll)
            filterText->SetText(tr("All"));
        else
            filterText->SetText(tr("Important"));
    }
}