void CAddonMgr::RemoveAddon(const CStdString& ID) { if (m_cpluff && m_cp_context) m_cpluff->uninstall_plugin(m_cp_context,ID.c_str()); }
CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlElement* pControlNode, bool insideContainer) { // get the control type CStdString strType = GetType(pControlNode); CGUIControl::GUICONTROLTYPES type = TranslateControlType(strType); int id = 0; float posX = 0, posY = 0; float width = 0, height = 0; float minWidth = 0; int left = 0, right = 0, up = 0, down = 0, next = 0, prev = 0; vector<CGUIActionDescriptor> leftActions, rightActions, upActions, downActions, nextActions, prevActions; int pageControl = 0; CGUIInfoColor colorDiffuse(0xFFFFFFFF); int defaultControl = 0; bool defaultAlways = false; CStdString strTmp; int singleInfo = 0; CStdString strLabel; int iUrlSet=0; int iToggleSelect; float spinWidth = 16; float spinHeight = 16; float spinPosX = 0, spinPosY = 0; float checkWidth = 0, checkHeight = 0; CStdString strSubType; int iType = SPIN_CONTROL_TYPE_TEXT; int iMin = 0; int iMax = 100; int iInterval = 1; float fMin = 0.0f; float fMax = 1.0f; float fInterval = 0.1f; bool bReverse = true; bool bReveal = false; CTextureInfo textureBackground, textureLeft, textureRight, textureMid, textureOverlay; CTextureInfo textureNib, textureNibFocus, textureBar, textureBarFocus; CTextureInfo textureLeftFocus, textureRightFocus; CTextureInfo textureUp, textureDown; CTextureInfo textureUpFocus, textureDownFocus; CTextureInfo texture, borderTexture; CGUIInfoLabel textureFile; CTextureInfo textureCheckMark, textureCheckMarkNF; CTextureInfo textureFocus, textureNoFocus; CTextureInfo textureAltFocus, textureAltNoFocus; CTextureInfo textureRadioOn, textureRadioOff; CTextureInfo imageNoFocus, imageFocus; CGUIInfoLabel texturePath; CRect borderSize; float sliderWidth = 150, sliderHeight = 16; CPoint offset; bool bHasPath = false; vector<CGUIActionDescriptor> clickActions; vector<CGUIActionDescriptor> altclickActions; vector<CGUIActionDescriptor> focusActions; vector<CGUIActionDescriptor> unfocusActions; vector<CGUIActionDescriptor> textChangeActions; CStdString strTitle = ""; CStdString strRSSTags = ""; int iNumSlots = 7; float buttonGap = 5; int iDefaultSlot = 2; int iMovementRange = 0; bool bHorizontal = false; int iAlpha = 0; bool bWrapAround = true; bool bSmoothScrolling = true; CAspectRatio aspect; #ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY if (insideContainer) // default for inside containers is keep aspect.ratio = CAspectRatio::AR_KEEP; #endif int iVisibleCondition = 0; CGUIInfoBool allowHiddenFocus(false); int enableCondition = 0; vector<CAnimation> animations; bool bScrollLabel = false; bool bPulse = true; unsigned int timePerImage = 0; unsigned int fadeTime = 0; unsigned int timeToPauseAtEnd = 0; bool randomized = false; bool loop = true; bool wrapMultiLine = false; ORIENTATION orientation = VERTICAL; bool showOnePage = true; bool scrollOut = true; int preloadItems = 0; CLabelInfo labelInfo; CLabelInfo spinInfo; CGUIInfoColor textColor3; CGUIInfoColor headlineColor; float radioWidth = 0; float radioHeight = 0; float radioPosX = 0; float radioPosY = 0; CStdString altLabel; CStdString strLabel2; CStdString action; int focusPosition = 0; int scrollTime = 200; int timeBlocks = 36; int rulerUnit = 12; bool useControlCoords = false; bool renderFocusedLast = false; CRect hitRect; CPoint camera; bool hasCamera = false; bool resetOnLabelChange = true; bool bPassword = false; ///////////////////////////////////////////////////////////////////////////// // Read control properties from XML // if (!pControlNode->Attribute("id", (int*) &id)) XMLUtils::GetInt(pControlNode, "id", (int&) id); // backward compatibility - not desired // TODO: Perhaps we should check here whether id is valid for focusable controls // such as buttons etc. For labels/fadelabels/images it does not matter XMLUtils::GetFloat(pControlNode, "posx", posX); XMLUtils::GetFloat(pControlNode, "posy", posY); // Convert these from relative coords CStdString pos; XMLUtils::GetString(pControlNode, "posx", pos); if (pos.Right(1) == "r") posX = rect.Width() - posX; XMLUtils::GetString(pControlNode, "posy", pos); if (pos.Right(1) == "r") posY = rect.Height() - posY; GetDimension(pControlNode, "width", width, minWidth); XMLUtils::GetFloat(pControlNode, "height", height); XMLUtils::GetFloat(pControlNode, "offsetx", offset.x); XMLUtils::GetFloat(pControlNode, "offsety", offset.y); // adjust width and height accordingly for groups. Groups should // take the width/height of the parent (adjusted for positioning) // if none is defined. if (type == CGUIControl::GUICONTROL_GROUP || type == CGUIControl::GUICONTROL_GROUPLIST) { if (!width) width = max(rect.x2 - posX, 0.0f); if (!height) height = max(rect.y2 - posY, 0.0f); } hitRect.SetRect(posX, posY, posX + width, posY + height); GetHitRect(pControlNode, hitRect); if (!GetNavigation(pControlNode, "onup", up, upActions)) up = id - 1; if (!GetNavigation(pControlNode, "ondown", down, downActions)) down = id + 1; if (!GetNavigation(pControlNode, "onleft", left, leftActions)) left = id; if (!GetNavigation(pControlNode, "onright", right, rightActions)) right = id; if (!GetNavigation(pControlNode, "onnext", next, nextActions)) next = id; if (!GetNavigation(pControlNode, "onprev", prev, prevActions)) prev = id; if (XMLUtils::GetInt(pControlNode, "defaultcontrol", defaultControl)) { const char *always = pControlNode->FirstChildElement("defaultcontrol")->Attribute("always"); if (always && strnicmp(always, "true", 4) == 0) defaultAlways = true; } XMLUtils::GetInt(pControlNode, "pagecontrol", pageControl); GetInfoColor(pControlNode, "colordiffuse", colorDiffuse); GetConditionalVisibility(pControlNode, iVisibleCondition, allowHiddenFocus); GetCondition(pControlNode, "enable", enableCondition); CRect animRect(posX, posY, posX + width, posY + height); GetAnimations(pControlNode, animRect, animations); GetInfoColor(pControlNode, "textcolor", labelInfo.textColor); GetInfoColor(pControlNode, "focusedcolor", labelInfo.focusedColor); GetInfoColor(pControlNode, "disabledcolor", labelInfo.disabledColor); GetInfoColor(pControlNode, "shadowcolor", labelInfo.shadowColor); GetInfoColor(pControlNode, "selectedcolor", labelInfo.selectedColor); XMLUtils::GetFloat(pControlNode, "textoffsetx", labelInfo.offsetX); XMLUtils::GetFloat(pControlNode, "textoffsety", labelInfo.offsetY); int angle = 0; // use the negative angle to compensate for our vertically flipped cartesian plane if (XMLUtils::GetInt(pControlNode, "angle", angle)) labelInfo.angle = (float)-angle; CStdString strFont; if (XMLUtils::GetString(pControlNode, "font", strFont)) labelInfo.font = g_fontManager.GetFont(strFont); GetAlignment(pControlNode, "align", labelInfo.align); uint32_t alignY = 0; if (GetAlignmentY(pControlNode, "aligny", alignY)) labelInfo.align |= alignY; if (XMLUtils::GetFloat(pControlNode, "textwidth", labelInfo.width)) labelInfo.align |= XBFONT_TRUNCATED; GetMultipleString(pControlNode, "onclick", clickActions); GetMultipleString(pControlNode, "ontextchange", textChangeActions); GetMultipleString(pControlNode, "onfocus", focusActions); GetMultipleString(pControlNode, "onunfocus", unfocusActions); GetMultipleString(pControlNode, "altclick", altclickActions); CStdString infoString; if (XMLUtils::GetString(pControlNode, "info", infoString)) singleInfo = g_infoManager.TranslateString(infoString); GetTexture(pControlNode, "texturefocus", textureFocus); GetTexture(pControlNode, "texturenofocus", textureNoFocus); GetTexture(pControlNode, "alttexturefocus", textureAltFocus); GetTexture(pControlNode, "alttexturenofocus", textureAltNoFocus); CStdString strToggleSelect; XMLUtils::GetString(pControlNode, "usealttexture", strToggleSelect); XMLUtils::GetString(pControlNode, "selected", strToggleSelect); iToggleSelect = g_infoManager.TranslateString(strToggleSelect); XMLUtils::GetBoolean(pControlNode, "haspath", bHasPath); GetTexture(pControlNode, "textureup", textureUp); GetTexture(pControlNode, "texturedown", textureDown); GetTexture(pControlNode, "textureupfocus", textureUpFocus); GetTexture(pControlNode, "texturedownfocus", textureDownFocus); GetTexture(pControlNode, "textureleft", textureLeft); GetTexture(pControlNode, "textureright", textureRight); GetTexture(pControlNode, "textureleftfocus", textureLeftFocus); GetTexture(pControlNode, "texturerightfocus", textureRightFocus); GetInfoColor(pControlNode, "spincolor", spinInfo.textColor); if (XMLUtils::GetString(pControlNode, "spinfont", strFont)) spinInfo.font = g_fontManager.GetFont(strFont); if (!spinInfo.font) spinInfo.font = labelInfo.font; XMLUtils::GetFloat(pControlNode, "spinwidth", spinWidth); XMLUtils::GetFloat(pControlNode, "spinheight", spinHeight); XMLUtils::GetFloat(pControlNode, "spinposx", spinPosX); XMLUtils::GetFloat(pControlNode, "spinposy", spinPosY); XMLUtils::GetFloat(pControlNode, "markwidth", checkWidth); XMLUtils::GetFloat(pControlNode, "markheight", checkHeight); XMLUtils::GetFloat(pControlNode, "sliderwidth", sliderWidth); XMLUtils::GetFloat(pControlNode, "sliderheight", sliderHeight); GetTexture(pControlNode, "texturecheckmark", textureCheckMark); GetTexture(pControlNode, "texturecheckmarknofocus", textureCheckMarkNF); GetTexture(pControlNode, "textureradiofocus", textureRadioOn); // backward compatibility GetTexture(pControlNode, "textureradionofocus", textureRadioOff); GetTexture(pControlNode, "textureradioon", textureRadioOn); GetTexture(pControlNode, "textureradiooff", textureRadioOff); GetTexture(pControlNode, "texturesliderbackground", textureBackground); GetTexture(pControlNode, "texturesliderbar", textureBar); GetTexture(pControlNode, "texturesliderbarfocus", textureBarFocus); GetTexture(pControlNode, "textureslidernib", textureNib); GetTexture(pControlNode, "textureslidernibfocus", textureNibFocus); XMLUtils::GetString(pControlNode, "title", strTitle); XMLUtils::GetString(pControlNode, "tagset", strRSSTags); GetInfoColor(pControlNode, "headlinecolor", headlineColor); GetInfoColor(pControlNode, "titlecolor", textColor3); if (XMLUtils::GetString(pControlNode, "subtype", strSubType)) { strSubType.ToLower(); if ( strSubType == "int") iType = SPIN_CONTROL_TYPE_INT; else if ( strSubType == "page") iType = SPIN_CONTROL_TYPE_PAGE; else if ( strSubType == "float") iType = SPIN_CONTROL_TYPE_FLOAT; else iType = SPIN_CONTROL_TYPE_TEXT; } if (!GetIntRange(pControlNode, "range", iMin, iMax, iInterval)) { GetFloatRange(pControlNode, "range", fMin, fMax, fInterval); } XMLUtils::GetBoolean(pControlNode, "reverse", bReverse); XMLUtils::GetBoolean(pControlNode, "reveal", bReveal); GetTexture(pControlNode, "texturebg", textureBackground); GetTexture(pControlNode, "lefttexture", textureLeft); GetTexture(pControlNode, "midtexture", textureMid); GetTexture(pControlNode, "righttexture", textureRight); GetTexture(pControlNode, "overlaytexture", textureOverlay); // the <texture> tag can be overridden by the <info> tag GetInfoTexture(pControlNode, "texture", texture, textureFile); GetTexture(pControlNode, "bordertexture", borderTexture); GetTexture(pControlNode, "imagefolder", imageNoFocus); GetTexture(pControlNode, "imagefolderfocus", imageFocus); // fade label can have a whole bunch, but most just have one vector<CGUIInfoLabel> infoLabels; GetInfoLabels(pControlNode, "label", infoLabels); GetString(pControlNode, "label", strLabel); GetString(pControlNode, "altlabel", altLabel); GetString(pControlNode, "label2", strLabel2); XMLUtils::GetBoolean(pControlNode, "wrapmultiline", wrapMultiLine); XMLUtils::GetInt(pControlNode,"urlset",iUrlSet); // stuff for button scroller if ( XMLUtils::GetString(pControlNode, "orientation", strTmp) ) { if (strTmp.ToLower() == "horizontal") { bHorizontal = true; orientation = HORIZONTAL; } } XMLUtils::GetFloat(pControlNode, "buttongap", buttonGap); XMLUtils::GetFloat(pControlNode, "itemgap", buttonGap); XMLUtils::GetInt(pControlNode, "numbuttons", iNumSlots); XMLUtils::GetInt(pControlNode, "movement", iMovementRange); XMLUtils::GetInt(pControlNode, "defaultbutton", iDefaultSlot); XMLUtils::GetInt(pControlNode, "alpha", iAlpha); XMLUtils::GetBoolean(pControlNode, "wraparound", bWrapAround); XMLUtils::GetBoolean(pControlNode, "smoothscrolling", bSmoothScrolling); GetAspectRatio(pControlNode, "aspectratio", aspect); XMLUtils::GetBoolean(pControlNode, "scroll", bScrollLabel); XMLUtils::GetBoolean(pControlNode,"pulseonselect", bPulse); XMLUtils::GetInt(pControlNode, "timeblocks", timeBlocks); XMLUtils::GetInt(pControlNode, "rulerunit", rulerUnit); GetInfoTexture(pControlNode, "imagepath", texture, texturePath); XMLUtils::GetUInt(pControlNode,"timeperimage", timePerImage); XMLUtils::GetUInt(pControlNode,"fadetime", fadeTime); XMLUtils::GetUInt(pControlNode,"pauseatend", timeToPauseAtEnd); XMLUtils::GetBoolean(pControlNode, "randomize", randomized); XMLUtils::GetBoolean(pControlNode, "loop", loop); XMLUtils::GetBoolean(pControlNode, "scrollout", scrollOut); XMLUtils::GetFloat(pControlNode, "radiowidth", radioWidth); XMLUtils::GetFloat(pControlNode, "radioheight", radioHeight); XMLUtils::GetFloat(pControlNode, "radioposx", radioPosX); XMLUtils::GetFloat(pControlNode, "radioposy", radioPosY); CStdString borderStr; if (XMLUtils::GetString(pControlNode, "bordersize", borderStr)) GetRectFromString(borderStr, borderSize); XMLUtils::GetBoolean(pControlNode, "showonepage", showOnePage); XMLUtils::GetInt(pControlNode, "focusposition", focusPosition); XMLUtils::GetInt(pControlNode, "scrolltime", scrollTime); XMLUtils::GetInt(pControlNode, "preloaditems", preloadItems, 0, 2); XMLUtils::GetBoolean(pControlNode, "usecontrolcoords", useControlCoords); XMLUtils::GetBoolean(pControlNode, "renderfocusedlast", renderFocusedLast); XMLUtils::GetBoolean(pControlNode, "resetonlabelchange", resetOnLabelChange); XMLUtils::GetBoolean(pControlNode, "password", bPassword); // view type VIEW_TYPE viewType = VIEW_TYPE_NONE; CStdString viewLabel; if (type == CGUIControl::GUICONTAINER_PANEL) { viewType = VIEW_TYPE_ICON; viewLabel = g_localizeStrings.Get(536); } else if (type == CGUIControl::GUICONTAINER_LIST) { viewType = VIEW_TYPE_LIST; viewLabel = g_localizeStrings.Get(535); } else { viewType = VIEW_TYPE_WRAP; viewLabel = g_localizeStrings.Get(541); } TiXmlElement *itemElement = pControlNode->FirstChildElement("viewtype"); if (itemElement && itemElement->FirstChild()) { CStdString type = itemElement->FirstChild()->Value(); if (type == "list") viewType = VIEW_TYPE_LIST; else if (type == "icon") viewType = VIEW_TYPE_ICON; else if (type == "biglist") viewType = VIEW_TYPE_BIG_LIST; else if (type == "bigicon") viewType = VIEW_TYPE_BIG_ICON; else if (type == "wide") viewType = VIEW_TYPE_WIDE; else if (type == "bigwide") viewType = VIEW_TYPE_BIG_WIDE; else if (type == "wrap") viewType = VIEW_TYPE_WRAP; else if (type == "bigwrap") viewType = VIEW_TYPE_BIG_WRAP; const char *label = itemElement->Attribute("label"); if (label) viewLabel = CGUIInfoLabel::GetLabel(FilterLabel(label)); } TiXmlElement *cam = pControlNode->FirstChildElement("camera"); if (cam) { hasCamera = true; cam->QueryFloatAttribute("x", &camera.x); cam->QueryFloatAttribute("y", &camera.y); } XMLUtils::GetInt(pControlNode, "scrollspeed", labelInfo.scrollSpeed); spinInfo.scrollSpeed = labelInfo.scrollSpeed; GetString(pControlNode, "scrollsuffix", labelInfo.scrollSuffix); spinInfo.scrollSuffix = labelInfo.scrollSuffix; XMLUtils::GetString(pControlNode, "action", action); ///////////////////////////////////////////////////////////////////////////// // Instantiate a new control using the properties gathered above // CGUIControl *control = NULL; if (type == CGUIControl::GUICONTROL_GROUP) { if (insideContainer) { control = new CGUIListGroup(parentID, id, posX, posY, width, height); } else { control = new CGUIControlGroup( parentID, id, posX, posY, width, height); ((CGUIControlGroup *)control)->SetDefaultControl(defaultControl, defaultAlways); ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast); } } else if (type == CGUIControl::GUICONTROL_GROUPLIST) { control = new CGUIControlGroupList( parentID, id, posX, posY, width, height, buttonGap, pageControl, orientation, useControlCoords, labelInfo.align, scrollTime); ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast); } else if (type == CGUIControl::GUICONTROL_LABEL) { const CGUIInfoLabel &content = (infoLabels.size()) ? infoLabels[0] : CGUIInfoLabel(""); if (insideContainer) { // inside lists we use CGUIListLabel control = new CGUIListLabel(parentID, id, posX, posY, width, height, labelInfo, content, bScrollLabel); } else { control = new CGUILabelControl( parentID, id, posX, posY, width, height, labelInfo, wrapMultiLine, bHasPath); ((CGUILabelControl *)control)->SetInfo(content); ((CGUILabelControl *)control)->SetWidthControl(minWidth, bScrollLabel); } } else if (type == CGUIControl::GUICONTROL_EDIT) { control = new CGUIEditControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, strLabel); if (bPassword) ((CGUIEditControl *) control)->SetInputType(CGUIEditControl::INPUT_TYPE_PASSWORD, 0); ((CGUIEditControl *) control)->SetTextChangeActions(textChangeActions); } else if (type == CGUIControl::GUICONTROL_VIDEO) { control = new CGUIVideoControl( parentID, id, posX, posY, width, height); } else if (type == CGUIControl::GUICONTROL_FADELABEL) { control = new CGUIFadeLabelControl( parentID, id, posX, posY, width, height, labelInfo, scrollOut, timeToPauseAtEnd, resetOnLabelChange); ((CGUIFadeLabelControl *)control)->SetInfo(infoLabels); } else if (type == CGUIControl::GUICONTROL_RSS) { control = new CGUIRSSControl( parentID, id, posX, posY, width, height, labelInfo, textColor3, headlineColor, strRSSTags); std::map<int,CSettings::RssSet>::iterator iter=g_settings.m_mapRssUrls.find(iUrlSet); if (iter != g_settings.m_mapRssUrls.end()) { ((CGUIRSSControl *)control)->SetUrls(iter->second.url,iter->second.rtl); ((CGUIRSSControl *)control)->SetIntervals(iter->second.interval); } else CLog::Log(LOGERROR,"invalid rss url set referenced in skin"); } else if (type == CGUIControl::GUICONTROL_BUTTON) { control = new CGUIButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo); ((CGUIButtonControl *)control)->SetLabel(strLabel); ((CGUIButtonControl *)control)->SetLabel2(strLabel2); ((CGUIButtonControl *)control)->SetClickActions(clickActions); ((CGUIButtonControl *)control)->SetFocusActions(focusActions); ((CGUIButtonControl *)control)->SetUnFocusActions(unfocusActions); } else if (type == CGUIControl::GUICONTROL_TOGGLEBUTTON) { control = new CGUIToggleButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, textureAltFocus, textureAltNoFocus, labelInfo); ((CGUIToggleButtonControl *)control)->SetLabel(strLabel); ((CGUIToggleButtonControl *)control)->SetAltLabel(altLabel); ((CGUIToggleButtonControl *)control)->SetClickActions(clickActions); ((CGUIToggleButtonControl *)control)->SetAltClickActions(altclickActions); ((CGUIToggleButtonControl *)control)->SetFocusActions(focusActions); ((CGUIToggleButtonControl *)control)->SetUnFocusActions(unfocusActions); ((CGUIToggleButtonControl *)control)->SetToggleSelect(iToggleSelect); } else if (type == CGUIControl::GUICONTROL_CHECKMARK) { control = new CGUICheckMarkControl( parentID, id, posX, posY, width, height, textureCheckMark, textureCheckMarkNF, checkWidth, checkHeight, labelInfo); ((CGUICheckMarkControl *)control)->SetLabel(strLabel); } else if (type == CGUIControl::GUICONTROL_RADIO) { control = new CGUIRadioButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, textureRadioOn, textureRadioOff); ((CGUIRadioButtonControl *)control)->SetLabel(strLabel); ((CGUIRadioButtonControl *)control)->SetRadioDimensions(radioPosX, radioPosY, radioWidth, radioHeight); ((CGUIRadioButtonControl *)control)->SetToggleSelect(iToggleSelect); ((CGUIRadioButtonControl *)control)->SetClickActions(clickActions); ((CGUIRadioButtonControl *)control)->SetFocusActions(focusActions); ((CGUIRadioButtonControl *)control)->SetUnFocusActions(unfocusActions); } else if (type == CGUIControl::GUICONTROL_MULTISELECT) { CGUIInfoLabel label; if (infoLabels.size()) label = infoLabels[0]; control = new CGUIMultiSelectTextControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, label); } else if (type == CGUIControl::GUICONTROL_SPIN) { control = new CGUISpinControl( parentID, id, posX, posY, width, height, textureUp, textureDown, textureUpFocus, textureDownFocus, labelInfo, iType); ((CGUISpinControl *)control)->SetReverse(bReverse); if (iType == SPIN_CONTROL_TYPE_INT) { ((CGUISpinControl *)control)->SetRange(iMin, iMax); } else if (iType == SPIN_CONTROL_TYPE_PAGE) { ((CGUISpinControl *)control)->SetRange(iMin, iMax); ((CGUISpinControl *)control)->SetShowRange(true); ((CGUISpinControl *)control)->SetReverse(false); ((CGUISpinControl *)control)->SetShowOnePage(showOnePage); } else if (iType == SPIN_CONTROL_TYPE_FLOAT) { ((CGUISpinControl *)control)->SetFloatRange(fMin, fMax); ((CGUISpinControl *)control)->SetFloatInterval(fInterval); } } else if (type == CGUIControl::GUICONTROL_SLIDER) { control = new CGUISliderControl( parentID, id, posX, posY, width, height, textureBar, textureNib, textureNibFocus, SPIN_CONTROL_TYPE_TEXT); ((CGUISliderControl *)control)->SetInfo(singleInfo); ((CGUISliderControl *)control)->SetAction(action); } else if (type == CGUIControl::GUICONTROL_SETTINGS_SLIDER) { labelInfo.align |= XBFONT_CENTER_Y; // always center text vertically control = new CGUISettingsSliderControl( parentID, id, posX, posY, width, height, sliderWidth, sliderHeight, textureFocus, textureNoFocus, textureBar, textureNib, textureNibFocus, labelInfo, SPIN_CONTROL_TYPE_TEXT); ((CGUISettingsSliderControl *)control)->SetText(strLabel); ((CGUISettingsSliderControl *)control)->SetInfo(singleInfo); } else if (type == CGUIControl::GUICONTROL_SCROLLBAR) { control = new CGUIScrollBar( parentID, id, posX, posY, width, height, textureBackground, textureBar, textureBarFocus, textureNib, textureNibFocus, orientation, showOnePage); } else if (type == CGUIControl::GUICONTROL_PROGRESS) { control = new CGUIProgressControl( parentID, id, posX, posY, width, height, textureBackground, textureLeft, textureMid, textureRight, textureOverlay, bReveal); ((CGUIProgressControl *)control)->SetInfo(singleInfo); } else if (type == CGUIControl::GUICONTROL_IMAGE) { if (strType == "largeimage") texture.useLarge = true; // use a bordered texture if we have <bordersize> or <bordertexture> specified. if (borderTexture.filename.IsEmpty() && borderStr.IsEmpty()) control = new CGUIImage( parentID, id, posX, posY, width, height, texture); else control = new CGUIBorderedImage( parentID, id, posX, posY, width, height, texture, borderTexture, borderSize); #ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY if (insideContainer && textureFile.IsConstant()) aspect.ratio = CAspectRatio::AR_STRETCH; #endif ((CGUIImage *)control)->SetInfo(textureFile); ((CGUIImage *)control)->SetAspectRatio(aspect); ((CGUIImage *)control)->SetCrossFade(fadeTime); } else if (type == CGUIControl::GUICONTROL_MULTI_IMAGE) { control = new CGUIMultiImage( parentID, id, posX, posY, width, height, texture, timePerImage, fadeTime, randomized, loop, timeToPauseAtEnd); ((CGUIMultiImage *)control)->SetInfo(texturePath); ((CGUIMultiImage *)control)->SetAspectRatio(aspect); } else if (type == CGUIControl::GUICONTAINER_LIST) { control = new CGUIListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems); ((CGUIListContainer *)control)->LoadLayout(pControlNode); ((CGUIListContainer *)control)->LoadContent(pControlNode); ((CGUIListContainer *)control)->SetType(viewType, viewLabel); ((CGUIListContainer *)control)->SetPageControl(pageControl); ((CGUIListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_WRAPLIST) { control = new CGUIWrappingListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition); ((CGUIWrappingListContainer *)control)->LoadLayout(pControlNode); ((CGUIWrappingListContainer *)control)->LoadContent(pControlNode); ((CGUIWrappingListContainer *)control)->SetType(viewType, viewLabel); ((CGUIWrappingListContainer *)control)->SetPageControl(pageControl); ((CGUIWrappingListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_EPGGRID) { control = new CGUIEPGGridContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, timeBlocks, rulerUnit); ((CGUIEPGGridContainer *)control)->LoadLayout(pControlNode); // ((CGUIEPGGridContainer *)control)->LoadContent(pControlNode); /// } else if (type == CGUIControl::GUICONTAINER_FIXEDLIST) { control = new CGUIFixedListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition, iMovementRange); ((CGUIFixedListContainer *)control)->LoadLayout(pControlNode); ((CGUIFixedListContainer *)control)->LoadContent(pControlNode); ((CGUIFixedListContainer *)control)->SetType(viewType, viewLabel); ((CGUIFixedListContainer *)control)->SetPageControl(pageControl); ((CGUIFixedListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_PANEL) { control = new CGUIPanelContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems); ((CGUIPanelContainer *)control)->LoadLayout(pControlNode); ((CGUIPanelContainer *)control)->LoadContent(pControlNode); ((CGUIPanelContainer *)control)->SetType(viewType, viewLabel); ((CGUIPanelContainer *)control)->SetPageControl(pageControl); ((CGUIPanelContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTROL_TEXTBOX) { control = new CGUITextBox( parentID, id, posX, posY, width, height, labelInfo, scrollTime); ((CGUITextBox *)control)->SetPageControl(pageControl); if (infoLabels.size()) ((CGUITextBox *)control)->SetInfo(infoLabels[0]); ((CGUITextBox *)control)->SetAutoScrolling(pControlNode); } else if (type == CGUIControl::GUICONTROL_SELECTBUTTON) { control = new CGUISelectButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, textureBackground, textureLeft, textureLeftFocus, textureRight, textureRightFocus); ((CGUISelectButtonControl *)control)->SetLabel(strLabel); } else if (type == CGUIControl::GUICONTROL_MOVER) { control = new CGUIMoverControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus); } else if (type == CGUIControl::GUICONTROL_RESIZE) { control = new CGUIResizeControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus); } else if (type == CGUIControl::GUICONTROL_BUTTONBAR) { control = new CGUIButtonScroller( parentID, id, posX, posY, width, height, buttonGap, iNumSlots, iDefaultSlot, iMovementRange, bHorizontal, iAlpha, bWrapAround, bSmoothScrolling, textureFocus, textureNoFocus, labelInfo); ((CGUIButtonScroller *)control)->LoadButtons(pControlNode); } else if (type == CGUIControl::GUICONTROL_SPINEX) { control = new CGUISpinControlEx( parentID, id, posX, posY, width, height, spinWidth, spinHeight, labelInfo, textureFocus, textureNoFocus, textureUp, textureDown, textureUpFocus, textureDownFocus, labelInfo, iType); ((CGUISpinControlEx *)control)->SetSpinPosition(spinPosX); ((CGUISpinControlEx *)control)->SetText(strLabel); ((CGUISpinControlEx *)control)->SetReverse(bReverse); } else if (type == CGUIControl::GUICONTROL_VISUALISATION) { control = new CGUIVisualisationControl(parentID, id, posX, posY, width, height); } // things that apply to all controls if (control) { control->SetHitRect(hitRect); control->SetVisibleCondition(iVisibleCondition, allowHiddenFocus); control->SetEnableCondition(enableCondition); control->SetAnimations(animations); control->SetColorDiffuse(colorDiffuse); control->SetNavigation(up, down, left, right); control->SetTabNavigation(next,prev); control->SetNavigationActions(upActions, downActions, leftActions, rightActions); control->SetPulseOnSelect(bPulse); if (hasCamera) control->SetCamera(camera); } return control; }
bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { // We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] /* samba isn't thread safe with old interface, always lock */ CSingleLock lock(smb); smb.Init(); /* we need an url to do proper escaping */ CURL url(strPath); //Separate roots for the authentication and the containing items to allow browsing to work correctly CStdString strRoot = strPath; CStdString strAuth; lock.Leave(); // OpenDir is locked int fd = OpenDir(url, strAuth); if (fd < 0) return false; if (!CUtil::HasSlashAtEnd(strRoot)) strRoot += "/"; if (!CUtil::HasSlashAtEnd(strAuth)) strAuth += "/"; CStdString strFile; // need to keep the samba lock for as short as possible. // so we first cache all directory entries and then go over them again asking for stat // "stat" is locked each time. that way the lock is freed between stat requests vector<CachedDirEntry> vecEntries; struct smbc_dirent* dirEnt; lock.Enter(); while ((dirEnt = smbc_readdir(fd))) { CachedDirEntry aDir; aDir.type = dirEnt->smbc_type; aDir.name = dirEnt->name; vecEntries.push_back(aDir); } smbc_closedir(fd); lock.Leave(); for (size_t i=0; i<vecEntries.size(); i++) { CachedDirEntry aDir = vecEntries[i]; // We use UTF-8 internally, as does SMB strFile = aDir.name; if (!strFile.Equals(".") && !strFile.Equals("..") && aDir.type != SMBC_PRINTER_SHARE && aDir.type != SMBC_IPC_SHARE) { __int64 iSize = 0; bool bIsDir = true; __int64 lTimeDate = 0; bool hidden = false; if(strFile.Right(1).Equals("$") && aDir.type == SMBC_FILE_SHARE ) continue; // only stat files that can give proper responses if ( aDir.type == SMBC_FILE || aDir.type == SMBC_DIR ) { // set this here to if the stat should fail bIsDir = (aDir.type == SMBC_DIR); #ifndef _LINUX struct __stat64 info = {0}; #else struct stat info = {0}; #endif if (m_extFileInfo && g_advancedSettings.m_sambastatfiles) { // make sure we use the authenticated path wich contains any default username CStdString strFullName = strAuth + smb.URLEncode(strFile); lock.Enter(); if( smbc_stat(strFullName.c_str(), &info) == 0 ) { #ifndef _LINUX if ((info.st_mode & S_IXOTH)) hidden = true; #else char value[20]; // We poll for extended attributes which symbolizes bits but split up into a string. Where 0x02 is hidden and 0x12 is hidden directory. // According to the libsmbclient.h it's supposed to return 0 if ok, or the length of the string. It seems always to return the length wich is 4 if (smbc_getxattr(strFullName, "system.dos_attr.mode", value, sizeof(value)) > 0) { long longvalue = strtol(value, NULL, 16); if (longvalue & SMBC_DOS_MODE_HIDDEN) hidden = true; } else CLog::Log(LOGERROR, "Getting extended attributes for the share: '%s'\nunix_err:'%x' error: '%s'", strFullName.c_str(), errno, strerror(errno)); #endif bIsDir = (info.st_mode & S_IFDIR) ? true : false; lTimeDate = info.st_mtime; if(lTimeDate == 0) // if modification date is missing, use create date lTimeDate = info.st_ctime; iSize = info.st_size; } else CLog::Log(LOGERROR, "%s - Failed to stat file %s", __FUNCTION__, strFullName.c_str()); lock.Leave(); } } FILETIME fileTime, localTime; LONGLONG ll = Int32x32To64(lTimeDate & 0xffffffff, 10000000) + 116444736000000000ll; fileTime.dwLowDateTime = (DWORD) (ll & 0xffffffff); fileTime.dwHighDateTime = (DWORD)(ll >> 32); FileTimeToLocalFileTime(&fileTime, &localTime); if (bIsDir) { CFileItemPtr pItem(new CFileItem(strFile)); pItem->m_strPath = strRoot; // needed for network / workgroup browsing // skip if root if we are given a server if (aDir.type == SMBC_SERVER) { /* create url with same options, user, pass.. but no filename or host*/ CURL rooturl(strRoot); rooturl.SetFileName(""); rooturl.SetHostName(""); pItem->m_strPath = smb.URLEncode(rooturl); } pItem->m_strPath += aDir.name; if (!CUtil::HasSlashAtEnd(pItem->m_strPath)) pItem->m_strPath += '/'; pItem->m_bIsFolder = true; pItem->m_dateTime=localTime; if (hidden) pItem->SetProperty("file:hidden", true); items.Add(pItem); } else { CFileItemPtr pItem(new CFileItem(strFile)); pItem->m_strPath = strRoot + aDir.name; pItem->m_bIsFolder = false; pItem->m_dwSize = iSize; pItem->m_dateTime=localTime; if (hidden) pItem->SetProperty("file:hidden", true); items.Add(pItem); } } }
void CGUIDialogAudioSubtitleSettings::AddAudioStreams(unsigned int id) { SettingInfo setting; setting.id = id; setting.name = g_localizeStrings.Get(460); setting.type = SettingInfo::SPIN; setting.min = 0; setting.data = &m_audioStream; // get the number of audio strams for the current movie setting.max = (float)g_application.m_pPlayer->GetAudioStreamCount() - 1; m_audioStream = g_application.m_pPlayer->GetAudioStream(); if( m_audioStream < 0 ) m_audioStream = 0; // check if we have a single, stereo stream, and if so, allow us to split into // left, right or both if (!setting.max) { CStdString strAudioInfo; g_application.m_pPlayer->GetAudioInfo(strAudioInfo); int iNumChannels = atoi(strAudioInfo.Right(strAudioInfo.size() - strAudioInfo.Find("chns:") - 5).c_str()); CStdString strAudioCodec = strAudioInfo.Mid(7, strAudioInfo.Find(") VBR") - 5); bool bDTS = strstr(strAudioCodec.c_str(), "DTS") != 0; bool bAC3 = strstr(strAudioCodec.c_str(), "AC3") != 0; if (iNumChannels == 2 && !(bDTS || bAC3)) { // ok, enable these options /* if (g_settings.m_currentVideoSettings.m_AudioStream == -1) { // default to stereo stream g_settings.m_currentVideoSettings.m_AudioStream = 0; }*/ setting.max = 2; for (int i = 0; i <= setting.max; i++) setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(13320 + i))); m_audioStream = -g_settings.m_currentVideoSettings.m_AudioStream - 1; m_settings.push_back(setting); return; } } // cycle through each audio stream and add it to our list control for (int i = 0; i <= setting.max; ++i) { CStdString strItem; CStdString strName; g_application.m_pPlayer->GetAudioStreamName(i, strName); if (strName.length() == 0) strName = "Unnamed"; strItem.Format("%s (%i/%i)", strName.c_str(), i + 1, (int)setting.max + 1); setting.entry.push_back(make_pair(setting.entry.size(), strItem)); } if( setting.max < 0 ) { setting.max = 0; setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(231))); } m_settings.push_back(setting); }
CStdString CGUIDialogAudioSubtitleSettings::FormatDecibel(float value, float interval) { CStdString text; text.Format("%2.1f dB", value); return text; }
bool CAddonDatabase::IsAddonBlacklisted(const CStdString& addonID, const CStdString& version) { CStdString where = PrepareSQL("addonID='%s' and version='%s'",addonID.c_str(),version.c_str()); return !GetSingleValue("blacklist","addonID",where).IsEmpty(); }
//------------------------------------------------------------------------------------------------------------------- void Xcddb::parseData(const char *buffer) { //writeLog("parseData Start"); std::map<CStdString, CStdString> keywords; std::list<CStdString> keywordsOrder; // remember order of keywords as it appears in data received from CDDB // Collect all the keywords and put them in map. // Multiple occurrences of the same keyword indicate that // the data contained on those lines should be concatenated char *line; const char trenner[3] = {'\n', '\r', '\0'}; strtok((char*)buffer, trenner); // skip first line while ((line = strtok(0, trenner))) { // Lines that begin with # are comments, should be ignored if (line[0] != '#') { char *s = strstr(line, "="); if (s != NULL) { CStdString strKeyword(line, s - line); strKeyword.TrimRight(" "); CStdString strValue(s+1); strValue.Replace("\\n", "\n"); strValue.Replace("\\t", "\t"); strValue.Replace("\\\\", "\\"); g_charsetConverter.unknownToUTF8(strValue); std::map<CStdString, CStdString>::const_iterator it = keywords.find(strKeyword); if (it != keywords.end()) strValue = it->second + strValue; // keyword occured before, concatenate else keywordsOrder.push_back(strKeyword); keywords[strKeyword] = strValue; } } } // parse keywords for (std::list<CStdString>::const_iterator it = keywordsOrder.begin(); it != keywordsOrder.end(); ++it) { CStdString strKeyword = *it; CStdString strValue = keywords[strKeyword]; if (strKeyword == "DTITLE") { // DTITLE may contain artist and disc title, separated with " / ", // for example: DTITLE=Modern Talking / Album: Victory (The 11th Album) bool found = false; for (int i = 0; i < strValue.GetLength() - 2; i++) { if (strValue[i] == ' ' && strValue[i + 1] == '/' && strValue[i + 2] == ' ') { m_strDisk_artist = TrimToUTF8(strValue.Left(i)); m_strDisk_title = TrimToUTF8(strValue.Mid(i+3)); found = true; break; } } if (!found) m_strDisk_title = TrimToUTF8(strValue); } else if (strKeyword == "DYEAR") m_strYear = TrimToUTF8(strValue); else if (strKeyword== "DGENRE") m_strGenre = TrimToUTF8(strValue); else if (strKeyword.Left(6) == "TTITLE") addTitle(strKeyword + "=" + strValue); else if (strKeyword == "EXTD") { CStdString strExtd(strValue); if (m_strYear.IsEmpty()) { // Extract Year from extended info // as a fallback int iPos = strExtd.Find("YEAR:"); if (iPos > -1) // You never know if you really get UTF-8 strings from cddb g_charsetConverter.unknownToUTF8(strExtd.Mid(iPos + 6, 4), m_strYear); } if (m_strGenre.IsEmpty()) { // Extract ID3 Genre // as a fallback int iPos = strExtd.Find("ID3G:"); if (iPos > -1) { CStdString strGenre = strExtd.Mid(iPos + 5, 4); strGenre.TrimLeft(' '); if (StringUtils::IsNaturalNumber(strGenre)) { CID3Tag tag; m_strGenre=tag.ParseMP3Genre(strGenre); } } } } else if (strKeyword.Left(4) == "EXTT") addExtended(strKeyword + "=" + strValue); } //writeLog("parseData Ende"); }
void XBPyThread::Process() { CLog::Log(LOGDEBUG,"Python thread: start processing"); int m_Py_file_input = Py_file_input; // get the global lock PyEval_AcquireLock(); PyThreadState* state = Py_NewInterpreter(); if (!state) { PyEval_ReleaseLock(); CLog::Log(LOGERROR,"Python thread: FAILED to get thread state!"); return; } // swap in my thread state PyThreadState_Swap(state); m_pExecuter->InitializeInterpreter(); CLog::Log(LOGDEBUG, "%s - The source file to load is %s", __FUNCTION__, m_source); // get path from script file name and add python path's // this is used for python so it will search modules from script path first CStdString scriptDir; CUtil::GetDirectory(_P(m_source), scriptDir); CUtil::RemoveSlashAtEnd(scriptDir); CStdString path = scriptDir; // add on any addon modules the user has installed ADDON::VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON::ADDON_SCRIPT_MODULE, addons); for (unsigned int i = 0; i < addons.size(); ++i) path += PY_PATH_SEP + _P(addons[i]->LibPath()); // and add on whatever our default path is path += PY_PATH_SEP; #if (defined USE_EXTERNAL_PYTHON) { // we want to use sys.path so it includes site-packages // if this fails, default to using Py_GetPath PyObject *sysMod(PyImport_ImportModule("sys")); // must call Py_DECREF when finished PyObject *sysModDict(PyModule_GetDict(sysMod)); // borrowed ref, no need to delete PyObject *pathObj(PyDict_GetItemString(sysModDict, "path")); // borrowed ref, no need to delete if( pathObj && PyList_Check(pathObj) ) { for( int i = 0; i < PyList_Size(pathObj); i++ ) { PyObject *e = PyList_GetItem(pathObj, i); // borrowed ref, no need to delete if( e && PyString_Check(e) ) { path += PyString_AsString(e); // returns internal data, don't delete or modify path += PY_PATH_SEP; } } } else { path += Py_GetPath(); } Py_DECREF(sysMod); // release ref to sysMod } #else path += Py_GetPath(); #endif // set current directory and python's path. if (m_argv != NULL) PySys_SetArgv(m_argc, m_argv); CLog::Log(LOGDEBUG, "%s - Setting the Python path to %s", __FUNCTION__, path.c_str()); PySys_SetPath((char *)path.c_str()); CLog::Log(LOGDEBUG, "%s - Entering source directory %s", __FUNCTION__, scriptDir.c_str()); PyObject* module = PyImport_AddModule((char*)"__main__"); PyObject* moduleDict = PyModule_GetDict(module); // when we are done initing we store thread state so we can be aborted PyThreadState_Swap(NULL); PyEval_ReleaseLock(); // we need to check if we was asked to abort before we had inited bool stopping = false; { CSingleLock lock(m_pExecuter->m_critSection); m_threadState = state; stopping = m_stopping; } PyEval_AcquireLock(); PyThreadState_Swap(state); xbp_chdir(scriptDir.c_str()); if (!stopping) { if (m_type == 'F') { // run script from file FILE *fp = fopen_utf8(_P(m_source).c_str(), "r"); if (fp) { PyObject *f = PyString_FromString(_P(m_source).c_str()); PyDict_SetItemString(moduleDict, "__file__", f); Py_DECREF(f); PyRun_File(fp, _P(m_source).c_str(), m_Py_file_input, moduleDict, moduleDict); fclose(fp); } else CLog::Log(LOGERROR, "%s not found!", m_source); } else { //run script PyRun_String(m_source, m_Py_file_input, moduleDict, moduleDict); } } if (!PyErr_Occurred()) CLog::Log(LOGINFO, "Scriptresult: Success"); else if (PyErr_ExceptionMatches(PyExc_SystemExit)) CLog::Log(LOGINFO, "Scriptresult: Aborted"); else { PyObject* exc_type; PyObject* exc_value; PyObject* exc_traceback; PyObject* pystring; pystring = NULL; PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); if (exc_type == 0 && exc_value == 0 && exc_traceback == 0) { CLog::Log(LOGINFO, "Strange: No Python exception occured"); } else { if (exc_type != NULL && (pystring = PyObject_Str(exc_type)) != NULL && (PyString_Check(pystring))) { PyObject *tracebackModule; CLog::Log(LOGINFO, "-->Python script returned the following error<--"); CLog::Log(LOGERROR, "Error Type: %s", PyString_AsString(PyObject_Str(exc_type))); if (PyObject_Str(exc_value)) CLog::Log(LOGERROR, "Error Contents: %s", PyString_AsString(PyObject_Str(exc_value))); tracebackModule = PyImport_ImportModule((char*)"traceback"); if (tracebackModule != NULL) { PyObject *tbList, *emptyString, *strRetval; tbList = PyObject_CallMethod(tracebackModule, (char*)"format_exception", (char*)"OOO", exc_type, exc_value == NULL ? Py_None : exc_value, exc_traceback == NULL ? Py_None : exc_traceback); emptyString = PyString_FromString(""); strRetval = PyObject_CallMethod(emptyString, (char*)"join", (char*)"O", tbList); CLog::Log(LOGERROR, "%s", PyString_AsString(strRetval)); Py_DECREF(tbList); Py_DECREF(emptyString); Py_DECREF(strRetval); Py_DECREF(tracebackModule); } CLog::Log(LOGINFO, "-->End of Python script error report<--"); } else { pystring = NULL; CLog::Log(LOGINFO, "<unknown exception type>"); } CGUIDialogKaiToast *pDlgToast = (CGUIDialogKaiToast*)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST); if (pDlgToast) { CStdString desc; CStdString path; CStdString script; CUtil::Split(m_source, path, script); if (script.Equals("default.py")) { CStdString path2; CUtil::RemoveSlashAtEnd(path); CUtil::Split(path, path2, script); } desc.Format(g_localizeStrings.Get(2100), script); pDlgToast->QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(257), desc); } } Py_XDECREF(exc_type); Py_XDECREF(exc_value); // caller owns all 3 Py_XDECREF(exc_traceback); // already NULL'd out Py_XDECREF(pystring); } PyObject *m = PyImport_AddModule((char*)"xbmc"); if(!m || PyObject_SetAttrString(m, (char*)"abortRequested", PyBool_FromLong(1))) CLog::Log(LOGERROR, "Scriptresult: failed to set abortRequested"); // make sure all sub threads have finished for(PyThreadState* s = state->interp->tstate_head, *old = NULL; s;) { if(s == state) { s = s->next; continue; } if(old != s) { CLog::Log(LOGINFO, "Scriptresult: Waiting on thread %"PRIu64, (uint64_t)s->thread_id); old = s; } Py_BEGIN_ALLOW_THREADS Sleep(100); Py_END_ALLOW_THREADS s = state->interp->tstate_head; } // pending calls must be cleared out PyXBMC_ClearPendingCalls(state); PyThreadState_Swap(NULL); PyEval_ReleaseLock(); { CSingleLock lock(m_pExecuter->m_critSection); m_threadState = NULL; } PyEval_AcquireLock(); PyThreadState_Swap(state); m_pExecuter->DeInitializeInterpreter(); Py_EndInterpreter(state); PyThreadState_Swap(NULL); PyEval_ReleaseLock(); }
static void ParseItemMRSS(CFileItem* item, SResources& resources, TiXmlElement* item_child, const CStdString& name, const CStdString& xmlns, const CStdString& path) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); CStdString text = item_child->GetText(); if(name == "content") { SResource res; res.tag = "media:content"; res.mime = item_child->Attribute("type"); res.path = item_child->Attribute("url"); if(item_child->Attribute("width")) res.width = atoi(item_child->Attribute("width")); if(item_child->Attribute("height")) res.height = atoi(item_child->Attribute("height")); if(item_child->Attribute("bitrate")) res.bitrate = atoi(item_child->Attribute("bitrate")); if(item_child->Attribute("duration")) res.duration = atoi(item_child->Attribute("duration")); if(item_child->Attribute("fileSize")) res.size = _atoi64(item_child->Attribute("fileSize")); resources.push_back(res); ParseItem(item, resources, item_child, path); } else if(name == "group") { ParseItem(item, resources, item_child, path); } else if(name == "thumbnail") { if(item_child->GetText() && IsPathToThumbnail(item_child->GetText())) item->SetThumbnailImage(item_child->GetText()); else { const char * url = item_child->Attribute("url"); if(url && IsPathToThumbnail(url)) item->SetThumbnailImage(url); } } else if (name == "title") { if(text.IsEmpty()) return; if(text.length() > item->m_strTitle.length()) item->m_strTitle = text; } else if(name == "description") { if(text.IsEmpty()) return; CStdString description = text; if(CStdString(item_child->Attribute("type")) == "html") HTML::CHTMLUtil::RemoveTags(description); item->SetProperty("description", description); } else if(name == "category") { if(text.IsEmpty()) return; CStdString scheme = item_child->Attribute("scheme"); /* okey this is silly, boxee what did you think?? */ if (scheme == "urn:boxee:genre") vtag->m_genre = StringUtils::Split(text, g_advancedSettings.m_videoItemSeparator); else if(scheme == "urn:boxee:title-type") { if (text == "tv") item->SetProperty("boxee:istvshow", true); else if(text == "movie") item->SetProperty("boxee:ismovie", true); } else if(scheme == "urn:boxee:episode") vtag->m_iEpisode = atoi(text.c_str()); else if(scheme == "urn:boxee:season") vtag->m_iSeason = atoi(text.c_str()); else if(scheme == "urn:boxee:show-title") vtag->m_strShowTitle = text.c_str(); else if(scheme == "urn:boxee:view-count") vtag->m_playCount = atoi(text.c_str()); else if(scheme == "urn:boxee:source") item->SetProperty("boxee:provider_source", text); else vtag->m_genre = StringUtils::Split(text, g_advancedSettings.m_videoItemSeparator); } else if(name == "rating") { CStdString scheme = item_child->Attribute("scheme"); if(scheme == "urn:user") vtag->m_fRating = (float)atof(text.c_str()); else vtag->m_strMPAARating = text; } else if(name == "credit") { CStdString role = item_child->Attribute("role"); if (role == "director") vtag->m_director.push_back(text); else if(role == "author" || role == "writer") vtag->m_writingCredits.push_back(text); else if(role == "actor") { SActorInfo actor; actor.strName = text; vtag->m_cast.push_back(actor); } } else if(name == "copyright") vtag->m_studio = StringUtils::Split(text, g_advancedSettings.m_videoItemSeparator); else if(name == "keywords") item->SetProperty("keywords", text); }
bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); switch (button) { case CONTEXT_BUTTON_INFO: { if (!item->IsVideoDb()) return CGUIWindowMusicBase::OnContextButton(itemNumber,button); // music videos - artists if (item->GetPath().Left(14).Equals("videodb://3/4/")) { long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); if (idArtist == -1) return false; CStdString path; path.Format("musicdb://2/%ld/", idArtist); CArtist artist; m_musicdatabase.GetArtistInfo(idArtist,artist,false); *item = CFileItem(artist); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Update(m_vecItems->GetPath()); m_viewControl.SetSelectedItem(itemNumber); return true; } // music videos - albums if (item->GetPath().Left(14).Equals("videodb://3/5/")) { long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel()); if (idAlbum == -1) return false; CStdString path; path.Format("musicdb://3/%ld/", idAlbum); CAlbum album; m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL); *item = CFileItem(path,album); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Update(m_vecItems->GetPath()); m_viewControl.SetSelectedItem(itemNumber); return true; } if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.IsEmpty()) { CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV); if (pWindow) { ADDON::ScraperPtr info; pWindow->OnInfo(item.get(),info); Update(m_vecItems->GetPath()); } } return true; } case CONTEXT_BUTTON_INFO_ALL: OnInfoAll(itemNumber); return true; case CONTEXT_BUTTON_UPDATE_LIBRARY: { g_application.StartMusicScan(""); return true; } case CONTEXT_BUTTON_SET_DEFAULT: g_settings.m_defaultMusicLibSource = GetQuickpathName(item->GetPath()); g_settings.Save(); return true; case CONTEXT_BUTTON_CLEAR_DEFAULT: g_settings.m_defaultMusicLibSource.Empty(); g_settings.Save(); return true; case CONTEXT_BUTTON_GO_TO_ARTIST: { CStdString strPath; CVideoDatabase database; database.Open(); strPath.Format("videodb://3/4/%ld/",database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator))); g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath); return true; } case CONTEXT_BUTTON_PLAY_OTHER: { CVideoDatabase database; database.Open(); CVideoInfoTag details; database.GetMusicVideoInfo("",details,database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle())); g_application.getApplicationMessenger().PlayFile(CFileItem(details)); return true; } case CONTEXT_BUTTON_MARK_WATCHED: CGUIWindowVideoBase::MarkWatched(item,true); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->GetPath()); return true; case CONTEXT_BUTTON_MARK_UNWATCHED: CGUIWindowVideoBase::MarkWatched(item,false); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->GetPath()); return true; case CONTEXT_BUTTON_RENAME: CGUIWindowVideoBase::UpdateVideoTitle(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->GetPath()); return true; case CONTEXT_BUTTON_DELETE: if (item->IsPlayList() || item->IsSmartPlayList()) { item->m_bIsFolder = false; CFileUtils::DeleteItem(item); } else { CGUIWindowVideoNav::DeleteItem(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); } Update(m_vecItems->GetPath()); return true; case CONTEXT_BUTTON_SET_CONTENT: { bool bScan=false; ADDON::ScraperPtr scraper; CStdString path(item->GetPath()); CQueryParams params; CDirectoryNode::GetDatabaseInfo(item->GetPath(), params); CONTENT_TYPE content = CONTENT_ALBUMS; if (params.GetAlbumId() != -1) path.Format("musicdb://3/%i/",params.GetAlbumId()); else if (params.GetArtistId() != -1) { path.Format("musicdb://2/%i/",params.GetArtistId()); content = CONTENT_ARTISTS; } if (m_vecItems->GetPath().Equals("musicdb://1/") || item->GetPath().Equals("musicdb://2/")) { content = CONTENT_ARTISTS; } if (!m_musicdatabase.GetScraperForPath(path, scraper, ADDON::ScraperTypeFromContent(content))) { ADDON::AddonPtr defaultScraper; if (ADDON::CAddonMgr::Get().GetDefault(ADDON::ScraperTypeFromContent(content), defaultScraper)) { scraper = boost::dynamic_pointer_cast<ADDON::CScraper>(defaultScraper->Clone(defaultScraper)); } } if (CGUIDialogContentSettings::Show(scraper, bScan, content)) { m_musicdatabase.SetScraperForPath(path,scraper); if (bScan) OnInfoAll(itemNumber,true); } return true; } default: break; } return CGUIWindowMusicBase::OnContextButton(itemNumber, button); }
CStdString CGUIWindowMusicNav::GetStartFolder(const CStdString &dir) { if (dir.Equals("Genres")) return "musicdb://1/"; else if (dir.Equals("Artists")) return "musicdb://2/"; else if (dir.Equals("Albums")) return "musicdb://3/"; else if (dir.Equals("Singles")) return "musicdb://10/"; else if (dir.Equals("Songs")) return "musicdb://4/"; else if (dir.Equals("Top100")) return "musicdb://5/"; else if (dir.Equals("Top100Songs")) return "musicdb://5/1/"; else if (dir.Equals("Top100Albums")) return "musicdb://5/2/"; else if (dir.Equals("RecentlyAddedAlbums")) return "musicdb://6/"; else if (dir.Equals("RecentlyPlayedAlbums")) return "musicdb://7/"; else if (dir.Equals("Compilations")) return "musicdb://8/"; else if (dir.Equals("Years")) return "musicdb://9/"; return CGUIWindowMusicBase::GetStartFolder(dir); }
bool CGUIWindowMusicNav::GetDirectory(const CStdString &strDirectory, CFileItemList &items) { if (m_bDisplayEmptyDatabaseMessage) return true; if (strDirectory.IsEmpty()) AddSearchFolder(); if (m_thumbLoader.IsLoading()) m_thumbLoader.StopThread(); bool bResult = CGUIWindowMusicBase::GetDirectory(strDirectory, items); if (bResult) { if (items.IsPlayList()) OnRetrieveMusicInfo(items); if (!items.IsMusicDb()) { items.SetCachedMusicThumbs(); m_thumbLoader.Load(*m_vecItems); } } // update our content in the info manager if (strDirectory.Left(10).Equals("videodb://")) { CVideoDatabaseDirectory dir; VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(strDirectory); if (node == VIDEODATABASEDIRECTORY::NODE_TYPE_TITLE_MUSICVIDEOS) items.SetContent("musicvideos"); } else if (strDirectory.Left(10).Equals("musicdb://")) { CMusicDatabaseDirectory dir; NODE_TYPE node = dir.GetDirectoryChildType(strDirectory); if (node == NODE_TYPE_ALBUM || node == NODE_TYPE_ALBUM_RECENTLY_ADDED || node == NODE_TYPE_ALBUM_RECENTLY_PLAYED || node == NODE_TYPE_ALBUM_TOP100 || node == NODE_TYPE_ALBUM_COMPILATIONS || node == NODE_TYPE_YEAR_ALBUM) items.SetContent("albums"); else if (node == NODE_TYPE_ARTIST) items.SetContent("artists"); else if (node == NODE_TYPE_SONG || node == NODE_TYPE_SONG_TOP100 || node == NODE_TYPE_SINGLES) items.SetContent("songs"); else if (node == NODE_TYPE_GENRE) items.SetContent("genres"); else if (node == NODE_TYPE_YEAR) items.SetContent("years"); } else if (strDirectory.Equals("special://musicplaylists")) items.SetContent("playlists"); else if (strDirectory.Equals("plugin://music/")) items.SetContent("plugins"); else if (items.IsPlayList()) items.SetContent("songs"); return bResult; }
CStdString CGUIWindowMusicNav::GetQuickpathName(const CStdString& strPath) const { if (strPath.Equals("musicdb://1/")) return "Genres"; else if (strPath.Equals("musicdb://2/")) return "Artists"; else if (strPath.Equals("musicdb://3/")) return "Albums"; else if (strPath.Equals("musicdb://4/")) return "Songs"; else if (strPath.Equals("musicdb://5/")) return "Top100"; else if (strPath.Equals("musicdb://5/2/")) return "Top100Songs"; else if (strPath.Equals("musicdb://5/1/")) return "Top100Albums"; else if (strPath.Equals("musicdb://6/")) return "RecentlyAddedAlbums"; else if (strPath.Equals("musicdb://7/")) return "RecentlyPlayedAlbums"; else if (strPath.Equals("musicdb://8/")) return "Compilations"; else if (strPath.Equals("musicdb://9/")) return "Years"; else if (strPath.Equals("musicdb://10/")) return "Singles"; else if (strPath.Equals("special://musicplaylists/")) return "Playlists"; else { CLog::Log(LOGERROR, " CGUIWindowMusicNav::GetQuickpathName: Unknown parameter (%s)", strPath.c_str()); return strPath; } }
AddonPtr CAddonMgr::Factory(const cp_extension_t *props) { if (!PlatformSupportsAddon(props->plugin)) return AddonPtr(); /* Check if user directories need to be created */ const cp_cfg_element_t *settings = GetExtElement(props->configuration, "settings"); if (settings) CheckUserDirs(settings); const TYPE type = TranslateType(props->ext_point_id); switch (type) { case ADDON_PLUGIN: case ADDON_SCRIPT: return AddonPtr(new CPluginSource(props)); case ADDON_SCRIPT_LIBRARY: case ADDON_SCRIPT_LYRICS: case ADDON_SCRIPT_SUBTITLES: case ADDON_SCRIPT_MODULE: case ADDON_WEB_INTERFACE: return AddonPtr(new CAddon(props)); case ADDON_SCRIPT_WEATHER: { // Eden (API v2.0) broke old weather add-ons AddonPtr result(new CAddon(props)); AddonVersion ver1 = AddonVersion(GetXbmcApiVersionDependency(result)); AddonVersion ver2 = AddonVersion("2.0"); if (ver1 < ver2) { CLog::Log(LOGINFO,"%s: Weather add-ons for api < 2.0 unsupported (%s)",__FUNCTION__,result->ID().c_str()); return AddonPtr(); } return result; } case ADDON_SERVICE: return AddonPtr(new CService(props)); case ADDON_SCRAPER_ALBUMS: case ADDON_SCRAPER_ARTISTS: case ADDON_SCRAPER_MOVIES: case ADDON_SCRAPER_MUSICVIDEOS: case ADDON_SCRAPER_TVSHOWS: case ADDON_SCRAPER_LIBRARY: return AddonPtr(new CScraper(props)); case ADDON_VIZ: case ADDON_SCREENSAVER: { // begin temporary platform handling for Dlls // ideally platforms issues will be handled by C-Pluff // this is not an attempt at a solution CStdString value; if (type == ADDON_SCREENSAVER && 0 == strnicmp(props->plugin->identifier, "screensaver.xbmc.builtin.", 25)) { // built in screensaver return AddonPtr(new CAddon(props)); } #if defined(_LINUX) && !defined(__APPLE__) if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_linux")) && value.empty()) break; #elif defined(_WIN32) && defined(HAS_SDL_OPENGL) if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_wingl")) && value.empty()) break; #elif defined(_WIN32) && defined(HAS_DX) if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_windx")) && value.empty()) break; #elif defined(__APPLE__) if ((value = GetExtValue(props->plugin->extensions->configuration, "@library_osx")) && value.empty()) break; #endif if (type == ADDON_VIZ) { #if defined(HAS_VISUALISATION) return AddonPtr(new CVisualisation(props)); #endif } else return AddonPtr(new CScreenSaver(props)); } case ADDON_SKIN: return AddonPtr(new CSkinInfo(props)); case ADDON_VIZ_LIBRARY: return AddonPtr(new CAddonLibrary(props)); case ADDON_REPOSITORY: return AddonPtr(new CRepository(props)); default: break; } return AddonPtr(); }
bool CMusicInfoScanner::DownloadAlbumInfo(const CStdString& strPath, const CStdString& strArtist, const CStdString& strAlbum, bool& bCanceled, CMusicAlbumInfo& albumInfo, CGUIDialogProgress* pDialog) { CAlbum album; VECSONGS songs; XFILE::MUSICDATABASEDIRECTORY::CQueryParams params; XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(strPath, params); bCanceled = false; m_musicDatabase.Open(); if (m_musicDatabase.HasAlbumInfo(params.GetAlbumId()) && m_musicDatabase.GetAlbumInfo(params.GetAlbumId(),album,&songs)) return true; // find album info ADDON::ScraperPtr info; if (!m_musicDatabase.GetScraperForPath(strPath, info, ADDON::ADDON_SCRAPER_ALBUMS) || !info) { m_musicDatabase.Close(); return false; } if (m_pObserver) { m_pObserver->OnStateChanged(DOWNLOADING_ALBUM_INFO); m_pObserver->OnDirectoryChanged(strAlbum); } // clear our scraper cache info->ClearCache(); CMusicInfoScraper scraper(info); // handle nfo files CStdString strAlbumPath, strNfo; m_musicDatabase.GetAlbumPath(params.GetAlbumId(),strAlbumPath); URIUtils::AddFileToFolder(strAlbumPath,"album.nfo",strNfo); CNfoFile::NFOResult result=CNfoFile::NO_NFO; CNfoFile nfoReader; if (XFILE::CFile::Exists(strNfo)) { CLog::Log(LOGDEBUG,"Found matching nfo file: %s", strNfo.c_str()); result = nfoReader.Create(strNfo, info, -1, strPath); if (result == CNfoFile::FULL_NFO) { CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__); CAlbum album; nfoReader.GetDetails(album); m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, album.songs); GetAlbumArtwork(params.GetAlbumId(), album); m_musicDatabase.Close(); return true; } else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO) { CScraperUrl scrUrl(nfoReader.ScraperUrl()); CMusicAlbumInfo album("nfo",scrUrl); info = nfoReader.GetScraperInfo(); CLog::Log(LOGDEBUG,"-- nfo-scraper: %s",info->Name().c_str()); CLog::Log(LOGDEBUG,"-- nfo url: %s", scrUrl.m_url[0].m_url.c_str()); scraper.SetScraperInfo(info); scraper.GetAlbums().push_back(album); } else CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.CheckValidOrFallback(g_guiSettings.GetString("musiclibrary.albumsscraper"))) { // the current scraper is invalid, as is the default - bail CLog::Log(LOGERROR, "%s - current and default scrapers are invalid. Pick another one", __FUNCTION__); return false; } if (!scraper.GetAlbumCount()) scraper.FindAlbumInfo(strAlbum, strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); bCanceled = true; } Sleep(1); } CGUIDialogSelect *pDlg=NULL; int iSelectedAlbum=0; if (result == CNfoFile::NO_NFO) { iSelectedAlbum = -1; // set negative so that we can detect a failure if (scraper.Succeeded() && scraper.GetAlbumCount() >= 1) { int bestMatch = -1; double bestRelevance = 0; double minRelevance = THRESHOLD; if (scraper.GetAlbumCount() > 1) // score the matches { //show dialog with all albums found if (pDialog) { pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); pDlg->SetHeading(g_localizeStrings.Get(181).c_str()); pDlg->Reset(); pDlg->EnableButton(true, 413); // manual } for (int i = 0; i < scraper.GetAlbumCount(); ++i) { CMusicAlbumInfo& info = scraper.GetAlbum(i); double relevance = info.GetRelevance(); if (relevance < 0) relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, strAlbum, info.GetAlbum().strArtist, strArtist); // if we're doing auto-selection (ie querying all albums at once, then allow 95->100% for perfect matches) // otherwise, perfect matches only if (relevance >= max(minRelevance, bestRelevance)) { // we auto-select the best of these bestRelevance = relevance; bestMatch = i; } if (pDialog) { // set the label to [relevance] album - artist CStdString strTemp; strTemp.Format("[%0.2f] %s", relevance, info.GetTitle2()); CFileItem item(strTemp); item.m_idepth = i; // use this to hold the index of the album in the scraper pDlg->Add(&item); } if (relevance > .99f) // we're so close, no reason to search further break; } } else { CMusicAlbumInfo& info = scraper.GetAlbum(0); double relevance = info.GetRelevance(); if (relevance < 0) relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, strAlbum, info.GetAlbum().strArtist, strArtist); if (relevance < THRESHOLD) { m_musicDatabase.Close(); return false; } bestRelevance = relevance; bestMatch = 0; } iSelectedAlbum = bestMatch; if (pDialog && bestRelevance < THRESHOLD) { pDlg->Sort(false); pDlg->DoModal(); // and wait till user selects one if (pDlg->GetSelectedLabel() < 0) { // none chosen if (!pDlg->IsButtonPressed()) { bCanceled = true; return false; } // manual button pressed CStdString strNewAlbum = strAlbum; if (!CGUIDialogKeyboard::ShowAndGetInput(strNewAlbum, g_localizeStrings.Get(16011), false)) return false; if (strNewAlbum == "") return false; CStdString strNewArtist = strArtist; if (!CGUIDialogKeyboard::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return false; pDialog->SetLine(0, strNewAlbum); pDialog->SetLine(1, strNewArtist); pDialog->Progress(); m_musicDatabase.Close(); return DownloadAlbumInfo(strPath,strNewArtist,strNewAlbum,bCanceled,albumInfo,pDialog); } iSelectedAlbum = pDlg->GetSelectedItem().m_idepth; } } if (iSelectedAlbum < 0) { m_musicDatabase.Close(); return false; } } scraper.LoadAlbumInfo(iSelectedAlbum); while (!scraper.Completed()) { if (m_bStop) { bCanceled = true; scraper.Cancel(); } Sleep(1); } if (scraper.Succeeded()) { albumInfo = scraper.GetAlbum(iSelectedAlbum); album = scraper.GetAlbum(iSelectedAlbum).GetAlbum(); if (result == CNfoFile::COMBINED_NFO) nfoReader.GetDetails(album); m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, scraper.GetAlbum(iSelectedAlbum).GetSongs(),false); } else { m_musicDatabase.Close(); return false; } // check thumb stuff GetAlbumArtwork(params.GetAlbumId(), album); m_musicDatabase.Close(); return true; }
static void ParseItem(CFileItem* item, TiXmlElement* root, const CStdString& path) { SResources resources; ParseItem(item, resources, root, path); const char* prio[] = { "media:content", "voddler:trailer", "rss:enclosure", "svtplay:broadcasts", "svtplay:xmllink", "rss:link", "rss:guid", NULL }; CStdString mime; if (FindMime(resources, "video/")) mime = "video/"; else if(FindMime(resources, "audio/")) mime = "audio/"; else if(FindMime(resources, "application/rss")) mime = "application/rss"; else if(FindMime(resources, "image/")) mime = "image/"; int maxrate = g_guiSettings.GetInt("network.bandwidth"); if(maxrate == 0) maxrate = INT_MAX; SResources::iterator best = resources.end(); for(const char** type = prio; *type && best == resources.end(); type++) { for(SResources::iterator it = resources.begin(); it != resources.end(); it++) { if(it->mime.Left(mime.length()) != mime) continue; if(it->tag == *type) { if(best == resources.end()) { best = it; continue; } if(it->bitrate == best->bitrate) { if(it->width*it->height > best->width*best->height) best = it; continue; } if(it->bitrate > maxrate) { if(it->bitrate < best->bitrate) best = it; continue; } if(it->bitrate > best->bitrate) { best = it; continue; } } } } if(best != resources.end()) { item->SetMimeType(best->mime); item->SetPath(best->path); item->m_dwSize = best->size; if(best->duration) item->SetProperty("duration", StringUtils::SecondsToTimeString(best->duration)); /* handling of mimetypes fo directories are sub optimal at best */ if(best->mime == "application/rss+xml" && item->GetPath().Left(7).Equals("http://")) item->SetPath("rss://" + item->GetPath().Mid(7)); if(item->GetPath().Left(6).Equals("rss://")) item->m_bIsFolder = true; else item->m_bIsFolder = false; } if(!item->m_strTitle.IsEmpty()) item->SetLabel(item->m_strTitle); if(item->HasVideoInfoTag()) { CVideoInfoTag* vtag = item->GetVideoInfoTag(); if(item->HasProperty("duration") && vtag->m_strRuntime.IsEmpty()) vtag->m_strRuntime = item->GetProperty("duration").asString(); if(item->HasProperty("description") && vtag->m_strPlot.IsEmpty()) vtag->m_strPlot = item->GetProperty("description").asString(); if(vtag->m_strPlotOutline.IsEmpty() && !vtag->m_strPlot.IsEmpty()) { int pos = vtag->m_strPlot.Find('\n'); if(pos >= 0) vtag->m_strPlotOutline = vtag->m_strPlot.Left(pos); else vtag->m_strPlotOutline = vtag->m_strPlot; } if(!vtag->m_strRuntime.IsEmpty()) item->SetLabel2(vtag->m_strRuntime); } }
void TempFolderHelper::RemoveFolder(CStdString sFolder) { if(!CGeneral::RemoveDir(sFolder.c_str())) ThrowException(_T("Failed to delete temporary managed folder"), -1); }
bool CMultiPathDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CLog::Log(LOGDEBUG,"CMultiPathDirectory::GetDirectory(%s)", strPath.c_str()); vector<CStdString> vecPaths; if (!GetPaths(strPath, vecPaths)) return false; XbmcThreads::EndTime progressTime(3000); // 3 seconds before showing progress bar CGUIDialogProgress* dlgProgress = NULL; unsigned int iFailures = 0; for (unsigned int i = 0; i < vecPaths.size(); ++i) { // show the progress dialog if we have passed our time limit if (progressTime.IsTimePast() && !dlgProgress) { dlgProgress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); if (dlgProgress) { dlgProgress->SetHeading(15310); dlgProgress->SetLine(0, 15311); dlgProgress->SetLine(1, ""); dlgProgress->SetLine(2, ""); dlgProgress->StartModal(); dlgProgress->ShowProgressBar(true); dlgProgress->SetProgressMax((int)vecPaths.size()*2); dlgProgress->Progress(); } } if (dlgProgress) { CURL url(vecPaths[i]); dlgProgress->SetLine(1, url.GetWithoutUserDetails()); dlgProgress->SetProgressAdvance(); dlgProgress->Progress(); } CFileItemList tempItems; CLog::Log(LOGDEBUG,"Getting Directory (%s)", vecPaths[i].c_str()); if (CDirectory::GetDirectory(vecPaths[i], tempItems, m_strFileMask, m_useFileDirectories, m_allowPrompting, m_cacheDirectory, m_extFileInfo)) items.Append(tempItems); else { CLog::Log(LOGERROR,"Error Getting Directory (%s)", vecPaths[i].c_str()); iFailures++; } if (dlgProgress) { dlgProgress->SetProgressAdvance(); dlgProgress->Progress(); } } if (dlgProgress) dlgProgress->Close(); if (iFailures == vecPaths.size()) return false; // merge like-named folders into a sub multipath:// style url MergeItems(items); return true; }
CStdString Xcddb::GetCacheFile(unsigned int disc_id) const { CStdString strFileName; strFileName.Format("%x.cddb", disc_id); return URIUtils::AddFileToFolder(cCacheDir, strFileName); }
void CMusicInfoScraper::FindAlbuminfo() { CStdString strAlbum=m_strAlbum; CStdString strHTML; m_vecAlbums.erase(m_vecAlbums.begin(), m_vecAlbums.end()); CScraperParser parser; if (!parser.Load(_P("q:\\system\\scrapers\\music\\"+m_info.strPath))) return; if (!m_info.settings.GetPluginRoot() || m_info.settings.GetSettings().IsEmpty()) { m_info.settings.LoadSettingsXML(_P("q:\\system\\scrapers\\music\\"+m_info.strPath)); m_info.settings.SaveFromDefault(); } parser.m_param[0] = strAlbum; parser.m_param[1] = m_strArtist; CUtil::URLEncode(parser.m_param[0]); CUtil::URLEncode(parser.m_param[1]); CScraperUrl scrURL; scrURL.ParseString(parser.Parse("CreateAlbumSearchUrl")); if (!CScraperUrl::Get(scrURL.m_url[0], strHTML, m_http) || strHTML.size() == 0) { CLog::Log(LOGERROR, "%s: Unable to retrieve web site",__FUNCTION__); return; } parser.m_param[0] = strHTML; CStdString strXML = parser.Parse("GetAlbumSearchResults",&m_info.settings); if (strXML.IsEmpty()) { CLog::Log(LOGERROR, "%s: Unable to parse web site",__FUNCTION__); return; } if (strXML.Find("encoding=\"utf-8\"") < 0) g_charsetConverter.stringCharsetToUtf8(strXML); // ok, now parse the xml file TiXmlDocument doc; doc.Parse(strXML.c_str(),0,TIXML_ENCODING_UTF8); if (!doc.RootElement()) { CLog::Log(LOGERROR, "%s: Unable to parse xml",__FUNCTION__); return; } TiXmlHandle docHandle( &doc ); TiXmlElement* album = docHandle.FirstChild( "results" ).FirstChild( "entity" ).Element(); if (!album) return; while (album) { TiXmlNode* title = album->FirstChild("title"); TiXmlElement* link = album->FirstChildElement("url"); TiXmlNode* artist = album->FirstChild("artist"); TiXmlNode* year = album->FirstChild("year"); if (title && title->FirstChild()) { CStdString strTitle = title->FirstChild()->Value(); CStdString strArtist; CStdString strAlbumName; if (artist && artist->FirstChild()) { strArtist = artist->FirstChild()->Value(); strAlbumName.Format("%s - %s",strArtist.c_str(),strTitle.c_str()); } else strAlbumName = strTitle; if (year && year->FirstChild()) strAlbumName.Format("%s (%s)",strAlbumName.c_str(),year->FirstChild()->Value()); CScraperUrl url; if (!link) url.ParseString(scrURL.m_xml); while (link && link->FirstChild()) { url.ParseElement(link); link = link->NextSiblingElement("url"); } CMusicAlbumInfo newAlbum(strTitle, strArtist, strAlbumName, url); m_vecAlbums.push_back(newAlbum); } album = album->NextSiblingElement(); } if (m_vecAlbums.size()>0) m_bSuccessfull=true; return; }
//------------------------------------------------------------------------------------------------------------------- bool Xcddb::queryCDinfo(CCdInfo* pInfo) { if ( pInfo == NULL ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo pInfo == NULL"); m_lastError = E_PARAMETER_WRONG; return false; } int lead_out = pInfo->GetTrackCount(); int real_track_count = pInfo->GetTrackCount(); unsigned long discid = pInfo->GetCddbDiscId(); unsigned long frames[100]; //########################################################## // if ( queryCache(discid) ) { CLog::Log(LOGDEBUG, "Xcddb::queryCDinfo discid [%08lx] already cached", discid); return true; } //########################################################## // for (int i = 0;i < lead_out;i++) { frames[i] = pInfo->GetTrackInformation( i + 1 ).nFrames; if (i > 0 && frames[i] < frames[i - 1]) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo E_TOC_INCORRECT"); m_lastError = E_TOC_INCORRECT; return false; } } unsigned long complete_length = pInfo->GetDiscLength(); //########################################################## // Open socket to cddb database if ( !openSocket() ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error opening socket"); m_lastError = E_NETWORK_ERROR_OPEN_SOCKET; return false; } CStdString recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //OK, read/write allowed case 201: //OK, read only break; case 432: //No connections allowed: permission denied case 433: //No connections allowed: X users allowed, Y currently active case 434: //No connections allowed: system load too high default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Send the Hello message CStdString strGreeting = "cddb hello xbmc xbmc XBMC/"+g_infoManager.GetLabel(SYSTEM_BUILD_VERSION); if ( ! Send(strGreeting.c_str()) ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", strGreeting.c_str()); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //Handshake successful case 402: //Already shook hands break; case 431: //Handshake not successful, closing connection default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Set CDDB protocol-level to 5 if ( ! Send("proto 5")) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", "proto 5"); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //CDDB protocol level: current cur_level, supported supp_level case 201: //OK, protocol version now: cur_level case 502: //Protocol level already cur_level break; case 501: //Illegal protocol level. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Compose the cddb query string char query_buffer[1024]; strcpy(query_buffer, ""); strcat(query_buffer, "cddb query"); { char tmp_buffer[256]; sprintf(tmp_buffer, " %08lx", discid); strcat(query_buffer, tmp_buffer); } { char tmp_buffer[256]; sprintf(tmp_buffer, " %i", real_track_count); strcat(query_buffer, tmp_buffer); } for (int i = 0;i < lead_out;i++) { char tmp_buffer[256]; sprintf(tmp_buffer, " %lu", frames[i]); strcat(query_buffer, tmp_buffer); } { char tmp_buffer[256]; sprintf(tmp_buffer, " %lu", complete_length); strcat(query_buffer, tmp_buffer); } //########################################################## // Query for matches if ( ! Send(query_buffer)) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", query_buffer); m_lastError = E_NETWORK_ERROR_SEND; return false; } // 200 rock d012180e Soundtrack / Hackers CStdString read_buffer; recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 200: //Found exact match strtok((char *)recv_buffer.c_str(), " "); read_buffer.Format("cddb read %s %08x", strtok(NULL, " "), discid); break; case 210: //Found exact matches, list follows (until terminating marker) case 211: //Found inexact matches, list follows (until terminating marker) /* soundtrack bf0cf90f Modern Talking / Victory - The 11th Album rock c90cf90f Modern Talking / Album: Victory (The 11th Album) misc de0d020f Modern Talking / Ready for the victory rock e00d080f Modern Talking / Album: Victory (The 11th Album) rock c10d150f Modern Talking / Victory (The 11th Album) . */ recv_buffer += Recv(true); addInexactList(recv_buffer.c_str()); m_lastError=E_WAIT_FOR_INPUT; return false; //This is actually good. The calling method will handle this case 202: //No match found CLog::Log(LOGNOTICE, "Xcddb::queryCDinfo No match found in CDDB database when doing the query shown below:\n%s",query_buffer); case 403: //Database entry is corrupt case 409: //No handshake default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Read the data from cddb if ( !Send(read_buffer) ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", read_buffer.c_str()); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(true); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 210: //OK, CDDB database entry follows (until terminating marker) // Cool, I got it ;-) writeCacheFile( recv_buffer.c_str(), discid ); parseData(recv_buffer.c_str()); break; case 401: //Specified CDDB entry not found. case 402: //Server error. case 403: //Database entry is corrupt. case 409: //No handshake. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Quit if ( ! Send("quit") ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error sending \"%s\"", "quit"); m_lastError = E_NETWORK_ERROR_SEND; return false; } recv_buffer = Recv(false); m_lastError = atoi(recv_buffer.c_str()); switch(m_lastError) { case 0: //By some reason, also 0 is a valid value. This is not documented, and might depend on that no string was found and atoi then returns 0 case 230: //Closing connection. Goodbye. break; case 530: //error, closing connection. default: CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error: \"%s\"", recv_buffer.c_str()); return false; } //########################################################## // Close connection if ( !closeSocket() ) { CLog::Log(LOGERROR, "Xcddb::queryCDinfo Error closing socket"); m_lastError = E_NETWORK_ERROR_SEND; return false; } return true; }
CStdString DvSaveFormatConverter::NormaliseExtension(CStdString sExtension) { sExtension.TrimLeft(L'.'); sExtension.Normalize(); return sExtension; }
CStdString CGUIDialogAudioSubtitleSettings::PercentAsDecibel(float value, float interval) { CStdString text; text.Format("%2.1f dB", CAEUtil::PercentToGain(value)); return text; }
void CGUIWindow::SetProperty(const CStdString &key, double value) { CStdString strVal; strVal.Format("%f", value); SetProperty(key, strVal); }
void CAnimation::Create(const TiXmlElement *node, const FRECT &rect) { if (!node || !node->FirstChild()) return; // conditions and reversibility const char *condition = node->Attribute("condition"); if (condition) m_condition = g_infoManager.TranslateString(condition); const char *reverse = node->Attribute("reversible"); if (reverse && strcmpi(reverse, "false") == 0) m_reversible = false; const TiXmlElement *effect = node->FirstChildElement("effect"); CStdString type = node->FirstChild()->Value(); m_type = ANIM_TYPE_CONDITIONAL; if (effect) // new layout type = node->Attribute("type"); if (type.Left(7).Equals("visible")) m_type = ANIM_TYPE_VISIBLE; else if (type.Equals("hidden")) m_type = ANIM_TYPE_HIDDEN; else if (type.Equals("focus")) m_type = ANIM_TYPE_FOCUS; else if (type.Equals("unfocus")) m_type = ANIM_TYPE_UNFOCUS; else if (type.Equals("windowopen")) m_type = ANIM_TYPE_WINDOW_OPEN; else if (type.Equals("windowclose")) m_type = ANIM_TYPE_WINDOW_CLOSE; // sanity check if (m_type == ANIM_TYPE_CONDITIONAL) { if (!m_condition) { CLog::Log(LOGERROR, "Control has invalid animation type (no condition or no type)"); return; } // pulsed or loop animations const char *pulse = node->Attribute("pulse"); if (pulse && strcmpi(pulse, "true") == 0) m_repeatAnim = ANIM_REPEAT_PULSE; const char *loop = node->Attribute("loop"); if (loop && strcmpi(loop, "true") == 0) m_repeatAnim = ANIM_REPEAT_LOOP; } m_delay = 0xffffffff; if (!effect) { // old layout: // <animation effect="fade" start="0" end="100" delay="10" time="2000" condition="blahdiblah" reversible="false">focus</animation> CStdString type = node->Attribute("effect"); AddEffect(type, node, rect); } while (effect) { // new layout: // <animation type="focus" condition="blahdiblah" reversible="false"> // <effect type="fade" start="0" end="100" delay="10" time="2000" /> // ... // </animation> CStdString type = effect->Attribute("type"); AddEffect(type, effect, rect); effect = effect->NextSiblingElement("effect"); } }
bool CMusicInfoScanner::DoScan(const CStdString& strDirectory) { if (m_pObserver) m_pObserver->OnDirectoryChanged(strDirectory); /* * remove this path from the list we're processing. This must be done prior to * the check for file or folder exclusion to prevent an infinite while loop * in Process(). */ set<CStdString>::iterator it = m_pathsToScan.find(strDirectory); if (it != m_pathsToScan.end()) m_pathsToScan.erase(it); // Discard all excluded files defined by m_musicExcludeRegExps CStdStringArray regexps = g_advancedSettings.m_audioExcludeFromScanRegExps; if (CUtil::ExcludeFileOrFolder(strDirectory, regexps)) return true; // load subfolder CFileItemList items; CDirectory::GetDirectory(strDirectory, items, g_settings.m_musicExtensions + "|.jpg|.tbn|.lrc|.cdg"); // sort and get the path hash. Note that we don't filter .cue sheet items here as we want // to detect changes in the .cue sheet as well. The .cue sheet items only need filtering // if we have a changed hash. items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); CStdString hash; GetPathHash(items, hash); // get the folder's thumb (this will cache the album thumb). items.SetMusicThumb(true); // true forces it to get a remote thumb // check whether we need to rescan or not CStdString dbHash; if (!m_musicDatabase.GetPathHash(strDirectory, dbHash) || dbHash != hash) { // path has changed - rescan if (dbHash.IsEmpty()) CLog::Log(LOGDEBUG, "%s Scanning dir '%s' as not in the database", __FUNCTION__, strDirectory.c_str()); else CLog::Log(LOGDEBUG, "%s Rescanning dir '%s' due to change", __FUNCTION__, strDirectory.c_str()); // filter items in the sub dir (for .cue sheet support) items.FilterCueItems(); items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); // and then scan in the new information if (RetrieveMusicInfo(items, strDirectory) > 0) { if (m_pObserver) m_pObserver->OnDirectoryScanned(strDirectory); } // save information about this folder m_musicDatabase.SetPathHash(strDirectory, hash); } else { // path is the same - no need to rescan CLog::Log(LOGDEBUG, "%s Skipping dir '%s' due to no change", __FUNCTION__, strDirectory.c_str()); m_currentItem += CountFiles(items, false); // false for non-recursive // notify our observer of our progress if (m_pObserver) { if (m_itemCount>0) m_pObserver->OnSetProgress(m_currentItem, m_itemCount); m_pObserver->OnDirectoryScanned(strDirectory); } } // now scan the subfolders for (int i = 0; i < items.Size(); ++i) { CFileItemPtr pItem = items[i]; if (m_bStop) break; // if we have a directory item (non-playlist) we then recurse into that folder if (pItem->m_bIsFolder && !pItem->IsParentFolder() && !pItem->IsPlayList()) { CStdString strPath=pItem->m_strPath; if (!DoScan(strPath)) { m_bStop = true; } } } return !m_bStop; }
// Android apk directory i/o. Depends on libzip // Basically the same format as zip. // We might want to refactor CZipDirectory someday... ////////////////////////////////////////////////////////////////////// bool CAPKDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { // uses a <fully qualified path>/filename.apk/... CURL url(strPath); CStdString path = url.GetFileName(); CStdString host = url.GetHostName(); URIUtils::AddSlashAtEnd(path); // host name might be encoded rfc1738.txt, decode it. CURL::Decode(host); int zip_flags = 0, zip_error = 0, dir_marker = 0; struct zip *zip_archive; zip_archive = zip_open(host.c_str(), zip_flags, &zip_error); if (!zip_archive || zip_error) { CLog::Log(LOGERROR, "CAPKDirectory::GetDirectory: Unable to open archive : '%s'", host.c_str()); return false; } CStdString test_name; int numFiles = zip_get_num_files(zip_archive); for (int zip_index = 0; zip_index < numFiles; zip_index++) { test_name = zip_get_name(zip_archive, zip_index, zip_flags); // check for non matching path. if (!test_name.Left(path.size()).Equals(path)) continue; // libzip does not index folders, only filenames. We search for a /, // add it if it's not in our list already, and hope that no one has // any "file/name.exe" files in a zip. dir_marker = test_name.Find('/', path.size() + 1); if (dir_marker > 0) { // return items relative to path test_name=test_name.Left(dir_marker); if (items.Contains(host + "/" + test_name)) continue; } struct zip_stat sb; zip_stat_init(&sb); if (zip_stat_index(zip_archive, zip_index, zip_flags, &sb) != -1) { g_charsetConverter.unknownToUTF8(test_name); CFileItemPtr pItem(new CFileItem(test_name)); pItem->m_dwSize = sb.size; pItem->m_dateTime = sb.mtime; pItem->m_bIsFolder = dir_marker > 0 ; pItem->SetPath(host + "/" + test_name); pItem->SetLabel(test_name.Right(test_name.size() - path.size())); items.Add(pItem); } } zip_close(zip_archive); return true; }
int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString& strDirectory) { CSongMap songsMap; // get all information for all files in current directory from database, and remove them if (m_musicDatabase.RemoveSongsFromPath(strDirectory, songsMap)) m_needsCleanup = true; VECSONGS songsToAdd; CStdStringArray regexps = g_advancedSettings.m_audioExcludeFromScanRegExps; // for every file found, but skip folder for (int i = 0; i < items.Size(); ++i) { CFileItemPtr pItem = items[i]; CStdString strExtension; URIUtils::GetExtension(pItem->m_strPath, strExtension); if (m_bStop) return 0; // Discard all excluded files defined by m_musicExcludeRegExps if (CUtil::ExcludeFileOrFolder(pItem->m_strPath, regexps)) continue; // dont try reading id3tags for folders, playlists or shoutcast streams if (!pItem->m_bIsFolder && !pItem->IsPlayList() && !pItem->IsPicture() && !pItem->IsLyrics() ) { m_currentItem++; // CLog::Log(LOGDEBUG, "%s - Reading tag for: %s", __FUNCTION__, pItem->m_strPath.c_str()); // grab info from the song CSong *dbSong = songsMap.Find(pItem->m_strPath); CMusicInfoTag& tag = *pItem->GetMusicInfoTag(); if (!tag.Loaded() ) { // read the tag from a file auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(pItem->m_strPath)); if (NULL != pLoader.get()) pLoader->Load(pItem->m_strPath, tag); } // if we have the itemcount, notify our // observer with the progress we made if (m_pObserver && m_itemCount>0) m_pObserver->OnSetProgress(m_currentItem, m_itemCount); if (tag.Loaded()) { CSong song(tag); // ensure our song has a valid filename or else it will assert in AddSong() if (song.strFileName.IsEmpty()) { // copy filename from path in case UPnP or other tag loaders didn't specify one (FIXME?) song.strFileName = pItem->m_strPath; // if we still don't have a valid filename, skip the song if (song.strFileName.IsEmpty()) { // this shouldn't ideally happen! CLog::Log(LOGERROR, "Skipping song since it doesn't seem to have a filename"); continue; } } song.iStartOffset = pItem->m_lStartOffset; song.iEndOffset = pItem->m_lEndOffset; if (dbSong) { // keep the db-only fields intact on rescan... song.iTimesPlayed = dbSong->iTimesPlayed; song.lastPlayed = dbSong->lastPlayed; song.iKaraokeNumber = dbSong->iKaraokeNumber; if (song.rating == '0') song.rating = dbSong->rating; } pItem->SetMusicThumb(); song.strThumb = pItem->GetThumbnailImage(); songsToAdd.push_back(song); // CLog::Log(LOGDEBUG, "%s - Tag loaded for: %s", __FUNCTION__, pItem->m_strPath.c_str()); } else CLog::Log(LOGDEBUG, "%s - No tag found for: %s", __FUNCTION__, pItem->m_strPath.c_str()); } } CheckForVariousArtists(songsToAdd); if (!items.HasThumbnail()) UpdateFolderThumb(songsToAdd, items.m_strPath); // finally, add these to the database set<CStdString> artistsToScan; set< pair<CStdString, CStdString> > albumsToScan; m_musicDatabase.BeginTransaction(); for (unsigned int i = 0; i < songsToAdd.size(); ++i) { if (m_bStop) { m_musicDatabase.RollbackTransaction(); return i; } CSong &song = songsToAdd[i]; m_musicDatabase.AddSong(song, false); artistsToScan.insert(song.strArtist); albumsToScan.insert(make_pair(song.strAlbum, song.strArtist)); } m_musicDatabase.CommitTransaction(); bool bCanceled; for (set<CStdString>::iterator i = artistsToScan.begin(); i != artistsToScan.end(); ++i) { bCanceled = false; long iArtist = m_musicDatabase.GetArtistByName(*i); if (find(m_artistsScanned.begin(),m_artistsScanned.end(),iArtist) == m_artistsScanned.end()) { m_artistsScanned.push_back(iArtist); if (!m_bStop && g_guiSettings.GetBool("musiclibrary.downloadinfo")) { CStdString strPath; strPath.Format("musicdb://2/%u/",iArtist); if (!DownloadArtistInfo(strPath,*i, bCanceled)) // assume we want to retry m_artistsScanned.pop_back(); } else GetArtistArtwork(iArtist, *i); } } if (g_guiSettings.GetBool("musiclibrary.downloadinfo")) { for (set< pair<CStdString, CStdString> >::iterator i = albumsToScan.begin(); i != albumsToScan.end(); ++i) { if (m_bStop) return songsToAdd.size(); long iAlbum = m_musicDatabase.GetAlbumByName(i->first, i->second); CStdString strPath; strPath.Format("musicdb://3/%u/",iAlbum); bCanceled = false; if (find(m_albumsScanned.begin(), m_albumsScanned.end(), iAlbum) == m_albumsScanned.end()) { CMusicAlbumInfo albumInfo; if (DownloadAlbumInfo(strPath, i->second, i->first, bCanceled, albumInfo)) m_albumsScanned.push_back(iAlbum); } } } if (m_pObserver) m_pObserver->OnStateChanged(READING_MUSIC_INFO); return songsToAdd.size(); }
bool CGUIDialogPVRChannelManager::OnMessage(CGUIMessage& message) { unsigned int iControl = 0; unsigned int iMessage = message.GetMessage(); switch (iMessage) { case GUI_MSG_WINDOW_DEINIT: { Clear(); } break; case GUI_MSG_WINDOW_INIT: { CGUIWindow::OnMessage(message); m_iSelected = 0; m_bIsRadio = false; m_bMovingMode = false; m_bContainsChanges = false; SetProperty("IsRadio", ""); Update(); SetData(m_iSelected); return true; } break; case GUI_MSG_CLICKED: { iControl = message.GetSenderId(); if (iControl == CONTROL_LIST_CHANNELS) { if (!m_bMovingMode) { int iAction = message.GetParam1(); int iItem = m_viewControl.GetSelectedItem(); /* Check file item is in list range and get his pointer */ if (iItem < 0 || iItem >= (int)m_channelItems->Size()) return true; /* Process actions */ if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK) { /* Show Contextmenu */ OnPopupMenu(iItem); } } else { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (pItem) { pItem->SetProperty("Changed", true); pItem->Select(false); m_bMovingMode = false; m_bContainsChanges = true; return true; } else return false; } } else if (iControl == BUTTON_OK) { SaveList(); Close(); return true; } else if (iControl == BUTTON_APPLY) { SaveList(); return true; } else if (iControl == BUTTON_CANCEL) { Close(); return true; } else if (iControl == BUTTON_RADIO_TV) { if (m_bContainsChanges) { // prompt user for confirmation of channel record CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); if (!pDialog) return true; pDialog->SetHeading(20052); pDialog->SetLine(0, ""); pDialog->SetLine(1, 19212); pDialog->SetLine(2, 20103); pDialog->DoModal(); if (pDialog->IsConfirmed()) SaveList(); } m_iSelected = 0; m_bMovingMode = false; m_bContainsChanges = false; m_bIsRadio = !m_bIsRadio; SetProperty("IsRadio", m_bIsRadio ? "true" : ""); Update(); SetData(m_iSelected); return true; } else if (iControl == RADIOBUTTON_ACTIVE) { CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_ACTIVE); if (pRadioButton) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (pItem) { pItem->SetProperty("Changed", true); pItem->SetProperty("ActiveChannel", pRadioButton->IsSelected()); m_bContainsChanges = true; Renumber(); } } } else if (iControl == EDIT_NAME) { CGUIEditControl *pEdit = (CGUIEditControl *)GetControl(EDIT_NAME); if (pEdit) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (pItem) { pItem->SetProperty("Changed", true); pItem->SetProperty("Name", pEdit->GetLabel2()); m_bContainsChanges = true; } } } else if (iControl == BUTTON_CHANNEL_LOGO) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (!pItem) return false; if (g_settings.GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; else if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; // setup our thumb list CFileItemList items; // add the current thumb, if available if (!pItem->GetProperty("Icon").IsEmpty()) { CFileItemPtr current(new CFileItem("thumb://Current", false)); current->SetThumbnailImage(pItem->GetPVRChannelInfoTag()->IconPath()); current->SetLabel(g_localizeStrings.Get(20016)); items.Add(current); } else if (pItem->HasThumbnail()) { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it. CFileItemPtr current(new CFileItem("thumb://Current", false)); current->SetThumbnailImage(pItem->GetThumbnailImage()); current->SetLabel(g_localizeStrings.Get(20016)); items.Add(current); } // and add a "no thumb" entry as well CFileItemPtr nothumb(new CFileItem("thumb://None", false)); nothumb->SetIconImage(pItem->GetIconImage()); nothumb->SetLabel(g_localizeStrings.Get(20018)); items.Add(nothumb); CStdString strThumb; VECSOURCES shares; if (g_guiSettings.GetString("pvrmenu.iconpath") != "") { CMediaSource share1; share1.strPath = g_guiSettings.GetString("pvrmenu.iconpath"); share1.strName = g_localizeStrings.Get(19018); shares.push_back(share1); } g_mediaManager.GetLocalDrives(shares); if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb)) return false; if (strThumb == "thumb://Current") return true; if (strThumb == "thumb://None") strThumb = ""; pItem->SetProperty("Icon", strThumb); pItem->SetProperty("Changed", true); m_bContainsChanges = true; return true; } else if (iControl == RADIOBUTTON_USEEPG) { CGUIRadioButtonControl *pRadioButton = (CGUIRadioButtonControl *)GetControl(RADIOBUTTON_USEEPG); if (pRadioButton) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (pItem) { pItem->SetProperty("Changed", true); pItem->SetProperty("UseEPG", pRadioButton->IsSelected()); m_bContainsChanges = true; } } } else if (iControl == SPIN_EPGSOURCE_SELECTION) { /// TODO: Add EPG scraper support return true; CGUISpinControlEx *pSpin = (CGUISpinControlEx *)GetControl(SPIN_EPGSOURCE_SELECTION); if (pSpin) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (pItem) { pItem->SetProperty("EPGSource", (int)0); pItem->SetProperty("Changed", true); m_bContainsChanges = true; return true; } } } else if (iControl == BUTTON_GROUP_MANAGER) { /* Load group manager dialog */ CGUIDialogPVRGroupManager* pDlgInfo = (CGUIDialogPVRGroupManager*)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_GROUP_MANAGER); if (!pDlgInfo) return false; pDlgInfo->SetRadio(m_bIsRadio); /* Open dialog window */ pDlgInfo->DoModal(); return true; } else if (iControl == BUTTON_EDIT_CHANNEL) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (!pItem) return false; if (pItem->GetPropertyBOOL("Virtual")) { CStdString strURL = pItem->GetProperty("StreamURL"); if (CGUIDialogKeyboard::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false)) pItem->SetProperty("StreamURL", strURL); return true; } CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); return true; } else if (iControl == BUTTON_DELETE_CHANNEL) { CFileItemPtr pItem = m_channelItems->Get(m_iSelected); if (!pItem) return false; // prompt user for confirmation of channel record CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); if (!pDialog) return true; pDialog->SetHeading(19211); pDialog->SetLine(0, ""); pDialog->SetLine(1, 750); pDialog->SetLine(2, ""); pDialog->DoModal(); if (pDialog->IsConfirmed()) { if (pItem->GetPropertyBOOL("Virtual")) { CPVRDatabase *database = CPVRManager::Get()->GetTVDatabase(); database->Open(); database->Delete(*pItem->GetPVRChannelInfoTag()); database->Close(); m_channelItems->Remove(m_iSelected); m_viewControl.SetItems(*m_channelItems); Renumber(); return true; } CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); } return true; } else if (iControl == BUTTON_NEW_CHANNEL) { std::vector<long> clients; CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!pDlgSelect) return false; pDlgSelect->SetHeading(19213); // Select Client pDlgSelect->Add(g_localizeStrings.Get(19209)); clients.push_back(XBMC_VIRTUAL_CLIENTID); CLIENTMAPITR itr; for (itr = CPVRManager::Get()->Clients()->begin() ; itr != CPVRManager::Get()->Clients()->end(); itr++) { CStdString strClient = (*itr).second->GetBackendName() + ":" + (*itr).second->GetConnectionString(); clients.push_back((*itr).first); pDlgSelect->Add(strClient); } pDlgSelect->DoModal(); int selection = pDlgSelect->GetSelectedLabel(); if (selection >= 0 && selection <= (int) clients.size()) { int clientID = clients[selection]; if (clientID == XBMC_VIRTUAL_CLIENTID) { CStdString strURL = ""; if (CGUIDialogKeyboard::ShowAndGetInput(strURL, g_localizeStrings.Get(19214), false)) { if (!strURL.IsEmpty()) { CPVRChannel newchannel(m_bIsRadio); newchannel.SetChannelName(g_localizeStrings.Get(19204)); newchannel.SetEPGEnabled(false); newchannel.SetVirtual(true); newchannel.SetStreamURL(strURL); newchannel.SetClientID(XBMC_VIRTUAL_CLIENTID); CPVRDatabase *database = CPVRManager::Get()->GetTVDatabase(); database->Open(); database->Persist(newchannel); database->Close(); CFileItemPtr channel(new CFileItem(newchannel)); if (channel) { channel->SetProperty("ActiveChannel", true); channel->SetProperty("Name", g_localizeStrings.Get(19204)); channel->SetProperty("UseEPG", false); channel->SetProperty("Icon", newchannel.IconPath()); channel->SetProperty("EPGSource", (int)0); channel->SetProperty("ClientName", g_localizeStrings.Get(19209)); m_channelItems->AddFront(channel, m_iSelected); m_viewControl.SetItems(*m_channelItems); Renumber(); } } } } else { CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); } } return true; } } break; } return CGUIDialog::OnMessage(message); }
CLinuxTimezone::CLinuxTimezone() : m_IsDST(0) { char* line = NULL; size_t linelen = 0; int nameonfourthfield = 0; CStdString s; vector<CStdString> tokens; // Load timezones FILE* fp = fopen("/usr/share/zoneinfo/zone.tab", "r"); if (fp) { CStdString countryCode; CStdString timezoneName; while (getdelim(&line, &linelen, '\n', fp) > 0) { tokens.clear(); s = line; s.TrimLeft(" \t").TrimRight(" \n"); if (s.length() == 0) continue; if (s[0] == '#') continue; CUtil::Tokenize(s, tokens, " \t"); if (tokens.size() < 3) continue; countryCode = tokens[0]; timezoneName = tokens[2]; if (m_timezonesByCountryCode.count(countryCode) == 0) { vector<CStdString> timezones; timezones.push_back(timezoneName); m_timezonesByCountryCode[countryCode] = timezones; } else { vector<CStdString>& timezones = m_timezonesByCountryCode[countryCode]; timezones.push_back(timezoneName); } m_countriesByTimezoneName[timezoneName] = countryCode; } fclose(fp); } if (line) { free(line); line = NULL; linelen = 0; } // Load countries fp = fopen("/usr/share/zoneinfo/iso3166.tab", "r"); if (!fp) { fp = fopen("/usr/share/misc/iso3166", "r"); nameonfourthfield = 1; } if (fp) { CStdString countryCode; CStdString countryName; while (getdelim(&line, &linelen, '\n', fp) > 0) { s = line; s.TrimLeft(" \t").TrimRight(" \n"); if (s.length() == 0) continue; if (s[0] == '#') continue; // Search for the first non space from the 2nd character and on int i = 2; while (s[i] == ' ' || s[i] == '\t') i++; if (nameonfourthfield) { // skip three letter while (s[i] != ' ' && s[i] != '\t') i++; while (s[i] == ' ' || s[i] == '\t') i++; // skip number while (s[i] != ' ' && s[i] != '\t') i++; while (s[i] == ' ' || s[i] == '\t') i++; } countryCode = s.Left(2); countryName = s.Mid(i); m_counties.push_back(countryName); m_countryByCode[countryCode] = countryName; m_countryByName[countryName] = countryCode; } sort(m_counties.begin(), m_counties.end(), sortstringbyname()); fclose(fp); } free(line); }