PageRenderTime 84ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 2ms

/animeplugin3/MyAnimePlugin3/Windows/MainWindow.cs

https://bitbucket.org/gibwar/jmm-test
C# | 6383 lines | 4770 code | 1172 blank | 441 comment | 1268 complexity | 2668427969cd4f7a48e0ceea8b6abd0b MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Forms;
  4. using ConsoleApplication2.com.amazon.webservices;
  5. using MediaPortal.GUI.Library;
  6. using MediaPortal.Dialogs;
  7. using MyAnimePlugin3.ConfigFiles;
  8. using MyAnimePlugin3.DataHelpers;
  9. using System.IO;
  10. using Cornerstone.MP;
  11. using System.ComponentModel;
  12. using System.Threading;
  13. using System.Xml;
  14. using BinaryNorthwest;
  15. using System.Runtime.InteropServices;
  16. using MyAnimePlugin3.Downloads;
  17. using Action = MediaPortal.GUI.Library.Action;
  18. using System.Collections;
  19. using MyAnimePlugin3.ViewModel;
  20. using MyAnimePlugin3.ImageManagement;
  21. using MyAnimePlugin3.MultiSortLib;
  22. using MediaPortal.Player;
  23. namespace MyAnimePlugin3
  24. {
  25. public class MainWindow : GUIWindow, ISetupForm
  26. {
  27. #region GUI Controls
  28. [SkinControlAttribute(2)]
  29. protected GUIButtonControl btnDisplayOptions = null;
  30. //[SkinControlAttribute(3)] protected GUIButtonControl btnLayout = null;
  31. [SkinControlAttribute(4)]
  32. protected GUIButtonControl btnSettings = null;
  33. [SkinControlAttribute(11)]
  34. protected GUIButtonControl btnChangeLayout = null;
  35. [SkinControlAttribute(12)]
  36. protected GUIButtonControl btnSwitchUser = null;
  37. [SkinControlAttribute(920)] protected GUIButtonControl btnWindowContinueWatching = null;
  38. [SkinControlAttribute(921)] protected GUIButtonControl btnWindowUtilities = null;
  39. [SkinControlAttribute(922)] protected GUIButtonControl btnWindowCalendar = null;
  40. [SkinControlAttribute(923)] protected GUIButtonControl btnWindowDownloads = null;
  41. //[SkinControlAttribute(924)] protected GUIButtonControl btnWindowCollectionStats = null;
  42. [SkinControlAttribute(925)] protected GUIButtonControl btnWindowRecommendations = null;
  43. [SkinControlAttribute(926)] protected GUIButtonControl btnWindowRandom = null;
  44. [SkinControlAttribute(927)] protected GUIButtonControl btnWindowPlaylists = null;
  45. [SkinControlAttribute(50)]
  46. protected GUIFacadeControl m_Facade = null;
  47. //[SkinControlAttribute(51)]
  48. //protected GUIListControl test = null;
  49. //[SkinControlAttribute(526)] protected GUIImage loadingImage = null;
  50. // let the skins react to what we are displaying
  51. // all these controls are imported from Anime3_Dummy.xml
  52. [SkinControlAttribute(1232)]
  53. protected GUILabelControl dummyIsFanartLoaded = null;
  54. [SkinControlAttribute(1233)]
  55. protected GUILabelControl dummyIsDarkFanartLoaded = null;
  56. [SkinControlAttribute(1234)]
  57. protected GUILabelControl dummyIsLightFanartLoaded = null;
  58. [SkinControlAttribute(1235)]
  59. protected GUILabelControl dummyLayoutListMode = null;
  60. [SkinControlAttribute(1236)]
  61. protected GUILabelControl dummyLayoutFilmstripMode = null;
  62. [SkinControlAttribute(1242)]
  63. protected GUILabelControl dummyLayoutWideBanners = null;
  64. [SkinControlAttribute(1237)]
  65. protected GUILabelControl dummyIsSeries = null;
  66. [SkinControlAttribute(1238)]
  67. protected GUILabelControl dummyIsGroups = null;
  68. [SkinControlAttribute(1250)]
  69. protected GUILabelControl dummyIsGroupFilters = null;
  70. [SkinControlAttribute(1239)]
  71. protected GUILabelControl dummyIsEpisodes = null;
  72. [SkinControlAttribute(1240)]
  73. protected GUILabelControl dummyIsEpisodeTypes = null;
  74. [SkinControlAttribute(1241)]
  75. protected GUILabelControl dummyIsFanartColorAvailable = null;
  76. [SkinControlAttribute(1243)]
  77. protected GUILabelControl dummyIsWatched = null;
  78. [SkinControlAttribute(1244)]
  79. protected GUILabelControl dummyIsAvailable = null;
  80. [SkinControlAttribute(1245)]
  81. protected GUILabelControl dummyFave = null;
  82. [SkinControlAttribute(1246)]
  83. protected GUILabelControl dummyMissingEps = null;
  84. [SkinControlAttribute(1247)]
  85. protected GUILabelControl dummyUserHasVotedSeries = null;
  86. [SkinControlAttribute(3401)]
  87. protected GUILabelControl dummyQueueAniDB = null;
  88. [SkinControlAttribute(3402)]
  89. protected GUILabelControl dummyQueueHasher = null;
  90. [SkinControlAttribute(3403)]
  91. protected GUILabelControl dummyQueueImages = null;
  92. [SkinControlAttribute(3463)]
  93. protected GUIControl dummyFindActive = null;
  94. [SkinControlAttribute(3464)]
  95. protected GUIControl dummyFindModeT9 = null;
  96. [SkinControlAttribute(3465)]
  97. protected GUIControl dummyFindModeText = null;
  98. #endregion
  99. public static Listlevel listLevel = Listlevel.GroupFilter;
  100. public static object parentLevelObject = null;
  101. private static Random groupRandom = new Random();
  102. public static RandomSeriesEpisodeLevel RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.All;
  103. public static RandomObjectType RandomWindow_RandomType = RandomObjectType.Series;
  104. public static object RandomWindow_LevelObject = null;
  105. public static AnimeSeriesVM RandomWindow_CurrentSeries = null;
  106. public static AnimeEpisodeVM RandomWindow_CurrentEpisode = null;
  107. public static int RandomWindow_MatchesFound = 0;
  108. public static bool RandomWindow_SeriesWatched = true;
  109. public static bool RandomWindow_SeriesUnwatched = true;
  110. public static bool RandomWindow_SeriesPartiallyWatched = true;
  111. public static bool RandomWindow_SeriesOnlyComplete = true;
  112. public static bool RandomWindow_SeriesAllCategories = true;
  113. public static string RandomWindow_SeriesCategories = "";
  114. public static bool RandomWindow_EpisodeWatched = true;
  115. public static bool RandomWindow_EpisodeUnwatched = true;
  116. public static bool RandomWindow_EpisodeAllCategories = true;
  117. public static string RandomWindow_EpisodeCategories = "";
  118. //private bool fanartSet = false;
  119. private readonly int artworkDelay = 5;
  120. private System.Timers.Timer displayGrpFilterTimer = null;
  121. private System.Timers.Timer displayGrpTimer = null;
  122. public static int? animeSeriesIDToBeRated = null;
  123. public static AnimePluginSettings settings = null;
  124. public static JMMServerHelper ServerHelper = new JMMServerHelper();
  125. public static List<string> completedTorrents = new List<string>();
  126. public static DownloadSearchCriteria currentDownloadSearch = null;
  127. public static List<DownloadSearchCriteria> downloadSearchHistory = new List<DownloadSearchCriteria>();
  128. public static List<List<TorrentLink>> downloadSearchResultsHistory = new List<List<TorrentLink>>();
  129. public static int LastFocusType = -1; //
  130. public static int LastFocusID = -1; //
  131. public static int GlobalSeriesID = -1; // either AnimeSeriesID
  132. public static int GlobalAnimeID = -1; // AnimeID
  133. public static int GlobalSeiyuuID = -1; // SeiyuuID
  134. public static int CurrentCalendarMonth = DateTime.Now.Month;
  135. public static int CurrentCalendarYear = DateTime.Now.Year;
  136. public static int CurrentCalendarButton = 4;
  137. public static VideoHandler vidHandler;
  138. public static UTorrentHelper uTorrent = new UTorrentHelper();
  139. public static View currentView = null;
  140. public static ViewClassification currentViewClassification = ViewClassification.Views;
  141. public static string currentStaticViewID = ""; // used to stored current year, genre etc in static views
  142. private GUIFacadeControl.Layout groupViewMode = GUIFacadeControl.Layout.List; // Poster List
  143. private GUIFacadeControl.Layout seriesViewMode = GUIFacadeControl.Layout.List;
  144. //private GUIFacadeControl.Layout episodeTypesViewMode = GUIFacadeControl.Layout.List; // List
  145. private GUIFacadeControl.Layout episodesViewMode = GUIFacadeControl.Layout.List; // List
  146. private List<GUIListItem> itemsForDelayedImgLoading = null;
  147. private BackgroundWorker workerFacade = null;
  148. private BackgroundWorker downloadImagesWorker = new BackgroundWorker();
  149. public static ImageDownloader imageHelper = null;
  150. private AsyncImageResource listPoster = null;
  151. private AsyncImageResource fanartTexture = null;
  152. //private bool isInitialGroupLoad = true;
  153. public static GroupFilterVM curGroupFilter = null;
  154. public static GroupFilterVM curGroupFilterSub = null;
  155. public static GroupFilterVM curGroupFilterSub2 = null;
  156. public static AnimeGroupVM curAnimeGroup = null;
  157. public static AnimeGroupVM curAnimeGroupViewed = null;
  158. public static AnimeSeriesVM curAnimeSeries = null;
  159. public static AnimeEpisodeTypeVM curAnimeEpisodeType = null;
  160. private AnimeEpisodeVM curAnimeEpisode = null;
  161. Dictionary<int, QuickSort> GroupFilterQuickSorts = null;
  162. private System.Timers.Timer searchTimer = null;
  163. private System.Timers.Timer autoUpdateTimer = null;
  164. private SearchCollection search = null;
  165. private List<GUIListItem> lstFacadeItems = null;
  166. private string searchSound = "click.wav";
  167. public delegate void OnToggleWatchedHandler(List<AnimeEpisodeVM> episodes, bool state);
  168. public event OnToggleWatchedHandler OnToggleWatched;
  169. protected void ToggleWatchedEvent(List<AnimeEpisodeVM> episodes, bool state)
  170. {
  171. if (OnToggleWatched != null)
  172. {
  173. OnToggleWatched(episodes, state);
  174. }
  175. }
  176. public delegate void OnRateSeriesHandler(AnimeSeriesVM series, string rateValue);
  177. public event OnRateSeriesHandler OnRateSeries;
  178. protected void RateSeriesEvent(AnimeSeriesVM series, string rateValue)
  179. {
  180. if (OnRateSeries != null)
  181. {
  182. OnRateSeries(series, rateValue);
  183. }
  184. }
  185. public MainWindow()
  186. {
  187. // get ID of windowplugin belonging to this setup
  188. // enter your own unique code
  189. GetID = Constants.PlugInInfo.ID;
  190. try
  191. {
  192. settings = new AnimePluginSettings();
  193. imageHelper = new ImageDownloader();
  194. imageHelper.Init();
  195. listPoster = new AsyncImageResource();
  196. listPoster.Property = "#Anime3.GroupSeriesPoster";
  197. listPoster.Delay = artworkDelay;
  198. fanartTexture = new AsyncImageResource();
  199. fanartTexture.Property = "#Anime3.Fanart.1";
  200. fanartTexture.Delay = artworkDelay;
  201. GroupFilterQuickSorts = new Dictionary<int, QuickSort>();
  202. //searching
  203. searchTimer = new System.Timers.Timer();
  204. searchTimer.AutoReset = true;
  205. searchTimer.Interval = settings.FindTimeout_s * 1000;
  206. searchTimer.Elapsed += new System.Timers.ElapsedEventHandler(searchTimer_Elapsed);
  207. //set the search key sound to the same sound for the REMOTE_1 key
  208. Key key = new Key('1', (int)Keys.D1);
  209. MediaPortal.GUI.Library.Action action = new MediaPortal.GUI.Library.Action();
  210. ActionTranslator.GetAction(GetID, key, ref action);
  211. searchSound = action.SoundFileName;
  212. // timer for automatic updates
  213. autoUpdateTimer = new System.Timers.Timer();
  214. autoUpdateTimer.AutoReset = true;
  215. autoUpdateTimer.Interval = 5 * 60 * 1000; // 5 minutes * 60 seconds
  216. autoUpdateTimer.Elapsed += new System.Timers.ElapsedEventHandler(autoUpdateTimer_Elapsed);
  217. downloadImagesWorker.DoWork += new DoWorkEventHandler(downloadImagesWorker_DoWork);
  218. this.OnToggleWatched += new OnToggleWatchedHandler(MainWindow_OnToggleWatched);
  219. g_Player.PlayBackEnded += new g_Player.EndedHandler(g_Player_PlayBackEnded);
  220. }
  221. catch (Exception ex)
  222. {
  223. BaseConfig.MyAnimeLog.Write(ex.ToString());
  224. throw;
  225. }
  226. }
  227. void MainWindow_OnToggleWatched(List<AnimeEpisodeVM> episodes, bool state)
  228. {
  229. string msg = string.Format("OnToggleWatched: {0} / {1}", episodes.Count, state);
  230. BaseConfig.MyAnimeLog.Write(msg);
  231. }
  232. private void DownloadAllImages()
  233. {
  234. //if (!downloadImagesWorker.IsBusy)
  235. // downloadImagesWorker.RunWorkerAsync();
  236. }
  237. void downloadImagesWorker_DoWork(object sender, DoWorkEventArgs e)
  238. {
  239. // 1. Download posters from AniDB
  240. List<JMMServerBinary.Contract_AniDBAnime> contracts = JMMServerVM.Instance.clientBinaryHTTP.GetAllAnime();
  241. int i = 0;
  242. foreach (JMMServerBinary.Contract_AniDBAnime anime in contracts)
  243. {
  244. //Thread.Sleep(5); // don't use too many resources
  245. imageHelper.DownloadAniDBCover(new AniDB_AnimeVM(anime), false);
  246. i++;
  247. //if (i == 80) break;
  248. }
  249. // 2. Download posters from TvDB
  250. List<JMMServerBinary.Contract_TvDB_ImagePoster> posters = JMMServerVM.Instance.clientBinaryHTTP.GetAllTvDBPosters(null);
  251. foreach (JMMServerBinary.Contract_TvDB_ImagePoster poster in posters)
  252. {
  253. //Thread.Sleep(5); // don't use too many resources
  254. imageHelper.DownloadTvDBPoster(new TvDB_ImagePosterVM(poster), false);
  255. }
  256. // 2a. Download posters from MovieDB
  257. List<JMMServerBinary.Contract_MovieDB_Poster> moviePosters = JMMServerVM.Instance.clientBinaryHTTP.GetAllMovieDBPosters(null);
  258. foreach (JMMServerBinary.Contract_MovieDB_Poster poster in moviePosters)
  259. {
  260. //Thread.Sleep(5); // don't use too many resources
  261. imageHelper.DownloadMovieDBPoster(new MovieDB_PosterVM(poster), false);
  262. }
  263. // 3. Download wide banners from TvDB
  264. List<JMMServerBinary.Contract_TvDB_ImageWideBanner> banners = JMMServerVM.Instance.clientBinaryHTTP.GetAllTvDBWideBanners(null);
  265. foreach (JMMServerBinary.Contract_TvDB_ImageWideBanner banner in banners)
  266. {
  267. //Thread.Sleep(5); // don't use too many resources
  268. imageHelper.DownloadTvDBWideBanner(new TvDB_ImageWideBannerVM(banner), false);
  269. }
  270. // 4. Download fanart from TvDB
  271. List<JMMServerBinary.Contract_TvDB_ImageFanart> fanarts = JMMServerVM.Instance.clientBinaryHTTP.GetAllTvDBFanart(null);
  272. foreach (JMMServerBinary.Contract_TvDB_ImageFanart fanart in fanarts)
  273. {
  274. //Thread.Sleep(5); // don't use too many resources
  275. imageHelper.DownloadTvDBFanart(new TvDB_ImageFanartVM(fanart), false);
  276. }
  277. // 4a. Download fanart from MovieDB
  278. List<JMMServerBinary.Contract_MovieDB_Fanart> movieFanarts = JMMServerVM.Instance.clientBinaryHTTP.GetAllMovieDBFanart(null);
  279. foreach (JMMServerBinary.Contract_MovieDB_Fanart fanart in movieFanarts)
  280. {
  281. //Thread.Sleep(5); // don't use too many resources
  282. imageHelper.DownloadMovieDBFanart(new MovieDB_FanartVM(fanart), false);
  283. }
  284. // 5. Download episode images from TvDB
  285. List<JMMServerBinary.Contract_TvDB_Episode> eps = JMMServerVM.Instance.clientBinaryHTTP.GetAllTvDBEpisodes(null);
  286. foreach (JMMServerBinary.Contract_TvDB_Episode episode in eps)
  287. {
  288. //Thread.Sleep(5); // don't use too many resources
  289. imageHelper.DownloadTvDBEpisode(new TvDB_EpisodeVM(episode), false);
  290. }
  291. // 6. Download posters from Trakt
  292. List<JMMServerBinary.Contract_Trakt_ImagePoster> traktPosters = JMMServerVM.Instance.clientBinaryHTTP.GetAllTraktPosters(null);
  293. foreach (JMMServerBinary.Contract_Trakt_ImagePoster traktposter in traktPosters)
  294. {
  295. //Thread.Sleep(5); // don't use too many resources
  296. if (string.IsNullOrEmpty(traktposter.ImageURL)) continue;
  297. imageHelper.DownloadTraktPoster(new Trakt_ImagePosterVM(traktposter), false);
  298. }
  299. // 7. Download fanart from Trakt
  300. List<JMMServerBinary.Contract_Trakt_ImageFanart> traktFanarts = JMMServerVM.Instance.clientBinaryHTTP.GetAllTraktFanart(null);
  301. foreach (JMMServerBinary.Contract_Trakt_ImageFanart traktFanart in traktFanarts)
  302. {
  303. //Thread.Sleep(5); // don't use too many resources
  304. if (string.IsNullOrEmpty(traktFanart.ImageURL)) continue;
  305. imageHelper.DownloadTraktFanart(new Trakt_ImageFanartVM(traktFanart), false);
  306. }
  307. // 8. Download episode images from Trakt
  308. List<JMMServerBinary.Contract_Trakt_Episode> traktEpisodes = JMMServerVM.Instance.clientBinaryHTTP.GetAllTraktEpisodes(null);
  309. foreach (JMMServerBinary.Contract_Trakt_Episode traktEp in traktEpisodes)
  310. {
  311. //Thread.Sleep(5); // don't use too many resources
  312. if (string.IsNullOrEmpty(traktEp.EpisodeImage)) continue;
  313. // special case for trak episodes
  314. // Trakt will return the fanart image when no episode image exists, but we don't want this
  315. int pos = traktEp.EpisodeImage.IndexOf(@"episodes/");
  316. if (pos <= 0) continue;
  317. imageHelper.DownloadTraktEpisode(new Trakt_EpisodeVM(traktEp), false);
  318. }
  319. }
  320. #region External Event Handlers
  321. #endregion
  322. public override bool Init()
  323. {
  324. try
  325. {
  326. BaseConfig.MyAnimeLog.Write("INIT MAIN WINDOW");
  327. vidHandler = new VideoHandler();
  328. vidHandler.DefaultAudioLanguage = settings.DefaultAudioLanguage;
  329. vidHandler.DefaultSubtitleLanguage = settings.DefaultSubtitleLanguage;
  330. }
  331. catch (Exception ex)
  332. {
  333. BaseConfig.MyAnimeLog.Write("Error on init: {0}", ex.ToString());
  334. }
  335. return Load(GUIGraphicsContext.Skin + @"\Anime3_Main.xml");
  336. }
  337. void Instance_ServerStatusEvent(Events.ServerStatusEventArgs ev)
  338. {
  339. setGUIProperty("HasherQueueCount", ev.HasherQueueCount.ToString());
  340. setGUIProperty("HasherQueueState", ev.HasherQueueState);
  341. setGUIProperty("HasherQueueRunning", ev.HasherQueueRunning ? "Running" : "Paused");
  342. setGUIProperty("GeneralQueueCount", ev.GeneralQueueCount.ToString());
  343. setGUIProperty("GeneralQueueState", ev.GeneralQueueState);
  344. setGUIProperty("GeneralQueueRunning", ev.GeneralQueueRunning ? "Running" : "Paused");
  345. setGUIProperty("ImagesQueueCount", ev.ImagesQueueCount.ToString());
  346. setGUIProperty("ImagesQueueState", ev.ImagesQueueState);
  347. setGUIProperty("ImagesQueueRunning", ev.ImagesQueueRunning ? "Running" : "Paused");
  348. if (dummyQueueAniDB != null) dummyQueueAniDB.Visible = ev.GeneralQueueCount >= 0;
  349. if (dummyQueueHasher != null) dummyQueueHasher.Visible = ev.HasherQueueCount >= 0;
  350. if (dummyQueueImages != null) dummyQueueImages.Visible = ev.ImagesQueueCount >= 0;
  351. }
  352. #region ISetupForm Members
  353. // Returns the name of the plugin which is shown in the plugin menu
  354. public string PluginName()
  355. {
  356. return Constants.PlugInInfo.NAME;
  357. }
  358. // Returns the description of the plugin is shown in the plugin menu
  359. public string Description()
  360. {
  361. return Constants.PlugInInfo.DESCRIPTION;
  362. }
  363. // Returns the author of the plugin which is shown in the plugin menu
  364. public string Author()
  365. {
  366. return Constants.PlugInInfo.AUTHOR;
  367. }
  368. // show the setup dialog
  369. public void ShowPlugin()
  370. {
  371. frmConfig cfg = new frmConfig();
  372. cfg.ShowDialog();
  373. }
  374. // Indicates whether plugin can be enabled/disabled
  375. public bool CanEnable()
  376. {
  377. return true;
  378. }
  379. // Enter the id number here again
  380. public int GetWindowId()
  381. {
  382. return Constants.PlugInInfo.ID;
  383. }
  384. // Indicates if plugin is enabled by default;
  385. public bool DefaultEnabled()
  386. {
  387. return true;
  388. }
  389. // indicates if a plugin has it's own setup screen
  390. public bool HasSetup()
  391. {
  392. return true;
  393. }
  394. /// <summary>
  395. /// If the plugin should have it's own button on the main menu of MediaPortal then it
  396. /// should return true to this method, otherwise if it should not be on home
  397. /// it should return false
  398. /// </summary>
  399. /// <param name="strButtonText">text the button should have</param>
  400. /// <param name="strButtonImage">image for the button, or empty for default</param>
  401. /// <param name="strButtonImageFocus">image for the button, or empty for default</param>
  402. /// <param name="strPictureImage">subpicture for the button or empty for none</param>
  403. /// <returns>true : plugin needs it's own button on home
  404. /// false : plugin does not need it's own button on home</returns>
  405. public bool GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage)
  406. {
  407. AnimePluginSettings sett = new AnimePluginSettings();
  408. strButtonText = sett.PluginName;
  409. strButtonImage = String.Empty;
  410. strButtonImageFocus = String.Empty;
  411. strPictureImage = "hover_my anime3.jpg";
  412. return true;
  413. }
  414. #endregion
  415. private void EvaluateVisibility()
  416. {
  417. bool fave = false;
  418. bool missing = false;
  419. if (curAnimeGroup != null)
  420. {
  421. if (curAnimeGroup.IsFave == 1)
  422. fave = true;
  423. //BaseConfig.MyAnimeLog.Write("settings.ShowMissing: {0}", settings.ShowMissing);
  424. bool missingVisible = false;
  425. if (settings.ShowMissing && listLevel == Listlevel.Series && curAnimeSeries != null)
  426. {
  427. missingVisible = curAnimeSeries.HasMissingEpisodesGroups;
  428. }
  429. if (settings.ShowMissing && listLevel == Listlevel.Group)
  430. {
  431. missingVisible = curAnimeGroup.HasMissingEpisodes;
  432. }
  433. if (settings.ShowMissing)
  434. {
  435. missing = missingVisible;
  436. }
  437. if (dummyFave != null) dummyFave.Visible = fave;
  438. if (dummyMissingEps != null) dummyMissingEps.Visible = missing;
  439. //BaseConfig.MyAnimeLog.Write("EvaluateVisibility:: {0} - {1} - {2}", imgListFave != null, curAnimeGroup.IsFave, dummyLayoutListMode.Visible);
  440. }
  441. //EvaluateServerStatus();
  442. }
  443. protected override void OnPageDestroy(int new_windowId)
  444. {
  445. hook.IsEnabled = false;
  446. hook.UnHook();
  447. hook = null;
  448. UnSubClass();
  449. base.OnPageDestroy(new_windowId);
  450. }
  451. #region Detect application focus
  452. const int GWL_WNDPROC = (-4);
  453. const int WM_ACTIVATEAPP = 0x1C;
  454. // This static method is required because legacy OSes do not support
  455. // SetWindowLongPtr
  456. public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong)
  457. {
  458. if (IntPtr.Size == 8)
  459. return SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
  460. else
  461. return new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
  462. }
  463. [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
  464. private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
  465. [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
  466. private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
  467. [DllImport("user32.dll", EntryPoint = "CallWindowProc")]
  468. private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, int msg, int wParam, int lParam);
  469. private delegate int WindowProc(IntPtr hwnd, int msg, int wParam, int lParam);
  470. IntPtr DefWindowProc = IntPtr.Zero;
  471. WindowProc NewWindowProc = null;
  472. void SubClass()
  473. {
  474. IntPtr hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
  475. NewWindowProc = new WindowProc(MyWindowProc);
  476. DefWindowProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(NewWindowProc));
  477. }
  478. void UnSubClass()
  479. {
  480. IntPtr hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
  481. DefWindowProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, DefWindowProc);
  482. DefWindowProc = IntPtr.Zero;
  483. }
  484. int MyWindowProc(System.IntPtr hWnd, int msg, int wParam, int lParam)
  485. {
  486. if (msg == WM_ACTIVATEAPP)
  487. {
  488. //disable keyboard hook if app is inactive
  489. // wParam=1 when activating, 0 when desactivating
  490. hook.IsEnabled = (wParam == 1);
  491. }
  492. return CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam);
  493. }
  494. #endregion
  495. protected override void OnPageLoad()
  496. {
  497. BaseConfig.MyAnimeLog.Write("Starting page load...");
  498. SubClass();
  499. hook = new KeyboardHook();
  500. hook.KeyDown += new KeyEventHandlerEx(hook_KeyDown);
  501. hook.KeyUp += new KeyEventHandlerEx(hook_KeyUp);
  502. hook.IsEnabled = true;
  503. if (!isFirstInitDone)
  504. OnFirstStart();
  505. currentViewClassification = settings.LastViewClassification;
  506. currentStaticViewID = settings.LastStaticViewID;
  507. currentView = settings.LastView;
  508. groupViewMode = settings.LastGroupViewMode;
  509. m_Facade.CurrentLayout = groupViewMode;
  510. //backdrop.LoadingImage = loadingImage;
  511. Console.Write(JMMServerVM.Instance.ServerOnline.ToString());
  512. LoadFacade();
  513. m_Facade.Focus = true;
  514. SkinSettings.Load();
  515. //MainWindow.anidbProcessor.UpdateVotesHTTP(MainWindow.settings.Username, MainWindow.settings.Password);
  516. autoUpdateTimer.Start();
  517. BaseConfig.MyAnimeLog.Write("Thumbs Setting Folder: {0}", settings.ThumbsFolder);
  518. //searching
  519. setGUIProperty(guiProperty.FindInput, " ");
  520. setGUIProperty(guiProperty.FindText, " ");
  521. setGUIProperty(guiProperty.FindMatch, " ");
  522. search = new SearchCollection();
  523. search.List = m_Facade;
  524. search.ListItemSearchProperty = "DVDLabel";
  525. search.Mode = settings.FindMode;
  526. search.StartWord = settings.FindStartWord;
  527. UpdateSearchPanel(false);
  528. DownloadAllImages();
  529. }
  530. void autoUpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  531. {
  532. }
  533. private void AddFacadeItem(GUIListItem item)
  534. {
  535. int selectedIndex = m_Facade.SelectedListItemIndex;
  536. SaveOrRestoreFacadeItems(false);
  537. m_Facade.Add(item);
  538. if (searchTimer.Enabled)
  539. DoSearch(selectedIndex);
  540. }
  541. private void LoadFacade()
  542. {
  543. try
  544. {
  545. if (workerFacade == null)
  546. {
  547. workerFacade = new BackgroundWorker();
  548. workerFacade.WorkerReportsProgress = true;
  549. workerFacade.WorkerSupportsCancellation = true;
  550. workerFacade.DoWork += new DoWorkEventHandler(workerFacade_DoWork);
  551. workerFacade.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerFacade_RunWorkerCompleted);
  552. workerFacade.ProgressChanged += new ProgressChangedEventHandler(workerFacade_ProgressChanged);
  553. }
  554. lock (workerFacade)
  555. {
  556. if (workerFacade.IsBusy) // we have to wait - complete method will call LoadFacade again
  557. {
  558. if (!workerFacade.CancellationPending)
  559. workerFacade.CancelAsync();
  560. return;
  561. }
  562. prepareLoadFacade();
  563. workerFacade.RunWorkerAsync();
  564. }
  565. }
  566. catch (Exception ex)
  567. {
  568. BaseConfig.MyAnimeLog.Write("LoadFacade ERROR:: {0}", ex);
  569. }
  570. }
  571. void prepareLoadFacade()
  572. {
  573. try
  574. {
  575. GUIControl.ClearControl(this.GetID, m_Facade.GetID);
  576. SetFacade();
  577. this.m_Facade.ListLayout.Clear();
  578. if (this.m_Facade.ThumbnailLayout != null)
  579. this.m_Facade.ThumbnailLayout.Clear();
  580. if (this.m_Facade.FilmstripLayout != null)
  581. this.m_Facade.FilmstripLayout.Clear();
  582. if (this.m_Facade.CoverFlowLayout != null)
  583. this.m_Facade.CoverFlowLayout.Clear();
  584. if (m_Facade != null) m_Facade.Focus = true;
  585. }
  586. catch (Exception ex)
  587. {
  588. BaseConfig.MyAnimeLog.Write(ex.ToString());
  589. }
  590. }
  591. void workerFacade_ProgressChanged(object sender, ProgressChangedEventArgs e)
  592. {
  593. try
  594. {
  595. BackgroundFacadeLoadingArgument arg = e.UserState as BackgroundFacadeLoadingArgument;
  596. if (workerFacade.CancellationPending)
  597. {
  598. BaseConfig.MyAnimeLog.Write("bg_ProgressChanged cancelled");
  599. return;
  600. }
  601. if (arg == null || arg.Type == BackGroundLoadingArgumentType.None) return;
  602. switch (arg.Type)
  603. {
  604. case BackGroundLoadingArgumentType.ListFullElement:
  605. case BackGroundLoadingArgumentType.ListElementForDelayedImgLoading:
  606. List<GUIListItem> ls = arg.Argument as List<GUIListItem>;
  607. if (m_Facade != null && ls != null && ls.Count > 0)
  608. {
  609. foreach (GUIListItem gli in ls)
  610. {
  611. //BaseConfig.MyAnimeLog.Write("workerFacade_ProgressChanged - ListElementForDelayedImgLoading");
  612. // Messages are not recieved in OnMessage for Filmstrip, instead subscribe to OnItemSelected
  613. if (m_Facade.CurrentLayout == GUIFacadeControl.Layout.Filmstrip || m_Facade.CurrentLayout == GUIFacadeControl.Layout.CoverFlow)
  614. gli.OnItemSelected += new GUIListItem.ItemSelectedHandler(onFacadeItemSelected);
  615. AddFacadeItem(gli);
  616. if (arg.Type == BackGroundLoadingArgumentType.ListElementForDelayedImgLoading)
  617. {
  618. if (itemsForDelayedImgLoading == null)
  619. itemsForDelayedImgLoading = new List<GUIListItem>();
  620. itemsForDelayedImgLoading.Add(gli);
  621. }
  622. }
  623. if (this.m_Facade.SelectedListItemIndex < 1)
  624. {
  625. this.m_Facade.Focus = true;
  626. SelectItem(arg.IndexArgument);
  627. }
  628. }
  629. break;
  630. case BackGroundLoadingArgumentType.DelayedImgLoading:
  631. {
  632. if (itemsForDelayedImgLoading != null && itemsForDelayedImgLoading.Count > arg.IndexArgument)
  633. {
  634. string image = arg.Argument as string;
  635. itemsForDelayedImgLoading[arg.IndexArgument].IconImageBig = image;
  636. }
  637. }
  638. break;
  639. case BackGroundLoadingArgumentType.DelayedImgInit:
  640. itemsForDelayedImgLoading = null;
  641. break;
  642. case BackGroundLoadingArgumentType.SetFacadeMode:
  643. GUIFacadeControl.Layout viewMode = (GUIFacadeControl.Layout)arg.Argument;
  644. //setFacadeMode(viewMode);
  645. break;
  646. case BackGroundLoadingArgumentType.ElementSelection:
  647. {
  648. // thread told us which element it'd like to select
  649. // however the user might have already started moving around
  650. // if that is the case, we don't select anything
  651. if (this.m_Facade != null && this.m_Facade.SelectedListItemIndex < 1)
  652. {
  653. this.m_Facade.Focus = true;
  654. SelectItem(arg.IndexArgument);
  655. }
  656. }
  657. break;
  658. }
  659. }
  660. catch (Exception ex)
  661. {
  662. BaseConfig.MyAnimeLog.Write(string.Format("Error in bg_ProgressChanged: {0}: {1}", ex.Message, ex.InnerException));
  663. }
  664. }
  665. bool m_bQuickSelect = false;
  666. void SelectItem(int index)
  667. {
  668. //BaseConfig.MyAnimeLog.Write("SelectItem: {0}", index.ToString());
  669. // Hack for 'set' SelectedListItemIndex not being implemented in Filmstrip View
  670. // Navigate to selected using OnAction instead
  671. if (m_Facade.CurrentLayout == GUIFacadeControl.Layout.Filmstrip || m_Facade.CurrentLayout == GUIFacadeControl.Layout.CoverFlow)
  672. {
  673. if (listLevel == Listlevel.Series || listLevel == Listlevel.Group)
  674. {
  675. int currentIndex = m_Facade.SelectedListItemIndex;
  676. if (index >= 0 && index < m_Facade.Count && index != currentIndex)
  677. {
  678. m_bQuickSelect = true;
  679. int increment = (currentIndex < index) ? 1 : -1;
  680. MediaPortal.GUI.Library.Action.ActionType actionType = (currentIndex < index) ? MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_RIGHT : MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_LEFT;
  681. for (int i = currentIndex; i != index; i += increment)
  682. {
  683. // Now push fields to skin
  684. if (i == (index - increment))
  685. m_bQuickSelect = false;
  686. m_Facade.OnAction(new MediaPortal.GUI.Library.Action(actionType, 0, 0));
  687. }
  688. m_bQuickSelect = false;
  689. }
  690. else
  691. {
  692. if (listLevel == Listlevel.Group && m_Facade.Count > 0)
  693. {
  694. Group_OnItemSelected(m_Facade.SelectedListItem);
  695. }
  696. }
  697. }
  698. }
  699. else
  700. m_Facade.SelectedListItemIndex = index;
  701. }
  702. void workerFacade_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  703. {
  704. // ZF - seems to be crashing because of facade being null sometimes, before getting inside the plugin
  705. if (m_Facade == null)
  706. return;
  707. if (e.Cancelled)
  708. {
  709. LoadFacade(); // we only cancel if the user clicked something while we were still loading
  710. // whatever was selected we will enter (this is because m_selected whatever will not get updated
  711. // even if the user selects somethign else while we wait for cancellation due to it being a different listlevel)
  712. return;
  713. }
  714. if (m_Facade == null)
  715. return;
  716. m_Facade.Focus = true;
  717. }
  718. void workerFacade_DoWork(object sender, DoWorkEventArgs e)
  719. {
  720. bgLoadFacade();
  721. if (workerFacade.CancellationPending)
  722. e.Cancel = true;
  723. }
  724. void ReportFacadeLoadingProgress(BackGroundLoadingArgumentType type, int indexArgument, object state)
  725. {
  726. if (!workerFacade.CancellationPending)
  727. {
  728. BackgroundFacadeLoadingArgument Arg = new BackgroundFacadeLoadingArgument();
  729. Arg.Type = type;
  730. Arg.IndexArgument = indexArgument;
  731. Arg.Argument = state;
  732. workerFacade.ReportProgress(0, Arg);
  733. }
  734. }
  735. void bgLoadFacade()
  736. {
  737. try
  738. {
  739. GUIListItem item = null;
  740. int selectedIndex = -1;
  741. int count = 0;
  742. bool delayedImageLoading = false;
  743. List<AnimeGroupVM> groups = null;
  744. List<GroupFilterVM> groupFilters = null;
  745. List<GUIListItem> list = new List<GUIListItem>();
  746. BackGroundLoadingArgumentType type = BackGroundLoadingArgumentType.None;
  747. switch (listLevel)
  748. {
  749. #region Group Filters
  750. case Listlevel.GroupFilter:
  751. {
  752. // List/Poster/Banner
  753. setGUIProperty("SimpleCurrentView", "Group Filters");
  754. if (groupViewMode != GUIFacadeControl.Layout.List)
  755. {
  756. // reinit the itemsList
  757. delayedImageLoading = true;
  758. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgInit, 0, null);
  759. }
  760. // text as usual
  761. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.SetFacadeMode, 0, GUIFacadeControl.Layout.List);
  762. if (workerFacade.CancellationPending)
  763. return;
  764. BaseConfig.MyAnimeLog.Write("bgLoadFacde: Group Filters");
  765. groupFilters = FacadeHelper.GetGroupFilters();
  766. type = BackGroundLoadingArgumentType.ListFullElement;
  767. setGUIProperty(guiProperty.GroupCount, groupFilters.Count.ToString());
  768. foreach (GroupFilterVM grpFilter in groupFilters)
  769. {
  770. if (workerFacade.CancellationPending) return;
  771. try
  772. {
  773. item = null;
  774. SetGroupFilterListItem(ref item, grpFilter);
  775. if (curGroupFilter != null)
  776. {
  777. if (grpFilter.GroupFilterID.Value == curGroupFilter.GroupFilterID.Value)
  778. {
  779. selectedIndex = count;
  780. }
  781. }
  782. else
  783. {
  784. if (selectedIndex == -1)
  785. selectedIndex = count;
  786. }
  787. if (workerFacade.CancellationPending) return;
  788. else
  789. {
  790. list.Add(item);
  791. }
  792. }
  793. catch (Exception ex)
  794. {
  795. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  796. BaseConfig.MyAnimeLog.Write(msg);
  797. }
  798. count++;
  799. }
  800. }
  801. break;
  802. #endregion
  803. #region Group Filters - Sub
  804. case Listlevel.GroupFilterSub:
  805. {
  806. // List/Poster/Banner
  807. setGUIProperty("SimpleCurrentView", curGroupFilter.GroupFilterName);
  808. if (groupViewMode != GUIFacadeControl.Layout.List)
  809. {
  810. // reinit the itemsList
  811. delayedImageLoading = true;
  812. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgInit, 0, null);
  813. }
  814. // text as usual
  815. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.SetFacadeMode, 0, GUIFacadeControl.Layout.List);
  816. if (workerFacade.CancellationPending)
  817. return;
  818. BaseConfig.MyAnimeLog.Write("bgLoadFacde: Group Filters");
  819. groupFilters = FacadeHelper.GetGroupFilters();
  820. type = BackGroundLoadingArgumentType.ListFullElement;
  821. setGUIProperty(guiProperty.GroupCount, "0");
  822. foreach (GroupFilterVM grpFilter in FacadeHelper.GetTopLevelPredefinedGroupFilters())
  823. {
  824. if (workerFacade.CancellationPending) return;
  825. try
  826. {
  827. item = null;
  828. SetGroupFilterListItem(ref item, grpFilter);
  829. if (curGroupFilter != null)
  830. {
  831. if (grpFilter.GroupFilterID.Value == curGroupFilter.GroupFilterID.Value)
  832. {
  833. selectedIndex = count;
  834. }
  835. }
  836. else
  837. {
  838. if (selectedIndex == -1)
  839. selectedIndex = count;
  840. }
  841. if (workerFacade.CancellationPending) return;
  842. else
  843. {
  844. list.Add(item);
  845. }
  846. }
  847. catch (Exception ex)
  848. {
  849. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  850. BaseConfig.MyAnimeLog.Write(msg);
  851. }
  852. count++;
  853. }
  854. }
  855. break;
  856. #endregion
  857. #region Group Filters - Sub2
  858. case Listlevel.GroupFilterSub2:
  859. {
  860. // List/Poster/Banner
  861. setGUIProperty("SimpleCurrentView", curGroupFilter.GroupFilterName);
  862. if (groupViewMode != GUIFacadeControl.Layout.List)
  863. {
  864. // reinit the itemsList
  865. delayedImageLoading = true;
  866. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgInit, 0, null);
  867. }
  868. // text as usual
  869. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.SetFacadeMode, 0, GUIFacadeControl.Layout.List);
  870. if (workerFacade.CancellationPending)
  871. return;
  872. BaseConfig.MyAnimeLog.Write("bgLoadFacde: Group Filters");
  873. groupFilters = FacadeHelper.GetGroupFilters();
  874. type = BackGroundLoadingArgumentType.ListFullElement;
  875. setGUIProperty(guiProperty.GroupCount, "0");
  876. foreach (GroupFilterVM grpFilter in FacadeHelper.GetGroupFiltersForPredefined(curGroupFilterSub))
  877. {
  878. if (workerFacade.CancellationPending) return;
  879. try
  880. {
  881. item = null;
  882. SetGroupFilterListItem(ref item, grpFilter);
  883. if (curGroupFilter != null)
  884. {
  885. if (grpFilter.GroupFilterID.Value == curGroupFilter.GroupFilterID.Value)
  886. {
  887. selectedIndex = count;
  888. }
  889. }
  890. else
  891. {
  892. if (selectedIndex == -1)
  893. selectedIndex = count;
  894. }
  895. if (workerFacade.CancellationPending) return;
  896. else
  897. {
  898. list.Add(item);
  899. }
  900. }
  901. catch (Exception ex)
  902. {
  903. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  904. BaseConfig.MyAnimeLog.Write(msg);
  905. }
  906. count++;
  907. }
  908. }
  909. break;
  910. #endregion
  911. #region Groups
  912. case Listlevel.Group:
  913. {
  914. // List/Poster/Banner
  915. setGUIProperty("SimpleCurrentView", curGroupFilter.GroupFilterName);
  916. if (groupViewMode != GUIFacadeControl.Layout.List)
  917. {
  918. // reinit the itemsList
  919. delayedImageLoading = true;
  920. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgInit, 0, null);
  921. }
  922. if (groupViewMode != GUIFacadeControl.Layout.List)
  923. {
  924. // graphical
  925. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.SetFacadeMode, 0, GUIFacadeControl.Layout.AlbumView);
  926. }
  927. else
  928. {
  929. // text as usual
  930. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.SetFacadeMode, 0, GUIFacadeControl.Layout.List);
  931. }
  932. if (workerFacade.CancellationPending)
  933. return;
  934. if (curGroupFilterSub2 == null)
  935. groups = JMMServerHelper.GetAnimeGroupsForFilter(curGroupFilter);
  936. else
  937. {
  938. groups = new List<AnimeGroupVM>();
  939. List<AnimeGroupVM> tempGroups = JMMServerHelper.GetAnimeGroupsForFilter(GroupFilterHelper.AllGroupsFilter);
  940. foreach (AnimeGroupVM grp in tempGroups)
  941. {
  942. if (curGroupFilterSub2.GroupFilterID.Value == Constants.StaticGF.Predefined_Categories_Child)
  943. {
  944. if (grp.Categories.Contains(curGroupFilterSub2.PredefinedCriteria))
  945. groups.Add(grp);
  946. }
  947. if (curGroupFilterSub2.GroupFilterID.Value == Constants.StaticGF.Predefined_Years_Child)
  948. {
  949. // find all the groups that qualify by this year
  950. int startYear = 0;
  951. if (!grp.Stat_AirDate_Min.HasValue) continue;
  952. startYear = grp.Stat_AirDate_Min.Value.Year;
  953. int endYear = int.MaxValue;
  954. if (grp.Stat_AirDate_Max.HasValue) endYear = grp.Stat_AirDate_Max.Value.Year;
  955. int critYear = 0;
  956. if (!int.TryParse(curGroupFilterSub2.PredefinedCriteria, out critYear)) continue;
  957. if (critYear >= startYear && critYear <= endYear) groups.Add(grp);
  958. }
  959. }
  960. }
  961. // re-sort if user has set a quick sort
  962. if (GroupFilterQuickSorts.ContainsKey(curGroupFilter.GroupFilterID.Value))
  963. {
  964. BaseConfig.MyAnimeLog.Write("APPLYING QUICK SORT");
  965. GroupFilterSorting sortType = GroupFilterHelper.GetEnumForText_Sorting(GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value].SortType);
  966. SortPropOrFieldAndDirection sortProp = GroupFilterHelper.GetSortDescription(sortType, GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value].SortDirection);
  967. List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>();
  968. sortCriteria.Add(sortProp);
  969. groups = Sorting.MultiSort<AnimeGroupVM>(groups, sortCriteria);
  970. }
  971. // Update Series Count Property
  972. setGUIProperty(guiProperty.GroupCount, groups.Count.ToString());
  973. type = (groupViewMode != GUIFacadeControl.Layout.List) ? BackGroundLoadingArgumentType.ListElementForDelayedImgLoading : BackGroundLoadingArgumentType.ListFullElement;
  974. int seriesCount = 0;
  975. double totalTime = 0;
  976. DateTime start = DateTime.Now;
  977. BaseConfig.MyAnimeLog.Write("Building groups: " + curGroupFilter.GroupFilterName);
  978. foreach (AnimeGroupVM grp in groups)
  979. {
  980. if (workerFacade.CancellationPending) return;
  981. try
  982. {
  983. item = null;
  984. //BaseConfig.MyAnimeLog.Write(string.Format("{0} - {1}", grp.GroupName, grp.AniDBRating));
  985. SetGroupListItem(ref item, grp);
  986. if (settings.HideWatchedFiles && grp.UnwatchedEpisodeCount <= 0)
  987. {
  988. //watched files should be hidden and entire group is watched
  989. // -> hide entire group
  990. continue;
  991. }
  992. seriesCount += grp.AllSeriesCount;
  993. if (curAnimeGroup != null)
  994. {
  995. if (grp.AnimeGroupID == curAnimeGroup.AnimeGroupID)
  996. {
  997. selectedIndex = count;
  998. }
  999. }
  1000. else
  1001. {
  1002. if (selectedIndex == -1)
  1003. selectedIndex = count;
  1004. }
  1005. if (workerFacade.CancellationPending) return;
  1006. else
  1007. {
  1008. list.Add(item);
  1009. }
  1010. }
  1011. catch (Exception ex)
  1012. {
  1013. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  1014. BaseConfig.MyAnimeLog.Write(msg);
  1015. }
  1016. count++;
  1017. }
  1018. TimeSpan ts2 = DateTime.Now - start;
  1019. totalTime += ts2.TotalMilliseconds;
  1020. BaseConfig.MyAnimeLog.Write("Total time for rendering groups: {0}-{1}", groups.Count, totalTime);
  1021. setGUIProperty(guiProperty.SeriesCount, seriesCount.ToString());
  1022. }
  1023. break;
  1024. #endregion
  1025. #region Series
  1026. case Listlevel.Series:
  1027. {
  1028. // this level includes series as well as sub-groups
  1029. if (seriesViewMode != GUIFacadeControl.Layout.List)
  1030. {
  1031. // reinit the itemsList
  1032. delayedImageLoading = true;
  1033. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgInit, 0, null);
  1034. }
  1035. if (workerFacade.CancellationPending) return;
  1036. List<SortPropOrFieldAndDirection> sortCriteria = null;
  1037. List<AnimeGroupVM> subGroups = curAnimeGroupViewed.SubGroups;
  1038. if (subGroups.Count > 0)
  1039. {
  1040. sortCriteria = new List<SortPropOrFieldAndDirection>();
  1041. sortCriteria.Add(new SortPropOrFieldAndDirection("SortName", false, SortType.eString));
  1042. subGroups = Sorting.MultiSort<AnimeGroupVM>(subGroups, sortCriteria);
  1043. }
  1044. // get the series for this group
  1045. List<AnimeSeriesVM> seriesList = curAnimeGroupViewed.ChildSeries;
  1046. if (seriesList.Count > 0)
  1047. {
  1048. sortCriteria = new List<SortPropOrFieldAndDirection>();
  1049. sortCriteria.Add(new SortPropOrFieldAndDirection("AirDate", false, SortType.eDateTime));
  1050. seriesList = Sorting.MultiSort<AnimeSeriesVM>(seriesList, sortCriteria);
  1051. }
  1052. //if (seriesList.Count == 0)
  1053. // bFacadeEmpty = true;
  1054. // Update Series Count Property
  1055. setGUIProperty(guiProperty.SeriesCount, seriesList.Count.ToString());
  1056. // now sort the groups by air date
  1057. type = BackGroundLoadingArgumentType.ListFullElement;
  1058. foreach (AnimeGroupVM grp in subGroups)
  1059. {
  1060. if (workerFacade.CancellationPending) return;
  1061. try
  1062. {
  1063. item = null;
  1064. SetGroupListItem(ref item, grp);
  1065. if (settings.HideWatchedFiles && grp.UnwatchedEpisodeCount <= 0)
  1066. {
  1067. //watched files should be hidden and entire group is watched
  1068. // -> hide entire group
  1069. continue;
  1070. }
  1071. if (workerFacade.CancellationPending) return;
  1072. else
  1073. {
  1074. list.Add(item);
  1075. }
  1076. }
  1077. catch (Exception ex)
  1078. {
  1079. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  1080. BaseConfig.MyAnimeLog.Write(msg);
  1081. }
  1082. }
  1083. foreach (AnimeSeriesVM ser in seriesList)
  1084. {
  1085. //BaseConfig.MyAnimeLog.Write("LoadFacade-Series:: {0}", ser);
  1086. if (workerFacade.CancellationPending) return;
  1087. try
  1088. {
  1089. item = null;
  1090. SetSeriesListItem(ref item, ser);
  1091. if (settings.HideWatchedFiles && ser.UnwatchedEpisodeCount <= 0)
  1092. {
  1093. //watched files should be hidden and entire series is watched
  1094. // -> hide entire series
  1095. continue;
  1096. }
  1097. if (workerFacade.CancellationPending) return;
  1098. else
  1099. {
  1100. list.Add(item);
  1101. }
  1102. }
  1103. catch (Exception ex)
  1104. {
  1105. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  1106. BaseConfig.MyAnimeLog.Write(msg);
  1107. }
  1108. count++;
  1109. }
  1110. }
  1111. break;
  1112. #endregion
  1113. #region Episode Types
  1114. case Listlevel.EpisodeTypes:
  1115. {
  1116. if (workerFacade.CancellationPending) return;
  1117. //List<AnimeEpisodeType> anEpTypes = AnimeSeries.GetEpisodeTypes(curAnimeSeries.AnimeSeriesID.Value);
  1118. type = BackGroundLoadingArgumentType.ListFullElement;
  1119. foreach (AnimeEpisodeTypeVM anEpType in curAnimeSeries.EpisodeTypesToDisplay)
  1120. {
  1121. item = null;
  1122. SetEpisodeTypeListItem(ref item, anEpType);
  1123. if (workerFacade.CancellationPending) return;
  1124. else
  1125. {
  1126. list.Add(item);
  1127. }
  1128. count++;
  1129. }
  1130. }
  1131. break;
  1132. #endregion
  1133. #region Episodes
  1134. case Listlevel.Episode:
  1135. {
  1136. if (workerFacade.CancellationPending) return;
  1137. if (curAnimeSeries == null) return;
  1138. // get the episodes for this series / episode types
  1139. //BaseConfig.MyAnimeLog.Write("GetEpisodes:: {0}", curAnimeSeries.AnimeSeriesID.Value);
  1140. //List<AnimeEpisode> episodeList = AnimeSeries.GetEpisodes(curAnimeSeries.AnimeSeriesID.Value);
  1141. curAnimeSeries.RefreshEpisodes();
  1142. List<AnimeEpisodeVM> episodeList = curAnimeSeries.GetEpisodesToDisplay(curAnimeEpisodeType.EpisodeType);
  1143. // Update Series Count Property
  1144. //setGUIProperty(guiProperty.SeriesCount, episodeList.Count.ToString());
  1145. bool foundFirstUnwatched = false;
  1146. type = BackGroundLoadingArgumentType.ListFullElement;
  1147. foreach (AnimeEpisodeVM ep in episodeList)
  1148. {
  1149. //BaseConfig.MyAnimeLog.Write("LoadFacade-Episodes:: {0}", ep);
  1150. if (workerFacade.CancellationPending) return;
  1151. try
  1152. {
  1153. item = null;
  1154. bool isWatched = SetEpisodeListItem(ref item, ep);
  1155. if (isWatched && settings.HideWatchedFiles)
  1156. continue;
  1157. if (!foundFirstUnwatched && !isWatched && ep.LocalFileCount > 0)
  1158. {
  1159. selectedIndex = count;
  1160. foundFirstUnwatched = true;
  1161. }
  1162. if (workerFacade.CancellationPending) return;
  1163. else
  1164. {
  1165. list.Add(item);
  1166. }
  1167. }
  1168. catch (Exception ex)
  1169. {
  1170. string msg = string.Format("The 'LoadFacade' function has generated an error displaying list items: {0} - {1}", listLevel, ex.ToString());
  1171. BaseConfig.MyAnimeLog.Write(msg);
  1172. }
  1173. count++;
  1174. }
  1175. SetFanartForEpisodes();
  1176. }
  1177. setGUIProperty(guiProperty.EpisodeCount, count.ToString());
  1178. break;
  1179. #endregion
  1180. }
  1181. #region Report ItemToAutoSelect
  1182. if (selectedIndex == -1)
  1183. selectedIndex = 0;
  1184. BaseConfig.MyAnimeLog.Write("Report ItemToAutoSelect: {0}", selectedIndex.ToString());
  1185. #endregion
  1186. ReportFacadeLoadingProgress(type, selectedIndex, list);
  1187. SetFacade();
  1188. #region DelayedImageLoading
  1189. // we only use delayed image loading for the main groups view
  1190. // since the other views will not have enough items to be concerned about
  1191. if (delayedImageLoading && groups != null)
  1192. {
  1193. BaseConfig.MyAnimeLog.Write("delayedImageLoading: Started");
  1194. // This is a perfect oportunity to use all cores on the machine
  1195. // we queue each image up to be loaded, resize and put them into memory in parallel
  1196. // Set the amount of threads to the amount of CPU cores in the machine.
  1197. int MaxThreads = Environment.ProcessorCount;
  1198. // This keeps track of how many of the threads have terminated
  1199. int done = 0;
  1200. // Pool of threads.
  1201. List<Thread> ImageLoadThreadPool = new List<Thread>();
  1202. // List of Groups in the facade. This is checked by the threads to get groups to load fanart for.
  1203. List<KeyValuePair<AnimeGroupVM, int>> FacadeGroups = new List<KeyValuePair<AnimeGroupVM, int>>();
  1204. // Fill the list of groups in order of their proximity to the current selection. This makes the groups currently shown load first, and then further out.
  1205. FacadeHelper.ProximityForEach(groups, selectedIndex, delegate(AnimeGroupVM grp, int currIndex)
  1206. {
  1207. FacadeGroups.Add(new KeyValuePair<AnimeGroupVM, int>(grp, currIndex));
  1208. });
  1209. // Create number of threads based on MaxThreads. MaxThreads should be the amount of CPU cores.
  1210. for (int i = 0; i < MaxThreads; i++)
  1211. {
  1212. // Create a new thread. The function it should run is written here using the delegate word.
  1213. Thread thread = new Thread(new ThreadStart(delegate()
  1214. {
  1215. // The number of groups left to load in the facade. Is renewed on each loop of the threads do while loop.
  1216. int FacadeGroupCount = 0;
  1217. do
  1218. {
  1219. // create varible to store the group.
  1220. KeyValuePair<AnimeGroupVM, int> group = new KeyValuePair<AnimeGroupVM, int>();
  1221. // The FacadeGroups list is accessed by all threads, therefor it is in a locked section to make it thread safe.
  1222. lock (FacadeGroups)
  1223. {
  1224. // Dtore into the facadeGroupCount varible which is in the threads scope.
  1225. FacadeGroupCount = FacadeGroups.Count;
  1226. // If there are groups left to load, and the facade is not stopping, load a group and remove it from the list.
  1227. if (FacadeGroupCount > 0 && !workerFacade.CancellationPending)
  1228. {
  1229. group = FacadeGroups[0];
  1230. FacadeGroups.RemoveAt(0);
  1231. }
  1232. // Ether their are no more groups or the facade is stopping, so we should exit while marking us as finished.
  1233. else
  1234. {
  1235. Interlocked.Increment(ref done);
  1236. return;
  1237. }
  1238. }
  1239. // If a group was loaded, get it's image, then report that the image is loaded to the facadeworker.
  1240. // the facade worker (which is another thread itself) will handle putting the image into the facade for us.
  1241. if (group.Key != null)
  1242. {
  1243. string img = ImageAllocator.GetGroupImage(group.Key, groupViewMode);
  1244. ReportFacadeLoadingProgress(BackGroundLoadingArgumentType.DelayedImgLoading, group.Value, img);
  1245. }
  1246. }
  1247. // while there are still groups left to load, repeat loop.
  1248. while (FacadeGroupCount > 0);
  1249. }));
  1250. // Make the thread a lower priority. Everything else should have a higher priority then this background image loading.
  1251. thread.Priority = ThreadPriority.BelowNormal;
  1252. // add this thread to the thread pool.
  1253. ImageLoadThreadPool.Add(thread);
  1254. }
  1255. // for each thread in the thread pool, start it.
  1256. foreach (Thread thread in ImageLoadThreadPool)
  1257. thread.Start();
  1258. // Do not continue untill all the image loading threads are finished. Currently we are in the facade background worker thread. The image loading threads call
  1259. // this thread's ProgressChanged function, which then adds the images that were loaded in to the facade. If we go beyond this point before the image loading
  1260. // threads finish, then that ProgressChanged function might not exisit any more since this facade background worker thread could have finished already.
  1261. while (done < MaxThreads)
  1262. Thread.Sleep(500);
  1263. BaseConfig.MyAnimeLog.Write("ImageLoad: Finished");
  1264. }
  1265. #endregion
  1266. if (animeSeriesIDToBeRated.HasValue && BaseConfig.Settings.DisplayRatingDialogOnCompletion)
  1267. {
  1268. JMMServerBinary.Contract_AnimeSeries contract = JMMServerVM.Instance.clientBinaryHTTP.GetSeries(animeSeriesIDToBeRated.Value,
  1269. JMMServerVM.Instance.CurrentUser.JMMUserID);
  1270. if (contract != null)
  1271. {
  1272. AnimeSeriesVM ser = new AnimeSeriesVM(contract);
  1273. Utils.PromptToRateSeriesOnCompletion(ser);
  1274. }
  1275. animeSeriesIDToBeRated = null;
  1276. }
  1277. }
  1278. catch (Exception e)
  1279. {
  1280. BaseConfig.MyAnimeLog.Write("The 'LoadFacade' function has generated an error: {0}", e.ToString());
  1281. }
  1282. }
  1283. private void SetEpisodeTypeListItem(ref GUIListItem item, AnimeEpisodeTypeVM epType)
  1284. {
  1285. string sIconList = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_ListIcon.png";
  1286. string sUnWatchedFilename = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_UnWatched_left.png";
  1287. try
  1288. {
  1289. item = new GUIListItem(epType.EpisodeTypeDescription);
  1290. item.DVDLabel = epType.EpisodeTypeDescription;
  1291. item.TVTag = epType;
  1292. int unwatched = 0;
  1293. int watched = 0;
  1294. if (curAnimeSeries != null)
  1295. curAnimeSeries.GetWatchedUnwatchedCount(epType.EpisodeType, ref unwatched, ref watched);
  1296. item.IsPlayed = (unwatched == 0);
  1297. View.eLabelStyleGroups style = View.eLabelStyleGroups.WatchedUnwatched;
  1298. switch (style)
  1299. {
  1300. case View.eLabelStyleGroups.WatchedUnwatched:
  1301. string space = " ";
  1302. item.Label3 = space + watched.ToString().PadLeft(3, '0');
  1303. item.IconImage = sIconList;
  1304. item.Label2 = unwatched.ToString().PadLeft(3, '0');
  1305. break;
  1306. /*case View.eLabelStyleGroups.Unwatched:
  1307. if (unwatched > 0)
  1308. {
  1309. item.IconImage = sUnWatchedFilename;
  1310. item.Label3 = unwatched.ToString() + " New";
  1311. item.Label2 = " ";
  1312. }
  1313. else
  1314. {
  1315. item.Label2 = " ";
  1316. item.Label3 = " ";
  1317. }
  1318. break;
  1319. case View.eLabelStyleGroups.TotalEpisodes:
  1320. int totalEps = unwatched + watched;
  1321. item.IconImage = sUnWatchedFilename;
  1322. item.Label3 = totalEps.ToString() + " Episodes";
  1323. item.Label2 = " ";
  1324. break;*/
  1325. }
  1326. }
  1327. catch (Exception ex)
  1328. {
  1329. BaseConfig.MyAnimeLog.Write("Failed to create episode type item: {0}", ex);
  1330. }
  1331. }
  1332. private bool SetSeriesListItem(ref GUIListItem item, AnimeSeriesVM ser)
  1333. {
  1334. string sIconList = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_ListIcon.png";
  1335. string sUnWatchedFilename = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_UnWatched_left.png";
  1336. if (seriesViewMode != GUIFacadeControl.Layout.List)
  1337. {
  1338. // Graphical Mode
  1339. item = new GUIListItem();
  1340. //item.IconImage = item.IconImageBig = ImageAllocator.GetSeriesBanner(ser, seriesViewMode);
  1341. }
  1342. else
  1343. {
  1344. item = new GUIListItem(ser.SeriesName);
  1345. View.eLabelStyleGroups style = settings.LabelStyleGroups;
  1346. switch (style)
  1347. {
  1348. case View.eLabelStyleGroups.WatchedUnwatched:
  1349. string unwatched = ser.UnwatchedEpisodeCount.ToString();
  1350. string watched = ser.WatchedEpisodeCount.ToString();
  1351. string space = " ";
  1352. item.Label3 = space + watched.ToString().PadLeft(3, '0');
  1353. item.IconImage = sIconList;
  1354. item.Label2 = unwatched.ToString().PadLeft(3, '0');
  1355. break;
  1356. case View.eLabelStyleGroups.Unwatched:
  1357. if (ser.UnwatchedEpisodeCount > 0)
  1358. {
  1359. item.IconImage = sUnWatchedFilename;
  1360. item.Label3 = ser.UnwatchedEpisodeCount.ToString() + " New";
  1361. item.Label2 = " ";
  1362. }
  1363. else
  1364. {
  1365. item.Label2 = " ";
  1366. item.Label3 = " ";
  1367. }
  1368. break;
  1369. case View.eLabelStyleGroups.TotalEpisodes:
  1370. int totalEps = ser.UnwatchedEpisodeCount + ser.WatchedEpisodeCount;
  1371. item.IconImage = sUnWatchedFilename;
  1372. item.Label3 = totalEps.ToString() + " Episodes";
  1373. item.Label2 = " ";
  1374. break;
  1375. }
  1376. }
  1377. item.DVDLabel = ser.SeriesName;
  1378. item.TVTag = ser;
  1379. item.IsPlayed = (ser.UnwatchedEpisodeCount == 0);
  1380. return true;
  1381. }
  1382. private bool SetGroupFilterListItem(ref GUIListItem item, GroupFilterVM grpFilter)
  1383. {
  1384. item = new GUIListItem(grpFilter.GroupFilterName);
  1385. item.DVDLabel = grpFilter.GroupFilterName;
  1386. item.TVTag = grpFilter;
  1387. item.IsPlayed = false;
  1388. return true;
  1389. }
  1390. private bool SetGroupListItem(ref GUIListItem item, AnimeGroupVM grp)
  1391. {
  1392. if (groupViewMode != GUIFacadeControl.Layout.List)
  1393. {
  1394. // Graphical Mode
  1395. item = new GUIListItem();
  1396. }
  1397. else
  1398. {
  1399. string sIconList = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_ListIcon.png"; // MyAnime3\anime3_ListIcon
  1400. //string sUnWatchedFilename = GUIGraphicsContext.Skin + @"\Media\MyAnime3\anime3_UnWatched_left.png";
  1401. item = new GUIListItem(grp.GroupName);
  1402. View.eLabelStyleGroups style = View.eLabelStyleGroups.WatchedUnwatched;
  1403. switch (style)
  1404. {
  1405. case View.eLabelStyleGroups.WatchedUnwatched:
  1406. // Available (Files are Local) Images
  1407. string unwatched = grp.UnwatchedEpisodeCount.ToString();
  1408. string watched = grp.WatchedEpisodeCount.ToString();
  1409. string space = " ";
  1410. //item.Label3 = space + watched.ToString().PadLeft(3, '0');
  1411. item.Label3 = space + watched.ToString().PadLeft(3, '0');
  1412. item.IconImage = sIconList;
  1413. item.Label2 = unwatched.ToString().PadLeft(3, '0');
  1414. break;
  1415. /*case View.eLabelStyleGroups.Unwatched:
  1416. if (grp.UnwatchedEpisodeCount > 0)
  1417. {
  1418. item.IconImage = sUnWatchedFilename;
  1419. item.Label3 = grp.UnwatchedEpisodeCount.ToString() + " New";
  1420. item.Label2 = " ";
  1421. }
  1422. else
  1423. {
  1424. item.Label2 = " ";
  1425. item.Label3 = " ";
  1426. }
  1427. break;
  1428. case View.eLabelStyleGroups.TotalEpisodes:
  1429. int totalEps = grp.UnwatchedEpisodeCount + grp.WatchedEpisodeCount;
  1430. item.IconImage = sUnWatchedFilename;
  1431. item.Label3 = totalEps.ToString() + " Eps";
  1432. item.Label2 = " ";
  1433. break;*/
  1434. }
  1435. }
  1436. item.DVDLabel = grp.GroupName;
  1437. item.TVTag = grp;
  1438. item.IsPlayed = (grp.UnwatchedEpisodeCount == 0);
  1439. return true;
  1440. }
  1441. /// <summary>
  1442. ///
  1443. /// </summary>
  1444. /// <param name="item"></param>
  1445. /// <param name="ep"></param>
  1446. /// <returns>whether this episode has been watched</returns>
  1447. private bool SetEpisodeListItem(ref GUIListItem item, AnimeEpisodeVM ep)
  1448. {
  1449. try
  1450. {
  1451. if (item == null)
  1452. {
  1453. item = new GUIListItem();
  1454. item.Label = ep.EpisodeNumberAndName;
  1455. item.Label2 = " ";
  1456. item.DVDLabel = ep.EpisodeNumberAndName;
  1457. item.TVTag = ep;
  1458. }
  1459. // for each anime episode we may actually have one or more files
  1460. // if one of the files has been watched we consider the episode watched
  1461. View.eLabelStyleEpisodes style = settings.LabelStyleEpisodes;
  1462. // get the AniDB_Episode info for this AnimeEpisode
  1463. /*if (ep.AniDB_EpisodeID.HasValue)
  1464. {
  1465. AniDB_Episode aniEp = new AniDB_Episode();
  1466. if (aniEp.Load(ep.AniDB_EpisodeID.Value))
  1467. {
  1468. string space = "";
  1469. if (style == View.eLabelStyleEpisodes.IconsDate)
  1470. item.Label3 = space + Utils.GetAniDBDateWithShortYear(aniEp.AirDate);
  1471. }
  1472. }*/
  1473. // get all the LocalFile records for this episode
  1474. bool isWatched = (ep.IsWatched == 1);
  1475. item.IsRemote = ep.LocalFileCount == 0;
  1476. item.IsPlayed = isWatched;
  1477. return isWatched;
  1478. }
  1479. catch (Exception ex)
  1480. {
  1481. BaseConfig.MyAnimeLog.Write("Failed to create episode item: {0}", ex);
  1482. return false;
  1483. }
  1484. }
  1485. private void TestPosters()
  1486. {
  1487. GUIControl.ClearControl(this.GetID, m_Facade.GetID);
  1488. foreach (string fileName in Directory.GetFiles(@"C:\Users\All Users\Team MediaPortal\MediaPortal\thumbs\AnimeThumbs\AniDB", "*.jpg"))
  1489. {
  1490. GUIListItem item = new GUIListItem("");
  1491. item.Label = "Label";
  1492. item.ThumbnailImage = fileName;
  1493. AddFacadeItem(item);
  1494. }
  1495. }
  1496. private void TestBanners()
  1497. {
  1498. GUIControl.ClearControl(this.GetID, m_Facade.GetID);
  1499. setGUIProperty(guiProperty.Title, "Kanokon");
  1500. GUIListItem item = new GUIListItem("");
  1501. //item.Label = "Label";
  1502. //item.Label2 = "xxxxx 2";
  1503. //item.Label3 = "xxxxx 3";
  1504. //item.ThumbnailImage = ImageAllocator.GetSeriesBannerFromFile(@"C:\htpc\banners\amaendayo1.jpg");
  1505. item.IconImage = @"C:\htpc\watched.png";
  1506. AddFacadeItem(item);
  1507. //item.TVTag = null;
  1508. GUIListItem item2 = new GUIListItem("");
  1509. //item2.Label = "Item 2";
  1510. //item2.ThumbnailImage = ImageAllocator.GetSeriesBannerFromFile(@"C:\htpc\banners\clannad2.jpg");
  1511. AddFacadeItem(item2);
  1512. //string img = ImageAllocator.GetSeriesBanner("Asu no Yoichi");
  1513. GUIListItem item3 = new GUIListItem("");
  1514. item3.Label = "";
  1515. //item3.ThumbnailImage = img;
  1516. AddFacadeItem(item3);
  1517. /*
  1518. GUIListItem item3 = new GUIListItem("Item 2");
  1519. //item3.Label = "Item 2";
  1520. item3.ThumbnailImage = @"C:\banner03.jpg";
  1521. AddFacadeItem(item3);
  1522. GUIListItem item4 = new GUIListItem("Item 2");
  1523. //item4.Label = "Item 2";
  1524. //item4.ThumbnailImage = @"C:\banner04.jpg";
  1525. AddFacadeItem(item4);
  1526. GUIListItem item5 = new GUIListItem("Item 2");
  1527. //item5.Label = "Item 2";
  1528. item5.ThumbnailImage = @"C:\banner05.jpg";
  1529. AddFacadeItem(item5);
  1530. GUIListItem item6 = new GUIListItem("Item 2");
  1531. //item6.Label = "Item 2";
  1532. item6.ThumbnailImage = @"C:\banner06.jpg";
  1533. AddFacadeItem(item6);
  1534. GUIListItem item7 = new GUIListItem("Item 2");
  1535. //item7.Label = "Item 2";
  1536. item7.ThumbnailImage = @"C:\banner07.jpg";
  1537. AddFacadeItem(item7);
  1538. */
  1539. }
  1540. private bool ShowLayoutMenu(string previousMenu)
  1541. {
  1542. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  1543. if (dlg == null)
  1544. return true;
  1545. //keep showing the dialog until the user closes it
  1546. int selectedLabel = 0;
  1547. string currentMenu = "Change Layout";
  1548. while (true)
  1549. {
  1550. dlg.Reset();
  1551. dlg.SetHeading(currentMenu);
  1552. if (previousMenu != string.Empty)
  1553. dlg.Add("<<< " + previousMenu);
  1554. dlg.Add("List Posters");
  1555. dlg.Add("Wide Banners");
  1556. dlg.Add("Filmstrip");
  1557. if (!m_Facade.IsNullLayout(GUIFacadeControl.Layout.CoverFlow))
  1558. dlg.Add("Coverflow");
  1559. dlg.SelectedLabel = selectedLabel;
  1560. dlg.DoModal(GUIWindowManager.ActiveWindow);
  1561. selectedLabel = dlg.SelectedLabel;
  1562. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  1563. switch (selection)
  1564. {
  1565. case 0:
  1566. //show previous
  1567. return true;
  1568. case 1:
  1569. groupViewMode = GUIFacadeControl.Layout.List;
  1570. break;
  1571. case 2:
  1572. groupViewMode = GUIFacadeControl.Layout.LargeIcons;
  1573. break;
  1574. case 3:
  1575. groupViewMode = GUIFacadeControl.Layout.Filmstrip;
  1576. break;
  1577. case 4:
  1578. // Disabled for now due to a bug - enable to see the issue
  1579. groupViewMode = GUIFacadeControl.Layout.CoverFlow;
  1580. break;
  1581. //Utils.DialogMsg("Disabled", "This Layout is temporarily disabled");
  1582. //return false;
  1583. default:
  1584. //close menu
  1585. return false;
  1586. }
  1587. break;
  1588. }
  1589. if (listLevel == Listlevel.Group)
  1590. {
  1591. settings.LastGroupViewMode = groupViewMode;
  1592. settings.Save();
  1593. }
  1594. LoadFacade();
  1595. return false;
  1596. }
  1597. private bool ShowDisplayOptionsMenu(string previousMenu)
  1598. {
  1599. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  1600. if (dlg == null)
  1601. return true;
  1602. //keep showing the dialog until the user closes it
  1603. int selectedLabel = 0;
  1604. string currentMenu = "Display Options";
  1605. while (true)
  1606. {
  1607. dlg.Reset();
  1608. dlg.SetHeading(currentMenu);
  1609. if (previousMenu != string.Empty)
  1610. dlg.Add("<<< " + previousMenu);
  1611. dlg.Add("Change Layout >>>");
  1612. dlg.SelectedLabel = selectedLabel;
  1613. dlg.DoModal(GUIWindowManager.ActiveWindow);
  1614. selectedLabel = dlg.SelectedLabel;
  1615. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  1616. switch (selection)
  1617. {
  1618. case 0:
  1619. //show previous
  1620. LoadFacade();
  1621. return true;
  1622. case 1:
  1623. if (!ShowLayoutMenu(currentMenu))
  1624. return false;
  1625. break;
  1626. default:
  1627. //close menu
  1628. return false;
  1629. }
  1630. }
  1631. }
  1632. #region Options Menus
  1633. private bool ShowOptionsMenu(string previousMenu)
  1634. {
  1635. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  1636. if (dlg == null)
  1637. return true;
  1638. //keep showing the dialog until the user closes it
  1639. int selectedLabel = 0;
  1640. string currentMenu = "Options";
  1641. while (true)
  1642. {
  1643. dlg.Reset();
  1644. dlg.SetHeading(currentMenu);
  1645. if (previousMenu != string.Empty)
  1646. dlg.Add("<<< " + previousMenu);
  1647. dlg.Add("AniDB >>>");
  1648. dlg.Add("Display >>>");
  1649. dlg.SelectedLabel = selectedLabel;
  1650. dlg.DoModal(GUIWindowManager.ActiveWindow);
  1651. selectedLabel = dlg.SelectedLabel;
  1652. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  1653. switch (selection)
  1654. {
  1655. case 0:
  1656. //show previous
  1657. return true;
  1658. case 1:
  1659. //if (!ShowOptionsAniDBMenu(currentMenu))
  1660. // return false;
  1661. break;
  1662. case 2:
  1663. if (!ShowOptionsDisplayMenu(currentMenu))
  1664. return false;
  1665. break;
  1666. default:
  1667. //close menu
  1668. return false;
  1669. }
  1670. }
  1671. }
  1672. private bool ShowOptionsDisplayMenu(string previousMenu)
  1673. {
  1674. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  1675. if (dlg == null)
  1676. return true;
  1677. //keep showing the dialog until the user closes it
  1678. int selectedLabel = 0;
  1679. string currentMenu = "Display Options";
  1680. while (true)
  1681. {
  1682. dlg.Reset();
  1683. dlg.SetHeading(currentMenu);
  1684. string showEps = string.Format("Only Show Available Episodes ({0})", settings.ShowOnlyAvailableEpisodes ? "On" : "Off");
  1685. string hideWatched = string.Format("Hide Watched Episodes ({0})", settings.HideWatchedFiles ? "On" : "Off");
  1686. string findFilter = string.Format("Find - Only Show Matches ({0})", settings.FindFilter ? "On" : "Off");
  1687. if (previousMenu != string.Empty)
  1688. dlg.Add("<<< " + previousMenu);
  1689. dlg.Add(showEps);
  1690. dlg.Add(hideWatched);
  1691. dlg.Add(findFilter);
  1692. dlg.SelectedLabel = selectedLabel;
  1693. dlg.DoModal(GUIWindowManager.ActiveWindow);
  1694. selectedLabel = dlg.SelectedLabel;
  1695. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  1696. switch (selection)
  1697. {
  1698. case 0:
  1699. //show previous
  1700. return true;
  1701. case 1:
  1702. settings.ShowOnlyAvailableEpisodes = !settings.ShowOnlyAvailableEpisodes;
  1703. LoadFacade();
  1704. break;
  1705. case 2:
  1706. settings.HideWatchedFiles = !settings.HideWatchedFiles;
  1707. LoadFacade();
  1708. break;
  1709. case 3:
  1710. settings.FindFilter = !settings.FindFilter;
  1711. if (searchTimer.Enabled)
  1712. {
  1713. SaveOrRestoreFacadeItems(false);
  1714. DoSearch(m_Facade.SelectedListItemIndex);
  1715. }
  1716. break;
  1717. default:
  1718. //close menu
  1719. return false;
  1720. }
  1721. settings.Save();
  1722. }
  1723. }
  1724. #endregion
  1725. private void ChangeView(View v)
  1726. {
  1727. BaseConfig.MyAnimeLog.Write(string.Format("ChangeView: {0} - {1}", currentViewClassification, v == null ? "" : v.Name));
  1728. currentViewClassification = ViewClassification.Views;
  1729. currentView = new View(v);
  1730. currentStaticViewID = "";
  1731. settings.LastView = currentView;
  1732. settings.LastViewClassification = currentViewClassification;
  1733. settings.LastStaticViewID = currentStaticViewID;
  1734. settings.Save();
  1735. //update skin
  1736. setGUIProperty("SimpleCurrentView", v.DisplayName);
  1737. }
  1738. private void ChangeStaticView(ViewClassification vClass, string id)
  1739. {
  1740. BaseConfig.MyAnimeLog.Write(string.Format("ChangeStaticView: {0} - {1}", vClass, id));
  1741. currentViewClassification = vClass;
  1742. currentStaticViewID = id;
  1743. settings.LastViewClassification = currentViewClassification;
  1744. settings.LastStaticViewID = currentStaticViewID;
  1745. settings.Save();
  1746. //update skin
  1747. setGUIProperty("SimpleCurrentView", currentStaticViewID);
  1748. }
  1749. private void SetFacade()
  1750. {
  1751. bool filmstrip = false;
  1752. bool widebanners = false;
  1753. bool coverflow = false;
  1754. bool listmode = false;
  1755. bool groups = false;
  1756. bool series = false;
  1757. bool episodes = false;
  1758. bool episodetypes = false;
  1759. bool groupfilters = false;
  1760. if (groupViewMode == GUIFacadeControl.Layout.List)
  1761. listmode = true;
  1762. else if (groupViewMode == GUIFacadeControl.Layout.Filmstrip)
  1763. filmstrip = true;
  1764. else if (groupViewMode == GUIFacadeControl.Layout.CoverFlow)
  1765. coverflow = true;
  1766. else
  1767. widebanners = true;
  1768. BaseConfig.MyAnimeLog.Write("SetFacade List Mode: {0}", listLevel);
  1769. if (listLevel == Listlevel.GroupFilter || listLevel == Listlevel.GroupFilterSub || listLevel == Listlevel.GroupFilterSub2)
  1770. {
  1771. m_Facade.CurrentLayout = GUIFacadeControl.Layout.List;
  1772. listmode = true;
  1773. widebanners = filmstrip = false;
  1774. groupfilters = true;
  1775. BaseConfig.MyAnimeLog.Write("SetFacade List Mode: {0}", listLevel);
  1776. }
  1777. if (listLevel == Listlevel.Group)
  1778. {
  1779. m_Facade.CurrentLayout = groupViewMode;
  1780. groups = true;
  1781. //BaseConfig.MyAnimeLog.Write("List Mode: {0}, IsGroups: {1}", this.dummyLayoutListMode.Visible, dummyIsGroups.Visible);
  1782. }
  1783. if (listLevel == Listlevel.Series)
  1784. {
  1785. m_Facade.CurrentLayout = GUIFacadeControl.Layout.List;
  1786. listmode = true;
  1787. widebanners = filmstrip = false;
  1788. series = true;
  1789. //BaseConfig.MyAnimeLog.Write("List Mode: {0}, IsSeries: {1}", this.dummyLayoutListMode.Visible, dummyIsSeries.Visible);
  1790. }
  1791. if (listLevel == Listlevel.EpisodeTypes)
  1792. {
  1793. //m_Facade.CurrentLayout = seriesViewMode;
  1794. m_Facade.CurrentLayout = GUIFacadeControl.Layout.List;
  1795. listmode = true;
  1796. widebanners = filmstrip = false;
  1797. episodetypes = true;
  1798. //BaseConfig.MyAnimeLog.Write("List Mode: {0}, IsEpisodeTypes: {1}", this.dummyLayoutListMode.Visible, dummyIsEpisodeTypes.Visible);
  1799. }
  1800. if (listLevel == Listlevel.Episode)
  1801. {
  1802. m_Facade.CurrentLayout = episodesViewMode; // always list
  1803. listmode = true;
  1804. widebanners = filmstrip = false;
  1805. episodes = true;
  1806. //BaseConfig.MyAnimeLog.Write("List Mode: {0}, dummyIsEpisodes: {1}", this.dummyLayoutListMode.Visible, dummyIsEpisodes.Visible);
  1807. }
  1808. //if (this.dummyLayoutFilmstripMode != null) BaseConfig.MyAnimeLog.Write("SetFacade: dummyLayoutFilmstripMode.Visible : {0}", this.dummyLayoutFilmstripMode.Visible);
  1809. //if (this.dummyLayoutWideBanners != null) BaseConfig.MyAnimeLog.Write("SetFacade: dummyLayoutWideBanners.Visible : {0}", this.dummyLayoutWideBanners.Visible);
  1810. //if (this.dummyLayoutListMode != null) BaseConfig.MyAnimeLog.Write("SetFacade: dummyLayoutListMode.Visible : {0}", this.dummyLayoutListMode.Visible);
  1811. EvaluateVisibility();
  1812. if (this.dummyLayoutFilmstripMode != null) dummyLayoutFilmstripMode.Visible = filmstrip;
  1813. if (this.dummyLayoutWideBanners != null) dummyLayoutWideBanners.Visible = widebanners;
  1814. if (this.dummyLayoutListMode != null) this.dummyLayoutListMode.Visible = listmode;
  1815. if (this.dummyIsGroups != null) this.dummyIsGroups.Visible = groups;
  1816. if (this.dummyIsGroupFilters != null) this.dummyIsGroupFilters.Visible = groupfilters;
  1817. if (this.dummyIsSeries != null) this.dummyIsSeries.Visible = series;
  1818. if (this.dummyIsEpisodeTypes != null) this.dummyIsEpisodeTypes.Visible = episodetypes;
  1819. if (this.dummyIsEpisodes != null) this.dummyIsEpisodes.Visible = episodes;
  1820. BaseConfig.MyAnimeLog.Write("SetFacade: Filters: {0} - Groups: {1} - Series: {2} - Episodes: {3}", groupfilters, groups, series, episodes);
  1821. // fix for skin visiblity problem during video playback.
  1822. if (GUIGraphicsContext.IsPlayingVideo)
  1823. GUIWindowManager.Render(0);
  1824. System.Windows.Forms.Application.DoEvents();
  1825. }
  1826. protected override void OnClicked(int controlId, GUIControl control, MediaPortal.GUI.Library.Action.ActionType actionType)
  1827. {
  1828. if (actionType == MediaPortal.GUI.Library.Action.ActionType.ACTION_MOUSE_DOUBLECLICK)
  1829. {
  1830. OnShowContextMenu();
  1831. return;
  1832. }
  1833. if (actionType == MediaPortal.GUI.Library.Action.ActionType.ACTION_PLAY)
  1834. {
  1835. if (MediaPortal.Player.g_Player.Playing == false)
  1836. BaseConfig.MyAnimeLog.Write("Pressed the play button");
  1837. }
  1838. if (this.btnDisplayOptions != null && control == this.btnDisplayOptions)
  1839. {
  1840. hook.IsEnabled = false;
  1841. ShowDisplayOptionsMenu("");
  1842. btnDisplayOptions.Focus = false;
  1843. Thread.Sleep(100); //make sure key-up's from the context menu aren't cought by the hook
  1844. hook.IsEnabled = true;
  1845. this.btnDisplayOptions.IsFocused = false;
  1846. return;
  1847. }
  1848. if (this.btnWindowUtilities != null && control == this.btnWindowUtilities)
  1849. {
  1850. SetGlobalIDs();
  1851. GUIWindowManager.ActivateWindow(Constants.WindowIDs.ADMIN);
  1852. this.btnWindowUtilities.IsFocused = false;
  1853. return;
  1854. }
  1855. if (this.btnWindowCalendar != null && control == this.btnWindowCalendar)
  1856. {
  1857. SetGlobalIDs();
  1858. GUIWindowManager.ActivateWindow(Constants.WindowIDs.CALENDAR);
  1859. //GUIWindowManager.ActivateWindow(Constants.WindowIDs.BROWSER);
  1860. this.btnWindowCalendar.IsFocused = false;
  1861. return;
  1862. }
  1863. if (this.btnWindowDownloads != null && control == this.btnWindowDownloads)
  1864. {
  1865. SetGlobalIDs();
  1866. GUIWindowManager.ActivateWindow(Constants.WindowIDs.DOWNLOADS);
  1867. this.btnWindowDownloads.IsFocused = false;
  1868. return;
  1869. }
  1870. if (this.btnWindowContinueWatching != null && control == this.btnWindowContinueWatching)
  1871. {
  1872. SetGlobalIDs();
  1873. GUIWindowManager.ActivateWindow(Constants.WindowIDs.WATCHING);
  1874. this.btnWindowContinueWatching.IsFocused = false;
  1875. return;
  1876. }
  1877. if (this.btnWindowRecommendations != null && control == this.btnWindowRecommendations)
  1878. {
  1879. SetGlobalIDs();
  1880. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RECOMMENDATIONS);
  1881. this.btnWindowRecommendations.IsFocused = false;
  1882. return;
  1883. }
  1884. if (this.btnWindowRandom != null && control == this.btnWindowRandom)
  1885. {
  1886. RandomWindow_LevelObject = GroupFilterHelper.AllGroupsFilter;
  1887. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.GroupFilter;
  1888. RandomWindow_RandomType = RandomObjectType.Series;
  1889. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  1890. this.btnWindowRandom.IsFocused = false;
  1891. return;
  1892. }
  1893. if (this.btnChangeLayout != null && control == this.btnChangeLayout)
  1894. {
  1895. ShowLayoutMenu("");
  1896. this.btnChangeLayout.IsFocused = false;
  1897. return;
  1898. }
  1899. if (this.btnSwitchUser != null && control == this.btnSwitchUser)
  1900. {
  1901. if (JMMServerVM.Instance.PromptUserLogin())
  1902. {
  1903. listLevel = Listlevel.GroupFilter;
  1904. curAnimeEpisode = null;
  1905. curAnimeGroup = null;
  1906. curAnimeSeries = null;
  1907. curGroupFilter = null;
  1908. // user has logged in, so save to settings so we will log in as the same user next time
  1909. settings.CurrentJMMUserID = JMMServerVM.Instance.CurrentUser.JMMUserID.ToString();
  1910. settings.Save();
  1911. LoadFacade();
  1912. }
  1913. this.btnSwitchUser.IsFocused = false;
  1914. return;
  1915. }
  1916. if (this.btnSettings != null && control == this.btnSettings)
  1917. {
  1918. hook.IsEnabled = false;
  1919. ShowOptionsDisplayMenu("");
  1920. btnDisplayOptions.Focus = false;
  1921. Thread.Sleep(100); //make sure key-up's from the context menu aren't cought by the hook
  1922. hook.IsEnabled = true;
  1923. this.btnSettings.IsFocused = false;
  1924. return;
  1925. }
  1926. try
  1927. {
  1928. if (actionType != MediaPortal.GUI.Library.Action.ActionType.ACTION_SELECT_ITEM) return; // some other events raised onClicked too for some reason?
  1929. if (control == this.m_Facade)
  1930. {
  1931. UpdateSearchPanel(false);
  1932. if (this.m_Facade.SelectedListItem == null || this.m_Facade.SelectedListItem.TVTag == null)
  1933. return;
  1934. switch (listLevel)
  1935. {
  1936. case Listlevel.GroupFilter:
  1937. curGroupFilter = this.m_Facade.SelectedListItem.TVTag as GroupFilterVM;
  1938. if (curGroupFilter == null) return;
  1939. if (curGroupFilter.GroupFilterID.Value == Constants.StaticGF.Predefined)
  1940. {
  1941. listLevel = Listlevel.GroupFilterSub;
  1942. curGroupFilterSub2 = null;
  1943. curGroupFilterSub = null;
  1944. }
  1945. else
  1946. {
  1947. listLevel = Listlevel.Group;
  1948. curGroupFilterSub2 = null;
  1949. curGroupFilterSub = null;
  1950. }
  1951. LoadFacade();
  1952. this.m_Facade.Focus = true;
  1953. break;
  1954. case Listlevel.GroupFilterSub:
  1955. curGroupFilterSub = this.m_Facade.SelectedListItem.TVTag as GroupFilterVM;
  1956. if (curGroupFilterSub == null) return;
  1957. curGroupFilterSub2 = null;
  1958. listLevel = Listlevel.GroupFilterSub2;
  1959. LoadFacade();
  1960. this.m_Facade.Focus = true;
  1961. break;
  1962. case Listlevel.GroupFilterSub2:
  1963. curGroupFilterSub2 = this.m_Facade.SelectedListItem.TVTag as GroupFilterVM;
  1964. if (curGroupFilterSub2 == null) return;
  1965. listLevel = Listlevel.Group;
  1966. LoadFacade();
  1967. this.m_Facade.Focus = true;
  1968. break;
  1969. case Listlevel.Group:
  1970. curAnimeGroup = this.m_Facade.SelectedListItem.TVTag as AnimeGroupVM;
  1971. if (curAnimeGroup == null) return;
  1972. curAnimeGroupViewed = curAnimeGroup;
  1973. // e.g. if there is only one series for the group, show the episode types
  1974. // if there is only for episode type for the series show the episodes
  1975. ShowChildrenLevelForGroup();
  1976. LoadFacade();
  1977. this.m_Facade.Focus = true;
  1978. break;
  1979. case Listlevel.Series:
  1980. if (this.m_Facade.SelectedListItem.TVTag == null) return;
  1981. // sub groups
  1982. if (this.m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeGroupVM))
  1983. {
  1984. curAnimeGroup = this.m_Facade.SelectedListItem.TVTag as AnimeGroupVM;
  1985. if (curAnimeGroup == null) return;
  1986. curAnimeGroupViewed = curAnimeGroup;
  1987. ShowChildrenLevelForGroup();
  1988. }
  1989. else if (this.m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeSeriesVM))
  1990. {
  1991. curAnimeSeries = this.m_Facade.SelectedListItem.TVTag as AnimeSeriesVM;
  1992. if (curAnimeSeries == null) return;
  1993. ShowChildrenLevelForSeries();
  1994. }
  1995. LoadFacade();
  1996. this.m_Facade.Focus = true;
  1997. break;
  1998. case Listlevel.EpisodeTypes:
  1999. curAnimeEpisodeType = this.m_Facade.SelectedListItem.TVTag as AnimeEpisodeTypeVM;
  2000. if (curAnimeEpisodeType == null) return;
  2001. listLevel = Listlevel.Episode;
  2002. SetFanartForEpisodes();
  2003. LoadFacade();
  2004. this.m_Facade.Focus = true;
  2005. break;
  2006. case Listlevel.Episode:
  2007. this.curAnimeEpisode = this.m_Facade.SelectedListItem.TVTag as AnimeEpisodeVM;
  2008. if (curAnimeEpisode == null) return;
  2009. BaseConfig.MyAnimeLog.Write("Selected to play: {0}", curAnimeEpisode.EpisodeNumberAndName);
  2010. vidHandler.ResumeOrPlay(curAnimeEpisode);
  2011. break;
  2012. }
  2013. }
  2014. }
  2015. catch (Exception ex)
  2016. {
  2017. BaseConfig.MyAnimeLog.Write("Error in OnClicked: {0} - {1}", ex.Message, ex.ToString());
  2018. }
  2019. base.OnClicked(controlId, control, actionType);
  2020. }
  2021. private void ShowChildrenLevelForSeries()
  2022. {
  2023. List<AnimeEpisodeTypeVM> episodeTypes = curAnimeSeries.EpisodeTypesToDisplay;
  2024. if (episodeTypes.Count > 1)
  2025. {
  2026. listLevel = Listlevel.EpisodeTypes;
  2027. }
  2028. else if (episodeTypes.Count == 1)
  2029. {
  2030. setGUIProperty(guiProperty.SeriesTitle, curAnimeSeries.SeriesName);
  2031. // only one so lets go straight to the episodes
  2032. curAnimeEpisodeType = episodeTypes[0];
  2033. listLevel = Listlevel.Episode;
  2034. SetFanartForEpisodes();
  2035. BaseConfig.MyAnimeLog.Write("Current list level: {0} - {1}", listLevel, curAnimeEpisodeType);
  2036. }
  2037. }
  2038. private void ShowChildrenLevelForGroup()
  2039. {
  2040. List<AnimeGroupVM> subGroups = curAnimeGroupViewed.SubGroups;
  2041. List<AnimeSeriesVM> seriesList = curAnimeGroupViewed.ChildSeries;
  2042. int subLevelCount = seriesList.Count + subGroups.Count;
  2043. if (subLevelCount > 1)
  2044. {
  2045. listLevel = Listlevel.Series;
  2046. LoadFacade();
  2047. return;
  2048. }
  2049. else if (subLevelCount == 1)
  2050. {
  2051. // keep drilling down until we find a series
  2052. // or more than one sub level
  2053. while (subLevelCount == 1 && subGroups.Count > 0)
  2054. {
  2055. curAnimeGroupViewed = subGroups[0];
  2056. curAnimeGroup = subGroups[0];
  2057. subGroups = curAnimeGroup.SubGroups;
  2058. seriesList = curAnimeGroup.ChildSeries;
  2059. subLevelCount = seriesList.Count + subGroups.Count;
  2060. }
  2061. if (subGroups.Count == 0)
  2062. {
  2063. // means we got all the way down to a series
  2064. if (seriesList.Count > 1)
  2065. {
  2066. listLevel = Listlevel.Series;
  2067. }
  2068. else if (seriesList.Count == 1)
  2069. {
  2070. curAnimeSeries = seriesList[0];
  2071. ShowChildrenLevelForSeries();
  2072. }
  2073. }
  2074. else
  2075. {
  2076. // else we have more than one sub level to display
  2077. listLevel = Listlevel.Series;
  2078. }
  2079. }
  2080. }
  2081. public void SetFanartForEpisodes()
  2082. {
  2083. // do this so that after an episode is played and the page is reloaded, we will always show the correct fanart
  2084. if (curAnimeSeries == null) return;
  2085. LoadFanart(curAnimeSeries);
  2086. //LoadFanart(curAnimeSeries);
  2087. }
  2088. public override void DeInit()
  2089. {
  2090. BaseConfig.MyAnimeLog.Write("DeInit");
  2091. base.DeInit();
  2092. }
  2093. public override void OnAction(MediaPortal.GUI.Library.Action action)
  2094. {
  2095. //BaseConfig.MyAnimeLog.Write("Received action: {0}/{1}", action.wID, (char)(action.m_key.KeyChar));
  2096. switch (action.wID)
  2097. {
  2098. case MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_DOWN:
  2099. case MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_UP:
  2100. //Reset autoclose timer on search
  2101. if (searchTimer.Enabled)
  2102. {
  2103. searchTimer.Stop();
  2104. searchTimer.Start();
  2105. }
  2106. base.OnAction(action);
  2107. break;
  2108. case MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_LEFT:
  2109. case MediaPortal.GUI.Library.Action.ActionType.ACTION_MOVE_RIGHT:
  2110. base.OnAction(action);
  2111. break;
  2112. case MediaPortal.GUI.Library.Action.ActionType.ACTION_KEY_PRESSED:
  2113. //when the list is selected, search the input
  2114. if (GUIWindowManager.ActiveWindowEx == this.GetID)
  2115. {
  2116. if ((m_Facade.CurrentLayout == GUIFacadeControl.Layout.List && m_Facade.ListLayout.IsFocused)
  2117. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.LargeIcons && m_Facade.ThumbnailLayout.IsFocused)
  2118. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.Filmstrip && m_Facade.FilmstripLayout.IsFocused)
  2119. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.CoverFlow && m_Facade.CoverFlowLayout.IsFocused))
  2120. OnSearchChar((char)(action.m_key.KeyChar));
  2121. }
  2122. break;
  2123. case MediaPortal.GUI.Library.Action.ActionType.ACTION_PARENT_DIR:
  2124. case MediaPortal.GUI.Library.Action.ActionType.ACTION_HOME:
  2125. UpdateSearchPanel(false);
  2126. ImageAllocator.FlushAll();
  2127. GUIWindowManager.ShowPreviousWindow();
  2128. break;
  2129. case MediaPortal.GUI.Library.Action.ActionType.ACTION_PLAY:
  2130. BaseConfig.MyAnimeLog.Write("Received PLAY action");
  2131. try
  2132. {
  2133. if (listLevel == Listlevel.Group)
  2134. {
  2135. if (curAnimeGroup == null) return;
  2136. JMMServerBinary.Contract_AnimeEpisode contract = JMMServerVM.Instance.clientBinaryHTTP.GetNextUnwatchedEpisodeForGroup(curAnimeGroup.AnimeGroupID,
  2137. JMMServerVM.Instance.CurrentUser.JMMUserID);
  2138. if (contract == null) return;
  2139. AnimeEpisodeVM ep = new AnimeEpisodeVM(contract);
  2140. vidHandler.ResumeOrPlay(ep);
  2141. }
  2142. if (listLevel == Listlevel.Series)
  2143. {
  2144. //curAnimeSeries = null;
  2145. if (curAnimeSeries == null) return;
  2146. JMMServerBinary.Contract_AnimeEpisode contract = JMMServerVM.Instance.clientBinaryHTTP.GetNextUnwatchedEpisode(curAnimeSeries.AnimeSeriesID.Value,
  2147. JMMServerVM.Instance.CurrentUser.JMMUserID);
  2148. if (contract == null) return;
  2149. AnimeEpisodeVM ep = new AnimeEpisodeVM(contract);
  2150. vidHandler.ResumeOrPlay(ep);
  2151. }
  2152. }
  2153. catch (Exception ex)
  2154. {
  2155. BaseConfig.MyAnimeLog.Write(ex.ToString());
  2156. }
  2157. break;
  2158. case MediaPortal.GUI.Library.Action.ActionType.ACTION_PREVIOUS_MENU:
  2159. if (searchTimer.Enabled)
  2160. {
  2161. OnSearchAction(SearchAction.EndSearch);
  2162. return;
  2163. }
  2164. // back one level
  2165. if (listLevel == Listlevel.GroupFilter)
  2166. {
  2167. goto case MediaPortal.GUI.Library.Action.ActionType.ACTION_HOME;
  2168. }
  2169. else
  2170. {
  2171. string msg = string.Format("LIST LEVEL:: {0} - GF: {1} - GFSub2: {2}", listLevel, curGroupFilter, curGroupFilterSub2);
  2172. BaseConfig.MyAnimeLog.Write(msg);
  2173. if (listLevel == Listlevel.GroupFilterSub)
  2174. {
  2175. listLevel = Listlevel.GroupFilter;
  2176. curGroupFilterSub = null;
  2177. LoadFacade();
  2178. }
  2179. if (listLevel == Listlevel.GroupFilterSub2)
  2180. {
  2181. // go back to GROUP FILTERS
  2182. listLevel = Listlevel.GroupFilterSub;
  2183. curGroupFilterSub2 = null;
  2184. LoadFacade();
  2185. }
  2186. if (listLevel == Listlevel.Group)
  2187. {
  2188. if (curGroupFilterSub2 == null)
  2189. {
  2190. // go back to GROUP FILTERS
  2191. listLevel = Listlevel.GroupFilter;
  2192. }
  2193. else
  2194. {
  2195. listLevel = Listlevel.GroupFilterSub2;
  2196. }
  2197. LoadFacade();
  2198. curAnimeGroup = null;
  2199. }
  2200. if (listLevel == Listlevel.Series)
  2201. {
  2202. // go back to GROUP
  2203. AnimeGroupVM parentGroup = curAnimeGroupViewed.ParentGroup;
  2204. if (parentGroup == null)
  2205. listLevel = Listlevel.Group;
  2206. ShowParentLevelForGroup(parentGroup);
  2207. LoadFacade();
  2208. curAnimeEpisodeType = null;
  2209. curAnimeSeries = null;
  2210. }
  2211. if (listLevel == Listlevel.EpisodeTypes)
  2212. {
  2213. // go back to SERIES
  2214. AnimeSeriesVM parentSeries = curAnimeEpisodeType.AnimeSeries;
  2215. ShowParentLevelForSeries(parentSeries);
  2216. LoadFacade();
  2217. return;
  2218. }
  2219. if (listLevel == Listlevel.Episode)
  2220. {
  2221. AnimeSeriesVM parentSeries = curAnimeEpisodeType.AnimeSeries;
  2222. if (parentSeries.EpisodeTypesToDisplay.Count == 1)
  2223. ShowParentLevelForSeries(parentSeries);
  2224. else
  2225. {
  2226. listLevel = Listlevel.EpisodeTypes;
  2227. curAnimeEpisodeType = null;
  2228. }
  2229. LoadFacade();
  2230. return;
  2231. }
  2232. }
  2233. break;
  2234. default:
  2235. base.OnAction(action);
  2236. break;
  2237. }
  2238. }
  2239. private void ShowParentLevelForGroup(AnimeGroupVM grp)
  2240. {
  2241. while (grp != null)
  2242. {
  2243. List<AnimeGroupVM> subGroups = grp.SubGroups;
  2244. List<AnimeSeriesVM> seriesList = grp.ChildSeries;
  2245. if ((seriesList.Count + subGroups.Count) > 1)
  2246. {
  2247. curAnimeGroupViewed = grp;
  2248. curAnimeGroup = grp;
  2249. listLevel = Listlevel.Series;
  2250. return;
  2251. }
  2252. else
  2253. {
  2254. // go up one level
  2255. if (grp.AnimeGroupParentID.HasValue)
  2256. grp = grp.ParentGroup;
  2257. else
  2258. {
  2259. // only one series or subgroup so go all the way back to the group list
  2260. listLevel = Listlevel.Group;
  2261. curAnimeEpisodeType = null;
  2262. curAnimeSeries = null;
  2263. return;
  2264. }
  2265. }
  2266. }
  2267. }
  2268. private void ShowParentLevelForSeries(AnimeSeriesVM ser)
  2269. {
  2270. AnimeGroupVM grp = JMMServerHelper.GetGroup(ser.AnimeGroupID);
  2271. ShowParentLevelForGroup(grp);
  2272. }
  2273. #region Find
  2274. #region Keyboard hook
  2275. KeyboardHook hook = null;
  2276. private const string t9Chars = "0123456789";
  2277. bool IsChar(Keys k, ref char c)
  2278. {
  2279. string str = new KeysConverter().ConvertToString(k);
  2280. if (str.Length != 1)
  2281. return false;
  2282. c = str[0];
  2283. return true;
  2284. }
  2285. bool IsSearchChar(char c)
  2286. {
  2287. if (search == null)
  2288. return false;
  2289. if (search.Mode == SearchMode.t9)
  2290. return (t9Chars.IndexOf(c) > 0) || (c == '*') || (c == '#');
  2291. if (search.Mode == SearchMode.text)
  2292. return char.IsLetterOrDigit(c) || char.IsPunctuation(c) || (c == ' ');
  2293. return false;
  2294. }
  2295. void hook_KeyDown(object sender, KeyEventArgsEx e)
  2296. {
  2297. if (GUIWindowManager.ActiveWindowEx != this.GetID)
  2298. return;
  2299. //mark normal keys as handled, otherwise some other handler might be called
  2300. // (like 'home' for 'h')
  2301. if (!e.Alt && !e.Control && IsSearchChar(e.keyChar) && MediaPortal.Player.g_Player.Playing == false)
  2302. e.Handled = true;
  2303. }
  2304. void hook_KeyUp(object sender, KeyEventArgsEx e)
  2305. {
  2306. if (GUIWindowManager.ActiveWindowEx != this.GetID)
  2307. return;
  2308. try
  2309. {
  2310. //BaseConfig.MyAnimeLog.Write("e.KeyCode: {0} - {1} - {2}", e.KeyCode, e.keyChar, e.KeyValue);
  2311. }
  2312. catch { }
  2313. //when the list is selected, search the input
  2314. if ((m_Facade.CurrentLayout == GUIFacadeControl.Layout.List && m_Facade.ListLayout.IsFocused)
  2315. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.LargeIcons && m_Facade.ThumbnailLayout.IsFocused)
  2316. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.Filmstrip && m_Facade.FilmstripLayout.IsFocused)
  2317. || (m_Facade.CurrentLayout == GUIFacadeControl.Layout.CoverFlow && m_Facade.CoverFlowLayout.IsFocused))
  2318. {
  2319. e.Handled = true;
  2320. //catch ctrl+w and ctrl+m for toggling search word and mode
  2321. if (e.Control)
  2322. {
  2323. switch (e.KeyCode)
  2324. {
  2325. case Keys.W:
  2326. OnSearchAction(SearchAction.ToggleStartWord);
  2327. break;
  2328. case Keys.M:
  2329. OnSearchAction(SearchAction.ToggleMode);
  2330. break;
  2331. default:
  2332. e.Handled = false;
  2333. return; //do nothing
  2334. }
  2335. }
  2336. else
  2337. {
  2338. switch (e.KeyCode)
  2339. {
  2340. case Keys.Back:
  2341. OnSearchAction(SearchAction.DeleteChar);
  2342. break;
  2343. case Keys.Tab:
  2344. OnSearchAction(SearchAction.NextMatch);
  2345. break;
  2346. default:
  2347. if (!OnSearchChar(e.keyChar))
  2348. {
  2349. e.Handled = false;
  2350. return; //do nothing
  2351. }
  2352. break;
  2353. }
  2354. }
  2355. if (e.Handled)
  2356. {
  2357. //we handled the keypress: make some noise
  2358. if (!string.IsNullOrEmpty(searchSound) && !MediaPortal.Player.g_Player.Playing)
  2359. MediaPortal.Util.Utils.PlaySound(searchSound, false, true);
  2360. }
  2361. }
  2362. }
  2363. #endregion
  2364. string searchText = string.Empty;
  2365. string searchMatch = string.Empty;
  2366. enum SearchAction { ToggleMode, ToggleStartWord, NextMatch, DeleteChar, EndSearch };
  2367. private void OnSearchAction(SearchAction action)
  2368. {
  2369. //stop timer
  2370. if (searchTimer.Enabled)
  2371. searchTimer.Stop();
  2372. //process action
  2373. switch (action)
  2374. {
  2375. case SearchAction.ToggleMode:
  2376. search.Input = string.Empty;
  2377. searchText = string.Empty;
  2378. searchMatch = string.Empty;
  2379. search.Mode = (search.Mode == SearchMode.text) ? SearchMode.t9 : SearchMode.text;
  2380. settings.FindMode = search.Mode;
  2381. settings.Save();
  2382. break;
  2383. case SearchAction.ToggleStartWord:
  2384. search.StartWord = !search.StartWord;
  2385. settings.FindStartWord = search.StartWord;
  2386. settings.Save();
  2387. break;
  2388. case SearchAction.NextMatch:
  2389. DoSearch(m_Facade.SelectedListItemIndex + 1);
  2390. break;
  2391. case SearchAction.DeleteChar:
  2392. if (search.Input.Length > 0)
  2393. {
  2394. if (settings.FindFilter)
  2395. SaveOrRestoreFacadeItems(false);
  2396. search.Input = search.Input.Remove(search.Input.Length - 1);
  2397. DoSearch(m_Facade.SelectedListItemIndex);
  2398. }
  2399. break;
  2400. case SearchAction.EndSearch:
  2401. UpdateSearchPanel(false);
  2402. return;
  2403. }
  2404. //update screen
  2405. UpdateSearchPanel(true);
  2406. }
  2407. private void SaveOrRestoreFacadeItems(bool save)
  2408. {
  2409. if (save)
  2410. {
  2411. //save
  2412. lstFacadeItems = new List<GUIListItem>(m_Facade.Count);
  2413. for (int item = 0; item < m_Facade.Count; item++)
  2414. lstFacadeItems.Add(m_Facade[item]);
  2415. }
  2416. else if (lstFacadeItems != null)
  2417. {
  2418. //restore
  2419. GUIListItem selectedItem = m_Facade.SelectedListItem;
  2420. m_Facade.Clear();
  2421. for (int item = 0; item < lstFacadeItems.Count; item++)
  2422. {
  2423. m_Facade.Add(lstFacadeItems[item]);
  2424. if (lstFacadeItems[item] == selectedItem)
  2425. m_Facade.SelectedListItemIndex = m_Facade.Count - 1;
  2426. }
  2427. lstFacadeItems = null;
  2428. }
  2429. }
  2430. private bool OnSearchChar(char c)
  2431. {
  2432. if (!IsSearchChar(c))
  2433. return false;
  2434. if (search.Mode == SearchMode.t9)
  2435. {
  2436. if (c == '*' || c == '#')
  2437. {
  2438. if (string.IsNullOrEmpty(search.Input))
  2439. {
  2440. //if panel visible, process the special char
  2441. // otherwise just show the find panel
  2442. if (dummyFindActive == null || dummyFindActive.Visible)
  2443. {
  2444. if (c == '*')
  2445. OnSearchAction(SearchAction.ToggleStartWord);
  2446. //If we switched to text mode by accident we'd have to
  2447. // get a full keyboard to get back to T9 mode ...
  2448. // So switching mode with # is disabled
  2449. //else if (c == '#')
  2450. // OnSearchAction(SearchAction.ToggleMode);
  2451. }
  2452. else
  2453. {
  2454. UpdateSearchPanel(true);
  2455. }
  2456. }
  2457. else
  2458. {
  2459. if (c == '*')
  2460. OnSearchAction(SearchAction.DeleteChar);
  2461. else if (c == '#')
  2462. OnSearchAction(SearchAction.NextMatch);
  2463. }
  2464. return true;
  2465. }
  2466. else if (t9Chars.IndexOf(c) >= 0)
  2467. {
  2468. AddSearchChar(c);
  2469. return true;
  2470. }
  2471. }
  2472. else if (search.Mode == SearchMode.text)
  2473. {
  2474. if (char.IsLetterOrDigit(c) || char.IsPunctuation(c) || (c == ' '))
  2475. {
  2476. AddSearchChar(c);
  2477. return true;
  2478. }
  2479. }
  2480. return false;
  2481. }
  2482. private void AddSearchChar(char c)
  2483. {
  2484. //stop timer
  2485. if (searchTimer.Enabled)
  2486. searchTimer.Stop();
  2487. //add char
  2488. if (search.Mode == SearchMode.t9)
  2489. {
  2490. int n = (int)c - (int)'0';
  2491. if (n >= 0 && n <= 9)
  2492. {
  2493. //add number to sequence
  2494. search.Input = search.Input + c;
  2495. searchText = searchText + "?";
  2496. }
  2497. }
  2498. else if (search.Mode == SearchMode.text)
  2499. {
  2500. //add char to sequence
  2501. search.Input = search.Input + c;
  2502. searchText = searchText + "?";
  2503. }
  2504. //search
  2505. DoSearch(m_Facade.SelectedListItemIndex);
  2506. //update screen
  2507. UpdateSearchPanel(true);
  2508. }
  2509. private void DoSearch(int start)
  2510. {
  2511. SearchCollection.SearchMatch match = null;
  2512. //search
  2513. if (settings.FindFilter)
  2514. {
  2515. List<int> lstMatches = new List<int>();
  2516. if (search.GetMatches(start, lstMatches, ref match))
  2517. {
  2518. //copy current list
  2519. if (lstFacadeItems == null)
  2520. SaveOrRestoreFacadeItems(true);
  2521. //find all matching items
  2522. List<GUIListItem> lstMatchingItems = new List<GUIListItem>(lstMatches.Count);
  2523. int selectedItem = -1;
  2524. for (int index = 0; index < m_Facade.Count; index++)
  2525. {
  2526. if (lstMatches.Contains(index))
  2527. {
  2528. lstMatchingItems.Add(m_Facade[index]);
  2529. if (index == match.Index)
  2530. selectedItem = lstMatchingItems.Count - 1; ;
  2531. }
  2532. }
  2533. //update the list
  2534. m_Facade.Clear();
  2535. for (int index = 0; index < lstMatchingItems.Count; index++)
  2536. m_Facade.Add(lstMatchingItems[index]);
  2537. m_Facade.SelectedListItemIndex = selectedItem;
  2538. }
  2539. }
  2540. else
  2541. {
  2542. match = search.GetMatch(start);
  2543. //select match
  2544. SelectItem(match != null ? match.Index : -1);
  2545. }
  2546. //update sceen
  2547. if (match != null)
  2548. {
  2549. //match found
  2550. searchText = match.Text;
  2551. searchMatch = m_Facade.SelectedListItem.Label;
  2552. }
  2553. else
  2554. {
  2555. //no match found
  2556. searchText = new string('*', search.Input.Length);
  2557. searchMatch = string.Empty;
  2558. }
  2559. }
  2560. void searchTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  2561. {
  2562. UpdateSearchPanel(false);
  2563. }
  2564. private void UpdateSearchPanel(bool bShow)
  2565. {
  2566. if (searchTimer.Enabled)
  2567. searchTimer.Stop();
  2568. if (dummyFindActive != null)
  2569. dummyFindActive.Visible = bShow;
  2570. if (dummyFindModeT9 != null)
  2571. dummyFindModeT9.Visible = (search.Mode == SearchMode.t9);
  2572. if (dummyFindModeText != null)
  2573. dummyFindModeText.Visible = (search.Mode == SearchMode.text);
  2574. if (!bShow)
  2575. {
  2576. search.Input = string.Empty;
  2577. searchText = string.Empty;
  2578. searchMatch = string.Empty;
  2579. if (settings.FindFilter)
  2580. SaveOrRestoreFacadeItems(false);
  2581. }
  2582. setGUIProperty(guiProperty.FindInput, search.Input);
  2583. setGUIProperty(guiProperty.FindText, searchText);
  2584. setGUIProperty(guiProperty.FindMatch, searchMatch);
  2585. string searchMode = (search.Mode == SearchMode.t9) ? "T9" : "Text";
  2586. string startWord = search.StartWord ? "yes" : "no";
  2587. setGUIProperty(guiProperty.FindMode, searchMode);
  2588. setGUIProperty(guiProperty.FindStartWord, startWord);
  2589. if (search.Mode == SearchMode.t9)
  2590. {
  2591. if (string.IsNullOrEmpty(searchText))
  2592. {
  2593. setGUIProperty(guiProperty.FindSharpMode, "Next Match");
  2594. setGUIProperty(guiProperty.FindAsteriskMode, string.Format("Start Word ({0})", startWord));
  2595. }
  2596. else
  2597. {
  2598. setGUIProperty(guiProperty.FindSharpMode, "Next Match");
  2599. setGUIProperty(guiProperty.FindAsteriskMode, "Clear");
  2600. }
  2601. }
  2602. if (bShow)
  2603. searchTimer.Start();
  2604. }
  2605. #endregion
  2606. // triggered when a selection change was made on the facade
  2607. private void onFacadeItemSelected(GUIListItem item, GUIControl parent)
  2608. {
  2609. // if this is not a message from the facade, exit
  2610. if (parent != m_Facade && parent != m_Facade.FilmstripLayout && parent != m_Facade.CoverFlowLayout &&
  2611. parent != m_Facade.ThumbnailLayout && parent != m_Facade.ListLayout)
  2612. return;
  2613. if (m_Facade.SelectedListItem.TVTag == null) return;
  2614. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(GroupFilterVM))
  2615. GroupFilter_OnItemSelected(m_Facade.SelectedListItem);
  2616. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeGroupVM))
  2617. Group_OnItemSelected(m_Facade.SelectedListItem);
  2618. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeSeriesVM))
  2619. Series_OnItemSelected(m_Facade.SelectedListItem);
  2620. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeEpisodeTypeVM))
  2621. EpisodeType_OnItemSelected(m_Facade.SelectedListItem);
  2622. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeEpisodeVM))
  2623. Episode_OnItemSelected(m_Facade.SelectedListItem);
  2624. EvaluateVisibility();
  2625. }
  2626. public override bool OnMessage(GUIMessage message)
  2627. {
  2628. switch (message.Message)
  2629. {
  2630. case GUIMessage.MessageType.GUI_MSG_ITEM_FOCUS_CHANGED:
  2631. {
  2632. int iControl = message.SenderControlId;
  2633. if (iControl == (int)m_Facade.GetID)
  2634. {
  2635. if (m_Facade.SelectedListItem != null && m_Facade.SelectedListItem.TVTag != null)
  2636. {
  2637. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(GroupFilterVM))
  2638. {
  2639. GroupFilterVM gf = m_Facade.SelectedListItem.TVTag as GroupFilterVM;
  2640. if (LastFocusType == 1)
  2641. {
  2642. if (gf != null && gf.GroupFilterID.Value == LastFocusID) return true;
  2643. }
  2644. if (gf != null)
  2645. {
  2646. LastFocusType = 1;
  2647. LastFocusID = gf.GroupFilterID.Value;
  2648. }
  2649. GroupFilter_OnItemSelected(m_Facade.SelectedListItem);
  2650. }
  2651. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeGroupVM))
  2652. {
  2653. AnimeGroupVM obj = m_Facade.SelectedListItem.TVTag as AnimeGroupVM;
  2654. if (LastFocusType == 2)
  2655. {
  2656. if (obj != null && obj.AnimeGroupID == LastFocusID) return true;
  2657. }
  2658. if (obj != null)
  2659. {
  2660. LastFocusType = 2;
  2661. LastFocusID = obj.AnimeGroupID;
  2662. }
  2663. Group_OnItemSelected(m_Facade.SelectedListItem);
  2664. }
  2665. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeSeriesVM))
  2666. {
  2667. AnimeSeriesVM obj = m_Facade.SelectedListItem.TVTag as AnimeSeriesVM;
  2668. if (LastFocusType == 3)
  2669. {
  2670. if (obj != null && obj.AnimeSeriesID.Value == LastFocusID) return true;
  2671. }
  2672. if (obj != null)
  2673. {
  2674. LastFocusType = 3;
  2675. LastFocusID = obj.AnimeSeriesID.Value;
  2676. }
  2677. Series_OnItemSelected(m_Facade.SelectedListItem);
  2678. }
  2679. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeEpisodeTypeVM))
  2680. {
  2681. AnimeEpisodeTypeVM obj = m_Facade.SelectedListItem.TVTag as AnimeEpisodeTypeVM;
  2682. if (LastFocusType == 4)
  2683. {
  2684. if (obj != null && (int)obj.EpisodeType == LastFocusID) return true;
  2685. }
  2686. if (obj != null)
  2687. {
  2688. LastFocusType = 4;
  2689. LastFocusID = (int)obj.EpisodeType;
  2690. }
  2691. EpisodeType_OnItemSelected(m_Facade.SelectedListItem);
  2692. }
  2693. if (m_Facade.SelectedListItem.TVTag.GetType() == typeof(AnimeEpisodeVM))
  2694. {
  2695. AnimeEpisodeVM obj = m_Facade.SelectedListItem.TVTag as AnimeEpisodeVM;
  2696. if (LastFocusType == 5)
  2697. {
  2698. if (obj != null && obj.AnimeEpisodeID == LastFocusID) return true;
  2699. }
  2700. if (obj != null)
  2701. {
  2702. LastFocusType = 5;
  2703. LastFocusID = obj.AnimeEpisodeID;
  2704. }
  2705. Episode_OnItemSelected(m_Facade.SelectedListItem);
  2706. }
  2707. }
  2708. }
  2709. }
  2710. EvaluateVisibility();
  2711. return true;
  2712. case GUIMessage.MessageType.GUI_MSG_PLAYBACK_ENDED:
  2713. case GUIMessage.MessageType.GUI_MSG_PLAYBACK_STOPPED:
  2714. {
  2715. //-- Need to reload the GUI to display changes
  2716. //-- if episode is classified as watched
  2717. LoadFacade();
  2718. }
  2719. return true;
  2720. default:
  2721. return base.OnMessage(message);
  2722. }
  2723. }
  2724. void g_Player_PlayBackEnded(g_Player.MediaType type, string filename)
  2725. {
  2726. }
  2727. static bool isFirstInitDone = false;
  2728. private void OnFirstStart()
  2729. {
  2730. if (isFirstInitDone)
  2731. return;
  2732. if (string.IsNullOrEmpty(MainWindow.settings.JMMServer_Address) || string.IsNullOrEmpty(MainWindow.settings.JMMServer_Port))
  2733. {
  2734. Utils.DialogMsg("Error", "Please exit MP and set your JMM Server location first");
  2735. return;
  2736. }
  2737. // check if we can connect to JMM Server
  2738. // and load the default user
  2739. List<JMMUserVM> allUsers = JMMServerHelper.GetAllUsers();
  2740. if (allUsers.Count == 0)
  2741. {
  2742. Utils.DialogMsg("Error", "Error connecting to JMM Server");
  2743. return;
  2744. }
  2745. else
  2746. {
  2747. // check for last jmm user
  2748. if (string.IsNullOrEmpty(MainWindow.settings.CurrentJMMUserID))
  2749. {
  2750. if (!JMMServerVM.Instance.PromptUserLogin())
  2751. return;
  2752. // user has logged in, so save to settings so we will log in as the same user next time
  2753. MainWindow.settings.CurrentJMMUserID = JMMServerVM.Instance.CurrentUser.JMMUserID.ToString();
  2754. settings.Save();
  2755. }
  2756. else
  2757. {
  2758. JMMUserVM selUser = null;
  2759. foreach (JMMUserVM user in allUsers)
  2760. {
  2761. if (user.JMMUserID.ToString().Equals(MainWindow.settings.CurrentJMMUserID))
  2762. {
  2763. selUser = user;
  2764. break;
  2765. }
  2766. }
  2767. if (selUser == null)
  2768. {
  2769. if (!JMMServerVM.Instance.PromptUserLogin())
  2770. return;
  2771. // user has logged in, so save to settings so we will log in as the same user next time
  2772. MainWindow.settings.CurrentJMMUserID = JMMServerVM.Instance.CurrentUser.JMMUserID.ToString();
  2773. settings.Save();
  2774. }
  2775. else
  2776. {
  2777. bool authed = JMMServerVM.Instance.AuthenticateUser(selUser.Username, "");
  2778. string password = "";
  2779. while (!authed)
  2780. {
  2781. // prompt user for a password
  2782. if (Utils.DialogText(ref password, true, GUIWindowManager.ActiveWindow))
  2783. {
  2784. authed = JMMServerVM.Instance.AuthenticateUser(selUser.Username, password);
  2785. if (!authed)
  2786. {
  2787. Utils.DialogMsg("Error", "Incorrect password, please try again");
  2788. }
  2789. }
  2790. else return;
  2791. }
  2792. JMMServerVM.Instance.SetCurrentUser(selUser);
  2793. // user has logged in, so save to settings so we will log in as the same user next time
  2794. settings.CurrentJMMUserID = JMMServerVM.Instance.CurrentUser.JMMUserID.ToString();
  2795. settings.Save();
  2796. }
  2797. }
  2798. }
  2799. JMMServerVM.Instance.ServerStatusEvent += new JMMServerVM.ServerStatusEventHandler(Instance_ServerStatusEvent);
  2800. isFirstInitDone = true;
  2801. }
  2802. private void GroupFilter_OnItemSelected(GUIListItem item)
  2803. {
  2804. GroupFilterVM grpFilter = item.TVTag as GroupFilterVM;
  2805. if (grpFilter == null) return;
  2806. curGroupFilter = grpFilter;
  2807. if (displayGrpFilterTimer != null)
  2808. displayGrpFilterTimer.Stop();
  2809. displayGrpFilterTimer = new System.Timers.Timer();
  2810. displayGrpFilterTimer.AutoReset = false;
  2811. displayGrpFilterTimer.Interval = BaseConfig.Settings.InfoDelay; // 250ms
  2812. displayGrpFilterTimer.Elapsed += new System.Timers.ElapsedEventHandler(displayGrpFilterTimer_Elapsed);
  2813. displayGrpFilterTimer.Enabled = true;
  2814. }
  2815. void displayGrpFilterTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  2816. {
  2817. GroupFilter_OnItemSelectedDisplay();
  2818. }
  2819. private void GroupFilter_OnItemSelectedDisplay()
  2820. {
  2821. if (curGroupFilter == null) return;
  2822. clearGUIProperty("GroupFilter.FilterName");
  2823. clearGUIProperty("GroupFilter.GroupCount");
  2824. setGUIProperty(guiProperty.SeriesTitle, curGroupFilter.GroupFilterName);
  2825. setGUIProperty(guiProperty.Title, curGroupFilter.GroupFilterName);
  2826. setGUIProperty("GroupFilter.FilterName", curGroupFilter.GroupFilterName);
  2827. AnimeGroupVM grp = null;
  2828. List<AnimeGroupVM> groups = JMMServerHelper.GetAnimeGroupsForFilter(curGroupFilter);
  2829. if (groups.Count > 0)
  2830. {
  2831. grp = groups[groupRandom.Next(0, groups.Count - 1)];
  2832. }
  2833. setGUIProperty("GroupFilter.GroupCount", groups.Count.ToString());
  2834. if (grp != null)
  2835. {
  2836. // Delayed Image Loading of Series Banners
  2837. listPoster.Filename = ImageAllocator.GetGroupImageAsFileName(grp, GUIFacadeControl.Layout.List);
  2838. LoadFanart(grp);
  2839. }
  2840. }
  2841. private void Group_OnItemSelected(GUIListItem item)
  2842. {
  2843. if (item == null || item.TVTag == null || !(item.TVTag is AnimeGroupVM))
  2844. return;
  2845. AnimeGroupVM grp = item.TVTag as AnimeGroupVM;
  2846. if (grp == null) return;
  2847. curAnimeGroup = grp;
  2848. if (displayGrpTimer != null)
  2849. displayGrpTimer.Stop();
  2850. displayGrpTimer = new System.Timers.Timer();
  2851. displayGrpTimer.AutoReset = false;
  2852. displayGrpTimer.Interval = BaseConfig.Settings.InfoDelay; // 250ms
  2853. displayGrpTimer.Elapsed += new System.Timers.ElapsedEventHandler(displayGrpTimer_Elapsed);
  2854. displayGrpTimer.Enabled = true;
  2855. }
  2856. void displayGrpTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  2857. {
  2858. Group_OnItemSelectedDisplay();
  2859. }
  2860. private void Group_OnItemSelectedDisplay()
  2861. {
  2862. // when displaying a group we could be at the group list level or series list level
  2863. // group level = top level groups
  2864. // series level = sub-groups
  2865. clearGUIProperty("SeriesGroup.Year");
  2866. clearGUIProperty("SeriesGroup.Genre");
  2867. clearGUIProperty("SeriesGroup.Episodes");
  2868. clearGUIProperty("SeriesGroup.EpisodesAvailable");
  2869. clearGUIProperty("SeriesGroup.Rating");
  2870. clearGUIProperty("SeriesGroup.EpisodeCountNormal");
  2871. clearGUIProperty("SeriesGroup.EpisodeCountSpecial");
  2872. clearGUIProperty("SeriesGroup.EpisodeCountNormalAvailable");
  2873. clearGUIProperty("SeriesGroup.EpisodeCountSpecialAvailable");
  2874. clearGUIProperty("SeriesGroup.EpisodeCountUnwatched");
  2875. clearGUIProperty("SeriesGroup.EpisodeCountWatched");
  2876. clearGUIProperty("SeriesGroup.RawRating");
  2877. clearGUIProperty("SeriesGroup.RatingVoteCount");
  2878. clearGUIProperty("SeriesGroup.MyRating");
  2879. clearGUIProperty("SeriesGroup.SeriesCount");
  2880. clearGUIProperty(guiProperty.Description);
  2881. if (curAnimeGroup == null) return;
  2882. setGUIProperty(guiProperty.Subtitle, "");
  2883. if (curAnimeGroup.Stat_UserVoteOverall.HasValue)
  2884. setGUIProperty("SeriesGroup.MyRating", Utils.FormatAniDBRating((double)curAnimeGroup.Stat_UserVoteOverall.Value));
  2885. // set info properties
  2886. // most of these properties actually come from the anidb_anime record
  2887. // we need to find all the series for this group
  2888. setGUIProperty("SeriesGroup.SeriesCount", curAnimeGroup.AllSeriesCount.ToString());
  2889. setGUIProperty("SeriesGroup.Genre", curAnimeGroup.CategoriesFormatted);
  2890. setGUIProperty("SeriesGroup.GenreShort", curAnimeGroup.CategoriesFormattedShort);
  2891. setGUIProperty("SeriesGroup.Year", curAnimeGroup.YearFormatted);
  2892. decimal totalRating = 0;
  2893. int totalVotes = 0;
  2894. int epCountNormal = 0;
  2895. int epCountSpecial = 0;
  2896. List<AnimeSeriesVM> seriesList = curAnimeGroup.ChildSeries;
  2897. if (seriesList.Count == 1)
  2898. {
  2899. setGUIProperty(guiProperty.SeriesTitle, seriesList[0].SeriesName);
  2900. setGUIProperty(guiProperty.Title, seriesList[0].SeriesName);
  2901. setGUIProperty(guiProperty.Description, seriesList[0].Description);
  2902. }
  2903. else
  2904. {
  2905. setGUIProperty(guiProperty.SeriesTitle, curAnimeGroup.GroupName);
  2906. setGUIProperty(guiProperty.Title, curAnimeGroup.GroupName);
  2907. setGUIProperty(guiProperty.Description, curAnimeGroup.ParsedDescription);
  2908. }
  2909. foreach (AnimeSeriesVM ser in seriesList)
  2910. {
  2911. totalRating += ((decimal)ser.AniDB_Anime.Rating * ser.AniDB_Anime.VoteCount);
  2912. totalRating += ((decimal)ser.AniDB_Anime.TempRating * ser.AniDB_Anime.TempVoteCount);
  2913. totalVotes += ser.AniDB_Anime.AniDBTotalVotes;
  2914. epCountNormal += ser.AniDB_Anime.EpisodeCountNormal;
  2915. epCountSpecial += ser.AniDB_Anime.EpisodeCountSpecial;
  2916. }
  2917. decimal AniDBRating = 0;
  2918. if (totalVotes == 0)
  2919. AniDBRating = 0;
  2920. else
  2921. AniDBRating = totalRating / (decimal)totalVotes / (decimal)100;
  2922. if (dummyUserHasVotedSeries != null) dummyUserHasVotedSeries.Visible = false;
  2923. // Only AniDB users have votes
  2924. BaseConfig.MyAnimeLog.Write("IsAniDBUserBool : " + JMMServerVM.Instance.CurrentUser.IsAniDBUserBool.ToString());
  2925. if (JMMServerVM.Instance.CurrentUser.IsAniDBUserBool)
  2926. {
  2927. BaseConfig.MyAnimeLog.Write("seriesList.Count : " + seriesList.Count.ToString());
  2928. if (seriesList.Count == 1)
  2929. {
  2930. AniDB_AnimeVM anAnime = seriesList[0].AniDB_Anime;
  2931. string myRating = anAnime.UserVoteFormatted;
  2932. if (string.IsNullOrEmpty(myRating))
  2933. clearGUIProperty("SeriesGroup.MyRating");
  2934. else
  2935. {
  2936. setGUIProperty("SeriesGroup.MyRating", myRating);
  2937. if (dummyUserHasVotedSeries != null) dummyUserHasVotedSeries.Visible = true;
  2938. BaseConfig.MyAnimeLog.Write("myRating : " + myRating.ToString());
  2939. BaseConfig.MyAnimeLog.Write("dummyUserHasVotedSeries.Visible : " + dummyUserHasVotedSeries.Visible.ToString());
  2940. }
  2941. }
  2942. }
  2943. string rating = Utils.FormatAniDBRating((double)AniDBRating) + " (" + totalVotes.ToString() + " votes)";
  2944. setGUIProperty("SeriesGroup.RawRating", Utils.FormatAniDBRating((double)AniDBRating));
  2945. setGUIProperty("SeriesGroup.RatingVoteCount", totalVotes.ToString());
  2946. setGUIProperty("SeriesGroup.Rating", rating);
  2947. // set watched/unavailable flag
  2948. if (dummyIsWatched != null) dummyIsWatched.Visible = (curAnimeGroup.UnwatchedEpisodeCount == 0);
  2949. string eps = epCountNormal.ToString() + " (" + epCountSpecial.ToString() + " Specials)";
  2950. //string epsa = epCountNormalAvailable.ToString() + " (" + epCountSpecialAvailable.ToString() + " Specials)";
  2951. setGUIProperty("SeriesGroup.Episodes", eps);
  2952. //setGUIProperty("SeriesGroup.EpisodesAvailable", epsa);
  2953. setGUIProperty("SeriesGroup.EpisodeCountNormal", epCountNormal.ToString());
  2954. setGUIProperty("SeriesGroup.EpisodeCountSpecial", epCountSpecial.ToString());
  2955. //setGUIProperty("SeriesGroup.EpisodeCountNormalAvailable", epCountNormalAvailable.ToString());
  2956. //setGUIProperty("SeriesGroup.EpisodeCountSpecialAvailable", epCountSpecialAvailable.ToString());
  2957. setGUIProperty("SeriesGroup.EpisodeCountUnwatched", curAnimeGroup.UnwatchedEpisodeCount.ToString());
  2958. setGUIProperty("SeriesGroup.EpisodeCountWatched", curAnimeGroup.WatchedEpisodeCount.ToString());
  2959. // Delayed Image Loading of Series Banners
  2960. listPoster.Filename = ImageAllocator.GetGroupImageAsFileName(curAnimeGroup, GUIFacadeControl.Layout.List);
  2961. LoadFanart(curAnimeGroup);
  2962. }
  2963. private void EpisodeType_OnItemSelected(GUIListItem item)
  2964. {
  2965. if (m_bQuickSelect)
  2966. return;
  2967. if (dummyIsAvailable != null) dummyIsAvailable.Visible = true;
  2968. clearGUIProperty("SeriesGroup.Year");
  2969. clearGUIProperty("SeriesGroup.Genre");
  2970. clearGUIProperty("SeriesGroup.Episodes");
  2971. clearGUIProperty("SeriesGroup.Rating");
  2972. clearGUIProperty(guiProperty.SeriesTitle);
  2973. clearGUIProperty(guiProperty.Subtitle);
  2974. clearGUIProperty(guiProperty.Description);
  2975. clearGUIProperty("SeriesGroup.EpisodeCountNormal");
  2976. clearGUIProperty("SeriesGroup.EpisodeCountSpecial");
  2977. clearGUIProperty("SeriesGroup.EpisodeCountUnwatched");
  2978. clearGUIProperty("SeriesGroup.EpisodeCountWatched");
  2979. clearGUIProperty("SeriesGroup.RatingVoteCount");
  2980. clearGUIProperty("SeriesGroup.RawRating");
  2981. if (item == null || item.TVTag == null || !(item.TVTag is AnimeEpisodeTypeVM))
  2982. return;
  2983. AnimeEpisodeTypeVM epType = item.TVTag as AnimeEpisodeTypeVM;
  2984. if (epType == null) return;
  2985. curAnimeEpisodeType = epType;
  2986. if (curAnimeSeries == null) return;
  2987. AniDB_AnimeVM anAnime = curAnimeSeries.AniDB_Anime;
  2988. setGUIProperty(guiProperty.SeriesTitle, curAnimeSeries.SeriesName);
  2989. setGUIProperty(guiProperty.Subtitle, "");
  2990. setGUIProperty(guiProperty.Description, curAnimeSeries.Description);
  2991. // set info properties
  2992. // most of these properties actually come from the anidb_anime record
  2993. // we need to find all the series for this group
  2994. setGUIProperty("SeriesGroup.Year", anAnime.Year);
  2995. setGUIProperty("SeriesGroup.Genre", anAnime.CategoriesFormatted);
  2996. setGUIProperty("SeriesGroup.GenreShort", anAnime.CategoriesFormattedShort);
  2997. string eps = anAnime.EpisodeCountNormal.ToString() + " (" + anAnime.EpisodeCountSpecial.ToString() + " Specials)";
  2998. setGUIProperty("SeriesGroup.Episodes", eps);
  2999. setGUIProperty("SeriesGroup.EpisodeCountNormal", anAnime.EpisodeCountNormal.ToString());
  3000. setGUIProperty("SeriesGroup.EpisodeCountSpecial", anAnime.EpisodeCountSpecial.ToString());
  3001. string rating = "";
  3002. rating = Utils.FormatAniDBRating((double)anAnime.AniDBRating) + " (" + anAnime.AniDBTotalVotes.ToString() + " votes)";
  3003. setGUIProperty("SeriesGroup.RawRating", Utils.FormatAniDBRating((double)anAnime.AniDBRating));
  3004. setGUIProperty("SeriesGroup.RatingVoteCount", anAnime.AniDBTotalVotes.ToString());
  3005. setGUIProperty("SeriesGroup.Rating", rating);
  3006. int unwatched = 0;
  3007. int watched = 0;
  3008. if (curAnimeSeries != null)
  3009. curAnimeSeries.GetWatchedUnwatchedCount(epType.EpisodeType, ref unwatched, ref watched);
  3010. // set watched/unavailable flag
  3011. if (dummyIsWatched != null) dummyIsWatched.Visible = (unwatched == 0);
  3012. setGUIProperty("SeriesGroup.EpisodeCountUnwatched", unwatched.ToString());
  3013. setGUIProperty("SeriesGroup.EpisodeCountWatched", watched.ToString());
  3014. // Delayed Image Loading of Series Banners
  3015. listPoster.Filename = ImageAllocator.GetSeriesImageAsFileName(curAnimeSeries, GUIFacadeControl.Layout.List);
  3016. }
  3017. private void Series_OnItemSelected(GUIListItem item)
  3018. {
  3019. // need to do this here as well because we display series and sub-groups in the same list
  3020. if (displayGrpTimer != null)
  3021. displayGrpTimer.Stop();
  3022. if (m_bQuickSelect)
  3023. return;
  3024. if (dummyIsAvailable != null) dummyIsAvailable.Visible = true;
  3025. clearGUIProperty("SeriesGroup.Year");
  3026. clearGUIProperty("SeriesGroup.Genre");
  3027. clearGUIProperty("SeriesGroup.Episodes");
  3028. clearGUIProperty("SeriesGroup.EpisodesAvailable");
  3029. clearGUIProperty("SeriesGroup.Rating");
  3030. clearGUIProperty(guiProperty.SeriesTitle);
  3031. clearGUIProperty(guiProperty.Subtitle);
  3032. clearGUIProperty(guiProperty.Description);
  3033. clearGUIProperty("SeriesGroup.EpisodeCountNormal");
  3034. clearGUIProperty("SeriesGroup.EpisodeCountSpecial");
  3035. clearGUIProperty("SeriesGroup.EpisodeCountNormalAvailable");
  3036. clearGUIProperty("SeriesGroup.EpisodeCountSpecialAvailable");
  3037. clearGUIProperty("SeriesGroup.EpisodeCountUnwatched");
  3038. clearGUIProperty("SeriesGroup.EpisodeCountWatched");
  3039. clearGUIProperty("SeriesGroup.RatingVoteCount");
  3040. clearGUIProperty("SeriesGroup.RawRating");
  3041. clearGUIProperty("SeriesGroup.MyRating");
  3042. clearGUIProperty(guiProperty.RomanjiTitle);
  3043. clearGUIProperty(guiProperty.EnglishTitle);
  3044. clearGUIProperty(guiProperty.KanjiTitle);
  3045. clearGUIProperty(guiProperty.RotatorTitle);
  3046. if (item == null || item.TVTag == null || !(item.TVTag is AnimeSeriesVM))
  3047. return;
  3048. AnimeSeriesVM ser = item.TVTag as AnimeSeriesVM;
  3049. if (ser == null) return;
  3050. BaseConfig.MyAnimeLog.Write(ser.ToString());
  3051. curAnimeSeries = ser;
  3052. setGUIProperty(guiProperty.SeriesTitle, ser.SeriesName);
  3053. setGUIProperty(guiProperty.Subtitle, "");
  3054. setGUIProperty(guiProperty.Description, ser.Description);
  3055. // set info properties
  3056. // most of these properties actually come from the anidb_anime record
  3057. // we need to find all the series for this group
  3058. AniDB_AnimeVM anAnime = ser.AniDB_Anime;
  3059. if (dummyUserHasVotedSeries != null) dummyUserHasVotedSeries.Visible = false;
  3060. // Only AniDB users have votes
  3061. if (JMMServerVM.Instance.CurrentUser.IsAniDBUserBool)
  3062. {
  3063. string myRating = anAnime.UserVoteFormatted;
  3064. if (string.IsNullOrEmpty(myRating))
  3065. clearGUIProperty("SeriesGroup.MyRating");
  3066. else
  3067. {
  3068. setGUIProperty("SeriesGroup.MyRating", myRating);
  3069. if (dummyUserHasVotedSeries != null) dummyUserHasVotedSeries.Visible = true;
  3070. }
  3071. }
  3072. BaseConfig.MyAnimeLog.Write(anAnime.ToString());
  3073. setGUIProperty("SeriesGroup.Year", anAnime.Year);
  3074. setGUIProperty("SeriesGroup.Genre", anAnime.CategoriesFormatted);
  3075. setGUIProperty("SeriesGroup.GenreShort", anAnime.CategoriesFormattedShort);
  3076. string eps = anAnime.EpisodeCountNormal.ToString() + " (" + anAnime.EpisodeCountSpecial.ToString() + " Specials)";
  3077. setGUIProperty("SeriesGroup.Episodes", eps);
  3078. setGUIProperty("SeriesGroup.EpisodeCountNormal", anAnime.EpisodeCountNormal.ToString());
  3079. setGUIProperty("SeriesGroup.EpisodeCountSpecial", anAnime.EpisodeCountSpecial.ToString());
  3080. string rating = "";
  3081. rating = Utils.FormatAniDBRating((double)anAnime.AniDBRating) + " (" + anAnime.AniDBTotalVotes.ToString() + " votes)";
  3082. setGUIProperty("SeriesGroup.RawRating", Utils.FormatAniDBRating((double)anAnime.AniDBRating));
  3083. setGUIProperty("SeriesGroup.RatingVoteCount", anAnime.AniDBTotalVotes.ToString());
  3084. setGUIProperty("SeriesGroup.Rating", rating);
  3085. // set watched/unavailable flag
  3086. if (dummyIsWatched != null) dummyIsWatched.Visible = (ser.UnwatchedEpisodeCount == 0);
  3087. setGUIProperty("SeriesGroup.EpisodeCountUnwatched", ser.UnwatchedEpisodeCount.ToString());
  3088. setGUIProperty("SeriesGroup.EpisodeCountWatched", ser.WatchedEpisodeCount.ToString());
  3089. // Delayed Image Loading of Series Banners
  3090. listPoster.Filename = ImageAllocator.GetSeriesImageAsFileName(ser, GUIFacadeControl.Layout.List);
  3091. LoadFanart(ser);
  3092. }
  3093. private string GetSeriesTypeLabel()
  3094. {
  3095. if (curAnimeEpisodeType != null) return curAnimeEpisodeType.EpisodeTypeDescription;
  3096. if (curAnimeSeries != null) return curAnimeSeries.SeriesName;
  3097. if (curAnimeGroup != null) return curAnimeGroup.GroupName;
  3098. return "";
  3099. }
  3100. private void Episode_OnItemSelected(GUIListItem item)
  3101. {
  3102. if (m_bQuickSelect)
  3103. return;
  3104. clearGUIProperty("Episode.MyRating");
  3105. clearGUIProperty("Episode.AirDate");
  3106. clearGUIProperty("Episode.Rating");
  3107. clearGUIProperty("Episode.RawRating");
  3108. clearGUIProperty("Episode.Length");
  3109. clearGUIProperty("Episode.FileInfo");
  3110. clearGUIProperty("Episode.EpisodeName");
  3111. clearGUIProperty("Episode.EpisodeDisplayName");
  3112. clearGUIProperty("Episode.Description");
  3113. clearGUIProperty("Episode.Image");
  3114. clearGUIProperty("Episode.SeriesTypeLabel");
  3115. clearGUIProperty("Episode.EpisodeRomanjiName");
  3116. clearGUIProperty("Episode.EpisodeEnglishName");
  3117. clearGUIProperty("Episode.EpisodeKanjiName");
  3118. clearGUIProperty("Episode.EpisodeRotator");
  3119. if (item == null || item.TVTag == null || !(item.TVTag is AnimeEpisodeVM))
  3120. return;
  3121. AnimeEpisodeVM ep = item.TVTag as AnimeEpisodeVM;
  3122. if (ep == null) return;
  3123. curAnimeEpisode = ep;
  3124. if (curAnimeEpisode.EpisodeImageLocation.Length > 0)
  3125. setGUIProperty("Episode.Image", curAnimeEpisode.EpisodeImageLocation);
  3126. if (!settings.HidePlot)
  3127. setGUIProperty("Episode.Description", curAnimeEpisode.EpisodeOverview);
  3128. else
  3129. {
  3130. if (curAnimeEpisode.EpisodeOverview.Trim().Length > 0 && ep.IsWatched == 0)
  3131. setGUIProperty("Episode.Description", "*** Hidden to prevent spoilers ***");
  3132. else
  3133. setGUIProperty("Episode.Description", curAnimeEpisode.EpisodeOverview);
  3134. }
  3135. setGUIProperty("Episode.EpisodeName", curAnimeEpisode.EpisodeName);
  3136. setGUIProperty("Episode.EpisodeDisplayName", curAnimeEpisode.DisplayName);
  3137. setGUIProperty("Episode.SeriesTypeLabel", GetSeriesTypeLabel());
  3138. setGUIProperty("Episode.AirDate", curAnimeEpisode.AirDateAsString);
  3139. setGUIProperty("Episode.Length", Utils.FormatSecondsToDisplayTime(curAnimeEpisode.AniDB_LengthSeconds));
  3140. setGUIProperty("Episode.Rating", curAnimeEpisode.AniDBRatingFormatted);
  3141. //setGUIProperty("Episode.RawRating", Utils.FormatAniDBRating(curAnimeEpisode.AniDB_Rating));
  3142. setGUIProperty("Episode.RawRating", curAnimeEpisode.AniDB_Rating);
  3143. if (dummyIsWatched != null) dummyIsWatched.Visible = (ep.IsWatched == 1);
  3144. if (dummyIsAvailable != null) dummyIsAvailable.Visible = true;
  3145. // get all the LocalFile rceords for this episode
  3146. List<VideoDetailedVM> fileLocalList = ep.FilesForEpisode;
  3147. bool norepeat = true;
  3148. string finfo = "";
  3149. foreach (VideoDetailedVM vid in fileLocalList)
  3150. finfo = vid.FileSelectionDisplay;
  3151. if (fileLocalList.Count == 1)
  3152. {
  3153. setGUIProperty("Episode.FileInfo", finfo);
  3154. }
  3155. else if (fileLocalList.Count > 1)
  3156. {
  3157. setGUIProperty("Episode.FileInfo", fileLocalList.Count.ToString() + " Files Available");
  3158. }
  3159. else if (fileLocalList.Count == 0)
  3160. {
  3161. if (dummyIsAvailable != null) dummyIsAvailable.Visible = false;
  3162. }
  3163. string logos = Logos.buildLogoImage(ep);
  3164. //MyAnimeLog.Write(logos);
  3165. BaseConfig.MyAnimeLog.Write(logos);
  3166. setGUIProperty(guiProperty.Logos, logos);
  3167. }
  3168. #region GUI Properties
  3169. public enum guiProperty
  3170. {
  3171. Title,
  3172. Subtitle,
  3173. Description,
  3174. CurrentView,
  3175. SimpleCurrentView,
  3176. NextView,
  3177. LastView,
  3178. SeriesBanner,
  3179. SeasonBanner,
  3180. EpisodeImage,
  3181. Logos,
  3182. SeriesCount,
  3183. GroupCount,
  3184. EpisodeCount,
  3185. RomanjiTitle,
  3186. EnglishTitle,
  3187. KanjiTitle,
  3188. RotatorTitle,
  3189. FindText,
  3190. FindMode,
  3191. FindStartWord,
  3192. FindInput,
  3193. FindMatch,
  3194. FindSharpMode,
  3195. FindAsteriskMode,
  3196. SeriesTitle,
  3197. EpisodesTypeTitle,
  3198. NotificationLine1,
  3199. NotificationLine2,
  3200. NotificationIcon,
  3201. NotificationAction
  3202. }
  3203. private string getGUIProperty(guiProperty which)
  3204. {
  3205. return getGUIProperty(which.ToString());
  3206. }
  3207. public static string getGUIProperty(string which)
  3208. {
  3209. return MediaPortal.GUI.Library.GUIPropertyManager.GetProperty("#Anime3." + which);
  3210. }
  3211. private void setGUIProperty(guiProperty which, string value)
  3212. {
  3213. setGUIProperty(which.ToString(), value);
  3214. }
  3215. public static void setGUIProperty(string which, string value)
  3216. {
  3217. MediaPortal.GUI.Library.GUIPropertyManager.SetProperty("#Anime3." + which, value);
  3218. }
  3219. private void clearGUIProperty(guiProperty which)
  3220. {
  3221. setGUIProperty(which, string.Empty);
  3222. }
  3223. public static void clearGUIProperty(string which)
  3224. {
  3225. setGUIProperty(which, "-"); // String.Empty doesn't work on non-initialized fields, as a result they would display as ugly #TVSeries.bla.bla
  3226. }
  3227. #endregion
  3228. private void LoadFanart(object objectWithFanart)
  3229. {
  3230. //BaseConfig.MyAnimeLog.Write("LOADING FANART FOR:: {0}", objectWithFanart.ToString());
  3231. try
  3232. {
  3233. DateTime start = DateTime.Now;
  3234. string desc = "";
  3235. Fanart fanart = null;
  3236. if (objectWithFanart.GetType() == typeof(AnimeGroupVM))
  3237. {
  3238. AnimeGroupVM grp = objectWithFanart as AnimeGroupVM;
  3239. fanart = new Fanart(grp);
  3240. desc = grp.GroupName;
  3241. }
  3242. if (objectWithFanart.GetType() == typeof(AnimeSeriesVM))
  3243. {
  3244. AnimeSeriesVM ser = objectWithFanart as AnimeSeriesVM;
  3245. fanart = new Fanart(ser);
  3246. desc = ser.SeriesName;
  3247. }
  3248. TimeSpan ts = DateTime.Now - start;
  3249. BaseConfig.MyAnimeLog.Write("GOT FANART details in: {0} ms ({1})", ts.TotalMilliseconds, desc);
  3250. BaseConfig.MyAnimeLog.Write("LOADING FANART: {0} - {1}", desc, fanart.FileName);
  3251. if (String.IsNullOrEmpty(fanart.FileName))
  3252. {
  3253. DisableFanart();
  3254. return;
  3255. }
  3256. fanartTexture.Filename = fanart.FileName;
  3257. if (this.dummyIsFanartLoaded != null)
  3258. this.dummyIsFanartLoaded.Visible = true;
  3259. }
  3260. catch (Exception ex)
  3261. {
  3262. BaseConfig.MyAnimeLog.Write(ex.ToString());
  3263. }
  3264. }
  3265. void DisableFanart()
  3266. {
  3267. //fanartSet = false;
  3268. fanartTexture.Filename = "";
  3269. if (this.dummyIsFanartLoaded != null)
  3270. this.dummyIsFanartLoaded.Visible = false;
  3271. }
  3272. protected override void OnShowContextMenu()
  3273. {
  3274. try
  3275. {
  3276. hook.IsEnabled = false;
  3277. switch (listLevel)
  3278. {
  3279. case Listlevel.GroupFilter:
  3280. ShowContextMenuGroupFilter("");
  3281. break;
  3282. case Listlevel.Group:
  3283. ShowContextMenuGroup("");
  3284. break;
  3285. case Listlevel.Series:
  3286. ShowContextMenuSeries("");
  3287. break;
  3288. case Listlevel.EpisodeTypes:
  3289. break;
  3290. case Listlevel.Episode:
  3291. ShowContextMenuEpisode("");
  3292. break;
  3293. }
  3294. Thread.Sleep(100); //make sure key-up's from the context menu aren't cought by the hook
  3295. if (hook != null) //hook may have fallen out of scope when using contect menu togo to another window.
  3296. hook.IsEnabled = true;
  3297. }
  3298. catch (Exception ex)
  3299. {
  3300. BaseConfig.MyAnimeLog.Write("Error in menu: {0}", ex);
  3301. }
  3302. }
  3303. private void AddContextMenuItem()
  3304. {
  3305. }
  3306. private bool SearchTheTvDB(AnimeSeriesVM ser, string searchCriteria, string previousMenu)
  3307. {
  3308. if (searchCriteria.Length == 0)
  3309. return true;
  3310. int aniDBID = ser.AniDB_Anime.AnimeID;
  3311. List<TVDBSeriesSearchResultVM> TVDBSeriesSearchResults = new List<TVDBSeriesSearchResultVM>();
  3312. List<JMMServerBinary.Contract_TVDBSeriesSearchResult> tvResults = JMMServerVM.Instance.clientBinaryHTTP.SearchTheTvDB(searchCriteria.Trim());
  3313. foreach (JMMServerBinary.Contract_TVDBSeriesSearchResult tvResult in tvResults)
  3314. TVDBSeriesSearchResults.Add(new TVDBSeriesSearchResultVM(tvResult));
  3315. BaseConfig.MyAnimeLog.Write("Found {0} tvdb results for {1}", TVDBSeriesSearchResults.Count, searchCriteria);
  3316. if (TVDBSeriesSearchResults.Count > 0)
  3317. {
  3318. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3319. if (dlg == null)
  3320. return true;
  3321. //keep showing the dialog until the user closes it
  3322. int selectedLabel = 0;
  3323. while (true)
  3324. {
  3325. dlg.Reset();
  3326. dlg.SetHeading("TvDB Search Results");
  3327. if (previousMenu != string.Empty)
  3328. dlg.Add("<<< " + previousMenu);
  3329. foreach (TVDBSeriesSearchResultVM res in TVDBSeriesSearchResults)
  3330. {
  3331. string disp = string.Format("{0} ({1}) / {2}", res.SeriesName, res.Language, res.Id);
  3332. dlg.Add(disp);
  3333. }
  3334. dlg.SelectedLabel = selectedLabel;
  3335. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3336. selectedLabel = dlg.SelectedLabel;
  3337. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3338. if (selection == 0)
  3339. return true; // previous menu
  3340. if (selection > 0 && selection <= TVDBSeriesSearchResults.Count)
  3341. {
  3342. TVDBSeriesSearchResultVM res = TVDBSeriesSearchResults[selection - 1];
  3343. LinkAniDBToTVDB(ser, aniDBID, res.SeriesID, 1);
  3344. return false;
  3345. }
  3346. return true;
  3347. }
  3348. }
  3349. else
  3350. {
  3351. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3352. if (null != dlgOK)
  3353. {
  3354. dlgOK.SetHeading("Search Results");
  3355. dlgOK.SetLine(1, string.Empty);
  3356. dlgOK.SetLine(2, "No results found");
  3357. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3358. }
  3359. return true;
  3360. }
  3361. }
  3362. private bool SearchTrakt(AnimeSeriesVM ser, string searchCriteria, string previousMenu)
  3363. {
  3364. if (searchCriteria.Length == 0)
  3365. return true;
  3366. int aniDBID = ser.AniDB_Anime.AnimeID;
  3367. List<TraktTVShowResponseVM> TraktSeriesSearchResults = new List<TraktTVShowResponseVM>();
  3368. List<JMMServerBinary.Contract_TraktTVShowResponse> traktResults = JMMServerVM.Instance.clientBinaryHTTP.SearchTrakt(searchCriteria);
  3369. foreach (JMMServerBinary.Contract_TraktTVShowResponse traktResult in traktResults)
  3370. TraktSeriesSearchResults.Add(new TraktTVShowResponseVM(traktResult));
  3371. BaseConfig.MyAnimeLog.Write("Found {0} trakt results for {1}", TraktSeriesSearchResults.Count, searchCriteria);
  3372. if (TraktSeriesSearchResults.Count > 0)
  3373. {
  3374. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3375. if (dlg == null)
  3376. return true;
  3377. //keep showing the dialog until the user closes it
  3378. int selectedLabel = 0;
  3379. while (true)
  3380. {
  3381. dlg.Reset();
  3382. dlg.SetHeading("Trakt Search Results");
  3383. if (previousMenu != string.Empty)
  3384. dlg.Add("<<< " + previousMenu);
  3385. foreach (TraktTVShowResponseVM res in TraktSeriesSearchResults)
  3386. {
  3387. string disp = string.Format("{0} ({1})", res.title, res.year);
  3388. dlg.Add(disp);
  3389. }
  3390. dlg.SelectedLabel = selectedLabel;
  3391. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3392. selectedLabel = dlg.SelectedLabel;
  3393. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3394. if (selection == 0)
  3395. return true; // previous menu
  3396. if (selection > 0 && selection <= TraktSeriesSearchResults.Count)
  3397. {
  3398. TraktTVShowResponseVM res = TraktSeriesSearchResults[selection - 1];
  3399. LinkAniDBToTrakt(ser, aniDBID, res.TraktID, 1);
  3400. return false;
  3401. }
  3402. return true;
  3403. }
  3404. }
  3405. else
  3406. {
  3407. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3408. if (null != dlgOK)
  3409. {
  3410. dlgOK.SetHeading("Search Results");
  3411. dlgOK.SetLine(1, string.Empty);
  3412. dlgOK.SetLine(2, "No results found");
  3413. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3414. }
  3415. return true;
  3416. }
  3417. }
  3418. private bool SearchTheTvDBMenu(AnimeSeriesVM ser, string previousMenu)
  3419. {
  3420. //string searchCriteria = "";
  3421. int aniDBID = ser.AniDB_Anime.AnimeID;
  3422. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3423. if (dlg == null)
  3424. return true;
  3425. //keep showing the dialog until the user closes it
  3426. int selectedLabel = 0;
  3427. string currentMenu = "Search The TvDB";
  3428. while (true)
  3429. {
  3430. dlg.Reset();
  3431. dlg.SetHeading(currentMenu);
  3432. if (previousMenu != string.Empty)
  3433. dlg.Add("<<< " + previousMenu);
  3434. dlg.Add("Search using: " + ser.AniDB_Anime.FormattedTitle);
  3435. dlg.Add("Manual Search");
  3436. CrossRef_AniDB_TvDBResultVM CrossRef_AniDB_TvDBResult = null;
  3437. JMMServerBinary.Contract_CrossRef_AniDB_TvDBResult xref = JMMServerVM.Instance.clientBinaryHTTP.GetTVDBCrossRefWebCache(aniDBID);
  3438. if (xref != null)
  3439. {
  3440. CrossRef_AniDB_TvDBResult = new CrossRef_AniDB_TvDBResultVM(xref);
  3441. dlg.Add("Community Says: " + CrossRef_AniDB_TvDBResult.SeriesName);
  3442. }
  3443. dlg.SelectedLabel = selectedLabel;
  3444. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3445. selectedLabel = dlg.SelectedLabel;
  3446. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3447. switch (selection)
  3448. {
  3449. case 0:
  3450. //show previous
  3451. return true;
  3452. case 1:
  3453. if (!SearchTheTvDB(ser, ser.AniDB_Anime.FormattedTitle, currentMenu))
  3454. return false;
  3455. break;
  3456. case 2:
  3457. {
  3458. if (Utils.DialogText(ref searchText, GetID))
  3459. {
  3460. if (!SearchTheTvDB(ser, searchText, currentMenu))
  3461. return false;
  3462. }
  3463. }
  3464. break;
  3465. case 3:
  3466. LinkAniDBToTVDB(ser, ser.AniDB_Anime.AnimeID, CrossRef_AniDB_TvDBResult.TvDBID, CrossRef_AniDB_TvDBResult.TvDBSeasonNumber);
  3467. return false;
  3468. default:
  3469. //close menu
  3470. return false;
  3471. }
  3472. }
  3473. }
  3474. private bool SearchTraktMenu(AnimeSeriesVM ser, string previousMenu)
  3475. {
  3476. //string searchCriteria = "";
  3477. int aniDBID = ser.AniDB_Anime.AnimeID;
  3478. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3479. if (dlg == null)
  3480. return true;
  3481. //keep showing the dialog until the user closes it
  3482. int selectedLabel = 0;
  3483. string currentMenu = "Search Trakt";
  3484. while (true)
  3485. {
  3486. dlg.Reset();
  3487. dlg.SetHeading(currentMenu);
  3488. if (previousMenu != string.Empty)
  3489. dlg.Add("<<< " + previousMenu);
  3490. dlg.Add("Search using: " + ser.AniDB_Anime.FormattedTitle);
  3491. dlg.Add("Manual Search");
  3492. CrossRef_AniDB_TraktResultVM webCacheResult = null;
  3493. JMMServerBinary.Contract_CrossRef_AniDB_TraktResult xref = JMMServerVM.Instance.clientBinaryHTTP.GetTraktCrossRefWebCache(aniDBID);
  3494. if (xref != null)
  3495. {
  3496. webCacheResult = new CrossRef_AniDB_TraktResultVM(xref);
  3497. dlg.Add("Community Says: " + webCacheResult.ShowName);
  3498. }
  3499. dlg.SelectedLabel = selectedLabel;
  3500. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3501. selectedLabel = dlg.SelectedLabel;
  3502. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3503. switch (selection)
  3504. {
  3505. case 0:
  3506. //show previous
  3507. return true;
  3508. case 1:
  3509. if (!SearchTrakt(ser, ser.AniDB_Anime.FormattedTitle, currentMenu))
  3510. return false;
  3511. break;
  3512. case 2:
  3513. {
  3514. if (Utils.DialogText(ref searchText, GetID))
  3515. {
  3516. if (!SearchTrakt(ser, searchText, currentMenu))
  3517. return false;
  3518. }
  3519. }
  3520. break;
  3521. case 3:
  3522. LinkAniDBToTrakt(ser, ser.AniDB_Anime.AnimeID, webCacheResult.TraktID, webCacheResult.TraktSeasonNumber);
  3523. return false;
  3524. default:
  3525. //close menu
  3526. return false;
  3527. }
  3528. }
  3529. }
  3530. private void LinkAniDBToTrakt(AnimeSeriesVM ser, int animeID, string traktID, int season)
  3531. {
  3532. string res = JMMServerVM.Instance.clientBinaryHTTP.LinkAniDBTrakt(animeID, traktID, season);
  3533. if (res.Length > 0)
  3534. Utils.DialogMsg("Error", res);
  3535. ser = JMMServerHelper.GetSeries(ser.AnimeSeriesID.Value);
  3536. }
  3537. private void LinkAniDBToTVDB(AnimeSeriesVM ser, int animeID, int tvDBID, int season)
  3538. {
  3539. string res = JMMServerVM.Instance.clientBinaryHTTP.LinkAniDBTvDB(animeID, tvDBID, season);
  3540. if (res.Length > 0)
  3541. Utils.DialogMsg("Error", res);
  3542. ser = JMMServerHelper.GetSeries(ser.AnimeSeriesID.Value);
  3543. }
  3544. private void LinkAniDBToMovieDB(AnimeSeriesVM ser, int animeID, int movieID)
  3545. {
  3546. string res = JMMServerVM.Instance.clientBinaryHTTP.LinkAniDBOther(animeID, movieID, (int)CrossRefType.MovieDB);
  3547. if (res.Length > 0)
  3548. Utils.DialogMsg("Error", res);
  3549. ser = JMMServerHelper.GetSeries(ser.AnimeSeriesID.Value);
  3550. }
  3551. private void LinkAniDBToMAL(AnimeSeriesVM ser, int animeID, int malID, string malTitle)
  3552. {
  3553. if (ser.CrossRef_AniDB_MAL != null)
  3554. {
  3555. foreach (CrossRef_AniDB_MALVM xref in ser.CrossRef_AniDB_MAL)
  3556. JMMServerVM.Instance.clientBinaryHTTP.RemoveLinkAniDBMAL(xref.AnimeID, xref.StartEpisodeType, xref.StartEpisodeNumber);
  3557. }
  3558. string res = JMMServerVM.Instance.clientBinaryHTTP.LinkAniDBMAL(animeID, malID, malTitle, 1, 1);
  3559. if (res.Length > 0)
  3560. Utils.DialogMsg("Error", res);
  3561. ser = JMMServerHelper.GetSeries(ser.AnimeSeriesID.Value);
  3562. }
  3563. private bool SearchTheMovieDBMenu(AnimeSeriesVM ser, string previousMenu)
  3564. {
  3565. int aniDBID = ser.AniDB_Anime.AnimeID;
  3566. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3567. if (dlg == null)
  3568. return true;
  3569. //keep showing the dialog until the user closes it
  3570. int selectedLabel = 0;
  3571. string currentMenu = "Search The MovieDB";
  3572. while (true)
  3573. {
  3574. dlg.Reset();
  3575. dlg.SetHeading(currentMenu);
  3576. if (previousMenu != string.Empty)
  3577. dlg.Add("<<< " + previousMenu);
  3578. dlg.Add("Search using: " + ser.AniDB_Anime.FormattedTitle);
  3579. dlg.Add("Manual Search");
  3580. CrossRef_AniDB_OtherResultVM CrossRef_AniDB_OtherResult = null;
  3581. JMMServerBinary.Contract_CrossRef_AniDB_OtherResult xref = JMMServerVM.Instance.clientBinaryHTTP.GetOtherAnimeCrossRefWebCache(aniDBID, (int)CrossRefType.MovieDB);
  3582. if (xref != null)
  3583. {
  3584. CrossRef_AniDB_OtherResult = new CrossRef_AniDB_OtherResultVM(xref);
  3585. dlg.Add("Community Says: " + CrossRef_AniDB_OtherResult.CrossRefID.ToString());
  3586. }
  3587. dlg.SelectedLabel = selectedLabel;
  3588. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3589. selectedLabel = dlg.SelectedLabel;
  3590. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3591. switch (selection)
  3592. {
  3593. case 0:
  3594. //show previous
  3595. return true;
  3596. case 1:
  3597. if (!SearchTheMovieDB(ser, ser.AniDB_Anime.FormattedTitle, currentMenu))
  3598. return false;
  3599. break;
  3600. case 2:
  3601. {
  3602. string searchText = ser.AniDB_Anime.FormattedTitle;
  3603. if (Utils.DialogText(ref searchText, GetID))
  3604. {
  3605. if (!SearchTheMovieDB(ser, searchText, currentMenu))
  3606. return false;
  3607. }
  3608. }
  3609. break;
  3610. case 3:
  3611. LinkAniDBToMovieDB(ser, CrossRef_AniDB_OtherResult.AnimeID, int.Parse(CrossRef_AniDB_OtherResult.CrossRefID));
  3612. return false;
  3613. default:
  3614. //close menu
  3615. return false;
  3616. }
  3617. }
  3618. }
  3619. private bool SearchTheMovieDB(AnimeSeriesVM ser, string searchCriteria, string previousMenu)
  3620. {
  3621. if (searchCriteria.Length == 0)
  3622. return true;
  3623. int aniDBID = ser.AniDB_Anime.AnimeID;
  3624. List<MovieDBMovieSearchResultVM> MovieDBSeriesSearchResults = new List<MovieDBMovieSearchResultVM>();
  3625. List<JMMServerBinary.Contract_MovieDBMovieSearchResult> movieResults = JMMServerVM.Instance.clientBinaryHTTP.SearchTheMovieDB(searchCriteria.Trim());
  3626. foreach (JMMServerBinary.Contract_MovieDBMovieSearchResult movieResult in movieResults)
  3627. MovieDBSeriesSearchResults.Add(new MovieDBMovieSearchResultVM(movieResult));
  3628. BaseConfig.MyAnimeLog.Write("Found {0} moviedb results for {1}", MovieDBSeriesSearchResults.Count, searchCriteria);
  3629. if (MovieDBSeriesSearchResults.Count > 0)
  3630. {
  3631. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3632. if (dlg == null)
  3633. return true;
  3634. //keep showing the dialog until the user closes it
  3635. int selectedLabel = 0;
  3636. while (true)
  3637. {
  3638. dlg.Reset();
  3639. dlg.SetHeading("Search Results");
  3640. if (previousMenu != string.Empty)
  3641. dlg.Add("<<< " + previousMenu);
  3642. foreach (MovieDBMovieSearchResultVM res in MovieDBSeriesSearchResults)
  3643. dlg.Add(res.MovieName);
  3644. dlg.SelectedLabel = selectedLabel;
  3645. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3646. selectedLabel = dlg.SelectedLabel;
  3647. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3648. if (selection == 0)
  3649. return true; //previous menu
  3650. if (selection > 0 && selection <= MovieDBSeriesSearchResults.Count)
  3651. {
  3652. MovieDBMovieSearchResultVM res = MovieDBSeriesSearchResults[selection - 1];
  3653. LinkAniDBToMovieDB(ser, aniDBID, res.MovieID);
  3654. return false;
  3655. }
  3656. return true;
  3657. }
  3658. }
  3659. else
  3660. {
  3661. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3662. if (null != dlgOK)
  3663. {
  3664. dlgOK.SetHeading("Search Results");
  3665. dlgOK.SetLine(1, string.Empty);
  3666. dlgOK.SetLine(2, "No results found");
  3667. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3668. }
  3669. return true;
  3670. }
  3671. }
  3672. private bool SearchMALMenu(AnimeSeriesVM ser, string previousMenu)
  3673. {
  3674. int aniDBID = ser.AniDB_Anime.AnimeID;
  3675. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3676. if (dlg == null)
  3677. return true;
  3678. //keep showing the dialog until the user closes it
  3679. int selectedLabel = 0;
  3680. string currentMenu = "Search MAL";
  3681. while (true)
  3682. {
  3683. dlg.Reset();
  3684. dlg.SetHeading(currentMenu);
  3685. if (previousMenu != string.Empty)
  3686. dlg.Add("<<< " + previousMenu);
  3687. dlg.Add("Search using: " + ser.AniDB_Anime.FormattedTitle);
  3688. dlg.Add("Manual Search");
  3689. dlg.SelectedLabel = selectedLabel;
  3690. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3691. selectedLabel = dlg.SelectedLabel;
  3692. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3693. switch (selection)
  3694. {
  3695. case 0:
  3696. //show previous
  3697. return true;
  3698. case 1:
  3699. if (!SearchMAL(ser, ser.AniDB_Anime.FormattedTitle, currentMenu))
  3700. return false;
  3701. break;
  3702. case 2:
  3703. {
  3704. string searchText = ser.AniDB_Anime.FormattedTitle;
  3705. if (Utils.DialogText(ref searchText, GetID))
  3706. {
  3707. if (!SearchMAL(ser, searchText, currentMenu))
  3708. return false;
  3709. }
  3710. }
  3711. break;
  3712. default:
  3713. //close menu
  3714. return false;
  3715. }
  3716. }
  3717. }
  3718. private bool SearchMAL(AnimeSeriesVM ser, string searchCriteria, string previousMenu)
  3719. {
  3720. if (searchCriteria.Length == 0)
  3721. return true;
  3722. int aniDBID = ser.AniDB_Anime.AnimeID;
  3723. List<MALSearchResultVM> MALSearchResults = new List<MALSearchResultVM>();
  3724. List<JMMServerBinary.Contract_MALAnimeResponse> malResults = JMMServerVM.Instance.clientBinaryHTTP.SearchMAL(searchCriteria.Trim());
  3725. foreach (JMMServerBinary.Contract_MALAnimeResponse malResult in malResults)
  3726. MALSearchResults.Add(new MALSearchResultVM(malResult));
  3727. BaseConfig.MyAnimeLog.Write("Found {0} MAL results for {1}", MALSearchResults.Count, searchCriteria);
  3728. if (MALSearchResults.Count > 0)
  3729. {
  3730. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3731. if (dlg == null)
  3732. return true;
  3733. //keep showing the dialog until the user closes it
  3734. int selectedLabel = 0;
  3735. while (true)
  3736. {
  3737. dlg.Reset();
  3738. dlg.SetHeading("Search Results");
  3739. if (previousMenu != string.Empty)
  3740. dlg.Add("<<< " + previousMenu);
  3741. foreach (MALSearchResultVM res in MALSearchResults)
  3742. dlg.Add(string.Format("{0} ({1} Eps)", res.title, res.episodes));
  3743. dlg.SelectedLabel = selectedLabel;
  3744. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3745. selectedLabel = dlg.SelectedLabel;
  3746. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3747. if (selection == 0)
  3748. return true; //previous menu
  3749. if (selection > 0 && selection <= MALSearchResults.Count)
  3750. {
  3751. MALSearchResultVM res = MALSearchResults[selection - 1];
  3752. LinkAniDBToMAL(ser, aniDBID, res.id, res.title);
  3753. return false;
  3754. }
  3755. return true;
  3756. }
  3757. }
  3758. else
  3759. {
  3760. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3761. if (null != dlgOK)
  3762. {
  3763. dlgOK.SetHeading("Search Results");
  3764. dlgOK.SetLine(1, string.Empty);
  3765. dlgOK.SetLine(2, "No results found");
  3766. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3767. }
  3768. return true;
  3769. }
  3770. }
  3771. private bool ShowContextMenuEpisode(string previousMenu)
  3772. {
  3773. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  3774. if (currentitem == null)
  3775. return true;
  3776. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3777. if (dlg == null)
  3778. return true;
  3779. AnimeEpisodeVM episode = currentitem.TVTag as AnimeEpisodeVM;
  3780. if (episode == null)
  3781. return true;
  3782. //keep showing the dialog until the user closes it
  3783. int selectedLabel = 0;
  3784. string currentMenu = episode.EpisodeNumberAndName;
  3785. while (true)
  3786. {
  3787. dlg.Reset();
  3788. dlg.SetHeading(currentMenu);
  3789. if (previousMenu != string.Empty)
  3790. dlg.Add("<<< " + previousMenu);
  3791. bool isWatched = (episode.IsWatched == 1);
  3792. if (isWatched)
  3793. dlg.Add("Mark as Unwatched");
  3794. else
  3795. dlg.Add("Mark as Watched");
  3796. dlg.Add("Mark ALL as Watched");
  3797. dlg.Add("Mark ALL as Unwatched");
  3798. dlg.Add("Mark ALL PREVIOUS as Watched");
  3799. dlg.Add("Mark ALL PREVIOUS as Unwatched");
  3800. dlg.Add("Associate File With This Episode");
  3801. dlg.Add("Remove File From This Episode");
  3802. dlg.Add("Download this epsiode");
  3803. dlg.Add("Post-processing >>>");
  3804. dlg.SelectedLabel = selectedLabel;
  3805. dlg.DoModal(GUIWindowManager.ActiveWindow);
  3806. selectedLabel = dlg.SelectedLabel;
  3807. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  3808. switch (selection)
  3809. {
  3810. case 0:
  3811. //show previous
  3812. return true;
  3813. case 1:
  3814. { // Mark as Watched/Unwatched
  3815. BaseConfig.MyAnimeLog.Write("Toggle watched status: {0} - {1}", isWatched, episode);
  3816. episode.ToggleWatchedStatus(!isWatched);
  3817. LoadFacade();
  3818. return false;
  3819. }
  3820. case 2: // Mark ALL as Watched
  3821. {
  3822. JMMServerVM.Instance.clientBinaryHTTP.SetWatchedStatusOnSeries(curAnimeSeries.AnimeSeriesID.Value,
  3823. true, int.MaxValue, (int)curAnimeEpisodeType.EpisodeType, JMMServerVM.Instance.CurrentUser.JMMUserID);
  3824. if (BaseConfig.Settings.DisplayRatingDialogOnCompletion)
  3825. {
  3826. JMMServerBinary.Contract_AnimeSeries contract = JMMServerVM.Instance.clientBinaryHTTP.GetSeries(curAnimeSeries.AnimeSeriesID.Value,
  3827. JMMServerVM.Instance.CurrentUser.JMMUserID);
  3828. if (contract != null)
  3829. {
  3830. AnimeSeriesVM ser = new AnimeSeriesVM(contract);
  3831. Utils.PromptToRateSeriesOnCompletion(ser);
  3832. }
  3833. }
  3834. LoadFacade();
  3835. return false;
  3836. }
  3837. case 3: // Mark ALL as Unwatched
  3838. {
  3839. JMMServerVM.Instance.clientBinaryHTTP.SetWatchedStatusOnSeries(curAnimeSeries.AnimeSeriesID.Value,
  3840. false, int.MaxValue, (int)curAnimeEpisodeType.EpisodeType, JMMServerVM.Instance.CurrentUser.JMMUserID);
  3841. LoadFacade();
  3842. return false;
  3843. }
  3844. case 4: // Mark ALL PREVIOUS as Watched
  3845. {
  3846. JMMServerVM.Instance.clientBinaryHTTP.SetWatchedStatusOnSeries(curAnimeSeries.AnimeSeriesID.Value,
  3847. true, episode.EpisodeNumber, (int)curAnimeEpisodeType.EpisodeType, JMMServerVM.Instance.CurrentUser.JMMUserID);
  3848. JMMServerBinary.Contract_AnimeSeries contract = JMMServerVM.Instance.clientBinaryHTTP.GetSeries(curAnimeSeries.AnimeSeriesID.Value,
  3849. JMMServerVM.Instance.CurrentUser.JMMUserID);
  3850. if (contract != null)
  3851. {
  3852. AnimeSeriesVM ser = new AnimeSeriesVM(contract);
  3853. Utils.PromptToRateSeriesOnCompletion(ser);
  3854. }
  3855. LoadFacade();
  3856. return false;
  3857. }
  3858. case 5: // Mark ALL PREVIOUS as Unwatched
  3859. {
  3860. JMMServerVM.Instance.clientBinaryHTTP.SetWatchedStatusOnSeries(curAnimeSeries.AnimeSeriesID.Value,
  3861. false, episode.EpisodeNumber, (int)curAnimeEpisodeType.EpisodeType, JMMServerVM.Instance.CurrentUser.JMMUserID);
  3862. LoadFacade();
  3863. return false;
  3864. }
  3865. case 6: // associate file with this episode
  3866. {
  3867. List<VideoLocalVM> unlinkedVideos = JMMServerHelper.GetUnlinkedVideos();
  3868. if (unlinkedVideos.Count == 0)
  3869. {
  3870. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3871. if (null != dlgOK)
  3872. {
  3873. dlgOK.SetHeading("Error");
  3874. dlgOK.SetLine(1, string.Empty);
  3875. dlgOK.SetLine(2, "No unlinked files to select");
  3876. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3877. }
  3878. break;
  3879. }
  3880. // ask the user which file they want to associate
  3881. IDialogbox dlg2 = (IDialogbox)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3882. dlg2.Reset();
  3883. dlg2.SetHeading("Select File");
  3884. foreach (VideoLocalVM fl in unlinkedVideos)
  3885. dlg2.Add(Path.GetFileName(fl.FullPath) + " - " + Path.GetDirectoryName(fl.FullPath));
  3886. dlg2.DoModal(GUIWindowManager.ActiveWindow);
  3887. if (dlg2.SelectedId > 0)
  3888. {
  3889. VideoLocalVM selectedFile = unlinkedVideos[dlg2.SelectedId - 1];
  3890. JMMServerHelper.LinkedFileToEpisode(selectedFile.VideoLocalID, episode.AnimeEpisodeID);
  3891. LoadFacade();
  3892. return false;
  3893. }
  3894. break;
  3895. }
  3896. case 7: // remove associated file
  3897. {
  3898. List<VideoDetailedVM> vidList = episode.FilesForEpisode;
  3899. if (vidList.Count == 0)
  3900. {
  3901. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  3902. if (null != dlgOK)
  3903. {
  3904. dlgOK.SetHeading("Error");
  3905. dlgOK.SetLine(1, string.Empty);
  3906. dlgOK.SetLine(2, "This episode has no associated files");
  3907. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  3908. }
  3909. break;
  3910. }
  3911. // ask the user which file they want to un-associate
  3912. IDialogbox dlg2 = (IDialogbox)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3913. dlg2.Reset();
  3914. dlg2.SetHeading("Select File");
  3915. foreach (VideoDetailedVM fl in vidList)
  3916. dlg2.Add(Path.GetFileName(fl.FileName));
  3917. dlg2.DoModal(GUIWindowManager.ActiveWindow);
  3918. if (dlg2.SelectedId > 0)
  3919. {
  3920. VideoDetailedVM selectedFile = vidList[dlg2.SelectedId - 1];
  3921. string res = JMMServerVM.Instance.clientBinaryHTTP.RemoveAssociationOnFile(selectedFile.VideoLocalID, episode.AniDB_EpisodeID);
  3922. if (!string.IsNullOrEmpty(res))
  3923. Utils.DialogMsg("Error", res);
  3924. LoadFacade();
  3925. return false;
  3926. }
  3927. break;
  3928. }
  3929. case 8:
  3930. DownloadHelper.SearchEpisode(curAnimeEpisode);
  3931. return false;
  3932. case 9:
  3933. if (!ShowContextMenuPostProcessing(currentMenu))
  3934. return false;
  3935. break;
  3936. default:
  3937. //close menu
  3938. return false;
  3939. }
  3940. }
  3941. }
  3942. private bool ShowContextMenuDatabases(AnimeSeriesVM ser, string previousMenu)
  3943. {
  3944. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  3945. if (dlg == null)
  3946. return true;
  3947. int mnuPrevious = -1;
  3948. int mnuTvDB = -1;
  3949. int mnuMovieDB = -1;
  3950. int mnuTvDBSub = -1;
  3951. int mnuMovieDBSub = -1;
  3952. int mnuTrakt = -1;
  3953. int mnuTraktSub = -1;
  3954. int mnuMAL = -1;
  3955. int mnuMALSub = -1;
  3956. int curMenu = -1;
  3957. //keep showing the dialog until the user closes it
  3958. int selectedLabel = 0;
  3959. string currentMenu = ser.SeriesName + " Databases";
  3960. bool hasTvDBLink = ser.CrossRef_AniDB_TvDB != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.TvDBSeries != null;
  3961. bool hasMovieDBLink = ser.CrossRef_AniDB_MovieDB != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.MovieDB_Movie != null;
  3962. bool hasTraktLink = ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.TraktShow != null;
  3963. bool hasMALLink = ser.CrossRef_AniDB_MAL != null && ser.CrossRef_AniDB_MAL.Count > 0;
  3964. while (true)
  3965. {
  3966. dlg.Reset();
  3967. dlg.SetHeading(currentMenu);
  3968. string tvdbText = "Search The TvDB";
  3969. string moviedbText = "Search The MovieDB";
  3970. string traktText = "Search Trakt.tv";
  3971. string malText = "Search MAL";
  3972. if (ser != null)
  3973. {
  3974. if (hasTvDBLink)
  3975. tvdbText += " (Current: " + ser.AniDB_Anime.AniDB_AnimeCrossRefs.TvDBSeries.SeriesName + ")";
  3976. if (hasMovieDBLink)
  3977. moviedbText += " (Current: " + ser.AniDB_Anime.AniDB_AnimeCrossRefs.MovieDB_Movie.MovieName + ")";
  3978. if (hasTraktLink)
  3979. traktText += " (Current: " + ser.AniDB_Anime.AniDB_AnimeCrossRefs.TraktShow.Title + ")";
  3980. if (hasMALLink)
  3981. {
  3982. if (ser.CrossRef_AniDB_MAL.Count == 1)
  3983. malText += " (Current: " + ser.CrossRef_AniDB_MAL[0].MALTitle + ")";
  3984. else
  3985. malText += " (Current: Multiple Links)";
  3986. }
  3987. }
  3988. if (previousMenu != string.Empty)
  3989. {
  3990. dlg.Add("<<< " + previousMenu);
  3991. curMenu++; mnuPrevious = curMenu;
  3992. }
  3993. if (ser != null && !hasMovieDBLink)
  3994. {
  3995. dlg.Add(tvdbText);
  3996. curMenu++; mnuTvDB = curMenu;
  3997. dlg.Add(traktText);
  3998. curMenu++; mnuTrakt = curMenu;
  3999. dlg.Add(malText);
  4000. curMenu++; mnuMAL = curMenu;
  4001. }
  4002. if (ser != null && !hasTvDBLink && !hasTraktLink)
  4003. {
  4004. dlg.Add(moviedbText);
  4005. curMenu++; mnuMovieDB = curMenu;
  4006. }
  4007. if (ser != null && hasTvDBLink)
  4008. {
  4009. dlg.Add("The Tv DB >>>");
  4010. curMenu++; mnuTvDBSub = curMenu;
  4011. }
  4012. if (ser != null && hasTraktLink)
  4013. {
  4014. dlg.Add("Trakt.tv >>>");
  4015. curMenu++; mnuTraktSub = curMenu;
  4016. }
  4017. if (ser != null && hasMALLink)
  4018. {
  4019. dlg.Add("MAL >>>");
  4020. curMenu++; mnuMALSub = curMenu;
  4021. }
  4022. if (ser != null && hasMovieDBLink)
  4023. {
  4024. dlg.Add("The Movie DB >>>");
  4025. curMenu++; mnuMovieDBSub = curMenu;
  4026. }
  4027. dlg.SelectedLabel = selectedLabel;
  4028. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4029. selectedLabel = dlg.SelectedLabel;
  4030. if (selectedLabel == mnuPrevious) return true;
  4031. if (selectedLabel == mnuTvDB)
  4032. {
  4033. if (!SearchTheTvDBMenu(ser, currentMenu))
  4034. return false;
  4035. }
  4036. if (selectedLabel == mnuTrakt)
  4037. {
  4038. if (!SearchTraktMenu(ser, currentMenu))
  4039. return false;
  4040. }
  4041. if (selectedLabel == mnuMAL)
  4042. {
  4043. if (!SearchMALMenu(ser, currentMenu))
  4044. return false;
  4045. }
  4046. if (selectedLabel == mnuMovieDB)
  4047. {
  4048. if (!SearchTheMovieDBMenu(ser, currentMenu))
  4049. return false;
  4050. }
  4051. if (selectedLabel == mnuTvDBSub)
  4052. {
  4053. if (!ShowContextMenuTVDB(ser, currentMenu))
  4054. return false;
  4055. }
  4056. if (selectedLabel == mnuTraktSub)
  4057. {
  4058. if (!ShowContextMenuTrakt(ser, currentMenu))
  4059. return false;
  4060. }
  4061. if (selectedLabel == mnuMALSub)
  4062. {
  4063. if (!ShowContextMenuMAL(ser, currentMenu))
  4064. return false;
  4065. }
  4066. if (selectedLabel == mnuMovieDBSub)
  4067. {
  4068. if (!ShowContextMenuMovieDB(ser, currentMenu))
  4069. return false;
  4070. }
  4071. return false;
  4072. }
  4073. }
  4074. private bool ShowContextMenuGroupEdit(string previousMenu)
  4075. {
  4076. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4077. if (dlg == null)
  4078. return true;
  4079. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4080. if (currentitem == null)
  4081. return true;
  4082. AnimeGroupVM grp = currentitem.TVTag as AnimeGroupVM;
  4083. if (grp == null)
  4084. return true;
  4085. List<AnimeSeriesVM> allSeries = grp.AllSeries;
  4086. AnimeSeriesVM equalSeries = null;
  4087. if (allSeries.Count == 1)
  4088. equalSeries = allSeries[0];
  4089. int mnuPrevious = -1;
  4090. int mnuChangeSortName = -1;
  4091. int mnuAudioLanguage = -1;
  4092. int mnuSubLanguage = -1;
  4093. int mnuDelete = -1;
  4094. int mnuRename = -1;
  4095. int mnuRemDefault = -1;
  4096. int mnuAddDefault = -1;
  4097. int curMenu = -1;
  4098. //keep showing the dialog until the user closes it
  4099. int selectedLabel = 0;
  4100. string currentMenu = grp.GroupName + " - Edit";
  4101. while (true)
  4102. {
  4103. dlg.Reset();
  4104. dlg.SetHeading(currentMenu);
  4105. dlg.Add("<<< " + previousMenu);
  4106. curMenu++; mnuPrevious = curMenu;
  4107. dlg.Add("Rename Group");
  4108. curMenu++; mnuRename = curMenu;
  4109. dlg.Add("Change Sort Name");
  4110. curMenu++; mnuChangeSortName = curMenu;
  4111. if (equalSeries != null)
  4112. {
  4113. dlg.Add("Set Default Audio Language");
  4114. curMenu++; mnuAudioLanguage = curMenu;
  4115. dlg.Add("Set Default Subtitle language");
  4116. curMenu++; mnuSubLanguage = curMenu;
  4117. }
  4118. if (grp.DefaultAnimeSeriesID.HasValue)
  4119. {
  4120. dlg.Add("Remove Default Series");
  4121. curMenu++; mnuRemDefault = curMenu;
  4122. }
  4123. if (allSeries.Count > 1)
  4124. {
  4125. dlg.Add("Set Default Series");
  4126. curMenu++; mnuAddDefault = curMenu;
  4127. }
  4128. dlg.Add("Delete This Group/Series/Episodes");
  4129. curMenu++; mnuDelete = curMenu;
  4130. dlg.SelectedLabel = selectedLabel;
  4131. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4132. selectedLabel = dlg.SelectedLabel;
  4133. if (selectedLabel == mnuPrevious)
  4134. return true;
  4135. if (selectedLabel == mnuRename)
  4136. {
  4137. string name = grp.GroupName;
  4138. if (Utils.DialogText(ref name, GetID) && name != string.Empty)
  4139. {
  4140. if (name != grp.GroupName)
  4141. {
  4142. grp.GroupName = name;
  4143. grp.SortName = Utils.GetSortName(name);
  4144. grp.Save();
  4145. LoadFacade();
  4146. }
  4147. return false;
  4148. }
  4149. }
  4150. if (selectedLabel == mnuChangeSortName)
  4151. {
  4152. string sortName = grp.SortName;
  4153. if (Utils.DialogText(ref sortName, GetID))
  4154. {
  4155. grp.SortName = sortName;
  4156. grp.Save();
  4157. LoadFacade();
  4158. return false;
  4159. }
  4160. }
  4161. if (selectedLabel == mnuAudioLanguage)
  4162. {
  4163. String language = equalSeries.DefaultAudioLanguage;
  4164. if (Utils.DialogLanguage(ref language, false))
  4165. {
  4166. equalSeries.DefaultAudioLanguage = language;
  4167. equalSeries.Save();
  4168. return false;
  4169. }
  4170. }
  4171. if (selectedLabel == mnuRemDefault)
  4172. {
  4173. JMMServerVM.Instance.clientBinaryHTTP.RemoveDefaultSeriesForGroup(grp.AnimeGroupID);
  4174. grp.DefaultAnimeSeriesID = null;
  4175. }
  4176. if (selectedLabel == mnuAddDefault)
  4177. {
  4178. AnimeSeriesVM ser = null;
  4179. if (Utils.DialogSelectSeries(ref ser, allSeries))
  4180. {
  4181. grp.DefaultAnimeSeriesID = ser.AnimeSeriesID;
  4182. JMMServerVM.Instance.clientBinaryHTTP.SetDefaultSeriesForGroup(grp.AnimeGroupID, ser.AnimeSeriesID.Value);
  4183. }
  4184. }
  4185. if (selectedLabel == mnuSubLanguage)
  4186. {
  4187. String language = equalSeries.DefaultSubtitleLanguage;
  4188. if (Utils.DialogLanguage(ref language, true))
  4189. {
  4190. equalSeries.DefaultSubtitleLanguage = language;
  4191. equalSeries.Save();
  4192. return false;
  4193. }
  4194. }
  4195. if (selectedLabel == mnuDelete)
  4196. {
  4197. if (Utils.DialogConfirm("Are you sure?"))
  4198. {
  4199. JMMServerVM.Instance.clientBinaryHTTP.DeleteAnimeGroup(grp.AnimeGroupID, false);
  4200. }
  4201. LoadFacade();
  4202. return false;
  4203. }
  4204. return false;
  4205. }
  4206. }
  4207. private bool ShowContextMenuSeriesInfo(string previousMenu)
  4208. {
  4209. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4210. if (currentitem == null)
  4211. return true;
  4212. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4213. if (dlg == null)
  4214. return true;
  4215. //keep showing the dialog until the user closes it
  4216. int selectedLabel = 0;
  4217. string currentMenu = "Series Information";
  4218. while (true)
  4219. {
  4220. dlg.Reset();
  4221. dlg.SetHeading(currentMenu);
  4222. if (previousMenu != string.Empty)
  4223. dlg.Add("<<< " + previousMenu);
  4224. dlg.Add("Characters/Actors");
  4225. dlg.Add("Related Series");
  4226. dlg.SelectedLabel = selectedLabel;
  4227. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4228. selectedLabel = dlg.SelectedLabel;
  4229. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4230. switch (selection)
  4231. {
  4232. case 0:
  4233. //show previous
  4234. return true;
  4235. case 1:
  4236. ShowCharacterWindow();
  4237. return false;
  4238. case 2:
  4239. ShowRelationsWindow();
  4240. return false;
  4241. default:
  4242. //close menu
  4243. return false;
  4244. }
  4245. }
  4246. }
  4247. private bool ShowContextMenuGroupFilter(string previousMenu)
  4248. {
  4249. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4250. if (currentitem == null)
  4251. return true;
  4252. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4253. if (dlg == null)
  4254. return true;
  4255. GroupFilterVM gf = currentitem.TVTag as GroupFilterVM;
  4256. if (gf == null)
  4257. return true;
  4258. int mnuPrev = -1;
  4259. int mnuRandomSeries = -1;
  4260. int mnuRandomEpisode = -1;
  4261. //keep showing the dialog until the user closes it
  4262. int selectedLabel = 0;
  4263. string currentMenu = gf.GroupFilterName;
  4264. while (true)
  4265. {
  4266. int curMenu = -1;
  4267. dlg.Reset();
  4268. dlg.SetHeading(currentMenu);
  4269. if (previousMenu != string.Empty)
  4270. {
  4271. dlg.Add("<<< " + previousMenu);
  4272. curMenu++; mnuPrev = curMenu;
  4273. }
  4274. dlg.Add("Random Series");
  4275. curMenu++; mnuRandomSeries = curMenu;
  4276. dlg.Add("Random Episode");
  4277. curMenu++; mnuRandomEpisode = curMenu;
  4278. dlg.SelectedLabel = selectedLabel;
  4279. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4280. selectedLabel = dlg.SelectedLabel;
  4281. if (selectedLabel == mnuPrev) return true;
  4282. if (selectedLabel == mnuRandomSeries)
  4283. {
  4284. RandomWindow_CurrentEpisode = null;
  4285. RandomWindow_CurrentSeries = null;
  4286. RandomWindow_LevelObject = gf;
  4287. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.GroupFilter;
  4288. RandomWindow_RandomType = RandomObjectType.Series;
  4289. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  4290. return false;
  4291. }
  4292. if (selectedLabel == mnuRandomEpisode)
  4293. {
  4294. RandomWindow_CurrentEpisode = null;
  4295. RandomWindow_CurrentSeries = null;
  4296. RandomWindow_LevelObject = gf;
  4297. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.GroupFilter;
  4298. RandomWindow_RandomType = RandomObjectType.Episode;
  4299. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  4300. return false;
  4301. }
  4302. }
  4303. }
  4304. private bool ShowContextMenuGroup(string previousMenu)
  4305. {
  4306. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4307. if (currentitem == null)
  4308. return true;
  4309. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4310. if (dlg == null)
  4311. return true;
  4312. AnimeGroupVM grp = currentitem.TVTag as AnimeGroupVM;
  4313. if (grp == null)
  4314. return true;
  4315. int mnuPrev = -1;
  4316. int mnuFave = -1;
  4317. int mnuWatched = -1;
  4318. int mnuUnwatched = -1;
  4319. int mnuEdit = -1;
  4320. int mnuQuickSort = -1;
  4321. int mnuRemoveQuickSort = -1;
  4322. int mnuDatabases = -1;
  4323. int mnuImages = -1;
  4324. int mnuSeries = -1;
  4325. int mnuRandomSeries = -1;
  4326. int mnuRandomEpisode = -1;
  4327. int mnuPostProcessing = -1;
  4328. //keep showing the dialog until the user closes it
  4329. int selectedLabel = 0;
  4330. string currentMenu = grp.GroupName;
  4331. while (true)
  4332. {
  4333. int curMenu = -1;
  4334. dlg.Reset();
  4335. dlg.SetHeading(currentMenu);
  4336. string faveText = "Add to Favorites";
  4337. if (grp.IsFave == 1)
  4338. faveText = "Remove from Favorites";
  4339. if (previousMenu != string.Empty)
  4340. {
  4341. dlg.Add("<<< " + previousMenu);
  4342. curMenu++; mnuPrev = curMenu;
  4343. }
  4344. dlg.Add(faveText);
  4345. curMenu++; mnuFave = curMenu;
  4346. dlg.Add("Mark ALL as Watched");
  4347. curMenu++; mnuWatched = curMenu;
  4348. dlg.Add("Mark ALL as Unwatched");
  4349. curMenu++; mnuUnwatched = curMenu;
  4350. dlg.Add("Edit Group >>>");
  4351. curMenu++; mnuEdit = curMenu;
  4352. dlg.Add("Quick Sort >>>");
  4353. curMenu++; mnuQuickSort = curMenu;
  4354. if (GroupFilterQuickSorts.ContainsKey(curGroupFilter.GroupFilterID.Value))
  4355. {
  4356. dlg.Add("Remove Quick Sort");
  4357. curMenu++; mnuRemoveQuickSort = curMenu;
  4358. }
  4359. if (grp.AllSeries.Count == 1)
  4360. {
  4361. dlg.Add("Databases >>>");
  4362. curMenu++; mnuDatabases = curMenu;
  4363. dlg.Add("Images >>>");
  4364. curMenu++; mnuImages = curMenu;
  4365. dlg.Add("Series Information");
  4366. curMenu++; mnuSeries = curMenu;
  4367. }
  4368. dlg.Add("Random Series");
  4369. curMenu++; mnuRandomSeries = curMenu;
  4370. dlg.Add("Random Episode");
  4371. curMenu++; mnuRandomEpisode = curMenu;
  4372. dlg.Add("Post-processing >>>");
  4373. curMenu++; mnuPostProcessing = curMenu;
  4374. dlg.SelectedLabel = selectedLabel;
  4375. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4376. selectedLabel = dlg.SelectedLabel;
  4377. if (selectedLabel == mnuPrev) return true;
  4378. if (selectedLabel == mnuFave)
  4379. {
  4380. grp.IsFave = grp.IsFave == 1 ? 0 : 1;
  4381. grp.Save();
  4382. EvaluateVisibility();
  4383. return false;
  4384. }
  4385. if (selectedLabel == mnuWatched)
  4386. {
  4387. foreach (AnimeSeriesVM ser in grp.AllSeries)
  4388. JMMServerHelper.SetWatchedStatusOnSeries(true, int.MaxValue, ser.AnimeSeriesID.Value);
  4389. LoadFacade();
  4390. return false;
  4391. }
  4392. if (selectedLabel == mnuUnwatched)
  4393. {
  4394. foreach (AnimeSeriesVM ser in grp.AllSeries)
  4395. JMMServerHelper.SetWatchedStatusOnSeries(false, int.MaxValue, ser.AnimeSeriesID.Value);
  4396. LoadFacade();
  4397. return false;
  4398. }
  4399. if (selectedLabel == mnuEdit)
  4400. {
  4401. if (!ShowContextMenuGroupEdit(currentMenu))
  4402. return false;
  4403. }
  4404. if (selectedLabel == mnuQuickSort)
  4405. {
  4406. string sortType = "";
  4407. GroupFilterSortDirection sortDirection = GroupFilterSortDirection.Asc;
  4408. if (GroupFilterQuickSorts.ContainsKey(curGroupFilter.GroupFilterID.Value))
  4409. sortDirection = GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value].SortDirection;
  4410. if (!Utils.DialogSelectGFQuickSort(ref sortType, ref sortDirection, curGroupFilter.GroupFilterName))
  4411. {
  4412. if (!GroupFilterQuickSorts.ContainsKey(curGroupFilter.GroupFilterID.Value))
  4413. GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value] = new QuickSort();
  4414. GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value].SortType = sortType;
  4415. GroupFilterQuickSorts[curGroupFilter.GroupFilterID.Value].SortDirection = sortDirection;
  4416. LoadFacade();
  4417. return false;
  4418. }
  4419. }
  4420. if (selectedLabel == mnuRemoveQuickSort)
  4421. {
  4422. GroupFilterQuickSorts.Remove(curGroupFilter.GroupFilterID.Value);
  4423. LoadFacade();
  4424. return false;
  4425. }
  4426. if (selectedLabel == mnuDatabases)
  4427. {
  4428. if (!ShowContextMenuDatabases(grp.AllSeries[0], "Group Menu"))
  4429. return false;
  4430. }
  4431. if (selectedLabel == mnuImages)
  4432. {
  4433. if (!ShowContextMenuImages(currentMenu))
  4434. return false;
  4435. }
  4436. if (selectedLabel == mnuSeries)
  4437. {
  4438. ShowAnimeInfoWindow();
  4439. return false;
  4440. }
  4441. if (selectedLabel == mnuRandomSeries)
  4442. {
  4443. RandomWindow_CurrentEpisode = null;
  4444. RandomWindow_CurrentSeries = null;
  4445. RandomWindow_LevelObject = grp;
  4446. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.Group;
  4447. RandomWindow_RandomType = RandomObjectType.Series;
  4448. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  4449. return false;
  4450. }
  4451. if (selectedLabel == mnuRandomEpisode)
  4452. {
  4453. RandomWindow_CurrentEpisode = null;
  4454. RandomWindow_CurrentSeries = null;
  4455. RandomWindow_LevelObject = grp;
  4456. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.Group;
  4457. RandomWindow_RandomType = RandomObjectType.Episode;
  4458. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  4459. return false;
  4460. }
  4461. if (selectedLabel == mnuPostProcessing)
  4462. {
  4463. ShowContextMenuPostProcessing(currentMenu);
  4464. return false;
  4465. }
  4466. }
  4467. }
  4468. private void ShowRelationsWindow()
  4469. {
  4470. SetGlobalIDs();
  4471. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RELATIONS, false);
  4472. }
  4473. private void ShowCharacterWindow()
  4474. {
  4475. SetGlobalIDs();
  4476. GUIWindowManager.ActivateWindow(Constants.WindowIDs.CHARACTERS, false);
  4477. }
  4478. private void ShowAnimeInfoWindow()
  4479. {
  4480. SetGlobalIDs();
  4481. GUIWindowManager.ActivateWindow(Constants.WindowIDs.ANIMEINFO, false);
  4482. }
  4483. private bool ShowContextMenuImages(string previousMenu)
  4484. {
  4485. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4486. if (currentitem == null)
  4487. return true;
  4488. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4489. if (dlg == null)
  4490. return true;
  4491. string displayName = "";
  4492. AnimeSeriesVM ser = null;
  4493. if (listLevel == Listlevel.Group)
  4494. {
  4495. displayName = curAnimeGroup.GroupName;
  4496. List<AnimeSeriesVM> allSeries = curAnimeGroup.AllSeries;
  4497. if (allSeries.Count == 1) ser = allSeries[0];
  4498. }
  4499. else
  4500. {
  4501. displayName = curAnimeSeries.SeriesName;
  4502. ser = curAnimeSeries;
  4503. }
  4504. //keep showing the dialog until the user closes it
  4505. int selectedLabel = 0;
  4506. string currentMenu = displayName;
  4507. while (true)
  4508. {
  4509. dlg.Reset();
  4510. dlg.SetHeading(currentMenu);
  4511. if (previousMenu != string.Empty)
  4512. dlg.Add("<<< " + previousMenu);
  4513. dlg.Add("Fanart");
  4514. dlg.Add("Posters");
  4515. dlg.Add("Wide Banners");
  4516. dlg.SelectedLabel = selectedLabel;
  4517. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4518. selectedLabel = dlg.SelectedLabel;
  4519. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4520. switch (selection)
  4521. {
  4522. case 0:
  4523. //show previous
  4524. return true;
  4525. case 1:
  4526. ShowFanartWindow();
  4527. return false;
  4528. case 2:
  4529. ShowPostersWindow();
  4530. return false;
  4531. case 3:
  4532. ShowWideBannersWindow();
  4533. return false;
  4534. default:
  4535. //close menu
  4536. return false;
  4537. }
  4538. }
  4539. }
  4540. private bool ShowContextMenuTVDB(AnimeSeriesVM ser, string previousMenu)
  4541. {
  4542. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4543. if (currentitem == null)
  4544. return true;
  4545. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4546. if (dlg == null)
  4547. return true;
  4548. int tvdbid = -1;
  4549. int season = -1;
  4550. string displayName = "";
  4551. if (ser.CrossRef_AniDB_TvDB != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.TvDBSeries != null)
  4552. {
  4553. displayName = ser.AniDB_Anime.AniDB_AnimeCrossRefs.TvDBSeries.SeriesName;
  4554. tvdbid = ser.AniDB_Anime.AniDB_AnimeCrossRefs.CrossRef_AniDB_TvDB.TvDBID;
  4555. season = ser.AniDB_Anime.AniDB_AnimeCrossRefs.CrossRef_AniDB_TvDB.TvDBSeasonNumber;
  4556. }
  4557. else
  4558. return false;
  4559. //keep showing the dialog until the user closes it
  4560. int selectedLabel = 0;
  4561. string currentMenu = displayName;
  4562. while (true)
  4563. {
  4564. dlg.Reset();
  4565. dlg.SetHeading(currentMenu);
  4566. if (previousMenu != string.Empty)
  4567. dlg.Add("<<< " + previousMenu);
  4568. dlg.Add("Remove TVDB Association");
  4569. dlg.Add("Switch Season (Current is " + season.ToString() + ")");
  4570. dlg.SelectedLabel = selectedLabel;
  4571. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4572. selectedLabel = dlg.SelectedLabel;
  4573. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4574. switch (selection)
  4575. {
  4576. case 0:
  4577. //show previous
  4578. return true;
  4579. case 1:
  4580. JMMServerVM.Instance.clientBinaryHTTP.RemoveLinkAniDBTvDB(ser.AniDB_Anime.AnimeID);
  4581. break;
  4582. case 2:
  4583. if (!ShowSeasonSelectionMenuTvDB(ser, ser.AniDB_Anime.AnimeID, tvdbid, currentMenu))
  4584. return false;
  4585. break;
  4586. default:
  4587. //close menu
  4588. return false;
  4589. }
  4590. }
  4591. }
  4592. private bool ShowContextMenuTrakt(AnimeSeriesVM ser, string previousMenu)
  4593. {
  4594. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4595. if (currentitem == null)
  4596. return true;
  4597. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4598. if (dlg == null)
  4599. return true;
  4600. string traktID = "";
  4601. int season = -1;
  4602. string displayName = "";
  4603. if (ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.CrossRef_AniDB_Trakt != null
  4604. && ser.AniDB_Anime.AniDB_AnimeCrossRefs.TraktShow != null)
  4605. {
  4606. displayName = ser.AniDB_Anime.AniDB_AnimeCrossRefs.TraktShow.Title;
  4607. traktID = ser.AniDB_Anime.AniDB_AnimeCrossRefs.CrossRef_AniDB_Trakt.TraktID;
  4608. season = ser.AniDB_Anime.AniDB_AnimeCrossRefs.CrossRef_AniDB_Trakt.TraktSeasonNumber;
  4609. }
  4610. else
  4611. return false;
  4612. //keep showing the dialog until the user closes it
  4613. int selectedLabel = 0;
  4614. string currentMenu = displayName;
  4615. while (true)
  4616. {
  4617. dlg.Reset();
  4618. dlg.SetHeading(currentMenu);
  4619. if (previousMenu != string.Empty)
  4620. dlg.Add("<<< " + previousMenu);
  4621. dlg.Add("Remove Trakt Association");
  4622. dlg.Add("Switch Season (Current is " + season.ToString() + ")");
  4623. dlg.SelectedLabel = selectedLabel;
  4624. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4625. selectedLabel = dlg.SelectedLabel;
  4626. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4627. switch (selection)
  4628. {
  4629. case 0:
  4630. //show previous
  4631. return true;
  4632. case 1:
  4633. JMMServerVM.Instance.clientBinaryHTTP.RemoveLinkAniDBTrakt(ser.AniDB_Anime.AnimeID);
  4634. break;
  4635. case 2:
  4636. if (!ShowSeasonSelectionMenuTrakt(ser, ser.AniDB_Anime.AnimeID, traktID, currentMenu))
  4637. return false;
  4638. break;
  4639. default:
  4640. //close menu
  4641. return false;
  4642. }
  4643. }
  4644. }
  4645. private bool ShowContextMenuMovieDB(AnimeSeriesVM ser, string previousMenu)
  4646. {
  4647. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4648. if (currentitem == null)
  4649. return true;
  4650. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4651. if (dlg == null)
  4652. return true;
  4653. //int moviedbid = -1;
  4654. string displayName = "";
  4655. if (ser.CrossRef_AniDB_MovieDB != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs != null && ser.AniDB_Anime.AniDB_AnimeCrossRefs.MovieDB_Movie != null)
  4656. {
  4657. displayName = ser.AniDB_Anime.AniDB_AnimeCrossRefs.MovieDB_Movie.MovieName;
  4658. }
  4659. else
  4660. return false;
  4661. //keep showing the dialog until the user closes it
  4662. int selectedLabel = 0;
  4663. string currentMenu = displayName;
  4664. while (true)
  4665. {
  4666. dlg.Reset();
  4667. dlg.SetHeading(currentMenu);
  4668. if (previousMenu != string.Empty)
  4669. dlg.Add("<<< " + previousMenu);
  4670. dlg.Add("Remove MovieDB Association");
  4671. dlg.SelectedLabel = selectedLabel;
  4672. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4673. selectedLabel = dlg.SelectedLabel;
  4674. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4675. switch (selection)
  4676. {
  4677. case 0:
  4678. //show previous
  4679. return true;
  4680. case 1:
  4681. JMMServerVM.Instance.clientBinaryHTTP.RemoveLinkAniDBOther(ser.AniDB_Anime.AnimeID, (int)CrossRefType.MovieDB);
  4682. return false;
  4683. default:
  4684. //close menu
  4685. return false;
  4686. }
  4687. }
  4688. }
  4689. private bool ShowContextMenuMAL(AnimeSeriesVM ser, string previousMenu)
  4690. {
  4691. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4692. if (currentitem == null)
  4693. return true;
  4694. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4695. if (dlg == null)
  4696. return true;
  4697. //int moviedbid = -1;
  4698. string displayName = "";
  4699. if (ser.CrossRef_AniDB_MAL != null && ser.CrossRef_AniDB_MAL.Count > 0)
  4700. {
  4701. if (ser.CrossRef_AniDB_MAL.Count == 1)
  4702. displayName = ser.CrossRef_AniDB_MAL[0].MALTitle;
  4703. else
  4704. displayName = "Multiple Links!";
  4705. }
  4706. else
  4707. return false;
  4708. //keep showing the dialog until the user closes it
  4709. int selectedLabel = 0;
  4710. string currentMenu = displayName;
  4711. while (true)
  4712. {
  4713. dlg.Reset();
  4714. dlg.SetHeading(currentMenu);
  4715. if (previousMenu != string.Empty)
  4716. dlg.Add("<<< " + previousMenu);
  4717. dlg.Add("Remove MAL Association");
  4718. dlg.SelectedLabel = selectedLabel;
  4719. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4720. selectedLabel = dlg.SelectedLabel;
  4721. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4722. switch (selection)
  4723. {
  4724. case 0:
  4725. //show previous
  4726. return true;
  4727. case 1:
  4728. foreach (CrossRef_AniDB_MALVM xref in ser.CrossRef_AniDB_MAL)
  4729. {
  4730. JMMServerVM.Instance.clientBinaryHTTP.RemoveLinkAniDBMAL(xref.AnimeID, xref.StartEpisodeType, xref.StartEpisodeNumber);
  4731. }
  4732. return false;
  4733. default:
  4734. //close menu
  4735. return false;
  4736. }
  4737. }
  4738. }
  4739. private bool ShowSeasonSelectionMenuTvDB(AnimeSeriesVM ser, int animeID, int tvdbid, string previousMenu)
  4740. {
  4741. try
  4742. {
  4743. List<int> seasons = JMMServerVM.Instance.clientBinaryHTTP.GetSeasonNumbersForSeries(tvdbid);
  4744. if (seasons.Count == 0)
  4745. {
  4746. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  4747. if (null != dlgOK)
  4748. {
  4749. dlgOK.SetHeading("Season Results");
  4750. dlgOK.SetLine(1, string.Empty);
  4751. dlgOK.SetLine(2, "No seasons found");
  4752. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  4753. }
  4754. return true;
  4755. }
  4756. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4757. if (dlg == null)
  4758. return true;
  4759. //keep showing the dialog until the user closes it
  4760. int selectedLabel = 0;
  4761. string currentMenu = "Select Season";
  4762. while (true)
  4763. {
  4764. dlg.Reset();
  4765. dlg.SetHeading(currentMenu);
  4766. if (previousMenu != string.Empty)
  4767. dlg.Add("<<< " + previousMenu);
  4768. foreach (int season in seasons)
  4769. dlg.Add("Season " + season.ToString());
  4770. dlg.SelectedLabel = selectedLabel;
  4771. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4772. selectedLabel = dlg.SelectedLabel;
  4773. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4774. if (selection == 0)
  4775. return true; //previous menu
  4776. if (selection > 0 && selection <= seasons.Count)
  4777. {
  4778. int selectedSeason = seasons[selection - 1];
  4779. LinkAniDBToTVDB(ser, animeID, tvdbid, selectedSeason);
  4780. }
  4781. return false;
  4782. }
  4783. }
  4784. catch (Exception ex)
  4785. {
  4786. BaseConfig.MyAnimeLog.Write("Error in ShowSeasonSelectionMenu:: {0}", ex);
  4787. }
  4788. return true;
  4789. }
  4790. private bool ShowSeasonSelectionMenuTrakt(AnimeSeriesVM ser, int animeID, string traktID, string previousMenu)
  4791. {
  4792. try
  4793. {
  4794. List<int> seasons = JMMServerVM.Instance.clientBinaryHTTP.GetSeasonNumbersForTrakt(traktID);
  4795. if (seasons.Count == 0)
  4796. {
  4797. GUIDialogOK dlgOK = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK);
  4798. if (null != dlgOK)
  4799. {
  4800. dlgOK.SetHeading("Season Results");
  4801. dlgOK.SetLine(1, string.Empty);
  4802. dlgOK.SetLine(2, "No seasons found");
  4803. dlgOK.DoModal(GUIWindowManager.ActiveWindow);
  4804. }
  4805. return true;
  4806. }
  4807. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4808. if (dlg == null)
  4809. return true;
  4810. //keep showing the dialog until the user closes it
  4811. int selectedLabel = 0;
  4812. string currentMenu = "Select Season";
  4813. while (true)
  4814. {
  4815. dlg.Reset();
  4816. dlg.SetHeading(currentMenu);
  4817. if (previousMenu != string.Empty)
  4818. dlg.Add("<<< " + previousMenu);
  4819. foreach (int season in seasons)
  4820. dlg.Add("Season " + season.ToString());
  4821. dlg.SelectedLabel = selectedLabel;
  4822. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4823. selectedLabel = dlg.SelectedLabel;
  4824. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4825. if (selection == 0)
  4826. return true; //previous menu
  4827. if (selection > 0 && selection <= seasons.Count)
  4828. {
  4829. int selectedSeason = seasons[selection - 1];
  4830. LinkAniDBToTrakt(ser, animeID, traktID, selectedSeason);
  4831. }
  4832. return false;
  4833. }
  4834. }
  4835. catch (Exception ex)
  4836. {
  4837. BaseConfig.MyAnimeLog.Write("Error in ShowSeasonSelectionMenu:: {0}", ex);
  4838. }
  4839. return true;
  4840. }
  4841. private bool ShowContextMenuSeriesEdit(string previousMenu)
  4842. {
  4843. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4844. if (dlg == null)
  4845. return true;
  4846. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4847. if (currentitem == null)
  4848. return true;
  4849. AnimeSeriesVM ser = currentitem.TVTag as AnimeSeriesVM;
  4850. if (ser == null)
  4851. return true;
  4852. //keep showing the dialog until the user closes it
  4853. int selectedLabel = 0;
  4854. string currentMenu = ser.SeriesName + " - Edit";
  4855. while (true)
  4856. {
  4857. dlg.Reset();
  4858. dlg.SetHeading(currentMenu);
  4859. if (previousMenu != string.Empty)
  4860. dlg.Add("<<< " + previousMenu);
  4861. dlg.Add("Set Default Audio Language");
  4862. dlg.Add("Set Default Subtitle language");
  4863. dlg.Add("Delete This Series/Episodes");
  4864. dlg.SelectedLabel = selectedLabel;
  4865. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4866. selectedLabel = dlg.SelectedLabel;
  4867. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4868. switch (selection)
  4869. {
  4870. case 0:
  4871. //show previous
  4872. return true;
  4873. case 1:
  4874. {
  4875. String language = ser.DefaultAudioLanguage;
  4876. if (Utils.DialogLanguage(ref language, false))
  4877. {
  4878. ser.DefaultAudioLanguage = language;
  4879. ser.Save();
  4880. return false;
  4881. }
  4882. }
  4883. break;
  4884. case 2:
  4885. {
  4886. String language = ser.DefaultSubtitleLanguage;
  4887. if (Utils.DialogLanguage(ref language, true))
  4888. {
  4889. ser.DefaultSubtitleLanguage = language;
  4890. ser.Save();
  4891. return false;
  4892. }
  4893. }
  4894. break;
  4895. case 3:
  4896. if (Utils.DialogConfirm("Are you sure?"))
  4897. {
  4898. JMMServerVM.Instance.clientBinaryHTTP.DeleteAnimeSeries(ser.AnimeSeriesID.Value, false, false);
  4899. LoadFacade();
  4900. return false;
  4901. }
  4902. break;
  4903. default:
  4904. //close menu
  4905. return false;
  4906. }
  4907. }
  4908. }
  4909. private bool ShowContextMenuSeries(string previousMenu)
  4910. {
  4911. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  4912. if (currentitem == null)
  4913. return true;
  4914. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  4915. if (dlg == null)
  4916. return true;
  4917. AnimeSeriesVM ser = currentitem.TVTag as AnimeSeriesVM;
  4918. if (ser == null)
  4919. return true;
  4920. //keep showing the dialog until the user closes it
  4921. int selectedLabel = 0;
  4922. string currentMenu = ser.SeriesName;
  4923. while (true)
  4924. {
  4925. dlg.Reset();
  4926. dlg.SetHeading(currentMenu);
  4927. if (previousMenu != string.Empty)
  4928. dlg.Add("<<< " + previousMenu);
  4929. dlg.Add("Series Information");
  4930. dlg.Add("Mark all as watched");
  4931. dlg.Add("Mark all as unwatched");
  4932. dlg.Add("Databases >>>");
  4933. dlg.Add("Images >>>");
  4934. dlg.Add("Edit Series >>>");
  4935. dlg.Add("Random Episode");
  4936. dlg.Add("Post-processing >>>");
  4937. dlg.SelectedLabel = selectedLabel;
  4938. dlg.DoModal(GUIWindowManager.ActiveWindow);
  4939. selectedLabel = dlg.SelectedLabel;
  4940. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  4941. switch (selection)
  4942. {
  4943. case 0:
  4944. //show previous
  4945. return true;
  4946. case 1:
  4947. ShowAnimeInfoWindow();
  4948. return false;
  4949. case 2: // Mark ALL as Watched
  4950. {
  4951. JMMServerHelper.SetWatchedStatusOnSeries(true, int.MaxValue, ser.AnimeSeriesID.Value);
  4952. JMMServerBinary.Contract_AnimeSeries contract = JMMServerVM.Instance.clientBinaryHTTP.GetSeries(ser.AnimeSeriesID.Value,
  4953. JMMServerVM.Instance.CurrentUser.JMMUserID);
  4954. if (contract != null)
  4955. {
  4956. AnimeSeriesVM serTemp = new AnimeSeriesVM(contract);
  4957. Utils.PromptToRateSeriesOnCompletion(serTemp);
  4958. }
  4959. LoadFacade();
  4960. return false;
  4961. }
  4962. case 3: // Mark ALL as Unwatched
  4963. {
  4964. JMMServerHelper.SetWatchedStatusOnSeries(false, int.MaxValue, ser.AnimeSeriesID.Value);
  4965. LoadFacade();
  4966. return false;
  4967. }
  4968. case 4:
  4969. if (!ShowContextMenuDatabases(ser, currentMenu))
  4970. return false;
  4971. break;
  4972. case 5:
  4973. if (!ShowContextMenuImages(currentMenu))
  4974. return false;
  4975. break;
  4976. case 6:
  4977. if (!ShowContextMenuSeriesEdit(currentMenu))
  4978. return false;
  4979. break;
  4980. case 7:
  4981. RandomWindow_CurrentEpisode = null;
  4982. RandomWindow_CurrentSeries = null;
  4983. RandomWindow_LevelObject = ser;
  4984. RandomWindow_RandomLevel = RandomSeriesEpisodeLevel.Series;
  4985. RandomWindow_RandomType = RandomObjectType.Episode;
  4986. GUIWindowManager.ActivateWindow(Constants.WindowIDs.RANDOM);
  4987. return false;
  4988. case 8:
  4989. if (!ShowContextMenuPostProcessing(currentMenu))
  4990. return false;
  4991. break;
  4992. default:
  4993. //close menu
  4994. return false;
  4995. }
  4996. }
  4997. }
  4998. private bool ShowContextMenuPostProcessing(string previousMenu)
  4999. {
  5000. GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU);
  5001. if (dlg == null)
  5002. return true;
  5003. GUIListItem currentitem = this.m_Facade.SelectedListItem;
  5004. if (currentitem == null)
  5005. return true;
  5006. AnimeGroupVM grp = currentitem.TVTag as AnimeGroupVM;
  5007. List<AnimeEpisodeVM> episodes = new List<AnimeEpisodeVM>();
  5008. if (grp == null)
  5009. {
  5010. AnimeSeriesVM ser = currentitem.TVTag as AnimeSeriesVM;
  5011. if (ser == null)
  5012. {
  5013. AnimeEpisodeVM ep = currentitem.TVTag as AnimeEpisodeVM;
  5014. episodes.Add(ep);
  5015. }
  5016. else
  5017. {
  5018. foreach (AnimeEpisodeVM ep in ser.AllEpisodes)
  5019. {
  5020. episodes.Add(ep);
  5021. }
  5022. }
  5023. }
  5024. else
  5025. {
  5026. List<AnimeSeriesVM> seriesList = grp.AllSeries;
  5027. foreach (AnimeSeriesVM ser in seriesList)
  5028. {
  5029. foreach (AnimeEpisodeVM ep in ser.AllEpisodes)
  5030. {
  5031. episodes.Add(ep);
  5032. }
  5033. }
  5034. }
  5035. if (episodes == null)
  5036. return true;
  5037. //keep showing the dialog until the user closes it
  5038. string currentMenu = "Associate with a ffdshow raw preset";
  5039. int selectedLabel = 0;
  5040. int intLabel = 0;
  5041. FFDShowHelper ffdshowHelper = new FFDShowHelper();
  5042. List<string> presets = ffdshowHelper.Presets;
  5043. string selectedPreset = ffdshowHelper.findSelectedPresetForMenu(episodes);
  5044. while (true)
  5045. {
  5046. dlg.Reset();
  5047. dlg.SetHeading(currentMenu);
  5048. if (previousMenu != string.Empty)
  5049. {
  5050. dlg.Add("<<< " + previousMenu);
  5051. intLabel++;
  5052. }
  5053. dlg.Add("Remove old preset association");
  5054. intLabel++;
  5055. foreach (string preset in presets)
  5056. {
  5057. dlg.Add("Set preset: " + preset);
  5058. // preset selected
  5059. if (selectedPreset == preset)
  5060. selectedLabel = intLabel;
  5061. intLabel++;
  5062. }
  5063. dlg.SelectedLabel = selectedLabel;
  5064. dlg.DoModal(GUIWindowManager.ActiveWindow);
  5065. selectedLabel = dlg.SelectedLabel;
  5066. int selection = selectedLabel + ((previousMenu == string.Empty) ? 1 : 0);
  5067. if (selection == 0)
  5068. {
  5069. //show previous
  5070. return true;
  5071. }
  5072. else if (selection == -1)
  5073. {
  5074. //close menu
  5075. return false;
  5076. }
  5077. else
  5078. {
  5079. string message = "";
  5080. if (selection == 1)
  5081. {
  5082. //DB remove preset
  5083. ffdshowHelper.deletePreset(episodes);
  5084. message = "Old preset successfully removed.";
  5085. }
  5086. else
  5087. {
  5088. //DB associate serie/group with preset
  5089. string choosenPreset = presets.ToArray()[selection - 2];
  5090. ffdshowHelper.addPreset(episodes, choosenPreset);
  5091. message = "Preset \"" + choosenPreset + "\" successfully added.";
  5092. }
  5093. Utils.DialogMsg("Confirmation", message);
  5094. return false;
  5095. }
  5096. }
  5097. }
  5098. private void SetGlobalIDs()
  5099. {
  5100. GlobalSeriesID = -1;
  5101. if (curAnimeGroup == null)
  5102. return;
  5103. AnimeSeriesVM ser = null;
  5104. List<AnimeSeriesVM> allSeries = curAnimeGroup.AllSeries;
  5105. if (allSeries.Count == 1)
  5106. ser = allSeries[0];
  5107. else
  5108. ser = curAnimeSeries;
  5109. if (ser == null) return;
  5110. GlobalSeriesID = ser.AnimeSeriesID.Value;
  5111. }
  5112. private void ShowFanartWindow()
  5113. {
  5114. SetGlobalIDs();
  5115. GUIWindowManager.ActivateWindow(Constants.WindowIDs.FANART, false);
  5116. }
  5117. private void ShowPostersWindow()
  5118. {
  5119. SetGlobalIDs();
  5120. GUIWindowManager.ActivateWindow(Constants.WindowIDs.POSTERS, false);
  5121. }
  5122. private void ShowWideBannersWindow()
  5123. {
  5124. SetGlobalIDs();
  5125. GUIWindowManager.ActivateWindow(Constants.WindowIDs.WIDEBANNERS, false);
  5126. }
  5127. }
  5128. enum conMenuActionGroup
  5129. {
  5130. ToggleAsFave = 1,
  5131. TvDBSearch = 2,
  5132. TvDB_Main = 3
  5133. }
  5134. public enum groupSort
  5135. {
  5136. Name = 1,
  5137. AniDBRating = 2,
  5138. UserRating = 3,
  5139. AirDate = 4,
  5140. WatchedDate = 5
  5141. }
  5142. enum conMenuActionTvDB
  5143. {
  5144. TvDB_Fanart = 1,
  5145. TvDB_DownloadWideBanners = 2,
  5146. TvDB_DownloadPosters = 3,
  5147. TvDB_SwitchSeason = 4,
  5148. TvDB_EpisodeInfo = 5
  5149. }
  5150. public enum Listlevel
  5151. {
  5152. Episode = 0, // The actual episodes
  5153. EpisodeTypes = 1, // Normal, Credits, Specials
  5154. Series = 2, // Da capo, Da Capo S2, Da Capo II etc
  5155. Group = 3, // Da Capo
  5156. GroupFilter = 4, // Favouritess
  5157. GroupFilterSub = 5, // Predefined - Categories
  5158. GroupFilterSub2 = 6 // Predefined - Categories - Action
  5159. }
  5160. public enum ViewType
  5161. {
  5162. All = 0,
  5163. Faves = 1,
  5164. FavesUnwatched = 2,
  5165. Genre = 3,
  5166. Year = 4,
  5167. CompleteSeries = 5,
  5168. NewSeason = 6
  5169. }
  5170. public enum ViewClassification
  5171. {
  5172. Views = 0,
  5173. StaticYears = 1,
  5174. StaticGenres = 2
  5175. }
  5176. enum BackGroundLoadingArgumentType
  5177. {
  5178. None,
  5179. DelayedImgLoading,
  5180. DelayedImgInit,
  5181. ElementSelection,
  5182. SetFacadeMode,
  5183. ListFullElement,
  5184. ListElementForDelayedImgLoading
  5185. }
  5186. public enum AniDBMyListSyncMode
  5187. {
  5188. AniDB_All = 1, // Take watched/unwatched status from AniDB
  5189. AniDB_WatchedOnly = 2 // Only take watched status from AniDB, update AniDB if local episode is watched
  5190. }
  5191. class BackgroundFacadeLoadingArgument
  5192. {
  5193. public BackGroundLoadingArgumentType Type = BackGroundLoadingArgumentType.None;
  5194. public object Argument = null;
  5195. public int IndexArgument = 0;
  5196. }
  5197. }