static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder) { CVariant variant = CJSONVariantParser::Parse(document); builder.SetAuthor(variant["author"].asString()); builder.SetDisclaimer(variant["disclaimer"].asString()); builder.SetBroken(variant["broken"].asString()); builder.SetPackageSize(variant["size"].asUnsignedInteger()); builder.SetPath(variant["path"].asString()); builder.SetFanart(variant["fanart"].asString()); builder.SetIcon(variant["icon"].asString()); std::vector<std::string> screenshots; for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it) screenshots.push_back(it->asString()); builder.SetScreenshots(std::move(screenshots)); builder.SetType(TranslateType(variant["extensions"][0].asString())); ADDONDEPS deps; for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it) { AddonVersion version((*it)["version"].asString()); deps.emplace((*it)["addonId"].asString(), std::make_pair(std::move(version), (*it)["optional"].asBoolean())); } builder.SetDependencies(std::move(deps)); InfoMap extraInfo; for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it) extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString()); builder.SetExtrainfo(std::move(extraInfo)); }
inline static QString toString(const InfoMap &infoMap, const QString sep="\n") { QString str(""); InfoMap::const_iterator it = infoMap.begin(); for (; it != infoMap.end() ; ++it) str += QString("[%1]:%2%3").arg(it.key()).arg(*it).arg(sep); return str; }
void MythGenericTree::SetTextFromMap(const InfoMap &infoMap, const QString &state) { InfoMap::const_iterator map_it = infoMap.begin(); while (map_it != infoMap.end()) { TextProperties textprop; textprop.text = (*map_it); textprop.state = state; m_strings[map_it.key()] = textprop; ++map_it; } }
mitk::PropertyPersistence::InfoMap mitk::PropertyPersistence::SelectInfo(const InfoMap &infoMap, const SelectFunctionType &selectFunction) { InfoMap result; for (auto pos : infoMap) { if (selectFunction(pos)) { result.insert(pos); } } return result; };
mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfo(const std::string &propertyName, const MimeTypeNameType &mime, bool allowMimeWildCard, bool allowNameRegEx) const { SelectFunctionType select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, mime); }; InfoMap selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, mime); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } if (selection.empty() && allowMimeWildCard) { // no perfect match => second run through with "any mime type" select = [propertyName](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } } InfoResultType result; for (const auto &pos : selection) { result.push_back(pos.second->UnRegExByName(propertyName).GetPointer()); } return result; }
Distribution combine(Distribution const& c, InfoMap const& info) { std::map<Cell, Value> tmp; for (size_t i = 0; i < c.size(); ++i) { Distribution const& w = info.at(c.at(i).first)->weights; Value const f = c.at(i).second; for (size_t j = 0; j < w.size(); ++j) { Cell const v = w.at(j).first; if (tmp.count(v) == 0) tmp[v] = 0; tmp[v] += f * w.at(j).second; } } Distribution result(tmp.size()); std::map<Cell, Value>::const_iterator iter = tmp.begin(); for (size_t i = 0; i < tmp.size(); ++i, ++iter) result[i] = std::make_pair(iter->first, iter->second); return result; }
inline void UserInfoCache::removeUser(int userId) { d_lock.lockWrite(); d_infoMap.erase(userId); d_lock.unlock(); }
bool PlayerContext::GetPlayingInfoMap(InfoMap &infoMap) const { bool loaded = false; LockPlayingInfo(__FILE__, __LINE__); if (playingInfo) { playingInfo->ToMap(infoMap); infoMap["tvstate"] = StateToString(playingState); infoMap["iconpath"] = ChannelUtil::GetIcon(playingInfo->GetChanID()); if ((playingInfo->IsVideoFile() || playingInfo->IsVideoDVD() || playingInfo->IsVideoBD()) && playingInfo->GetPathname() != playingInfo->GetBasename()) { infoMap["coverartpath"] = VideoMetaDataUtil::GetArtPath( playingInfo->GetPathname(), "Coverart"); infoMap["fanartpath"] = VideoMetaDataUtil::GetArtPath( playingInfo->GetPathname(), "Fanart"); infoMap["bannerpath"] = VideoMetaDataUtil::GetArtPath( playingInfo->GetPathname(), "Banners"); infoMap["screenshotpath"] = VideoMetaDataUtil::GetArtPath( playingInfo->GetPathname(), "Screenshots"); } if (player) player->GetCodecDescription(infoMap); infoMap.detach(); loaded = true; } UnlockPlayingInfo(__FILE__, __LINE__); return loaded; }
bool MediaAddonServer::QuitRequested() { CALLED(); InfoMap::iterator iterator = fInfoMap.begin(); for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) _DestroyInstantiatedFlavors(iterator->second); BMediaRoster::CurrentRoster()->Lock(); BMediaRoster::CurrentRoster()->Quit(); for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) _PutAddonIfPossible(iterator->second); return true; }
void ChannelEditor::SetText(const InfoMap &map) { if (map.contains("callsign")) m_callsignEdit->SetText(map.value("callsign")); if (map.contains("channum")) m_channumEdit->SetText(map.value("channum")); if (map.contains("channame")) m_channameEdit->SetText(map.value("channame")); if (map.contains("XMLTV")) m_xmltvidEdit->SetText(map.value("XMLTV")); }
/** * \brief Show and update the edit mode On Screen Display. The cut regions * are only refreshed if the deleteMap has been updated. */ void DeleteMap::UpdateOSD(uint64_t frame, double frame_rate, OSD *osd) { if (!osd || !m_ctx) return; CleanMap(); InfoMap infoMap; m_ctx->LockPlayingInfo(__FILE__, __LINE__); if (m_ctx->playingInfo) m_ctx->playingInfo->ToMap(infoMap); infoMap.detach(); m_ctx->UnlockPlayingInfo(__FILE__, __LINE__); QString cutmarker = " "; if (IsInDelete(frame)) cutmarker = tr("cut"); uint64_t total = m_ctx->player->GetTotalFrameCount(); QString timestr = CreateTimeString(frame, false, frame_rate, true); QString relTimeDisplay; relTimeDisplay = CreateTimeString(frame, true, frame_rate, false); QString relLengthDisplay; relLengthDisplay = CreateTimeString(total, true, frame_rate, false); infoMap["timedisplay"] = timestr; infoMap["framedisplay"] = QString::number(frame); infoMap["cutindicator"] = cutmarker; infoMap["title"] = tr("Edit"); infoMap["seekamount"] = m_seekText;; infoMap["reltimedisplay"] = relTimeDisplay; infoMap["rellengthdisplay"] = relLengthDisplay; //: example: "13:24 (10:23 of 24:37)" infoMap["fulltimedisplay"] = tr("%3 (%1 of %2)").arg(relTimeDisplay) .arg(relLengthDisplay).arg(timestr); QHash<QString,float> posMap; posMap.insert("position", (float)((double)frame/(double)total)); osd->SetValues("osd_program_editor", posMap, kOSDTimeout_None); osd->SetText("osd_program_editor", infoMap, kOSDTimeout_None); if (m_changed || total != m_cachedTotalForOSD) osd->SetRegions("osd_program_editor", m_deleteMap, total); m_changed = false; m_cachedTotalForOSD = total; }
inline int UserInfoCache::updateUserInfo(int userId, UserInfo *userInfo) { int ret = 1; //.. // Although we intend to update the information, we first acquire a *read* // *lock* to locate the item. This allows other threads to read the list while // we find the item. If we do not locate the item we can simply release the // *read* *lock* and return an error without causing any other *reading* thread // to block. (Again, other writers *will* block until this *read* *lock* is // released.) //.. d_lock.lockRead(); InfoMap::iterator it = d_infoMap.find(userId); if (d_infoMap.end() != it) { //.. // Since 'it != end()', we found the item. Now we need to upgrade to a *write* // *lock*. If we can't do this atomically, then we need to locate the item // again. This is because another thread may have changed 'd_infoMap' during // the time between our *read* and *write* locks. //.. if (d_lock.upgradeToWriteLock()) { it = d_infoMap.find(userId); } //.. // This is a little more costly, but since we don't expect many concurrent // writes, it should not happen often. In the (likely) event that we do // upgrade to a *write* *lock* atomically, then the second lookup above is not // performed. In any case, we can now update the information and release the // lock, since we already have a pointer to the item and we know that the list // could not have been changed by anyone else. //.. if (d_infoMap.end() != it) { it->second = *userInfo; ret = 0; } d_lock.unlock(); } else { d_lock.unlock(); } return ret; }
static void DeserializeMetadata(const std::string& document, CAddonBuilder& builder) { CVariant variant; if (!CJSONVariantParser::Parse(document, variant)) return; builder.SetAuthor(variant["author"].asString()); builder.SetDisclaimer(variant["disclaimer"].asString()); builder.SetBroken(variant["broken"].asString()); builder.SetPackageSize(variant["size"].asUnsignedInteger()); builder.SetPath(variant["path"].asString()); builder.SetIcon(variant["icon"].asString()); std::map<std::string, std::string> art; for (auto it = variant["art"].begin_map(); it != variant["art"].end_map(); ++it) art.emplace(it->first, it->second.asString()); builder.SetArt(std::move(art)); std::vector<std::string> screenshots; for (auto it = variant["screenshots"].begin_array(); it != variant["screenshots"].end_array(); ++it) screenshots.push_back(it->asString()); builder.SetScreenshots(std::move(screenshots)); builder.SetType(CAddonInfo::TranslateType(variant["extensions"][0].asString())); { std::vector<DependencyInfo> deps; for (auto it = variant["dependencies"].begin_array(); it != variant["dependencies"].end_array(); ++it) { deps.emplace_back( (*it)["addonId"].asString(), AddonVersion((*it)["version"].asString()), (*it)["optional"].asBoolean()); } builder.SetDependencies(std::move(deps)); } InfoMap extraInfo; for (auto it = variant["extrainfo"].begin_array(); it != variant["extrainfo"].end_array(); ++it) extraInfo.emplace((*it)["key"].asString(), (*it)["value"].asString()); builder.SetExtrainfo(std::move(extraInfo)); }
inline int UserInfoCache::addUserInfo(int userId, UserInfo *userInfo) { d_lock.lockRead(); bool found = !! d_infoMap.count(userId); if (! found) { if (d_lock.upgradeToWriteLock()) { found = !! d_infoMap.count(userId); } if (! found) { d_infoMap[userId] = *userInfo; } d_lock.unlock(); } else { d_lock.unlock(); } return found ? 1 : 0; }
inline int UserInfoCache::getUserInfo(int userId, UserInfo *userInfo) { int ret = 1; //.. // Getting the user info does not require any write access. We do, however, // need read access to 'd_infoMap', which is controlled by 'd_lock'. (Note // that writers *will* block until this *read* *lock* is released, but // concurrent reads are allowed.) The user info is copied into the // caller-owned location 'userInfo'. //.. d_lock.lockRead(); InfoMap::iterator it = d_infoMap.find(userId); if (d_infoMap.end() != it) { *userInfo = it->second; ret = 0; } d_lock.unlock(); return ret; }
void MediaAddonServer::_AddOnRemoved(ino_t fileNode) { // TODO: locking? FileMap::iterator foundFile = fFileMap.find(fileNode); if (foundFile == fFileMap.end()) { ERROR("MediaAddonServer::_AddOnRemoved: inode %Ld removed, but no " "media add-on found\n", fileNode); return; } media_addon_id id = foundFile->second; fFileMap.erase(foundFile); int32 oldFlavorCount; InfoMap::iterator foundInfo = fInfoMap.find(id); if (foundInfo == fInfoMap.end()) { ERROR("MediaAddonServer::_AddOnRemoved: couldn't get addon info for " "add-on %ld\n", id); oldFlavorCount = 1000; } else { AddOnInfo& info = foundInfo->second; oldFlavorCount = info.flavor_count; _DestroyInstantiatedFlavors(info); _PutAddonIfPossible(info); if (info.addon) { ERROR("MediaAddonServer::_AddOnRemoved: couldn't unload addon " "%ld since flavors are in use\n", id); } fInfoMap.erase(foundInfo); } gDormantNodeManager->UnregisterAddOn(id); BPrivate::media::notifications::FlavorsChanged(id, 0, oldFlavorCount); }
void MythUIText::ResetMap(const InfoMap &map) { QString newText = GetTemplateText(); if (newText.isEmpty()) newText = GetDefaultText(); QRegExp regexp("%(([^\\|%]+)?\\||\\|(.))?([\\w#]+)(\\|(.+))?%"); regexp.setMinimal(true); bool replaced = map.contains(objectName()); if (!replaced && !newText.isEmpty() && newText.contains(regexp)) { int pos = 0; QString translatedTemplate = qApp->translate("ThemeUI", newText.toUtf8()); while ((pos = regexp.indexIn(translatedTemplate, pos)) != -1) { QString key = regexp.cap(4).toLower().trimmed(); if (map.contains(key)) { replaced = true; break; } pos += regexp.matchedLength(); } } if (replaced) { Reset(); } }
void MythUIText::SetTextFromMap(const InfoMap &map) { QString newText = GetTemplateText(); if (newText.isEmpty()) newText = GetDefaultText(); QRegExp regexp("%(([^\\|%]+)?\\||\\|(.))?([\\w#]+)(\\|(.+))?%"); regexp.setMinimal(true); if (!newText.isEmpty() && newText.contains(regexp)) { int pos = 0; QString translatedTemplate = qApp->translate("ThemeUI", newText.toUtf8()); QString tempString = translatedTemplate; bool replaced = map.contains(objectName()); while ((pos = regexp.indexIn(translatedTemplate, pos)) != -1) { QString key = regexp.cap(4).toLower().trimmed(); QString replacement; if (map.contains(key)) { replaced = true; } if (!map.value(key).isEmpty()) { replacement = QString("%1%2%3%4") .arg(regexp.cap(2)) .arg(regexp.cap(3)) .arg(map.value(key)) .arg(regexp.cap(6)); } tempString.replace(regexp.cap(0), replacement); pos += regexp.matchedLength(); } if (replaced) { SetText(tempString); } } else if (map.contains(objectName())) { SetText(map.value(objectName())); } }
void MediaAddonServer::_AddOnAdded(const char* path, ino_t fileNode) { TRACE("\n\nMediaAddonServer::_AddOnAdded: path %s\n", path); media_addon_id id = gDormantNodeManager->RegisterAddOn(path); if (id <= 0) { ERROR("MediaAddonServer::_AddOnAdded: failed to register add-on %s\n", path); return; } TRACE("MediaAddonServer::_AddOnAdded: loading addon %ld now...\n", id); BMediaAddOn* addon = gDormantNodeManager->GetAddOn(id); if (addon == NULL) { ERROR("MediaAddonServer::_AddOnAdded: failed to get add-on %s\n", path); gDormantNodeManager->UnregisterAddOn(id); return; } TRACE("MediaAddonServer::_AddOnAdded: loading finished, id %ld\n", id); try { // put file's inode and addon's id into map fFileMap.insert(std::make_pair(fileNode, id)); AddOnInfo info; fInfoMap.insert(std::make_pair(id, info)); } catch (std::bad_alloc& exception) { fFileMap.erase(fileNode); return; } InfoMap::iterator found = fInfoMap.find(id); AddOnInfo& info = found->second; info.id = id; info.wants_autostart = false; // temporary default info.flavor_count = 0; info.addon = addon; // scan the flavors _ScanAddOnFlavors(addon); // need to call BMediaNode::WantsAutoStart() // after the flavors have been scanned info.wants_autostart = addon->WantsAutoStart(); if (info.wants_autostart) TRACE("add-on %ld WantsAutoStart!\n", id); // During startup, first all add-ons are loaded, then all // nodes (flavors) representing physical inputs and outputs // are instantiated. Next, all add-ons that need autostart // will be autostarted. Finally, add-ons that don't have // any active nodes (flavors) will be unloaded. // After startup is done, we simply do it for each new // loaded add-on, too. if (!fStartup) { _InstantiatePhysicalInputsAndOutputs(info); _InstantiateAutostartFlavors(info); _PutAddonIfPossible(info); // since something might have changed server_rescan_defaults_command cmd; SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd)); } // we do not call gDormantNodeManager->PutAddOn(id) // since it is done by _PutAddonIfPossible() }
void MediaAddonServer::_ScanAddOnFlavors(BMediaAddOn* addon) { ASSERT(addon->AddonID() > 0); TRACE("MediaAddonServer::_ScanAddOnFlavors: id %ld\n", addon->AddonID()); // cache the media_addon_id in a local variable to avoid // calling BMediaAddOn::AddonID() too often media_addon_id addonID = addon->AddonID(); // update the cached flavor count, get oldflavorcount and newflavorcount InfoMap::iterator found = fInfoMap.find(addonID); ASSERT(found != fInfoMap.end()); AddOnInfo& info = found->second; int32 oldFlavorCount = info.flavor_count; int32 newFlavorCount = addon->CountFlavors(); info.flavor_count = newFlavorCount; TRACE("%ld old flavors, %ld new flavors\n", oldflavorcount, newFlavorCount); // during the first update (i == 0), the server removes old dormant_flavor_infos for (int i = 0; i < newFlavorCount; i++) { const flavor_info* flavorInfo; TRACE("flavor %d:\n", i); if (addon->GetFlavorAt(i, &flavorInfo) != B_OK) { ERROR("MediaAddonServer::_ScanAddOnFlavors GetFlavorAt failed for " "index %d!\n", i); continue; } #if DEBUG >= 2 DumpFlavorInfo(flavorInfo); #endif dormant_flavor_info dormantFlavorInfo; dormantFlavorInfo = *flavorInfo; dormantFlavorInfo.node_info.addon = addonID; dormantFlavorInfo.node_info.flavor_id = flavorInfo->internal_id; strlcpy(dormantFlavorInfo.node_info.name, flavorInfo->name, B_MEDIA_NAME_LENGTH); size_t flattenedSize = dormantFlavorInfo.FlattenedSize(); size_t messageSize = flattenedSize + sizeof(server_register_dormant_node_command); server_register_dormant_node_command* message = (server_register_dormant_node_command*)malloc(messageSize); if (message == NULL) break; // The server should remove previously registered "dormant_flavor_info"s // during the first update, but after the first iteration, we don't // want the server to anymore remove old dormant_flavor_infos message->purge_id = i == 0 ? addonID : 0; message->type = dormantFlavorInfo.TypeCode(); message->flattened_size = flattenedSize; dormantFlavorInfo.Flatten(message->flattened_data, flattenedSize); status_t status = SendToServer(SERVER_REGISTER_DORMANT_NODE, message, messageSize); if (status != B_OK) { ERROR("MediaAddonServer::_ScanAddOnFlavors: couldn't register " "dormant node: %s\n", strerror(status)); } free(message); } // TODO: we currently pretend that all old flavors have been removed, this // could probably be done in a smarter way BPrivate::media::notifications::FlavorsChanged(addonID, newFlavorCount, oldFlavorCount); }
/** \fn GalleryWidget::ShowFileDetails() * \brief Shows the available details of the current image file. The details will only be shown if the file is an image. * \return void */ void GalleryWidget::ShowFileDetails() { ImageMetadata *im = m_fileDataList->at(m_index); if (!im) { delete im; return; } if (im->m_type != kImageFile) { delete im; return; } // First remove all entries m_infoList->Reset(); // This map holds all the exif tag values QMap<QString, QString> infoList; // Get all the available exif header information from the file // and create a data structure that can be displayed nicely QByteArray ba = m_fh->GetExifValues(im); if (ba.count() > 0) { bool readTagValues = false; QString key, value; QXmlStreamReader xml(ba); while (!xml.atEnd()) { xml.readNext(); // Read the general information if (xml.isStartElement() && (xml.name() == "Count" || xml.name() == "File" || xml.name() == "Path" || xml.name() == "Size" || xml.name() == "Extension")) infoList.insert(xml.name().toString(), xml.readElementText()); if (xml.isStartElement() && xml.name() == "ImageMetadataInfo") readTagValues = true; if (readTagValues) { if (xml.isStartElement() && xml.name() == "Label") key = xml.readElementText(); if (xml.isStartElement() && xml.name() == "Value") value = xml.readElementText(); } if (xml.isEndElement() && xml.name() == "ImageMetadataInfo") { readTagValues = false; infoList.insert(key, value); } } } // Now go through the info list and create a map for the mythui buttonlist QMap<QString, QString>::const_iterator i = infoList.constBegin(); while (i != infoList.constEnd()) { MythUIButtonListItem *item = new MythUIButtonListItem(m_infoList, ""); InfoMap infoMap; infoMap.insert("name", i.key()); QString value = tr("Not defined"); if (!i.value().isEmpty()) value = i.value(); infoMap.insert("value", value); item->SetTextFromMap(infoMap); ++i; } m_infoList->SetVisible(true); // All widgets are visible, remember this m_infoVisible = true; SetFocusWidget(m_infoList); delete im; }
void MediaAddonServer::ReadyToRun() { if (!be_roster->IsRunning("application/x-vnd.Be.media-server")) { // the media server is not running, let's quit fprintf(stderr, "The media_server is not running!\n"); Quit(); return; } // the control thread is already running at this point, // so we can talk to the media server and also receive // commands for instantiation ASSERT(fStartup == true); // The very first thing to do is to create the system time source, // register it with the server, and make it the default SYSTEM_TIME_SOURCE BMediaNode *timeSource = new SystemTimeSource; status_t result = fMediaRoster->RegisterNode(timeSource); if (result != B_OK) { fprintf(stderr, "Can't register system time source : %s\n", strerror(result)); debugger("Can't register system time source"); } if (timeSource->ID() != NODE_SYSTEM_TIMESOURCE_ID) debugger("System time source got wrong node ID"); media_node node = timeSource->Node(); result = MediaRosterEx(fMediaRoster)->SetNode(SYSTEM_TIME_SOURCE, &node); if (result != B_OK) debugger("Can't setup system time source as default"); // During startup, first all add-ons are loaded, then all // nodes (flavors) representing physical inputs and outputs // are instantiated. Next, all add-ons that need autostart // will be autostarted. Finally, add-ons that don't have // any active nodes (flavors) will be unloaded. char parameter[32]; size_t parameterLength = sizeof(parameter); bool safeMode = false; if (_kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, parameter, ¶meterLength) == B_OK) { if (!strcasecmp(parameter, "enabled") || !strcasecmp(parameter, "on") || !strcasecmp(parameter, "true") || !strcasecmp(parameter, "yes") || !strcasecmp(parameter, "enable") || !strcmp(parameter, "1")) safeMode = true; } fMonitorHandler = new MonitorHandler(this); AddHandler(fMonitorHandler); BMessage pulse(B_PULSE); fPulseRunner = new BMessageRunner(fMonitorHandler, &pulse, 1000000LL); // the monitor handler needs a pulse to check if add-ons are ready // load dormant media nodes const directory_which directories[] = { B_USER_ADDONS_DIRECTORY, B_COMMON_ADDONS_DIRECTORY, B_SYSTEM_ADDONS_DIRECTORY }; // when safemode, only B_SYSTEM_ADDONS_DIRECTORY is used for (uint32 i = safeMode ? 2 : 0; i < sizeof(directories) / sizeof(directory_which); i++) { BDirectory directory; node_ref nodeRef; BPath path; if (find_directory(directories[i], &path) == B_OK && path.Append("media") == B_OK && directory.SetTo(path.Path()) == B_OK && directory.GetNodeRef(&nodeRef) == B_OK) fMonitorHandler->AddDirectory(&nodeRef); } #ifdef USER_ADDON_PATH node_ref nodeRef; if (entry.SetTo(USER_ADDON_PATH) == B_OK && entry.GetNodeRef(&nodeRef) == B_OK) fMonitorHandler->AddDirectory(&nodeRef); #endif fStartup = false; InfoMap::iterator iterator = fInfoMap.begin(); for (; iterator != fInfoMap.end(); iterator++) _InstantiatePhysicalInputsAndOutputs(iterator->second); for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) _InstantiateAutostartFlavors(iterator->second); for (iterator = fInfoMap.begin(); iterator != fInfoMap.end(); iterator++) _PutAddonIfPossible(iterator->second); server_rescan_defaults_command cmd; SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd)); }
bool UPNPSubscription::ProcessRequest(HTTPRequest *pRequest) { if (!pRequest) return false; if (pRequest->m_sBaseUrl != "/Subscriptions") return false; if (pRequest->m_sMethod != "event") return false; LOG(VB_UPNP, LOG_DEBUG, LOC + QString("%1\n%2") .arg(pRequest->m_sRawRequest).arg(pRequest->m_sPayload)); if (pRequest->m_sPayload.isEmpty()) return true; pRequest->m_eResponseType = ResponseTypeHTML; QString nt = pRequest->m_mapHeaders["nt"]; QString nts = pRequest->m_mapHeaders["nts"]; bool no = (pRequest->m_eType == RequestTypeNotify); if (nt.isEmpty() || nts.isEmpty() || !no) { pRequest->m_nResponseStatus = 400; return true; } pRequest->m_nResponseStatus = 412; if (nt != "upnp:event" || nts != "upnp:propchange") return true; QString usn = pRequest->m_mapParams["usn"]; QString sid = pRequest->m_mapHeaders["sid"]; if (usn.isEmpty() || sid.isEmpty()) return true; // N.B. Validating the usn and uuid here might mean blocking for some time // while waiting for a subscription to complete. While this operates in a // worker thread, worker threads are a limited resource which we could // rapidly overload if a number of events arrive. Instead let the // subscribing objects validate the usn - the uuid should be superfluous. QString seq = pRequest->m_mapHeaders["seq"]; // mediatomb sends some extra character(s) at the end of the payload // which throw Qt, so try and trim them off int loc = pRequest->m_sPayload.lastIndexOf("propertyset>"); QString payload = (loc > -1) ? pRequest->m_sPayload.left(loc + 12) : pRequest->m_sPayload; LOG(VB_UPNP, LOG_DEBUG, LOC + QString("Payload:\n%1").arg(payload)); pRequest->m_nResponseStatus = 400; QDomDocument body; QString error; int errorCol = 0; int errorLine = 0; if (!body.setContent(payload, true, &error, &errorLine, &errorCol)) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to parse event: Line: %1 Col: %2 Error: '%3'") .arg(errorLine).arg(errorCol).arg(error)); return true; } LOG(VB_UPNP, LOG_DEBUG, LOC + "/n/n" + body.toString(4) + "/n/n"); QDomNodeList properties = body.elementsByTagName("property"); InfoMap results; // this deals with both one argument per property (compliant) and mutliple // arguments per property as sent by mediatomb for (int i = 0; i < properties.size(); i++) { QDomNodeList arguments = properties.at(i).childNodes(); for (int j = 0; j < arguments.size(); j++) { QDomElement e = arguments.at(j).toElement(); if (!e.isNull() && !e.text().isEmpty() && !e.tagName().isEmpty()) results.insert(e.tagName(), e.text()); } } // using MythObservable allows multiple objects to subscribe to the same // service but is less efficient from an eventing perspective, especially // if multiple objects are subscribing if (!results.isEmpty()) { pRequest->m_nResponseStatus = 200; results.insert("usn", usn); results.insert("seq", seq); MythInfoMapEvent me("UPNP_EVENT", results); dispatch(me); } return true; }
bool CAddonDatabase::GetRepositoryContent(const std::string& repoId, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; auto start = XbmcThreads::SystemClockMillis(); std::string commonConstraint = PrepareSQL( "JOIN addonlinkrepo ON addon.id=addonlinkrepo.idAddon " "JOIN repo ON addonlinkrepo.idRepo=repo.id " "WHERE repo.checksum IS NOT NULL AND repo.checksum != ''"); if (!repoId.empty()) commonConstraint += PrepareSQL(" AND repo.addonId='%s'", repoId.c_str()); commonConstraint += PrepareSQL(" ORDER BY addon.addonID"); std::vector<CAddonBuilder> result; // Read basic info from the `addon` table { std::string sql = PrepareSQL("SELECT addon.*, broken.reason FROM addon " "LEFT JOIN broken ON broken.addonID=addon.addonID ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); while (!m_pDS->eof()) { std::string addonId = m_pDS->fv(addon_addonID).get_asString(); AddonVersion version(m_pDS->fv(addon_version).get_asString()); if (!result.empty() && result.back().GetId() == addonId && result.back().GetVersion() >= version) { // We already have a version of this addon in our list which is newer. m_pDS->next(); continue; } CAddonBuilder builder; builder.SetId(addonId); builder.SetVersion(version); builder.SetType(TranslateType(m_pDS->fv(addon_type).get_asString())); builder.SetMinVersion(AddonVersion(m_pDS->fv(addon_minversion).get_asString())); builder.SetName(m_pDS->fv(addon_name).get_asString()); builder.SetSummary(m_pDS->fv(addon_summary).get_asString()); builder.SetDescription(m_pDS->fv(addon_description).get_asString()); builder.SetChangelog(m_pDS->fv(addon_changelog).get_asString()); builder.SetDisclaimer(m_pDS->fv(addon_disclaimer).get_asString()); builder.SetAuthor(m_pDS->fv(addon_author).get_asString()); builder.SetPath(m_pDS->fv(addon_path).get_asString()); builder.SetIcon(m_pDS->fv(addon_icon).get_asString()); builder.SetFanart(m_pDS->fv(addon_fanart).get_asString()); builder.SetBroken(m_pDS->fv(broken_reason).get_asString()); if (!result.empty() && result.back().GetId() == addonId) result.back() = std::move(builder); else result.push_back(std::move(builder)); m_pDS->next(); } } // Read extra info. { std::string sql = PrepareSQL( "SELECT addon.addonID as owner, addonextra.key, addonextra.value " "FROM addon JOIN addonextra ON addon.id=addonextra.id ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); for (auto& builder : result) { //move cursor to current or next addon while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId()) m_pDS->next(); InfoMap extraInfo; while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId()) { extraInfo.emplace(m_pDS->fv(1).get_asString(), m_pDS->fv(2).get_asString()); m_pDS->next(); } builder.SetExtrainfo(std::move(extraInfo)); } } // Read dependency info. { std::string sql = PrepareSQL( "SELECT addon.addonID as owner, dependencies.addon, dependencies.version, dependencies.optional " "FROM addon JOIN dependencies ON addon.id=dependencies.id ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); for (auto& builder : result) { //move cursor to the current or next addon while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId()) m_pDS->next(); ADDONDEPS dependencies; while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId()) { dependencies.emplace(m_pDS->fv(1).get_asString(), std::make_pair(AddonVersion(m_pDS->fv(2).get_asString()), m_pDS->fv(3).get_asBool())); m_pDS->next(); } builder.SetDependencies(std::move(dependencies)); } } m_pDS->close(); for (auto& builder : result) { auto addon = builder.Build(); if (addon) addons.push_back(std::move(addon)); } CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonDatabase::GetAddon(int id, AddonPtr &addon) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; std::string sql = "SELECT addon.*," " broken.reason," " addonextra.key, addonextra.value," " dependencies.addon, dependencies.version, dependencies.optional" " FROM addon" " LEFT JOIN broken" " ON broken.addonID = addon.addonID" " LEFT JOIN addonextra" " ON addonextra.id = addon.id" " LEFT JOIN dependencies" " ON dependencies.id = addon.id"; sql += PrepareSQL(" WHERE addon.id=%i", id); m_pDS2->query(sql); if (!m_pDS2->eof()) { const dbiplus::query_data &data = m_pDS2->get_result_set().records; const dbiplus::sql_record* const record = data[0]; CAddonBuilder builder; builder.SetId(record->at(addon_addonID).get_asString()); builder.SetType(TranslateType(record->at(addon_type).get_asString())); builder.SetVersion(AddonVersion(record->at(addon_version).get_asString())); builder.SetMinVersion(AddonVersion(record->at(addon_minversion).get_asString())); builder.SetName(record->at(addon_name).get_asString()); builder.SetSummary(record->at(addon_summary).get_asString()); builder.SetDescription(record->at(addon_description).get_asString()); builder.SetChangelog(record->at(addon_changelog).get_asString()); builder.SetDisclaimer(record->at(addon_disclaimer).get_asString()); builder.SetAuthor(record->at(addon_author).get_asString()); builder.SetBroken(record->at(broken_reason).get_asString()); builder.SetPath(record->at(addon_path).get_asString()); builder.SetIcon(record->at(addon_icon).get_asString()); builder.SetFanart(record->at(addon_fanart).get_asString()); InfoMap extrainfo; ADDONDEPS dependencies; /* while this is a cartesion join and we'll typically get multiple rows, we rely on the fact that extrainfo and dependencies are maps, so insert() will insert the first instance only */ for (dbiplus::query_data::const_iterator i = data.begin(); i != data.end(); ++i) { const dbiplus::sql_record* const record = *i; if (!record->at(addonextra_key).get_asString().empty()) extrainfo.insert(std::make_pair(record->at(addonextra_key).get_asString(), record->at(addonextra_value).get_asString())); if (!m_pDS2->fv(dependencies_addon).get_asString().empty()) dependencies.insert(std::make_pair(record->at(dependencies_addon).get_asString(), std::make_pair(AddonVersion(record->at(dependencies_version).get_asString()), record->at(dependencies_optional).get_asBool()))); } builder.SetExtrainfo(std::move(extrainfo)); builder.SetDependencies(std::move(dependencies)); addon = builder.Build(); return NULL != addon.get(); } } catch (...) { CLog::Log(LOGERROR, "%s failed on addon %i", __FUNCTION__, id); } addon.reset(); return false; }
/* ================== SV_DirectConnect A "connect" OOB command has been received ================== */ void SV_DirectConnect( netadr_t from, const Cmd::Args& args ) { if ( args.Argc() < 2 ) { return; } Log::Debug( "SVC_DirectConnect ()" ); InfoMap userinfo = InfoStringToMap(args.Argv(1)); // DHM - Nerve :: Update Server allows any protocol to connect // NOTE TTimo: but we might need to store the protocol around for potential non http/ftp clients int version = atoi( userinfo["protocol"].c_str() ); if ( version != PROTOCOL_VERSION ) { Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\nServer uses protocol version %i (yours is %i).", PROTOCOL_VERSION, version ); Log::Debug( " rejected connect from version %i", version ); return; } int qport = atoi( userinfo["qport"].c_str() ); auto clients_begin = svs.clients; auto clients_end = clients_begin + sv_maxclients->integer; client_t* reconnecting = std::find_if(clients_begin, clients_end, [&from, qport](const client_t& client) { return NET_CompareBaseAdr( from, client.netchan.remoteAddress ) && ( client.netchan.qport == qport || from.port == client.netchan.remoteAddress.port ); } ); if ( reconnecting != clients_end && svs.time - reconnecting->lastConnectTime < sv_reconnectlimit->integer * 1000 ) { Log::Debug( "%s: reconnect rejected: too soon", NET_AdrToString( from ) ); return; } if ( NET_IsLocalAddress( from ) ) { userinfo["ip"] = "loopback"; } else { // see if the challenge is valid (local clients don't need to challenge) Challenge::Duration ping_duration; if ( !ChallengeManager::MatchString( from, userinfo["challenge"], &ping_duration ) ) { Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n[err_dialog]No or bad challenge for address." ); return; } userinfo["ip"] = NET_AdrToString( from ); } client_t *new_client = nullptr; // if there is already a slot for this IP address, reuse it if ( reconnecting != clients_end ) { Log::Notice( "%s:reconnect\n", NET_AdrToString( from ) ); new_client = reconnecting; } else { // find a client slot // if "sv_privateClients" is set > 0, then that number // of client slots will be reserved for connections that // have "password" set to the value of "sv_privatePassword" // Info requests will report the maxclients as if the private // slots didn't exist, to prevent people from trying to connect // to a full server. // This is to allow us to reserve a couple slots here on our // servers so we can play without having to kick people. // check for privateClient password int startIndex = 0; if ( userinfo["password"] != sv_privatePassword->string ) { // skip past the reserved slots startIndex = sv_privateClients->integer; } new_client = std::find_if(clients_begin, clients_end, [](const client_t& client) { return client.state == clientState_t::CS_FREE; }); if ( new_client == clients_end ) { if ( NET_IsLocalAddress( from ) ) { int count = std::count_if(clients_begin+startIndex, clients_end, [](const client_t& client) { return SV_IsBot(&client); } ); // if they're all bots if ( count >= sv_maxclients->integer - startIndex ) { SV_DropClient( &svs.clients[ sv_maxclients->integer - 1 ], "only bots on server" ); new_client = &svs.clients[ sv_maxclients->integer - 1 ]; } else { Com_Error( errorParm_t::ERR_FATAL, "server is full on local connect" ); } } else { Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n%s", sv_fullmsg->string ); Log::Debug( "Rejected a connection." ); return; } } } // build a new connection // accept the new client // this is the only place a client_t is ever initialized memset( new_client, 0, sizeof( client_t ) ); int clientNum = new_client - svs.clients; #ifdef HAVE_GEOIP const char * country = NET_GeoIP_Country( &from ); if ( country ) { Log::Notice( "Client %i connecting from %s\n", clientNum, country ); userinfo["geoip"] = country; } else { Log::Notice( "Client %i connecting from somewhere unknown\n", clientNum ); } #else Log::Notice( "Client %i connecting\n", clientNum ); #endif new_client->gentity = SV_GentityNum( clientNum ); new_client->gentity->r.svFlags = 0; // save the address Netchan_Setup( netsrc_t::NS_SERVER, &new_client->netchan, from, qport ); // init the netchan queue // Save the pubkey Q_strncpyz( new_client->pubkey, userinfo["pubkey"].c_str(), sizeof( new_client->pubkey ) ); userinfo.erase("pubkey"); // save the userinfo Q_strncpyz( new_client->userinfo, InfoMapToString(userinfo).c_str(), sizeof( new_client->userinfo ) ); // get the game a chance to reject this connection or modify the userinfo char reason[ MAX_STRING_CHARS ]; if ( gvm.GameClientConnect( reason, sizeof( reason ), clientNum, true, false ) ) { Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "print\n[err_dialog]%s", reason ); Log::Debug( "Game rejected a connection: %s.", reason ); return; } SV_UserinfoChanged( new_client ); // send the connect packet to the client Net::OutOfBandPrint( netsrc_t::NS_SERVER, from, "connectResponse" ); Log::Debug( "Going from CS_FREE to CS_CONNECTED for %s", new_client->name ); new_client->state = clientState_t::CS_CONNECTED; new_client->nextSnapshotTime = svs.time; new_client->lastPacketTime = svs.time; new_client->lastConnectTime = svs.time; // when we receive the first packet from the client, we will // notice that it is from a different serverid and that the // gamestate message was not just sent, forcing a retransmit new_client->gamestateMessageNum = -1; // if this was the first client on the server, or the last client // the server can hold, send a heartbeat to the master. int count = std::count_if(clients_begin, clients_end, [](const client_t& client) { return client.state >= clientState_t::CS_CONNECTED; }); if ( count == 1 || count == sv_maxclients->integer ) { SV_Heartbeat_f(); } }
BuildTask *ResourceUnitHandler::GetNewBuildTask () { // task for metal or energy? ResourceManager *rm = globals->resourceManager; IAICallback *cb = globals->cb; InfoMap *imap = globals->map; // check if storage has to be build if (rm->averageProd.metal > config.StorageConfig.MinMetalIncome && cb->GetMetal () > cb->GetMetalStorage () * config.StorageConfig.MaxRatio && cb->GetMetalStorage() <= rm->averageProd.metal * config.StorageConfig.MaxMetalFactor) { BuildTask *t = CreateStorageTask (config.StorageConfig.MetalStorage.front()); if (t) return t; } if (rm->averageProd.energy > config.StorageConfig.MinEnergyIncome && cb->GetEnergy () > cb->GetEnergyStorage () * config.StorageConfig.MaxRatio && cb->GetEnergyStorage() <= rm->averageProd.energy * config.StorageConfig.MaxEnergyFactor) { BuildTask *t = CreateStorageTask (config.StorageConfig.EnergyStorage.front()); if (t) return t; } if (rm->buildMultiplier.energy * config.MetalBuildRatio < rm->buildMultiplier.metal * config.EnergyBuildRatio) { // pick an energy producing unit to build // find the unit type that has the highest energyMake/ResourceValue(buildcost) ratio and // does not with MaxResourceUpscale int best = -1; float bestRatio; float minWind = globals->cb->GetMinWind (); float maxWind = globals->cb->GetMaxWind (); for (int a=0;a<config.EnergyMakers.size();a++) { BuildTable::UDef*d = buildTable.GetCachedDef (config.EnergyMakers[a]); if (rm->averageProd.energy + d->make.energy > config.EnergyHeuristic.MaxUpscale * rm->averageProd.energy) continue; // calculate costs based on the heuristic parameters float cost = d->buildTime * config.EnergyHeuristic.BuildTime + d->cost.metal * config.EnergyHeuristic.MetalCost + d->cost.energy * config.EnergyHeuristic.EnergyCost; float energyProduction = d->make.energy; if (d->flags & CUD_WindGen) energyProduction += 0.5f * (minWind + maxWind); float ratio = energyProduction / cost; if (best < 0 || ratio > bestRatio) { best = config.EnergyMakers[a]; bestRatio = ratio; } } if (best >= 0) return new BuildTask (buildTable.GetDef (best)); } else { // pick a metal producing unit to build float3 st (globals->map->baseCenter.x, 0.0f, globals->map->baseCenter.y); int best=0; float bestScore; MetalSpot* bestSpot=0; // sector has been found, now calculate the best suitable metal extractor for (int a=0;a<config.MetalExtracters.size();a++) { BuildTable::UDef *d = buildTable.GetCachedDef (config.MetalExtracters[a]); const UnitDef* def= buildTable.GetDef (config.MetalExtracters[a]); MetalSpotID spotID = globals->metalmap->FindSpot(st, imap, def->extractsMetal); if (spotID<0) break; MetalSpot* spot = globals->metalmap->GetSpot (spotID); if (!spot->metalProduction) { logPrintf ("Metalmap error: No metal production on spot.\n"); spot->extractDepth=100; break; } // get threat info GameInfo *gi = imap->GetGameInfoFromMapSquare (spot->pos.x,spot->pos.y); float metalMake = spot->metalProduction * d->metalExtractDepth; float PaybackTime = d->cost.metal + gi->threat * config.MetalHeuristic.ThreatConversionFactor; PaybackTime /= metalMake; float score = config.MetalHeuristic.PaybackTimeFactor * PaybackTime + d->energyUse * config.MetalHeuristic.EnergyUsageFactor; float upscale = 1.0f + metalMake / (1.0f + rm->averageProd.metal); if (upscale > config.MetalHeuristic.PrefUpscale) score += config.MetalHeuristic.UpscaleOvershootFactor * (upscale - config.MetalHeuristic.PrefUpscale); logPrintf ("ResourceUnitHandler: %s has score %f with threat %f\n",def->name.c_str(),score,gi->threat); if (!best || bestScore < score) { bestScore = score; best = config.MetalExtracters[a]; bestSpot=spot; } } // compare the best extractor with the metal makers for (int a=0;a<config.MetalMakers.size();a++) { BuildTable::UDef *d = buildTable.GetCachedDef (config.MetalMakers[a]); const UnitDef* def = buildTable.GetDef (config.MetalMakers[a]); float PaybackTime = d->cost.metal / d->make.metal; float score = config.MetalHeuristic.PaybackTimeFactor * PaybackTime + d->energyUse * config.MetalHeuristic.EnergyUsageFactor; // calculate upscale and use it in the score if (rm->averageProd.metal>0.0f) { float upscale = 1.0f + d->make.metal / rm->averageProd.metal; if (upscale > config.MetalHeuristic.PrefUpscale) score += config.MetalHeuristic.UpscaleOvershootFactor * (upscale - config.MetalHeuristic.PrefUpscale); } logPrintf ("ResourceUnitHandler: %s has score %f\n",def->name.c_str(),score); if (!best || bestScore < score) { bestScore = score; best = config.MetalMakers[a]; } } if (best) { const UnitDef *def = buildTable.GetDef (best); Task *task = new Task (def); return task; } } return 0; }
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); }