PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/Application/Core/PlaylistManager.cs

http://yet-another-music-application.googlecode.com/
C# | 790 lines | 522 code | 85 blank | 183 comment | 157 complexity | 8bbcc12f209d821197eaab786449d690 MD5 | raw file
  1. /**
  2. * PlaylistManager.cs
  3. *
  4. * Takes care of managing the playlists.
  5. *
  6. * * * * * * * * *
  7. *
  8. * Copyright 2012 Simplare
  9. *
  10. * This code is part of the Stoffi Music Player Project.
  11. * Visit our website at: stoffiplayer.com
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version
  16. * 3 of the License, or (at your option) any later version.
  17. *
  18. * See stoffiplayer.com/license for more information.
  19. **/
  20. using System;
  21. using System.Collections;
  22. using System.Collections.Generic;
  23. using System.Collections.ObjectModel;
  24. using System.Collections.Specialized;
  25. using System.IO;
  26. using System.Linq;
  27. using System.Text;
  28. using System.Threading;
  29. using System.Xml;
  30. namespace Stoffi
  31. {
  32. /// <summary>
  33. /// Represents a manager that takes care of the playlist logic
  34. /// </summary>
  35. public static class PlaylistManager
  36. {
  37. #region Members
  38. private static String supportedFileFormats = "m3u;pls";
  39. #endregion
  40. #region Properties
  41. /// <summary>
  42. /// The currently active playlist that is being played.
  43. /// An empty string if no playlist is active.
  44. /// </summary>
  45. public static String CurrentPlaylist { get; set; }
  46. #endregion
  47. #region Methods
  48. #region Public
  49. /// <summary>
  50. /// Initializes the playlist manager
  51. /// </summary>
  52. public static void Initialize()
  53. {
  54. CurrentPlaylist = "";
  55. ThreadStart GUIThread = delegate()
  56. {
  57. foreach (PlaylistData playlist in SettingsManager.Playlists)
  58. {
  59. // fix null tracks
  60. bool allTracksNull = true;
  61. foreach (TrackData t in playlist.Tracks)
  62. if (t != null)
  63. {
  64. allTracksNull = false;
  65. break;
  66. }
  67. if (allTracksNull) playlist.Tracks.Clear();
  68. playlist.Tracks.CollectionChanged += TracksChanged;
  69. DispatchPlaylistModified(playlist, ModifyType.Created);
  70. }
  71. };
  72. if (SettingsManager.CurrentActiveNavigation.StartsWith("Playlist:"))
  73. CurrentPlaylist = SettingsManager.CurrentActiveNavigation.Split(new[]{':'},2)[1];
  74. Thread thread = new Thread(GUIThread);
  75. thread.Name = "Playlist Thread";
  76. thread.Priority = ThreadPriority.BelowNormal;
  77. thread.Start();
  78. }
  79. /// <summary>
  80. /// Add tracks to a playlist
  81. /// </summary>
  82. /// <param name="tracks">The list of tracks to be added</param>
  83. /// <param name="playlistName">The name of the playlist to add the tracks to</param>
  84. /// <param name="pos">The position to insert the track at (-1 means at the end)</param>
  85. public static void AddToPlaylist(List<object> tracks, String playlistName, int pos = -1)
  86. {
  87. PlaylistData playlist = FindPlaylist(playlistName);
  88. if (playlist == null) return;
  89. foreach (TrackData track in tracks)
  90. {
  91. if (!playlist.Tracks.Contains(track))
  92. {
  93. if (pos < 0 || pos >= playlist.Tracks.Count)
  94. playlist.Tracks.Add(track);
  95. else
  96. playlist.Tracks.Insert(pos, track);
  97. track.Source = "Playlist:" + playlist.Name;
  98. }
  99. }
  100. }
  101. /// <summary>
  102. /// Add tracks to a playlist
  103. /// </summary>
  104. /// <param name="tracks">The list of tracks to be added</param>
  105. /// <param name="playlistName">The name of the playlist to add the tracks to</param>
  106. /// <param name="pos">The position to insert the track at (-1 means at the end)</param>
  107. public static void AddToPlaylist(ObservableCollection<TrackData> tracks, String playlistName, int pos = -1)
  108. {
  109. PlaylistData playlist = FindPlaylist(playlistName);
  110. if (playlist == null) return;
  111. foreach (TrackData track in tracks)
  112. {
  113. if (!playlist.Tracks.Contains(track))
  114. {
  115. if (pos < 0 || pos >= playlist.Tracks.Count)
  116. playlist.Tracks.Add(track);
  117. else
  118. playlist.Tracks.Insert(pos, track);
  119. track.Source = "Playlist:" + playlist.Name;
  120. }
  121. }
  122. }
  123. /// <summary>
  124. /// Add tracks to a playlist
  125. /// </summary>
  126. /// <param name="tracks">The list of tracks to be added</param>
  127. /// <param name="playlistName">The name of the playlist to add the tracks to</param>
  128. /// <param name="pos">The position to insert the track at (-1 means at the end)</param>
  129. public static void AddToPlaylist(List<TrackData> tracks, String playlistName, int pos = -1)
  130. {
  131. PlaylistData playlist = FindPlaylist(playlistName);
  132. if (playlist == null) return;
  133. foreach (TrackData track in tracks)
  134. {
  135. // insert
  136. if (!playlist.Tracks.Contains(track))
  137. {
  138. if (pos < 0 || pos >= playlist.Tracks.Count)
  139. playlist.Tracks.Add(track);
  140. else
  141. playlist.Tracks.Insert(pos, track);
  142. track.Source = "Playlist:" + playlist.Name;
  143. }
  144. // move
  145. else if (pos != playlist.Tracks.IndexOf(track))
  146. {
  147. if (pos < 0 || pos >= playlist.Tracks.Count)
  148. {
  149. playlist.Tracks.Remove(track);
  150. playlist.Tracks.Add(track);
  151. }
  152. else if (pos < playlist.Tracks.IndexOf(track))
  153. {
  154. playlist.Tracks.Remove(track);
  155. playlist.Tracks.Insert(pos, track);
  156. }
  157. else
  158. {
  159. playlist.Tracks.Remove(track);
  160. playlist.Tracks.Insert(pos-1, track);
  161. }
  162. }
  163. }
  164. }
  165. /// <summary>
  166. /// Check to see if a file is a supported playlist file
  167. /// </summary>
  168. /// <param name="path">The filename to check</param>
  169. /// <returns>true of the file can be opened by Stoffi, otherwise false</returns>
  170. public static bool IsSupported(String path)
  171. {
  172. return path.StartsWith("playlist://") ||
  173. (supportedFileFormats.Split(';').Contains<string>(Path.GetExtension(path)));
  174. }
  175. /// <summary>
  176. /// Remove tracks from a playlist if they are found inside the playlist
  177. /// </summary>
  178. /// <param name="tracks">The list of t to be removed</param>
  179. /// <param name="playlistName">The name of the playlist to remove the t from</param>
  180. public static void RemoveFromPlaylist(List<TrackData> tracks, String playlistName)
  181. {
  182. PlaylistData playlist = FindPlaylist(playlistName);
  183. if (playlist != null)
  184. {
  185. foreach (TrackData track in tracks)
  186. foreach (TrackData trackInPlaylist in playlist.Tracks)
  187. if (trackInPlaylist.Path == track.Path)
  188. {
  189. playlist.Tracks.Remove(trackInPlaylist);
  190. break;
  191. }
  192. }
  193. }
  194. /// <summary>
  195. /// Creates a new playlist
  196. /// </summary>
  197. /// <param name="name">The name of the new playlist (this will be appended with a number if neccessary)</param>
  198. /// <returns>The newly created PlaylistData for the playlist</returns>
  199. public static PlaylistData CreatePlaylist(String name)
  200. {
  201. name = U.CleanXMLString(name);
  202. if (FindPlaylist(name) != null)
  203. {
  204. int pExt = 1;
  205. while (FindPlaylist(name + pExt) != null)
  206. pExt++;
  207. name = name + pExt;
  208. }
  209. PlaylistData playlist = new PlaylistData();
  210. playlist.Name = name;
  211. playlist.Time = 0;
  212. playlist.Tracks = new ObservableCollection<TrackData>();
  213. playlist.Tracks.CollectionChanged += TracksChanged;
  214. SettingsManager.Playlists.Add(playlist);
  215. DispatchPlaylistModified(playlist, ModifyType.Created);
  216. return playlist;
  217. }
  218. /// <summary>
  219. /// Renames a playlist. If a playlist with the new name already exist or the new name is either "Create new" or "" it will do nothing.
  220. /// </summary>
  221. /// <param name="oldName">The current name of the playlist to be renamed</param>
  222. /// <param name="newName">The new name of the playlist</param>
  223. public static void RenamePlaylist(String oldName, String newName)
  224. {
  225. newName = U.CleanXMLString(newName);
  226. PlaylistData pl = FindPlaylist(oldName);
  227. if (FindPlaylist(newName) != null)
  228. {
  229. int pExt = 1;
  230. while (FindPlaylist(newName + pExt) != null)
  231. pExt++;
  232. newName = newName + pExt;
  233. }
  234. if (pl != null && newName != "" && newName.ToLower() != U.T("NavigationCreateNew").ToLower())
  235. DispatchPlaylistRenamed(pl, oldName, newName);
  236. }
  237. /// <summary>
  238. /// Saves a playlist as a file
  239. /// </summary>
  240. /// <param name="path">The path of the saved playlist</param>
  241. /// <param name="name">The name of the playlist to save</param>
  242. public static void SavePlaylist(String path, String name)
  243. {
  244. PlaylistData pl = FindPlaylist(name);
  245. if (pl != null)
  246. {
  247. string ext = Path.GetExtension(path);
  248. System.IO.StreamWriter sw = System.IO.File.AppendText(path);
  249. if (ext == ".pls")
  250. {
  251. sw.WriteLine("[playlist]");
  252. sw.WriteLine("");
  253. int i = 0;
  254. foreach (TrackData track in pl.Tracks)
  255. {
  256. i++;
  257. sw.WriteLine(String.Format("File{0}={1}", i, track.Path));
  258. sw.WriteLine(String.Format("Title{0}={1}", i, track.Title));
  259. sw.WriteLine(String.Format("Length{0}={1}", i, (int)track.RawLength));
  260. sw.WriteLine("");
  261. }
  262. sw.WriteLine("NumberOfEntries=" + i);
  263. sw.WriteLine("Version=2");
  264. }
  265. else if (ext == ".m3u")
  266. {
  267. sw.WriteLine("#EXTM3U");
  268. sw.WriteLine("");
  269. foreach (TrackData track in pl.Tracks)
  270. {
  271. sw.WriteLine(String.Format("#EXTINF:{0},{1} - {2}", (int)track.RawLength, track.Artist, track.Title));
  272. sw.WriteLine(track.Path);
  273. sw.WriteLine("");
  274. }
  275. }
  276. sw.Close();
  277. }
  278. }
  279. /// <summary>
  280. /// Reads a file and creates a playlist using the name of the file.
  281. /// </summary>
  282. /// <param name="filename">The file to read</param>
  283. /// <returns>The PlaylistData of the newly created playlist</returns>
  284. public static PlaylistData LoadPlaylist(String filename)
  285. {
  286. //try
  287. //{
  288. string pName = Path.GetFileNameWithoutExtension(filename);
  289. if (FindPlaylist(pName) != null)
  290. {
  291. int pExt = 1;
  292. while (FindPlaylist(pName + pExt) != null)
  293. pExt++;
  294. pName = pName + pExt;
  295. }
  296. PlaylistData pl = CreatePlaylist(pName);
  297. StreamReader sr = new StreamReader(filename);
  298. string line;
  299. int nr = 0;
  300. if (Path.GetExtension(filename) == ".m3u")
  301. {
  302. bool ext = false;
  303. string inf = "";
  304. while ((line = sr.ReadLine()) != null)
  305. {
  306. nr++;
  307. if (line == "#EXTM3U")
  308. ext = true;
  309. else if (ext && line.StartsWith("#EXTINF:"))
  310. inf = line.Substring(8);
  311. else if (line.StartsWith("#") || line == "")
  312. continue;
  313. else
  314. {
  315. string path = line;
  316. if (!File.Exists(path) && File.Exists(Path.Combine(Path.GetDirectoryName(filename), path)))
  317. path = Path.Combine(Path.GetDirectoryName(filename), path);
  318. if (File.Exists(path))
  319. {
  320. string length = "";
  321. string artist = "";
  322. string title = "";
  323. if (inf != "")
  324. {
  325. if (!inf.Contains(','))
  326. {
  327. U.L(LogLevel.Warning, "PLAYLIST", "Bad format in " + filename + " on line "
  328. + nr + ": expecting ','");
  329. continue;
  330. }
  331. string[] split = inf.Split(',');
  332. length = split[0];
  333. if (split[1].Contains('-'))
  334. {
  335. artist = split[1].Split('-')[0];
  336. title = split[1].Split('-')[1];
  337. }
  338. else
  339. title = split[1];
  340. }
  341. if (!FilesystemManager.PathIsAdded(path))
  342. FilesystemManager.AddSource(new SourceData()
  343. {
  344. Data = path,
  345. HumanType = U.T("SourcesTypeFile"),
  346. Type = SourceType.File,
  347. Include = true
  348. });
  349. foreach (TrackData t in SettingsManager.FileTracks)
  350. if (t.Path == path)
  351. {
  352. if (!pl.Tracks.Contains(t))
  353. pl.Tracks.Add(t);
  354. break;
  355. }
  356. inf = "";
  357. }
  358. else if (YouTubeManager.IsYouTube(path))
  359. {
  360. string yid = YouTubeManager.GetYouTubeID(path);
  361. TrackData t = YouTubeManager.CreateTrack(yid);
  362. if (!pl.Tracks.Contains(t))
  363. pl.Tracks.Add(t);
  364. }
  365. }
  366. }
  367. }
  368. else if (Path.GetExtension(filename) == ".pls")
  369. {
  370. bool hdr = false;
  371. string version = "";
  372. int noe = 0;
  373. while ((line = sr.ReadLine()) != null)
  374. {
  375. nr++;
  376. if (line == "[playlist]")
  377. hdr = true;
  378. else if (!hdr)
  379. U.L(LogLevel.Warning, "PLAYLIST", "Bad format in " + filename + " on line "
  380. + nr + ": expecting '[playlist]'");
  381. else if (line.StartsWith("NumberOfEntries="))
  382. noe = Convert.ToInt32(line.Split('=')[1]);
  383. else if (line.StartsWith("Version="))
  384. version = line.Split('=')[1];
  385. }
  386. if (!hdr)
  387. U.L(LogLevel.Warning, "PLAYLIST", "Error in " + filename + ": No header found");
  388. else if (version != "2")
  389. U.L(LogLevel.Warning, "PLAYLIST", "Error in " + filename + ": Unsupported version '" +
  390. version + "'");
  391. else
  392. {
  393. sr.Close();
  394. sr = new StreamReader(filename);
  395. string[,] tracks = new string[noe, 3];
  396. nr = 0;
  397. while ((line = sr.ReadLine()) != null)
  398. {
  399. if (line.StartsWith("File") || line.StartsWith("Title") || line.StartsWith("Length"))
  400. {
  401. int tmp = 4;
  402. int index = 0;
  403. if (line.StartsWith("Title")) { tmp = 5; index = 1; }
  404. else if (line.StartsWith("Length")) { tmp = 6; index = 2; }
  405. string[] split = line.Split('=');
  406. int number = Convert.ToInt32(split[0].Substring(tmp));
  407. if (number > noe)
  408. U.L(LogLevel.Warning, "PLAYLIST", "Bad format in " + filename + " on line "
  409. + nr + ": entry number is '" + number + "' but NumberOfEntries is '" + noe + "'");
  410. else
  411. tracks[number-1, index] = split[1];
  412. }
  413. else if (!line.StartsWith("NumberOfEntries") && line != "[playlist]" && !line.StartsWith("Version="))
  414. {
  415. U.L(LogLevel.Warning, "PLAYLIST", "Bad format in " + filename + " on line "
  416. + nr + ": unexpected '" + line + "'");
  417. }
  418. }
  419. for (int i = 0; i < noe; i++)
  420. {
  421. string path = tracks[i, 0];
  422. if (!File.Exists(path) && File.Exists(Path.Combine(Path.GetDirectoryName(filename), path)))
  423. path = Path.Combine(Path.GetDirectoryName(filename), path);
  424. if (File.Exists(path))
  425. {
  426. if (!FilesystemManager.PathIsAdded(path))
  427. FilesystemManager.AddSource(new SourceData()
  428. {
  429. Data = path,
  430. HumanType = U.T("SourcesTypeFile"),
  431. Type = SourceType.File,
  432. Include = true
  433. });
  434. foreach (TrackData t in SettingsManager.FileTracks)
  435. if (t.Path == path)
  436. {
  437. if (!pl.Tracks.Contains(t))
  438. pl.Tracks.Add(t);
  439. break;
  440. }
  441. }
  442. else if (YouTubeManager.IsYouTube(path))
  443. {
  444. string yid = YouTubeManager.GetYouTubeID(path);
  445. TrackData t = YouTubeManager.CreateTrack(yid);
  446. if (!pl.Tracks.Contains(t))
  447. pl.Tracks.Add(t);
  448. }
  449. }
  450. }
  451. }
  452. sr.Close();
  453. return pl;
  454. // TODO: Replace with dispatching a custom event
  455. //}
  456. //catch (Exception e)
  457. //{
  458. // MessageBox.Show("Error trying to load playlist:\n" + e.Message, "Couldn't Load Playlist", MessageBoxButton.OK,
  459. // MessageBoxImage.Error);
  460. // return null;
  461. //}
  462. }
  463. /// <summary>
  464. /// Deletes a playlist
  465. /// </summary>
  466. /// <param name="name">The name of the playlist to delete</param>
  467. public static void RemovePlaylist(String name)
  468. {
  469. PlaylistData pl = FindPlaylist(name);
  470. if (pl != null)
  471. {
  472. DispatchPlaylistModified(pl, ModifyType.Removed);
  473. // and finally remove the playlist altogther (undo?)
  474. SettingsManager.Playlists.Remove(pl);
  475. }
  476. }
  477. /// <summary>
  478. /// Tries to find a playlist with a given name
  479. /// </summary>
  480. /// <param name="name">The name of the playlist to look for</param>
  481. /// <returns>The PlaylistData of the playlist with the name <paramref name="name"/> of such a playlist could be found, otherwise null.</returns>
  482. public static PlaylistData FindPlaylist(String name)
  483. {
  484. foreach (PlaylistData p in SettingsManager.Playlists)
  485. if (p.Name == name) return p;
  486. return null;
  487. }
  488. /// <summary>
  489. /// Update the "Last Played" and "Play Count" information of a given track
  490. /// </summary>
  491. /// <param name="RefTrack">The track that was just played</param>
  492. public static void TrackWasPlayed(TrackData RefTrack)
  493. {
  494. if (RefTrack == null) return;
  495. uint pc = RefTrack.PlayCount + 1;
  496. foreach (TrackData track in SettingsManager.FileTracks)
  497. {
  498. if (track.Path == RefTrack.Path)
  499. {
  500. track.PlayCount = pc;
  501. track.LastPlayed = DateTime.Now.ToString("g");
  502. track.RawLastPlayed = DateTime.Now.ToString("yyyyMMddHHmmss");
  503. }
  504. }
  505. foreach (TrackData track in SettingsManager.QueueTracks)
  506. {
  507. if (track.Path == RefTrack.Path)
  508. {
  509. track.PlayCount = pc;
  510. track.LastPlayed = DateTime.Now.ToString("g");
  511. track.RawLastPlayed = DateTime.Now.ToString("yyyyMMddHHmmss");
  512. }
  513. }
  514. foreach (TrackData track in SettingsManager.HistoryTracks)
  515. if (track.Path == RefTrack.Path)
  516. track.PlayCount = pc;
  517. foreach (PlaylistData playlist in SettingsManager.Playlists)
  518. {
  519. if (playlist.Name == CurrentPlaylist)
  520. {
  521. foreach (TrackData track in playlist.Tracks)
  522. {
  523. if (track.Path == RefTrack.Path)
  524. {
  525. track.PlayCount = pc;
  526. track.LastPlayed = DateTime.Now.ToString("g");
  527. track.RawLastPlayed = DateTime.Now.ToString("yyyyMMddHHmmss");
  528. }
  529. }
  530. }
  531. }
  532. }
  533. /// <summary>
  534. /// Finds all playlists that contains a given track.
  535. /// </summary>
  536. /// <param name="track">The track to look for</param>
  537. /// <returns>All playlists containing <paramref name="track"/></returns>
  538. public static List<PlaylistData> Has(TrackData track)
  539. {
  540. List<PlaylistData> has = new List<PlaylistData>();
  541. foreach (PlaylistData p in SettingsManager.Playlists)
  542. if (Contains(p, track))
  543. has.Add(p);
  544. return has;
  545. }
  546. /// <summary>
  547. /// Checks whether a given playlist contains a given track.
  548. /// </summary>
  549. /// <param name="playlist">The playlist to search in</param>
  550. /// <param name="track">The track to search for</param>
  551. /// <returns>True of <paramref name="playlist"/> contains <paramref name="track"/>, otherwise false</returns>
  552. public static bool Contains(PlaylistData playlist, TrackData track)
  553. {
  554. foreach (TrackData t in playlist.Tracks)
  555. if (t.Path == track.Path)
  556. return true;
  557. return false;
  558. }
  559. /// <summary>
  560. /// Checks whether a given playlist contains any of a given list of track.
  561. /// </summary>
  562. /// <param name="playlist">The playlist to search in</param>
  563. /// <param name="tracks">The tracks to search for</param>
  564. /// <returns>True of <paramref name="playlist"/> contains any of <paramref name="tracks"/>, otherwise false</returns>
  565. public static bool ContainsAny(PlaylistData playlist, List<TrackData> tracks)
  566. {
  567. foreach (TrackData t1 in playlist.Tracks)
  568. foreach (TrackData t2 in tracks)
  569. if (t1.Path == t2.Path)
  570. return true;
  571. return false;
  572. }
  573. /// <summary>
  574. /// Checks whether a given playlist contains all of a given list of track.
  575. /// </summary>
  576. /// <param name="playlist">The playlist to search in</param>
  577. /// <param name="tracks">The tracks to search for</param>
  578. /// <returns>True of <paramref name="playlist"/> contains all of <paramref name="tracks"/>, otherwise false</returns>
  579. public static bool ContainsAll(PlaylistData playlist, List<TrackData> tracks)
  580. {
  581. foreach (TrackData t1 in playlist.Tracks)
  582. foreach (TrackData t2 in tracks)
  583. if (t1.Path != t2.Path)
  584. return false;
  585. return playlist.Tracks.Count != 0;
  586. }
  587. #endregion
  588. #region Event handlers
  589. /// <summary>
  590. /// Updates the total time of all tracks of a playlist.
  591. /// </summary>
  592. /// <param name="sender">The sender of the event</param>
  593. /// <param name="e">The event data</param>
  594. private static void TracksChanged(object sender, NotifyCollectionChangedEventArgs e)
  595. {
  596. ObservableCollection<TrackData> tracks = sender as ObservableCollection<TrackData>;
  597. // find the playlist containing the track that sent the event
  598. PlaylistData pl = null;
  599. foreach (PlaylistData p in SettingsManager.Playlists)
  600. {
  601. if (p.Tracks == tracks)
  602. {
  603. pl = p;
  604. break;
  605. }
  606. }
  607. // no playlist found (weird!)
  608. if (pl == null) return;
  609. pl.Time = 0;
  610. foreach (TrackData t in pl.Tracks)
  611. pl.Time += t.RawLength;
  612. if (pl.Time < 0) pl.Time = 0;
  613. //// update gui if neccessary
  614. //if (ParentWindow.NavigationPane.CurrentSelectedNavigation == "Playlist:" + pl.Name)
  615. //{
  616. // ParentWindow.InfoPaneTracks.Text = pl.Tracks.Count.ToString() + " songs";
  617. // ParentWindow.InfoPaneDuration.Text = U.TimeSpanToLongString(new TimeSpan(0, 0, (int)pl.Time));
  618. //}
  619. }
  620. #endregion
  621. #region Dispatchers
  622. /// <summary>
  623. /// The dispatcher of the <see cref="PlaylistRenamed"/> event
  624. /// </summary>
  625. /// <param name="playlist">The playlist that was renamed</param>
  626. /// <param name="oldName">The name of the playlist before the change</param>
  627. /// <param name="newName">The name of the playlist after the change</param>
  628. private static void DispatchPlaylistRenamed(PlaylistData playlist, string oldName, string newName)
  629. {
  630. if (PlaylistRenamed != null)
  631. PlaylistRenamed(playlist, new RenamedEventArgs(WatcherChangeTypes.Renamed, "playlist", newName, oldName));
  632. }
  633. /// <summary>
  634. /// The dispatcher of the <see cref="PlaylistModified"/> event
  635. /// </summary>
  636. /// <param name="playlist">The playlist that was modified</param>
  637. /// <param name="type">The type of modification that occured</param>
  638. private static void DispatchPlaylistModified(PlaylistData playlist, ModifyType type)
  639. {
  640. if (PlaylistModified != null)
  641. PlaylistModified(playlist, new ModifiedEventArgs(type, null));
  642. }
  643. #endregion
  644. #endregion
  645. #region Events
  646. /// <summary>
  647. /// Occurs when a playlist has been renamed
  648. /// </summary>
  649. public static event RenamedEventHandler PlaylistRenamed;
  650. /// <summary>
  651. /// Occurs when a playlist has been created, removed or changed
  652. /// </summary>
  653. public static event ModifiedEventHandler PlaylistModified;
  654. #endregion
  655. }
  656. #region Delegates
  657. public delegate void ModifiedEventHandler(object sender, ModifiedEventArgs e);
  658. #endregion
  659. #region Event arguments
  660. /// <summary>
  661. /// Provides data for the events where something has been modified
  662. /// </summary>
  663. public class ModifiedEventArgs
  664. {
  665. /// <summary>
  666. /// Gets or sets the type of modification that occured
  667. /// </summary>
  668. public ModifyType Type { get; set; }
  669. /// <summary>
  670. /// Gets or sets the data of the modification
  671. /// </summary>
  672. public object Data { get; set; }
  673. /// <summary>
  674. /// Creates an instance of the ModifiedEventArgs class
  675. /// </summary>
  676. /// <param name="type">The type of modification that occured</param>
  677. /// <param name="data">The data of the modification</param>
  678. public ModifiedEventArgs(ModifyType type, object data)
  679. {
  680. Type = type;
  681. Data = data;
  682. }
  683. }
  684. #endregion
  685. #region Enums
  686. /// <summary>
  687. /// Represents the type of modification that can occur
  688. /// </summary>
  689. public enum ModifyType
  690. {
  691. /// <summary>
  692. /// The object was created
  693. /// </summary>
  694. Created,
  695. /// <summary>
  696. /// The object was removed
  697. /// </summary>
  698. Removed,
  699. /// <summary>
  700. /// The object was changed
  701. /// </summary>
  702. Changed
  703. }
  704. #endregion
  705. }