summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/GUIWindowAddonBrowser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/addons/GUIWindowAddonBrowser.cpp')
-rw-r--r--xbmc/addons/GUIWindowAddonBrowser.cpp677
1 files changed, 0 insertions, 677 deletions
diff --git a/xbmc/addons/GUIWindowAddonBrowser.cpp b/xbmc/addons/GUIWindowAddonBrowser.cpp
deleted file mode 100644
index f4560dd..0000000
--- a/xbmc/addons/GUIWindowAddonBrowser.cpp
+++ /dev/null
@@ -1,677 +0,0 @@
1/*
2 * Copyright (C) 2005-2013 Team XBMC
3 * http://xbmc.org
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include "GUIWindowAddonBrowser.h"
22#include "addons/AddonManager.h"
23#include "addons/Repository.h"
24#include "GUIDialogAddonInfo.h"
25#include "GUIDialogAddonSettings.h"
26#include "dialogs/GUIDialogBusy.h"
27#include "dialogs/GUIDialogOK.h"
28#include "dialogs/GUIDialogYesNo.h"
29#include "dialogs/GUIDialogSelect.h"
30#include "dialogs/GUIDialogFileBrowser.h"
31#include "GUIUserMessages.h"
32#include "guilib/GUIWindowManager.h"
33#include "utils/URIUtils.h"
34#include "URL.h"
35#include "FileItem.h"
36#include "filesystem/File.h"
37#include "filesystem/Directory.h"
38#include "filesystem/AddonsDirectory.h"
39#include "addons/AddonInstaller.h"
40#include "utils/JobManager.h"
41#include "utils/log.h"
42#include "threads/SingleLock.h"
43#include "settings/Settings.h"
44#include "settings/MediaSourceSettings.h"
45#include "utils/StringUtils.h"
46#include "AddonDatabase.h"
47#include "settings/AdvancedSettings.h"
48#include "storage/MediaManager.h"
49#include "LangInfo.h"
50#include "input/Key.h"
51#include "ContextMenuManager.h"
52
53#define CONTROL_AUTOUPDATE 5
54#define CONTROL_SHUTUP 6
55#define CONTROL_FOREIGNFILTER 7
56#define CONTROL_BROKENFILTER 8
57
58using namespace ADDON;
59using namespace XFILE;
60using namespace std;
61
62CGUIWindowAddonBrowser::CGUIWindowAddonBrowser(void)
63: CGUIMediaWindow(WINDOW_ADDON_BROWSER, "AddonBrowser.xml")
64{
65}
66
67CGUIWindowAddonBrowser::~CGUIWindowAddonBrowser()
68{
69}
70
71bool CGUIWindowAddonBrowser::OnMessage(CGUIMessage& message)
72{
73 switch ( message.GetMessage() )
74 {
75 case GUI_MSG_WINDOW_DEINIT:
76 {
77 if (m_thumbLoader.IsLoading())
78 m_thumbLoader.StopThread();
79 }
80 break;
81 case GUI_MSG_WINDOW_INIT:
82 {
83 m_rootDir.AllowNonLocalSources(false);
84
85 // is this the first time the window is opened?
86 if (m_vecItems->GetPath() == "?" && message.GetStringParam().empty())
87 m_vecItems->SetPath("");
88 }
89 break;
90 case GUI_MSG_CLICKED:
91 {
92 int iControl = message.GetSenderId();
93 if (iControl == CONTROL_AUTOUPDATE)
94 {
95 const CGUIControl *control = GetControl(CONTROL_AUTOUPDATE);
96 if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON)
97 CSettings::Get().SetInt("general.addonupdates", (CSettings::Get().GetInt("general.addonupdates")+1) % AUTO_UPDATES_MAX);
98 else
99 CSettings::Get().SetInt("general.addonupdates", (CSettings::Get().GetInt("general.addonupdates") == 0) ? 1 : 0);
100 UpdateButtons();
101 return true;
102 }
103 else if (iControl == CONTROL_SHUTUP)
104 {
105 CSettings::Get().ToggleBool("general.addonnotifications");
106 CSettings::Get().Save();
107 return true;
108 }
109 else if (iControl == CONTROL_FOREIGNFILTER)
110 {
111 CSettings::Get().ToggleBool("general.addonforeignfilter");
112 CSettings::Get().Save();
113 Refresh();
114 return true;
115 }
116 else if (iControl == CONTROL_BROKENFILTER)
117 {
118 CSettings::Get().ToggleBool("general.addonbrokenfilter");
119 CSettings::Get().Save();
120 Refresh();
121 return true;
122 }
123 else if (m_viewControl.HasControl(iControl)) // list/thumb control
124 {
125 // get selected item
126 int iItem = m_viewControl.GetSelectedItem();
127 int iAction = message.GetParam1();
128
129 // iItem is checked for validity inside these routines
130 if (iAction == ACTION_SHOW_INFO)
131 {
132 if (!m_vecItems->Get(iItem)->GetProperty("Addon.ID").empty())
133 return CGUIDialogAddonInfo::ShowForItem((*m_vecItems)[iItem]);
134 return false;
135 }
136 }
137 }
138 break;
139 case GUI_MSG_NOTIFY_ALL:
140 {
141 if (message.GetParam1() == GUI_MSG_UPDATE_ITEM && IsActive() && message.GetNumStringParams() == 1)
142 { // update this item
143 for (int i = 0; i < m_vecItems->Size(); ++i)
144 {
145 CFileItemPtr item = m_vecItems->Get(i);
146 if (item->GetProperty("Addon.ID") == message.GetStringParam())
147 {
148 SetItemLabel2(item);
149 return true;
150 }
151 }
152 }
153 }
154 break;
155 default:
156 break;
157 }
158 return CGUIMediaWindow::OnMessage(message);
159}
160
161void CGUIWindowAddonBrowser::GetContextButtons(int itemNumber, CContextButtons& buttons)
162{
163 if (itemNumber < 0 || itemNumber >= m_vecItems->Size())
164 return;
165
166 CFileItemPtr pItem = m_vecItems->Get(itemNumber);
167 if (!pItem->IsPath("addons://enabled/"))
168 buttons.Add(CONTEXT_BUTTON_SCAN,24034);
169
170 AddonPtr addon;
171 if (!CAddonMgr::Get().GetAddon(pItem->GetProperty("Addon.ID").asString(), addon, ADDON_UNKNOWN, false)) // allow disabled addons
172 return;
173
174 if (addon->Type() == ADDON_REPOSITORY && pItem->m_bIsFolder)
175 {
176 buttons.Add(CONTEXT_BUTTON_SCAN,24034);
177 buttons.Add(CONTEXT_BUTTON_REFRESH,24035);
178 }
179
180 buttons.Add(CONTEXT_BUTTON_INFO,24003);
181
182 if (addon->HasSettings())
183 buttons.Add(CONTEXT_BUTTON_SETTINGS,24020);
184
185 CContextMenuManager::Get().AddVisibleItems(pItem, buttons);
186}
187
188bool CGUIWindowAddonBrowser::OnContextButton(int itemNumber,
189 CONTEXT_BUTTON button)
190{
191 CFileItemPtr pItem = m_vecItems->Get(itemNumber);
192 if (pItem->IsPath("addons://enabled/"))
193 {
194 if (button == CONTEXT_BUTTON_SCAN)
195 {
196 CAddonMgr::Get().FindAddons();
197 return true;
198 }
199 }
200
201 AddonPtr addon;
202 if (CAddonMgr::Get().GetAddon(pItem->GetProperty("Addon.ID").asString(), addon, ADDON_UNKNOWN, false))
203 {
204 if (button == CONTEXT_BUTTON_SETTINGS)
205 return CGUIDialogAddonSettings::ShowAndGetInput(addon);
206
207 if (button == CONTEXT_BUTTON_REFRESH)
208 {
209 CAddonDatabase database;
210 database.Open();
211 database.DeleteRepository(addon->ID());
212 button = CONTEXT_BUTTON_SCAN;
213 }
214
215 if (button == CONTEXT_BUTTON_SCAN)
216 {
217 CAddonInstaller::Get().UpdateRepos(true);
218 return true;
219 }
220
221 if (button == CONTEXT_BUTTON_INFO)
222 {
223 CGUIDialogAddonInfo::ShowForItem(pItem);
224 return true;
225 }
226 }
227
228 return CGUIMediaWindow::OnContextButton(itemNumber, button);
229}
230
231class UpdateAddons : public IRunnable
232{
233 virtual void Run()
234 {
235 VECADDONS addons;
236 CAddonMgr::Get().GetAllOutdatedAddons(addons, true); // get local
237 for (VECADDONS::iterator i = addons.begin(); i != addons.end(); ++i)
238 {
239 std::string referer = StringUtils::Format("Referer=%s-%s.zip",(*i)->ID().c_str(),(*i)->Version().asString().c_str());
240 CAddonInstaller::Get().Install((*i)->ID(), true, referer); // force install
241 }
242 }
243};
244
245class UpdateRepos : public IRunnable
246{
247 virtual void Run()
248 {
249 CAddonInstaller::Get().UpdateRepos(true, true);
250 }
251};
252
253bool CGUIWindowAddonBrowser::OnClick(int iItem)
254{
255 CFileItemPtr item = m_vecItems->Get(iItem);
256 if (item->GetPath() == "addons://install/")
257 {
258 // pop up filebrowser to grab an installed folder
259 VECSOURCES shares = *CMediaSourceSettings::Get().GetSources("files");
260 g_mediaManager.GetLocalDrives(shares);
261 g_mediaManager.GetNetworkLocations(shares);
262 std::string path;
263 if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "*.zip", g_localizeStrings.Get(24041), path))
264 CAddonInstaller::Get().InstallFromZip(path);
265 return true;
266 }
267 else if (item->GetPath() == "addons://check/")
268 {
269 // perform the check for updates
270 UpdateRepos updater;
271 if (CGUIDialogBusy::Wait(&updater))
272 Refresh();
273 return true;
274 }
275 if (item->GetPath() == "addons://update_all/")
276 {
277 // fire off a threaded update of all addons
278 UpdateAddons updater;
279 if (CGUIDialogBusy::Wait(&updater))
280 return Update("addons://downloading/");
281 return true;
282 }
283 if (!item->m_bIsFolder)
284 {
285 // cancel a downloading job
286 if (item->HasProperty("Addon.Downloading"))
287 {
288 if (CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24000),
289 item->GetProperty("Addon.Name").asString(),
290 g_localizeStrings.Get(24066),""))
291 {
292 if (CAddonInstaller::Get().Cancel(item->GetProperty("Addon.ID").asString()))
293 Refresh();
294 }
295 return true;
296 }
297
298 CGUIDialogAddonInfo::ShowForItem(item);
299 return true;
300 }
301 if (item->IsPath("addons://search/"))
302 return Update(item->GetPath());
303
304 return CGUIMediaWindow::OnClick(iItem);
305}
306
307void CGUIWindowAddonBrowser::UpdateButtons()
308{
309 const CGUIControl *control = GetControl(CONTROL_AUTOUPDATE);
310 if (control && control->GetControlType() == CGUIControl::GUICONTROL_BUTTON)
311 { // set label
312 CSettingInt *setting = (CSettingInt *)CSettings::Get().GetSetting("general.addonupdates");
313 if (setting)
314 {
315 const StaticIntegerSettingOptions& options = setting->GetOptions();
316 for (StaticIntegerSettingOptions::const_iterator it = options.begin(); it != options.end(); ++it)
317 {
318 if (it->second == setting->GetValue())
319 {
320 SET_CONTROL_LABEL(CONTROL_AUTOUPDATE, it->first);
321 break;
322 }
323 }
324 }
325 }
326 else
327 { // old skin with toggle button - set on if auto updates are on
328 SET_CONTROL_SELECTED(GetID(),CONTROL_AUTOUPDATE, CSettings::Get().GetInt("general.addonupdates") == AUTO_UPDATES_ON);
329 }
330 SET_CONTROL_SELECTED(GetID(),CONTROL_SHUTUP, CSettings::Get().GetBool("general.addonnotifications"));
331 SET_CONTROL_SELECTED(GetID(),CONTROL_FOREIGNFILTER, CSettings::Get().GetBool("general.addonforeignfilter"));
332 SET_CONTROL_SELECTED(GetID(),CONTROL_BROKENFILTER, CSettings::Get().GetBool("general.addonbrokenfilter"));
333 CGUIMediaWindow::UpdateButtons();
334}
335
336static bool FilterVar(bool valid, const CVariant& variant,
337 const std::string& check)
338{
339 if (!valid)
340 return false;
341
342 if (variant.isNull() || variant.asString().empty())
343 return false;
344
345 std::string regions = variant.asString();
346 return regions.find(check) == std::string::npos;
347}
348
349bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory,
350 CFileItemList& items)
351{
352 bool result;
353 if (URIUtils::PathEquals(strDirectory, "addons://downloading/"))
354 {
355 VECADDONS addons;
356 CAddonInstaller::Get().GetInstallList(addons);
357
358 CURL url(strDirectory);
359 CAddonsDirectory::GenerateListing(url,addons,items);
360 result = true;
361 items.SetProperty("reponame",g_localizeStrings.Get(24067));
362 items.SetPath(strDirectory);
363
364 if (m_guiState.get() && !m_guiState->HideParentDirItems())
365 {
366 CFileItemPtr pItem(new CFileItem(".."));
367 pItem->SetPath(m_history.GetParentPath());
368 pItem->m_bIsFolder = true;
369 pItem->m_bIsShareOrDrive = false;
370 items.AddFront(pItem, 0);
371 }
372
373 }
374 else
375 {
376 result = CGUIMediaWindow::GetDirectory(strDirectory,items);
377 if (CSettings::Get().GetBool("general.addonforeignfilter"))
378 {
379 int i=0;
380 while (i < items.Size())
381 {
382 if (!FilterVar(true, items[i]->GetProperty("Addon.Language"), "en") ||
383 !FilterVar(true, items[i]->GetProperty("Addon.Language"), g_langInfo.GetLanguageLocale()))
384 {
385 i++;
386 }
387 else
388 items.Remove(i);
389 }
390 }
391 if (CSettings::Get().GetBool("general.addonbrokenfilter"))
392 {
393 for (int i = items.Size() - 1; i >= 0; i--)
394 {
395 if (!items[i]->GetProperty("Addon.Broken").empty())
396 { //check if it's installed
397 AddonPtr addon;
398 if (!CAddonMgr::Get().GetAddon(items[i]->GetProperty("Addon.ID").asString(), addon))
399 items.Remove(i);
400 }
401 }
402 }
403 }
404
405 if (strDirectory.empty() && CAddonInstaller::Get().IsDownloading())
406 {
407 CFileItemPtr item(new CFileItem("addons://downloading/",true));
408 item->SetLabel(g_localizeStrings.Get(24067));
409 item->SetLabelPreformated(true);
410 item->SetIconImage("DefaultNetwork.png");
411 items.Add(item);
412 }
413
414 items.SetContent("addons");
415
416 for (int i=0;i<items.Size();++i)
417 SetItemLabel2(items[i]);
418
419 return result;
420}
421
422void CGUIWindowAddonBrowser::SetItemLabel2(CFileItemPtr item)
423{
424 if (!item || item->m_bIsFolder) return;
425 unsigned int percent;
426 if (CAddonInstaller::Get().GetProgress(item->GetProperty("Addon.ID").asString(), percent))
427 {
428 std::string progress = StringUtils::Format(g_localizeStrings.Get(24042).c_str(), percent);
429 item->SetProperty("Addon.Status", progress);
430 item->SetProperty("Addon.Downloading", true);
431 }
432 else
433 item->ClearProperty("Addon.Downloading");
434 item->SetLabel2(item->GetProperty("Addon.Status").asString());
435 // to avoid the view state overriding label 2
436 item->SetLabelPreformated(true);
437}
438
439bool CGUIWindowAddonBrowser::Update(const std::string &strDirectory, bool updateFilterPath /* = true */)
440{
441 if (m_thumbLoader.IsLoading())
442 m_thumbLoader.StopThread();
443
444 if (!CGUIMediaWindow::Update(strDirectory, updateFilterPath))
445 return false;
446
447 m_thumbLoader.Load(*m_vecItems);
448
449 return true;
450}
451
452int CGUIWindowAddonBrowser::SelectAddonID(TYPE type, std::string &addonID, bool showNone /* = false */, bool showDetails /* = true */, bool showInstalled /* = true */, bool showInstallable /*= false */, bool showMore /* = true */)
453{
454 vector<ADDON::TYPE> types;
455 types.push_back(type);
456 return SelectAddonID(types, addonID, showNone, showDetails, showInstalled, showInstallable, showMore);
457}
458
459int CGUIWindowAddonBrowser::SelectAddonID(ADDON::TYPE type, vector<string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */)
460{
461 vector<ADDON::TYPE> types;
462 types.push_back(type);
463 return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, showInstalled, showInstallable, showMore);
464}
465
466int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, std::string &addonID, bool showNone /* = false */, bool showDetails /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */)
467{
468 vector<string> addonIDs;
469 if (!addonID.empty())
470 addonIDs.push_back(addonID);
471 int retval = SelectAddonID(types, addonIDs, showNone, showDetails, false, showInstalled, showInstallable, showMore);
472 if (addonIDs.size() > 0)
473 addonID = addonIDs.at(0);
474 else
475 addonID = "";
476 return retval;
477}
478
479int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, vector<string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */)
480{
481 // if we shouldn't show neither installed nor installable addons the list will be empty
482 if (!showInstalled && !showInstallable)
483 return 0;
484
485 // can't show the "Get More" button if we already show installable addons
486 if (showInstallable)
487 showMore = false;
488
489 CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
490 if (!dialog)
491 return 0;
492
493 // get rid of any invalid addon types
494 vector<ADDON::TYPE> validTypes(types.size());
495 std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; });
496
497 if (validTypes.empty())
498 return 0;
499
500 // get all addons to show
501 VECADDONS addons;
502 if (showInstalled)
503 {
504 for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
505 {
506 VECADDONS typeAddons;
507 if (*type == ADDON_AUDIO)
508 CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons);
509 else if (*type == ADDON_EXECUTABLE)
510 CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons);
511 else if (*type == ADDON_IMAGE)
512 CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons);
513 else if (*type == ADDON_VIDEO)
514 CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons);
515 else
516 CAddonMgr::Get().GetAddons(*type, typeAddons);
517
518 addons.insert(addons.end(), typeAddons.begin(), typeAddons.end());
519 }
520 }
521
522 if (showInstallable || showMore)
523 {
524 VECADDONS installableAddons;
525 CAddonDatabase database;
526 if (database.Open() && database.GetAddons(installableAddons))
527 {
528 for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();)
529 {
530 AddonPtr pAddon = *addon;
531
532 // check if the addon matches one of the provided addon types
533 bool matchesType = false;
534 for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
535 {
536 if (pAddon->IsType(*type))
537 {
538 matchesType = true;
539 break;
540 }
541 }
542
543 // only show addons that match one of the provided addon types and that aren't disabled
544 if (matchesType && !CAddonMgr::Get().IsAddonDisabled(pAddon->ID()))
545 {
546 // check if the addon is installed
547 bool isInstalled = CAddonMgr::Get().IsAddonInstalled(pAddon->ID());
548
549 // check if the addon is installed or can be installed
550 if ((showInstallable || showMore) && !isInstalled && CAddonMgr::Get().CanAddonBeInstalled(pAddon))
551 {
552 ++addon;
553 continue;
554 }
555 }
556
557 addon = installableAddons.erase(addon);
558 }
559
560 if (showInstallable)
561 addons.insert(addons.end(), installableAddons.begin(), installableAddons.end());
562 else if (showMore)
563 showMore = !installableAddons.empty();
564 }
565 }
566
567 if (addons.empty() && !showNone)
568 return 0;
569
570 // turn the addons into items
571 std::map<std::string, AddonPtr> addonMap;
572 CFileItemList items;
573 for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon)
574 {
575 CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, ""));
576 if (!items.Contains(item->GetPath()))
577 {
578 items.Add(item);
579 addonMap.insert(std::make_pair(item->GetPath(), *addon));
580 }
581 }
582
583 if (items.IsEmpty() && !showNone)
584 return 0;
585
586 std::string heading;
587 for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type)
588 {
589 if (!heading.empty())
590 heading += ", ";
591 heading += TranslateType(*type, true);
592 }
593
594 dialog->SetHeading(heading);
595 dialog->Reset();
596 dialog->SetUseDetails(showDetails);
597
598 if (multipleSelection)
599 {
600 showNone = false;
601 showMore = false;
602 dialog->EnableButton(true, 186);
603 }
604 else if (showMore)
605 dialog->EnableButton(true, 21452);
606
607 if (showNone)
608 {
609 CFileItemPtr item(new CFileItem("", false));
610 item->SetLabel(g_localizeStrings.Get(231));
611 item->SetLabel2(g_localizeStrings.Get(24040));
612 item->SetIconImage("DefaultAddonNone.png");
613 item->SetSpecialSort(SortSpecialOnTop);
614 items.Add(item);
615 }
616 items.Sort(SortByLabel, SortOrderAscending);
617
618 if (addonIDs.size() > 0)
619 {
620 for (vector<string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it)
621 {
622 CFileItemPtr item = items.Get(*it);
623 if (item)
624 item->Select(true);
625 }
626 }
627 dialog->SetItems(&items);
628 dialog->SetMultiSelection(multipleSelection);
629 dialog->DoModal();
630
631 // if the "Get More" button has been pressed and we haven't shown the
632 // installable addons so far show a list of installable addons
633 if (showMore&& dialog->IsButtonPressed())
634 return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false);
635
636 if (!dialog->IsConfirmed())
637 return 0;
638
639 addonIDs.clear();
640 const CFileItemList& list = dialog->GetSelectedItems();
641 for (int i = 0 ; i < list.Size() ; i++)
642 {
643 const CFileItemPtr& item = list.Get(i);
644
645 // check if one of the selected addons needs to be installed
646 if (showInstallable)
647 {
648 std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath());
649 if (itAddon != addonMap.end())
650 {
651 const AddonPtr& addon = itAddon->second;
652
653 // if the addon isn't installed we need to install it
654 if (!CAddonMgr::Get().IsAddonInstalled(addon->ID()))
655 {
656 AddonPtr installedAddon;
657 if (!CAddonInstaller::Get().InstallModal(addon->ID(), installedAddon, false))
658 continue;
659 }
660
661 // if the addon is disabled we need to enable it
662 if (CAddonMgr::Get().IsAddonDisabled(addon->ID()))
663 CAddonMgr::Get().DisableAddon(addon->ID(), false);
664 }
665 }
666
667 addonIDs.push_back(item->GetPath());
668 }
669 return 1;
670}
671
672std::string CGUIWindowAddonBrowser::GetStartFolder(const std::string &dir)
673{
674 if (URIUtils::PathStarts(dir, "addons://"))
675 return dir;
676 return CGUIMediaWindow::GetStartFolder(dir);
677}