/Application/GUI/Windows/MainWindow.xaml.cs

http://yet-another-music-application.googlecode.com/ · C# · 4225 lines · 3044 code · 419 blank · 762 comment · 855 complexity · 9652eeb869a0fa5525fb94a2d665a38c MD5 · raw file

Large files are truncated click here to view the full file

  1. /**
  2. * MainWindow.xaml.cs
  3. *
  4. * The logic behind the main window. Contains
  5. * the code that connects the different part
  6. * of Stoffi. Sort of like the spider in the net.
  7. *
  8. * * * * * * * * *
  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 GlassLib;
  21. using System;
  22. using System.ComponentModel;
  23. using System.Collections;
  24. using System.Collections.ObjectModel;
  25. using System.Collections.Generic;
  26. using System.Collections.Specialized;
  27. using System.Configuration;
  28. using System.Windows.Data;
  29. using System.Globalization;
  30. using System.IO;
  31. using System.Reflection;
  32. using System.Threading;
  33. using System.Windows;
  34. using System.Windows.Controls;
  35. using System.Windows.Input;
  36. using System.Windows.Media;
  37. using System.Windows.Media.Imaging;
  38. using System.Windows.Threading;
  39. using System.Windows.Interop;
  40. using System.Windows.Shell;
  41. using Hardcodet.Wpf.TaskbarNotification;
  42. using Microsoft.WindowsAPICodePack.Dialogs;
  43. using Microsoft.Win32;
  44. using Tomers.WPF.Localization;
  45. namespace Stoffi
  46. {
  47. /// <summary>
  48. /// Interaction logic for MainWindow.xaml
  49. /// </summary>
  50. public partial class StoffiWindow : Window, INotifyPropertyChanged
  51. {
  52. #region Members
  53. private KeyboardListener kListener = new KeyboardListener();
  54. public ContextMenu trayMenu;
  55. public MenuItem trayMenuShow;
  56. public MenuItem trayMenuPlay;
  57. public MenuItem trayMenuNext;
  58. public MenuItem trayMenuPrev;
  59. public MenuItem trayMenuExit;
  60. private ContextMenu addMenu;
  61. public MenuItem addMenuFile;
  62. public MenuItem addMenuFolder;
  63. public MenuItem addMenuPlaylist;
  64. private ContextMenu showMenu;
  65. public MenuItem showMenuDetailsPane;
  66. public MenuItem showMenuMenuBar;
  67. private ContextMenu toolsMenu;
  68. public MenuItem toolsMenuImporter;
  69. public MenuItem toolsMenuExporter;
  70. public MenuItem toolsMenuGenerate;
  71. public Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton taskbarPrev;
  72. public Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton taskbarPlay;
  73. public Microsoft.WindowsAPICodePack.Taskbar.ThumbnailToolbarButton taskbarNext;
  74. public TaskbarIcon trayIcon;
  75. private WindowState oldWindowState = WindowState.Minimized;
  76. private WindowState currentWindowState = WindowState.Normal;
  77. public System.Windows.Shell.JumpList jumpList;
  78. public System.Windows.Shell.JumpTask jumpTaskPlay;
  79. public System.Windows.Shell.JumpTask jumpTaskNext;
  80. public System.Windows.Shell.JumpTask jumpTaskPrev;
  81. private bool glassEffect = true;
  82. private List<Key> currentPressedKeys = new List<Key>();
  83. public Microsoft.WindowsAPICodePack.Taskbar.TabbedThumbnail taskbarPreview;
  84. private EditableTextBlock etbInEdit = null;
  85. private Equalizer equalizer = null;
  86. private DispatcherTimer resortDelay = new DispatcherTimer();
  87. private List<string> pathsThatWasChanged = new List<string>();
  88. public MenuItem listMenuPlay = new MenuItem();
  89. public MenuItem listMenuRemove = new MenuItem();
  90. public MenuItem listMenuDelete = new MenuItem();
  91. public MenuItem listMenuInfo = new MenuItem();
  92. public MenuItem listMenuQueue = new MenuItem();
  93. public MenuItem listMenuAddToNew = new MenuItem();
  94. public MenuItem listMenuAddToPlaylist = new MenuItem();
  95. public MenuItem listMenuRemoveFromPlaylist = new MenuItem();
  96. public MenuItem listMenuWatchOnYouTube = new MenuItem();
  97. public MenuItem listMenuShareSong = new MenuItem();
  98. private ContextMenu listMenu = new ContextMenu();
  99. private string dialogPath = @"C:\";
  100. private DispatcherTimer sourceModifiedDelay = new DispatcherTimer();
  101. private Hashtable sourceModifiedTracks = new Hashtable();
  102. private bool doRestart = false;
  103. private TrackData currentlySelectedTrack = null;
  104. private ScannerCallback sourceModifiedCallback;
  105. private bool resumeWhenBack = false; // whether or not to resume playback at login/unlock
  106. private object sourceModifiedCallbackParams;
  107. private bool initialized = false;
  108. private bool showMediaError = false; // whether or not to show errors from media manager as popup
  109. #endregion
  110. #region Properties
  111. /// <summary>
  112. /// The total time of all tracks in the history (in seconds)
  113. /// </summary>
  114. public double HistoryTime { get; private set; }
  115. /// <summary>
  116. /// The total time of all tracks in the queue (in seconds)
  117. /// </summary>
  118. public double QueueTime { get; private set; }
  119. /// <summary>
  120. /// The total time of all tracks in the library (in seconds)
  121. /// </summary>
  122. public double LibraryTime { get; private set; }
  123. /// <summary>
  124. /// A table of the TrackList for each playlist
  125. /// </summary>
  126. public Hashtable PlaylistTrackLists { get; private set; }
  127. /// <summary>
  128. /// The height of the details pane
  129. /// </summary>
  130. public double DetailsPaneHeight
  131. {
  132. get { return SettingsManager.DetailsPaneHeight; }
  133. set { SettingsManager.DetailsPaneHeight = value; }
  134. }
  135. #endregion
  136. #region Constructor
  137. /// <summary>
  138. ///
  139. /// </summary>
  140. public StoffiWindow()
  141. {
  142. U.L(LogLevel.Debug, "MAIN", "Creating main window");
  143. //SettingsManager.FirstRun = true;
  144. //*********** Next ***********/
  145. // TODO: In-place track edit
  146. // TODO: Images (currently playing, queue) in front of t + style
  147. // TODO: Images (currently playing) in front of playlists/library
  148. // TODO: MusicBrainz
  149. // TODO: Jumplist: playlists
  150. // TODO: Drag search text
  151. // TODO: Track score (how good is it?)
  152. // TODO: Last.fm support
  153. // TODO: Spotify
  154. // TODO: Spectrum
  155. // TODO: Views (album, artist, genre, all)
  156. // TODO: Playlist view
  157. // TODO: Network sources
  158. // TODO: Device sources
  159. // TODO: Tools for cutting track
  160. // TODO: Album cover download
  161. // TODO: Lyrics
  162. // TODO: Radio
  163. // TODO: TaskDialogs
  164. // TODO: Wikipedia
  165. // TODO: Social music
  166. U.L(LogLevel.Debug, "MAIN", "Setting culture");
  167. LanguageContext.Instance.Culture = CultureInfo.GetCultureInfo(SettingsManager.Language);
  168. if (!Microsoft.WindowsAPICodePack.Taskbar.TaskbarManager.IsPlatformSupported)
  169. {
  170. MessageBox.Show(U.T("MessageOldWindows", "Message"), U.T("MessageOldWindows", "Title"), MessageBoxButton.OK, MessageBoxImage.Error);
  171. Application.Current.Shutdown();
  172. return;
  173. }
  174. U.L(LogLevel.Debug, "MAIN", "Initialize");
  175. InitializeComponent();
  176. U.L(LogLevel.Debug, "MAIN", "Initialized");
  177. // we have to remove controls from their parent so "LastChildFill" doesn't screw everything up
  178. // we add them later on when they are toggled
  179. MainContainer.Children.Remove(ControlPanel);
  180. }
  181. #endregion
  182. #region Methods
  183. #region Public
  184. /// <summary>
  185. /// Restarts the application
  186. /// </summary>
  187. public void Restart()
  188. {
  189. doRestart = true;
  190. this.Close();
  191. }
  192. /// <summary>
  193. ///
  194. /// </summary>
  195. /// <param name="modifiers"></param>
  196. /// <returns></returns>
  197. public String GetModifiersAsText(List<Key> modifiers)
  198. {
  199. String txt = "";
  200. foreach (Key k in modifiers)
  201. {
  202. if (k == Key.LeftCtrl || k == Key.RightCtrl) txt += "Ctrl+";
  203. else if (k == Key.LeftAlt || k == Key.RightAlt) txt += "Alt+";
  204. else if (k == Key.LWin || k == Key.RWin) txt += "Win+";
  205. else if (k == Key.LeftShift || k == Key.RightShift) txt += "Shift+";
  206. }
  207. if (txt.Length > 0) return txt.Substring(0, txt.Length - 1);
  208. else return "";
  209. }
  210. /// <summary>
  211. ///
  212. /// </summary>
  213. /// <param name="k"></param>
  214. /// <returns></returns>
  215. public String KeyToString(Key k)
  216. {
  217. switch (k)
  218. {
  219. case Key.NumPad0:
  220. return "0 (numpad)";
  221. case Key.NumPad1:
  222. return "1 (numpad)";
  223. case Key.NumPad2:
  224. return "2 (numpad)";
  225. case Key.NumPad3:
  226. return "3 (numpad)";
  227. case Key.NumPad4:
  228. return "4 (numpad)";
  229. case Key.NumPad5:
  230. return "5 (numpad)";
  231. case Key.NumPad6:
  232. return "6 (numpad)";
  233. case Key.NumPad7:
  234. return "7 (numpad)";
  235. case Key.NumPad8:
  236. return "8 (numpad)";
  237. case Key.NumPad9:
  238. return "9 (numpad)";
  239. case Key.D0:
  240. return "0";
  241. case Key.D1:
  242. return "1";
  243. case Key.D2:
  244. return "2";
  245. case Key.D3:
  246. return "3";
  247. case Key.D4:
  248. return "4";
  249. case Key.D5:
  250. return "5";
  251. case Key.D6:
  252. return "6";
  253. case Key.D7:
  254. return "7";
  255. case Key.D8:
  256. return "8";
  257. case Key.D9:
  258. return "9";
  259. case Key.OemComma:
  260. return ",";
  261. case Key.OemPeriod:
  262. return ".";
  263. case Key.Subtract:
  264. return "-";
  265. case Key.Multiply:
  266. return "*";
  267. case Key.Divide:
  268. return "/";
  269. case Key.Add:
  270. return "+";
  271. case Key.Back:
  272. return "Backspace";
  273. case Key.OemMinus:
  274. return "-";
  275. case Key.CapsLock:
  276. return "CapsLock";
  277. case Key.Scroll:
  278. return "ScrollLock";
  279. case Key.PrintScreen:
  280. return "PrintScreen";
  281. case Key.Return:
  282. return "Enter";
  283. case Key.PageDown:
  284. return "PageDown";
  285. case Key.PageUp:
  286. return "PageUp";
  287. // TODO: hardcoded temporary fix
  288. case Key.Oem3:
  289. return "´";
  290. case Key.OemPlus:
  291. return "=";
  292. case Key.OemOpenBrackets:
  293. return "[";
  294. case Key.Oem6:
  295. return "]";
  296. case Key.Oem5:
  297. return @"\";
  298. case Key.Oem1:
  299. return ";";
  300. case Key.OemQuotes:
  301. return "'";
  302. case Key.OemQuestion:
  303. return "/";
  304. default:
  305. return k.ToString();
  306. }
  307. }
  308. /// <summary>
  309. ///
  310. /// </summary>
  311. /// <param name="argument"></param>
  312. public void CallFromSecondInstance(String argument)
  313. {
  314. if (argument == "/play")
  315. {
  316. PlayPause();
  317. }
  318. else if (argument == "/next")
  319. {
  320. MediaManager.Next();
  321. if (SettingsManager.MediaState != MediaState.Playing)
  322. MediaManager.Tick(null, null);
  323. }
  324. else if (argument == "/previous")
  325. {
  326. MediaManager.Previous();
  327. if (SettingsManager.MediaState != MediaState.Playing)
  328. MediaManager.Tick(null, null);
  329. }
  330. else
  331. {
  332. if (File.Exists(argument))
  333. {
  334. // file is a playlist
  335. if (PlaylistManager.IsSupported(argument))
  336. {
  337. PlaylistData pl = PlaylistManager.LoadPlaylist(argument);
  338. if (pl != null)
  339. {
  340. NavigationPane.SwitchNavigation("Playlist:" + pl.Name);
  341. if (pl.Tracks.Count > 0)
  342. {
  343. MediaManager.Load(pl.Tracks[0]);
  344. MediaManager.Play();
  345. }
  346. }
  347. }
  348. // file is a track
  349. else if (MediaManager.IsSupported(argument))
  350. {
  351. Open(argument);
  352. }
  353. }
  354. // TODO: bring to front
  355. }
  356. }
  357. /// <summary>
  358. /// Retrives the currently selected track list's source.
  359. /// </summary>
  360. /// <returns>The collection used as ItemsSource for the current track list</returns>
  361. public ObservableCollection<TrackData> GetCurrentTrackCollection()
  362. {
  363. if (SettingsManager.CurrentSelectedNavigation == "History")
  364. return SettingsManager.HistoryTracks;
  365. else if (SettingsManager.CurrentSelectedNavigation == "Queue")
  366. return SettingsManager.QueueTracks;
  367. else if (SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  368. {
  369. PlaylistData p = PlaylistManager.FindPlaylist(SettingsManager.CurrentSelectedNavigation.Split(new[] { ':' }, 2)[1]);
  370. if (p == null) return null;
  371. return p.Tracks;
  372. }
  373. else if (SettingsManager.CurrentSelectedNavigation == "Files")
  374. return SettingsManager.FileTracks;
  375. else if (SettingsManager.CurrentSelectedNavigation == "YouTube")
  376. return YouTubeManager.TrackSource;
  377. else
  378. return null;
  379. }
  380. /// <summary>
  381. ///
  382. /// </summary>
  383. /// <returns></returns>
  384. public ViewDetails GetCurrentTrackList()
  385. {
  386. if (SettingsManager.CurrentSelectedNavigation == "History")
  387. return HistoryTracks;
  388. else if (SettingsManager.CurrentSelectedNavigation == "Queue")
  389. return QueueTracks;
  390. else if (SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  391. return (ViewDetails)PlaylistTrackLists[SettingsManager.CurrentSelectedNavigation.Split(new[] { ':' }, 2)[1]];
  392. else if (SettingsManager.CurrentSelectedNavigation == "Files")
  393. return FileTracks;
  394. else if (SettingsManager.CurrentSelectedNavigation == "YouTube")
  395. return YouTubeContainer.YouTubeTracks;
  396. else
  397. return null;
  398. }
  399. /// <summary>
  400. ///
  401. /// </summary>
  402. /// <returns></returns>
  403. public ViewDetails GetActiveTrackList()
  404. {
  405. string can = SettingsManager.CurrentActiveNavigation;
  406. if (can == "History" || can == "Queue")
  407. can = SettingsManager.CurrentTrack == null ? "Files" : SettingsManager.CurrentTrack.Source;
  408. if (can.StartsWith("Playlist:"))
  409. {
  410. PlaylistData p = PlaylistManager.FindPlaylist(can.Split(new[] { ':' }, 2)[1]);
  411. if (p != null)
  412. return (ViewDetails)PlaylistTrackLists[p.Name];
  413. }
  414. if (can == "YouTube")
  415. return YouTubeContainer.YouTubeTracks;
  416. else
  417. return FileTracks;
  418. }
  419. /// <summary>
  420. ///
  421. /// </summary>
  422. /// <param name="name"></param>
  423. public void OnPropertyChanged(string name)
  424. {
  425. if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name));
  426. }
  427. #endregion
  428. #region Private
  429. /// <summary>
  430. /// Play the currently selected track
  431. /// </summary>
  432. /// <param name="resume">Resume at the current position if the selected track is the CurrentTrack</param>
  433. private void Play(bool resume = false)
  434. {
  435. showMediaError = true;
  436. if (resume && SettingsManager.CurrentTrack != null)
  437. MediaManager.Play();
  438. else if (GetCurrentTrackList().SelectedItem is TrackData)
  439. {
  440. string pl = "";
  441. if (SettingsManager.CurrentSelectedNavigation == "Library")
  442. pl = "";
  443. else if (SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  444. pl = SettingsManager.CurrentSelectedNavigation.Split(new[]{':'},2)[1];
  445. TrackData track = GetCurrentTrackList().SelectedItem as TrackData;
  446. MediaManager.TrackCollection = GetCurrentTrackList().Items;
  447. if (SettingsManager.CurrentSelectedNavigation == "History")
  448. SettingsManager.HistoryIndex = SettingsManager.HistoryTracks.IndexOf(track);
  449. else
  450. SettingsManager.HistoryIndex = SettingsManager.HistoryTracks.Count;
  451. SettingsManager.CurrentActiveNavigation = SettingsManager.CurrentSelectedNavigation;
  452. if (SettingsManager.CurrentActiveNavigation.StartsWith("Playlist:"))
  453. PlaylistManager.CurrentPlaylist = SettingsManager.CurrentActiveNavigation.Split(new[] { ':' }, 2)[1];
  454. else
  455. PlaylistManager.CurrentPlaylist = "";
  456. MediaManager.Stop();
  457. MediaManager.Load(track);
  458. MediaManager.Play();
  459. }
  460. }
  461. /// <summary>
  462. /// Toggle the play and pause state
  463. /// </summary>
  464. private void PlayPause()
  465. {
  466. if (SettingsManager.MediaState == MediaState.Playing)
  467. SettingsManager.MediaState = MediaState.Paused;
  468. else
  469. SettingsManager.MediaState = MediaState.Playing;
  470. }
  471. /// <summary>
  472. /// Removes a set of tracks from a given collection of tracks.
  473. /// </summary>
  474. /// <param name="tracksToRemove">The tracks to remove</param>
  475. /// <param name="tracks">The collection from where to remove the tracks</param>
  476. private void RemoveTracks(SortedList<string, TrackData> tracksToRemove, ObservableCollection<TrackData> tracks)
  477. {
  478. for (int i = 0; i < tracks.Count; i++)
  479. {
  480. if (tracksToRemove.ContainsKey(tracks[i].Path))
  481. {
  482. tracks.RemoveAt(i--);
  483. }
  484. }
  485. }
  486. /// <summary>
  487. /// Removes a set of tracks from a given collection of tracks.
  488. /// </summary>
  489. /// <param name="tracksToRemove">The tracks to remove</param>
  490. /// <param name="tracks">The collection from where to remove the tracks</param>
  491. private void RemoveTracks(SortedList<string, TrackData> tracksToRemove, List<TrackData> tracks)
  492. {
  493. for (int i = 0; i < tracks.Count; i++)
  494. {
  495. if (tracksToRemove.ContainsKey(tracks[i].Path))
  496. {
  497. tracks.RemoveAt(i--);
  498. }
  499. }
  500. }
  501. /// <summary>
  502. /// Removes tracks with a given filename for a specific collection of tracks
  503. /// </summary>
  504. /// <param name="filename">The filename of the tracks to remove</param>
  505. /// <param name="tracks">The collection of tracks from which to remove</param>
  506. private void RemoveTrack(String filename, ObservableCollection<TrackData> tracks)
  507. {
  508. for (int i = 0; i < tracks.Count; i++)
  509. {
  510. if (tracks[i].Path == filename)
  511. {
  512. tracks.RemoveAt(i);
  513. break;
  514. }
  515. }
  516. }
  517. /// <summary>
  518. /// Removes tracks with a given filename for a specific list of tracks
  519. /// </summary>
  520. /// <param name="filename">The filename of the tracks to remove</param>
  521. /// <param name="tracks">The list of tracks from which to remove</param>
  522. private void RemoveTrack(String filename, List<TrackData> tracks)
  523. {
  524. for (int i = 0; i < tracks.Count; i++)
  525. {
  526. if (tracks[i].Path == filename)
  527. {
  528. tracks.RemoveAt(i);
  529. break;
  530. }
  531. }
  532. }
  533. /// <summary>
  534. /// Reapply the sorting on a tracklist
  535. /// </summary>
  536. /// <param name="tl">The tracklist to re-sort</param>
  537. /// <param name="paths">A list of the paths that was changed</param>
  538. private void ResortTracklist(ViewDetails tl, List<string> paths)
  539. {
  540. bool resort = false;
  541. foreach (TrackData t in SettingsManager.FileTracks)
  542. {
  543. if (paths.Contains(t.Path))
  544. {
  545. resort = true;
  546. break;
  547. }
  548. }
  549. if (resort)
  550. {
  551. if (tl.Items.SortDescriptions.Count > 0)
  552. {
  553. SortDescription sd = tl.Items.SortDescriptions[0];
  554. tl.Items.SortDescriptions.Remove(sd);
  555. tl.Items.SortDescriptions.Insert(0, sd);
  556. }
  557. }
  558. }
  559. /// <summary>
  560. /// Load a file and add it according to the AddPolicy and play
  561. /// it according to the PlayPolicy
  562. /// </summary>
  563. /// <param name="filename">The filename of the track</param>
  564. /// <param name="forcePlay">Whether or not to override the PlayPolicy</param>
  565. private void Open(string filename, bool forcePlay = false)
  566. {
  567. U.L(LogLevel.Debug, "MAIN", "Opening " + filename);
  568. OpenAddPolicy DoAdd = SettingsManager.OpenAddPolicy;
  569. OpenPlayPolicy DoPlay = SettingsManager.OpenPlayPolicy;
  570. TrackData track = null;
  571. // add track
  572. if (DoAdd == OpenAddPolicy.Library || DoAdd == OpenAddPolicy.LibraryAndPlaylist)
  573. {
  574. // add track to library if needed
  575. track = FilesystemManager.GetTrack(filename);
  576. if (track == null)
  577. {
  578. U.L(LogLevel.Debug, "MAIN", "Adding to collection");
  579. FilesystemManager.AddSource(new SourceData()
  580. {
  581. Data = filename,
  582. Include = true,
  583. HumanType = U.T("SourcesTypeFile"),
  584. Type = SourceType.File
  585. });
  586. track = FilesystemManager.GetTrack(filename);
  587. }
  588. if (track == null)
  589. U.L(LogLevel.Warning, "MAIN", "Could not add track to Library: " + filename);
  590. // add track to current playlist as well
  591. if (DoAdd == OpenAddPolicy.LibraryAndPlaylist && track != null)
  592. {
  593. if (SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  594. {
  595. U.L(LogLevel.Debug, "MAIN", "Adding to current playlist");
  596. String playlistName = SettingsManager.CurrentSelectedNavigation.Split(new[]{':'},2)[1];
  597. List<object> tracks = new List<object>();
  598. tracks.Add(track);
  599. PlaylistManager.AddToPlaylist(tracks, playlistName);
  600. }
  601. }
  602. }
  603. // play track
  604. if (DoPlay != OpenPlayPolicy.DoNotPlay || forcePlay)
  605. {
  606. // create track if it is null
  607. if (track == null)
  608. {
  609. U.L(LogLevel.Debug, "MAIN", "Creating track");
  610. track = FilesystemManager.CreateTrack(filename);
  611. if (track == null)
  612. {
  613. U.L(LogLevel.Warning, "MAIN", "Could not create track for: " + filename);
  614. return;
  615. }
  616. FilesystemManager.UpdateTrack(track);
  617. }
  618. if (DoPlay == OpenPlayPolicy.Play || forcePlay)
  619. {
  620. U.L(LogLevel.Debug, "MAIN", "Playing track");
  621. MediaManager.Stop();
  622. MediaManager.Load(track);
  623. MediaManager.Play();
  624. if (DoAdd == OpenAddPolicy.LibraryAndPlaylist && SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  625. SettingsManager.CurrentActiveNavigation = SettingsManager.CurrentSelectedNavigation;
  626. else if (DoAdd == OpenAddPolicy.Library)
  627. SettingsManager.CurrentActiveNavigation = "Library";
  628. }
  629. else if (DoPlay == OpenPlayPolicy.BackOfQueue)
  630. MediaManager.Queue(new List<TrackData>() { track });
  631. else if (DoPlay == OpenPlayPolicy.FrontOfQueue)
  632. MediaManager.Queue(new List<TrackData>() { track }, 0);
  633. }
  634. }
  635. /// <summary>
  636. /// Creates a playlist track list and navigation items
  637. /// </summary>
  638. /// <param name="playlist">The data for the playlist to create</param>
  639. /// <param name="select">Whether to select the playlist after it has been created</param>
  640. private void CreatePlaylist(PlaylistData playlist, bool select = true)
  641. {
  642. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  643. {
  644. // create track list
  645. ViewDetails vd = new ViewDetails();
  646. Grid.SetRow(vd, 1);
  647. TrackContainer.Children.Add(vd);
  648. vd.ItemsSource = playlist.Tracks;
  649. playlist.Tracks.CollectionChanged +=
  650. new System.Collections.Specialized.NotifyCollectionChangedEventHandler(vd.ItemsSource_CollectionChanged);
  651. if (playlist.ListConfig == null)
  652. {
  653. ViewDetailsConfig vdc = SettingsManager.CreateListConfig();
  654. SettingsManager.InitViewDetailsConfig(vdc);
  655. vdc.HasNumber = true;
  656. playlist.ListConfig = vdc;
  657. }
  658. if (PlaylistTrackLists.ContainsKey(playlist.Name))
  659. PlaylistTrackLists.Remove(playlist.Name);
  660. PlaylistTrackLists.Add(playlist.Name, vd);
  661. vd.ContextMenu = listMenu;
  662. vd.Visibility = Visibility.Collapsed;
  663. vd.BorderThickness = new Thickness(0);
  664. vd.ItemsSource = playlist.Tracks;
  665. vd.Config = playlist.ListConfig;
  666. vd.FilterMatch = TrackList_SearchMatch;
  667. vd.SelectionChanged += new SelectionChangedEventHandler(TrackList_SelectionChanged);
  668. vd.MouseDoubleClick += new MouseButtonEventHandler(TrackList_MouseDoubleClick);
  669. vd.ContextMenuOpening += new ContextMenuEventHandler(TrackList_ContextMenuOpening);
  670. vd.FilesDropped += new FileDropEventHandler(TrackList_FilesDropped);
  671. vd.MoveItem += new MoveItemEventHandler(TrackList_MoveItem);
  672. // create the item in the navigation tree
  673. TreeViewItem item = new TreeViewItem();
  674. item.Selected += NavigationPane.Playlist_Selected;
  675. item.Drop += NavigationPane.Playlist_Drop;
  676. item.KeyDown += NavigationPlaylist_KeyDown;
  677. item.Tag = playlist.Name;
  678. item.Padding = new Thickness(8, 0, 0, 0);
  679. StackPanel sp = new StackPanel();
  680. sp.Orientation = System.Windows.Controls.Orientation.Horizontal;
  681. Image img = new Image();
  682. img.Source = Utilities.GetIcoImage("pack://application:,,,/GUI/Images/Icons/DiscAudio.ico", 16, 16);
  683. img.Width = 16;
  684. img.Height = 16;
  685. sp.Children.Add(img);
  686. EditableTextBlock etb = new EditableTextBlock();
  687. etb.EnteredEditMode += new EventHandler(EditableTextBlock_EnteredEditMode);
  688. etb.Text = playlist.Name;
  689. etb.Margin = new Thickness(5, 0, 5, 0);
  690. etb.Edited += NavigationPane.Playlist_Edited;
  691. sp.Children.Add(etb);
  692. item.Header = sp;
  693. item.ContextMenuOpening += new ContextMenuEventHandler(NavigationPane.Playlist_ContextMenuOpening);
  694. item.ContextMenu = NavigationPane.playlistMenu;
  695. NavigationPane.Playlists.Items.Insert(NavigationPane.Playlists.Items.Count - 1, item);
  696. if (select)
  697. item.Focus();
  698. // create list context menu items
  699. MenuItem miAdd = new MenuItem();
  700. miAdd.Header = playlist.Name;
  701. miAdd.Click += new RoutedEventHandler(listMenuAddToPlaylist_Click);
  702. listMenuAddToPlaylist.Visibility = System.Windows.Visibility.Visible;
  703. listMenuAddToPlaylist.Items.Insert(listMenuAddToPlaylist.Items.Count - 1, miAdd);
  704. MenuItem miDel = new MenuItem();
  705. miDel.Header = playlist.Name;
  706. miDel.Click += new RoutedEventHandler(listMenuRemoveFromPlaylist_Click);
  707. listMenuRemoveFromPlaylist.Visibility = System.Windows.Visibility.Visible;
  708. listMenuRemoveFromPlaylist.Items.Add(miDel);
  709. PlaybackControls.Search.AddPlaylist(playlist);
  710. }));
  711. }
  712. /// <summary>
  713. /// Updates the visibility of a given element according to the settings
  714. /// </summary>
  715. /// <param name="element">The element to update (menubar or details)</param>
  716. private void UpdateVisibility(string element)
  717. {
  718. switch (element)
  719. {
  720. case "menubar":
  721. bool mv = SettingsManager.MenuBarVisibile;
  722. showMenuMenuBar.IsChecked = mv;
  723. MenuItemViewMenuBar.IsChecked = mv;
  724. MenuBar.Visibility = mv ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
  725. break;
  726. case "details":
  727. bool dv = SettingsManager.DetailsPaneVisible;
  728. showMenuDetailsPane.IsChecked = dv;
  729. MenuItemViewDetailsPane.IsChecked = dv;
  730. DetailsRow.MinHeight = (dv ? 80 : 0);
  731. DetailsRow.Height = new GridLength((dv ? SettingsManager.DetailsPaneHeight : 0));
  732. DetailsPane.Visibility = dv ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
  733. HorizontalSplitter.Visibility = dv ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
  734. break;
  735. }
  736. }
  737. /// <summary>
  738. /// Updates the strings around the GUI, that are hardcoded, according to the current Language
  739. /// </summary>
  740. private void UpdateGUIStrings()
  741. {
  742. // change column headers of list views
  743. foreach (ViewDetailsColumn c in SettingsManager.SourceListConfig.Columns)
  744. {
  745. if (c.Binding == "HumanType") c.Text = U.T("ColumnType");
  746. else if (c.Binding == "Data") c.Text = U.T("ColumnLocation");
  747. }
  748. foreach (ViewDetailsColumn c in SettingsManager.YouTubeListConfig.Columns)
  749. {
  750. if (c.Binding == "Artist") c.Text = U.T("ColumnArtist");
  751. else if (c.Binding == "Title") c.Text = U.T("ColumnTitle");
  752. else if (c.Binding == "Path") c.Text = U.T("ColumnPath");
  753. else if (c.Binding == "Length") c.Text = U.T("ColumnLength");
  754. }
  755. foreach (ViewDetailsColumn c in SettingsManager.FileListConfig.Columns)
  756. {
  757. if (c.Binding == "Artist") c.Text = U.T("ColumnArtist");
  758. else if (c.Binding == "Title") c.Text = U.T("ColumnTitle");
  759. else if (c.Binding == "Album") c.Text = U.T("ColumnAlbum");
  760. else if (c.Binding == "Genre") c.Text = U.T("ColumnGenre");
  761. else if (c.Binding == "LastPlayed") c.Text = U.T("ColumnLastPlayed");
  762. else if (c.Binding == "Length") c.Text = U.T("ColumnLength");
  763. else if (c.Binding == "PlayCount") c.Text = U.T("ColumnPlayCount");
  764. else if (c.Binding == "Path") c.Text = U.T("ColumnPath");
  765. else if (c.Binding == "Track") c.Text = U.T("ColumnTrack");
  766. else if (c.Binding == "Year") c.Text = U.T("ColumnYear");
  767. }
  768. foreach (ViewDetailsColumn c in SettingsManager.QueueListConfig.Columns)
  769. {
  770. if (c.Binding == "Artist") c.Text = U.T("ColumnArtist");
  771. else if (c.Binding == "Title") c.Text = U.T("ColumnTitle");
  772. else if (c.Binding == "Album") c.Text = U.T("ColumnAlbum");
  773. else if (c.Binding == "Genre") c.Text = U.T("ColumnGenre");
  774. else if (c.Binding == "LastPlayed") c.Text = U.T("ColumnLastPlayed");
  775. else if (c.Binding == "Length") c.Text = U.T("ColumnLength");
  776. else if (c.Binding == "PlayCount") c.Text = U.T("ColumnPlayCount");
  777. else if (c.Binding == "Path") c.Text = U.T("ColumnPath");
  778. else if (c.Binding == "Track") c.Text = U.T("ColumnTrack");
  779. else if (c.Binding == "Year") c.Text = U.T("ColumnYear");
  780. }
  781. foreach (ViewDetailsColumn c in SettingsManager.HistoryListConfig.Columns)
  782. {
  783. if (c.Binding == "Artist") c.Text = U.T("ColumnArtist");
  784. else if (c.Binding == "Title") c.Text = U.T("ColumnTitle");
  785. else if (c.Binding == "Album") c.Text = U.T("ColumnAlbum");
  786. else if (c.Binding == "Genre") c.Text = U.T("ColumnGenre");
  787. else if (c.Binding == "LastPlayed") c.Text = U.T("ColumnPlayed");
  788. else if (c.Binding == "Length") c.Text = U.T("ColumnLength");
  789. else if (c.Binding == "PlayCount") c.Text = U.T("ColumnPlayCount");
  790. else if (c.Binding == "Path") c.Text = U.T("ColumnPath");
  791. else if (c.Binding == "Track") c.Text = U.T("ColumnTrack");
  792. else if (c.Binding == "Year") c.Text = U.T("ColumnYear");
  793. }
  794. foreach (PlaylistData p in SettingsManager.Playlists)
  795. foreach (ViewDetailsColumn c in p.ListConfig.Columns)
  796. {
  797. if (c.Binding == "Artist") c.Text = U.T("ColumnArtist");
  798. else if (c.Binding == "Title") c.Text = U.T("ColumnTitle");
  799. else if (c.Binding == "Album") c.Text = U.T("ColumnAlbum");
  800. else if (c.Binding == "Genre") c.Text = U.T("ColumnGenre");
  801. else if (c.Binding == "LastPlayed") c.Text = U.T("ColumnPlayed");
  802. else if (c.Binding == "Length") c.Text = U.T("ColumnLength");
  803. else if (c.Binding == "PlayCount") c.Text = U.T("ColumnPlayCount");
  804. else if (c.Binding == "Path") c.Text = U.T("ColumnPath");
  805. else if (c.Binding == "Track") c.Text = U.T("ColumnTrack");
  806. else if (c.Binding == "Year") c.Text = U.T("ColumnYear");
  807. }
  808. // change source types
  809. foreach (SourceData s in SettingsManager.Sources)
  810. switch (s.Type)
  811. {
  812. case SourceType.File:
  813. s.HumanType = U.T("SourcesTypeFile");
  814. break;
  815. case SourceType.Folder:
  816. s.HumanType = U.T("SourcesTypeFolder");
  817. break;
  818. case SourceType.Library:
  819. s.HumanType = U.T("SourcesTypeLibrary");
  820. break;
  821. }
  822. // change shortcuts
  823. ControlPanel.GlobalLabel.Content = U.T("ShortcutGlobal");
  824. foreach (TextBlock t in ControlPanel.ShortcutTitles)
  825. t.Text = U.T((string)t.Tag);
  826. foreach (TextBlock t in ControlPanel.ShortcutDescriptions)
  827. t.Text = U.T((string)t.Tag);
  828. foreach (Label l in ControlPanel.ShortcutLabels)
  829. l.Content = U.T((string)l.Tag);
  830. // change menus
  831. trayMenuShow.Header = U.T("TrayShow");
  832. trayMenuPlay.Header = U.T("TrayPlay");
  833. trayMenuNext.Header = U.T("TrayNext");
  834. trayMenuPrev.Header = U.T("TrayPrev");
  835. trayMenuExit.Header = U.T("TrayExit");
  836. taskbarPlay.Tooltip = U.T("TaskbarPlay");
  837. taskbarNext.Tooltip = U.T("TaskbarNext");
  838. taskbarPrev.Tooltip = U.T("TaskbarPrev");
  839. jumpTaskPlay.Title = U.T("JumpPlay", "Title");
  840. jumpTaskNext.Title = U.T("JumpNext", "Title");
  841. jumpTaskPrev.Title = U.T("JumpPrev", "Title");
  842. jumpTaskPlay.Description = U.T("JumpPlay", "Description");
  843. jumpTaskNext.Description = U.T("JumpNext", "Description");
  844. jumpTaskPrev.Description = U.T("JumpPrev", "Description");
  845. listMenuAddToPlaylist.Header = U.T("MenuAddToPlaylist", "Header");
  846. listMenuAddToNew.Header = U.T("MenuCreateNew", "Header");
  847. listMenuDelete.Header = U.T("MenuDelete");
  848. listMenuInfo.Header = U.T("MenuInfo");
  849. listMenuPlay.Header = U.T("MenuPlay");
  850. listMenuQueue.Header = U.T("MenuQueue");
  851. listMenuRemove.Header = U.T("MenuRemove");
  852. listMenuRemoveFromPlaylist.Header = U.T("MenuRemoveFromPlaylist", "Header");
  853. listMenuWatchOnYouTube.Header = U.T("MenuWatchOnYouTube");
  854. listMenuShareSong.Header = U.T("MenuShareSong");
  855. addMenuFile.Header = U.T("ToolbarAddTrack");
  856. addMenuFolder.Header = U.T("ToolbarAddFolder");
  857. addMenuPlaylist.Header = U.T("ToolbarAddPlaylist");
  858. showMenuDetailsPane.Header = U.T("ToolbarDetailsPane");
  859. showMenuMenuBar.Header = U.T("ToolbarMenuBar");
  860. toolsMenuExporter.Header = U.T("ToolbarExporter");
  861. toolsMenuImporter.Header = U.T("ToolbarImporter");
  862. toolsMenuGenerate.Header = U.T("ToolbarGeneratePlaylist");
  863. NavigationPane.playlistMenuRemove.Header = U.T("MenuRemovePlaylist");
  864. NavigationPane.playlistMenuRename.Header = U.T("MenuRenamePlaylist");
  865. NavigationPane.playlistMenuSave.Header = U.T("MenuSavePlaylist");
  866. NavigationPane.playlistMenuShare.Header = U.T("MenuSharePlaylist");
  867. NavigationPane.CreateNewPlaylistETB.Text = U.T("NavigationCreateNew");
  868. ControlPanel.menuRemove.Header = U.T("MenuRemove");
  869. // change tracklist header
  870. string csn = SettingsManager.CurrentSelectedNavigation;
  871. switch (csn)
  872. {
  873. case "Files":
  874. InfoPaneTitle.Text = U.T("NavigationFilesTitle");
  875. InfoPaneDuration.Text = U.TimeSpanToLongString(new TimeSpan(0, 0, (int)LibraryTime)); ;
  876. InfoPaneTracks.Text = SettingsManager.FileTracks.Count.ToString() + " " + U.T("HeaderTracks");
  877. break;
  878. case "Queue":
  879. InfoPaneTitle.Text = U.T("NavigationQueueTitle");
  880. InfoPaneDuration.Text = U.TimeSpanToLongString(new TimeSpan(0, 0, (int)QueueTime)); ;
  881. InfoPaneTracks.Text = SettingsManager.QueueTracks.Count.ToString() + " " + U.T("HeaderTracks");
  882. break;
  883. case "History":
  884. InfoPaneTitle.Text = U.T("NavigationHistoryTitle");
  885. InfoPaneDuration.Text = U.TimeSpanToLongString(new TimeSpan(0, 0, (int)HistoryTime)); ;
  886. InfoPaneTracks.Text = SettingsManager.HistoryTracks.Count.ToString() + " " + U.T("HeaderTracks");
  887. break;
  888. default:
  889. if (csn.StartsWith("Playlist:"))
  890. {
  891. PlaylistData p = PlaylistManager.FindPlaylist(csn.Split(new[] { ':' }, 2)[1]);
  892. InfoPaneTitle.Text = U.T("NavigationPlaylistTitle") + " '" + p.Name + "'";
  893. InfoPaneDuration.Text = U.TimeSpanToLongString(new TimeSpan(0, 0, (int)p.Time)); ;
  894. InfoPaneTracks.Text = p.Tracks.Count.ToString() + " " + U.T("HeaderTracks");
  895. }
  896. break;
  897. }
  898. }
  899. /// <summary>
  900. /// Will repaint the glass effect behind the playback pane.
  901. /// </summary>
  902. private void RefreshGlassEffect()
  903. {
  904. try
  905. {
  906. Dwm.Glass[this].Enabled = true;
  907. Thickness foo = new Thickness(1, 75, 1, 1);
  908. Dwm.Glass[this].Margins = foo;
  909. Background = Brushes.Transparent;
  910. glassEffect = true;
  911. }
  912. catch (Exception e)
  913. {
  914. U.L(LogLevel.Warning, "MAIN", "Could not set glass effect: " + e.Message);
  915. if (System.Windows.Forms.VisualStyles.VisualStyleInformation.DisplayName == "")
  916. Background = SystemColors.ControlBrush;
  917. else
  918. Background = SystemColors.GradientActiveCaptionBrush;
  919. glassEffect = false;
  920. }
  921. }
  922. /// <summary>
  923. /// Initializes the GUI
  924. /// </summary>
  925. private void InitGUI()
  926. {
  927. U.L(LogLevel.Debug, "MAIN", "Init settings manager");
  928. SettingsManager.Initialize();
  929. U.L(LogLevel.Debug, "MAIN", "Init service manager");
  930. ServiceManager.Initialize();
  931. // create playlists
  932. ThreadStart PlaylistThread = delegate()
  933. {
  934. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  935. {
  936. if (SettingsManager.CurrentSelectedNavigation == "YouTube")
  937. NavigationPane.Youtube.Focus();
  938. else if (SettingsManager.CurrentSelectedNavigation == "Queue")
  939. NavigationPane.Queue.Focus();
  940. else if (SettingsManager.CurrentSelectedNavigation == "History")
  941. NavigationPane.History.Focus();
  942. else if (!SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  943. NavigationPane.Files.Focus();
  944. // create playlists
  945. PlaylistManager.Initialize();
  946. foreach (PlaylistData playlist in SettingsManager.Playlists)
  947. CreatePlaylist(playlist, false);
  948. PlaylistManager.PlaylistModified += new ModifiedEventHandler(PlaylistManager_PlaylistModified);
  949. PlaylistManager.PlaylistRenamed += new RenamedEventHandler(PlaylistManager_PlaylistRenamed);
  950. // if csn == playlist: select
  951. if (SettingsManager.CurrentSelectedNavigation.StartsWith("Playlist:"))
  952. {
  953. string name = SettingsManager.CurrentSelectedNavigation.Split(new[] { ':' }, 2)[1];
  954. foreach (TreeViewItem tvi in NavigationPane.Playlists.Items)
  955. {
  956. if ((string)tvi.Tag == name)
  957. {
  958. tvi.Focus();
  959. break;
  960. }
  961. }
  962. }
  963. }));
  964. };
  965. ThreadStart GUIThread = delegate()
  966. {
  967. // init media manager
  968. ThreadStart MediaManagerThread = delegate()
  969. {
  970. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  971. {
  972. MediaManager.Initialize(new WindowInteropHelper(this).Handle);
  973. MediaManager.Browser = NowPlayingContainer.Browser;
  974. // load the track collection
  975. if (SettingsManager.CurrentActiveNavigation == "Queue")
  976. MediaManager.TrackCollection = QueueTracks.Items;
  977. else if (SettingsManager.CurrentActiveNavigation == "History")
  978. MediaManager.TrackCollection = HistoryTracks.Items;
  979. else if (SettingsManager.CurrentActiveNavigation == "YouTube")
  980. MediaManager.TrackCollection = YouTubeContainer.YouTubeTracks.Items;
  981. else if (SettingsManager.CurrentActiveNavigation.StartsWith("Playlist:"))
  982. {
  983. string pname = SettingsManager.CurrentActiveNavigation.Split(new[] { ':' }, 2)[1];
  984. ViewDetails p = (ViewDetails)PlaylistTrackLists[pname];
  985. if (p == null)
  986. MediaManager.TrackCollection = FileTracks.Items;
  987. else
  988. MediaManager.TrackCollection = p.Items;
  989. }
  990. else
  991. MediaManager.TrackCollection = FileTracks.Items;
  992. // check if we have any command line arguments
  993. String[] arguments = Environment.GetCommandLineArgs();
  994. if (arguments.Length > 1)
  995. {
  996. if (arguments[1] == "/play") MediaManager.Play();
  997. else if (arguments[1] == "/pause") MediaManager.Pause();
  998. else if (arguments[1] == "/stop") MediaManager.Stop();
  999. else if (arguments[1] == "/next") MediaManager.Next();
  1000. else if (arguments[1] == "/previous") MediaManager.Previous();
  1001. else if (File.Exists(arguments[1]) && MediaManager.IsSupported(arguments[1]))
  1002. {
  1003. Open(arguments[1], true);
  1004. }
  1005. }
  1006. }));
  1007. };
  1008. // init upgrade manager
  1009. ThreadStart UpgradeManagerThread = delegate()
  1010. {
  1011. UpgradeManager.Initialize(new TimeSpan(0, 60, 0));
  1012. UpgradeManager.Probe(null, null);
  1013. };
  1014. // init filesystem manager
  1015. ThreadStart FilesystemManagerThread = delegate()
  1016. {
  1017. FilesystemManager.Initialize();
  1018. if (SettingsManager.FirstRun)
  1019. {
  1020. FilesystemManager.ScanLibraries(true, false);
  1021. if (SettingsManager.Sources.Count == 0)
  1022. {
  1023. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  1024. {
  1025. Welcome dialog = new Welcome();
  1026. dialog.ShowDialog();
  1027. FilesystemManager.ScanSources();
  1028. }));
  1029. }
  1030. SettingsManager.FirstRun = false;
  1031. }
  1032. else
  1033. FilesystemManager.ScanLibraries(true);
  1034. };
  1035. // calculate play time
  1036. ThreadStart PTThread = delegate()
  1037. {
  1038. LibraryTime = 0;
  1039. QueueTime = 0;
  1040. HistoryTime = 0;
  1041. if (SettingsManager.FileTracks != null)
  1042. foreach (TrackData track in SettingsManager.FileTracks)
  1043. LibraryTime += track.RawLength;
  1044. if (SettingsManager.QueueTracks != null)
  1045. foreach (TrackData track in SettingsManager.QueueTracks)
  1046. QueueTime += track.RawLength;
  1047. if (SettingsManager.HistoryTracks != null)
  1048. foreach (TrackData track in SettingsManager.HistoryTracks)
  1049. HistoryTime += track.RawLength;
  1050. };
  1051. Thread mm_thread = new Thread(MediaManagerThread);
  1052. Thread um_thread = new Thread(UpgradeManagerThread);
  1053. Thread fm_thread = new Thread(FilesystemManagerThread);
  1054. Thread pt_thread = new Thread(PTThread);
  1055. mm_thread.Name = "Init Media Manager";
  1056. um_thread.Name = "Init Upgrade Manager";
  1057. fm_thread.Name = "Init Filesystem Manager";
  1058. pt_thread.Name = "Playing Time Thread";
  1059. mm_thread.Priority = ThreadPriority.BelowNormal;
  1060. um_thread.Priority = ThreadPriority.BelowNormal;
  1061. fm_thread.Priority = ThreadPriority.BelowNormal;
  1062. pt_thread.Priority = ThreadPriority.BelowNormal;
  1063. mm_thread.Start();
  1064. um_thread.Start();
  1065. fm_thread.Start();
  1066. pt_thread.Start();
  1067. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  1068. {
  1069. FileTracks.Config = SettingsManager.FileListConfig;
  1070. HistoryTracks.Config = SettingsManager.HistoryListConfig;
  1071. QueueTracks.Config = SettingsManager.QueueListConfig;
  1072. ControlPanel.SourceList.Config = SettingsManager.SourceListConfig;
  1073. YouTubeContainer.YouTubeTracks.Config = SettingsManager.YouTubeListConfig;
  1074. FileTracks.ItemsSource = SettingsManager.FileTracks;
  1075. QueueTracks.ItemsSource = SettingsManager.QueueTracks;
  1076. HistoryTracks.ItemsSource = SettingsManager.HistoryTracks;
  1077. ControlPanel.SourceList.ItemsSource = SettingsManager.Sources;
  1078. YouTubeContainer.Search(SettingsManager.YouTubeListConfig.Filter);
  1079. }));
  1080. SettingsManager.FileTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(FileTracks.ItemsSource_CollectionChanged);
  1081. SettingsManager.QueueTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(QueueTracks.ItemsSource_CollectionChanged);
  1082. SettingsManager.HistoryTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(HistoryTracks.ItemsSource_CollectionChanged);
  1083. SettingsManager.QueueTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(QueueTracks_CollectionChanged);
  1084. SettingsManager.HistoryTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(HistoryTracks_CollectionChanged);
  1085. SettingsManager.FileTracks.CollectionChanged += new NotifyCollectionChangedEventHandler(LibraryTracks_CollectionChanged);
  1086. jumpTaskPlay = new JumpTask()
  1087. {
  1088. Title = U.T("JumpPlay", "Title"),
  1089. Arguments = "/play",
  1090. Description = U.T("JumpPlay", "Description"),
  1091. IconResourceIndex = -1,
  1092. ApplicationPath = Assembly.GetEntryAssembly().CodeBase,
  1093. };
  1094. jumpTaskNext = new JumpTask()
  1095. {
  1096. Title = U.T("JumpNext", "Title"),
  1097. Arguments = "/next",
  1098. Description = U.T("JumpNext", "Description"),
  1099. IconResourceIndex = -1,
  1100. ApplicationPath = Assembly.GetEntryAssembly().CodeBase,
  1101. };
  1102. jumpTaskPrev = new JumpTask()
  1103. {
  1104. Title = U.T("JumpPrev", "Title"),
  1105. Arguments = "/previous",
  1106. Description = U.T("JumpPrev", "Description"),
  1107. IconResourceIndex = -1,
  1108. ApplicationPath = Assembly.GetEntryAssembly().CodeBase,
  1109. };
  1110. jumpList = new JumpList();
  1111. jumpList.JumpItems.Add(jumpTaskPlay);
  1112. jumpList.JumpItems.Add(jumpTaskNext);
  1113. jumpList.JumpItems.Add(jumpTaskPrev);
  1114. jumpList.ShowRecentCategory = true;
  1115. jumpList.ShowFrequentCategory = true;
  1116. Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate()
  1117. {
  1118. PlaybackControls.VolumeSlide.Value = SettingsManager.Volume;
  1119. NavigationColumn.Width = new GridLength(SettingsManager.NavigationPaneWidth);
  1120. double h = SettingsManager.DetailsPaneHeight;
  1121. DetailsRow.Height = new GridLength(h);
  1122. UpdateVisibility("menubar");
  1123. UpdateVisibility("details");
  1124. ControlPanel.InitShortcuts();
  1125. JumpList.SetJumpList(Application.Current, jumpList);
  1126. UpdateGUIStrings();
  1127. }));
  1128. };
  1129. Thread pl_thread = new Thread(PlaylistThread);
  1130. Thread gui_thread = new Thread(GUIThread);
  1131. pl_thread.Name = "Init Playlist Manager";
  1132. gui_thread.Name = "Init managers and GUI";
  1133. pl_thread.Priority = ThreadPriority.BelowNormal;
  1134. gui_thread.Priority = ThreadPriority.BelowNormal;
  1135. pl_thread.Start();
  1136. gui_thread.Start();
  1137. }
  1138. #endregion
  1139. #region Event handlers
  1140. /// <summary>
  1141. ///
  1142. /// </summary>
  1143. /// <param name="sender"></param>
  1144. /// <param name="e"></param>
  1145. private void Window_Loaded(object sender, RoutedEventArgs e)
  1146. {
  1147. U.L(LogLevel.Debug, "MAIN", "Loaded");
  1148. System.Windows.Forms.Application.EnableVisualStyles();
  1149. WindowState = (WindowState)Enum.Parse(typeof(WindowState), SettingsManager.WinState);
  1150. kListener.KeyDown += new RawKeyEventHandler(KListener_KeyDown);
  1151. kListener.KeyUp += new RawKeyEventHandler(KListener_KeyUp);
  1152. addMenu = new ContextMenu();
  1153. showMenu = new ContextMenu();
  1154. toolsMenu = new ContextMenu();
  1155. addMenuFile = new MenuItem();
  1156. addMenuFile.Header = U.T("ToolbarAddTrack");
  1157. addMenuFile.Click += AddFile_Clicked;
  1158. addMenuFolder = new MenuItem();
  1159. addMenuFolder.Header = U.T("ToolbarAddFolder");
  1160. addMenuFolder.Click += AddFolder_Clicked;
  1161. addMenuPlaylist = new MenuItem();
  1162. addMenuPlaylist.Header = U.T("ToolbarAddPlaylist");
  1163. addMenuPlaylist.Click += OpenPlaylist_Clicked;
  1164. showMenuDetailsPane = new MenuItem();
  1165. showMenuDetailsPane.Header = U.T("ToolbarDetailsPane");
  1166. showMenuDetailsPane.IsCheckable = true;
  1167. showMenuDetailsPane.Click += ToggleDetailsPane;
  1168. showMenuMenuBar = new MenuItem();
  1169. showMenuMenuBar.Header = U.T("ToolbarMenuBar");
  1170. showMenuMenuBar.IsCheckable = true;
  1171. showMenuMenuBar.Click += ToggleMenuBar;
  1172. toolsMenuImporter = new MenuItem();
  1173. toolsMenuImporter.Header = U.T("ToolbarImporter");
  1174. toolsMenuImporter.Click += Importer_Clicked;
  1175. toolsMenuExporter = new MenuItem();
  1176. toolsMenuExporter.Header = U.T("ToolbarExporter");
  1177. toolsMenuExporter.Click += Exporter_Clicked;
  1178. toolsMenuGenerate = new MenuItem();
  1179. toolsMenuGenerate.Header = U.T("ToolbarGeneratePlaylist");
  1180. toolsMenuGenerate.Click += GeneratePlaylist_Clicked;
  1181. addMenu.Items.Add(addMenuFile);
  1182. addMenu.Items.Add(addMenuFolder);
  1183. addMenu.Items.Add(addMenuPlaylist);
  1184. showMenu.Items.Add(showMenuMenuBar);
  1185. showMenu.Items.Add(showMenuDetailsPane);
  1186. toolsMenu.Items.Add(toolsMenuImporter);
  1187. toolsMenu.Items.Add(toolsMenuExporter);
  1188. toolsMenu.Items.Add(toolsMenuGenerate);
  1189. addMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
  1190. showMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
  1191. toolsMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
  1192. listMenuAddToPlaylist.Header = U.T("MenuAddToPlaylist", "Header");
  1193. listMenuDelete.Header = U.T("MenuDelete");
  1194. listMenuDelete.Click += new RoutedEventHandler(listMenuDelete_Click);
  1195. listMenuInfo.Header = U.T("MenuInfo");
  1196. listMenuInfo.Click += new RoutedEventHandler(listMenuInfo_Click);
  1197. listMenuPlay.Header = U.T("MenuPlay");
  1198. listMenuPlay.Click += new RoutedEventHandler(listMenuPlay_Click);
  1199. listMenuWatchOnYouTube.Header = U.T("MenuWatchOnYouTube");
  1200. listMenuWatchOnYouTube.Click += new RoutedEventHandler(listMenuWatchOnYouTube_Click);
  1201. listMenuQueue.Header = U.T("MenuQueue");
  1202. listMenuQueue.Click += new RoutedEventHandler(listMenuQueue_Click);
  1203. listMenuRemove.Header = U.T("MenuRemove");
  1204. listMenuRemove.Click += new RoutedEventHandler(listMenuRemove_Click);
  1205. listMenuRemoveFromPlaylist.Header = U.T("MenuRemoveFromPlaylist", "Header");
  1206. listMenuRemoveFromPlaylist.Visibility = System.Windows.Visibility.Collapsed;
  1207. listMenuAddToNew = new MenuItem();
  1208. listMenuAddToNew.Header = U.T("MenuCreateNew", "Header");
  1209. listMenuAddToNew.FontStyle = FontStyles.Italic;
  1210. listMenuAddToNew.Click += new RoutedEventHandler(listMenuAddToPlaylist_Click);
  1211. listMenuAddToPlaylist.Items.Add(listMenuAddToNew);
  1212. listMenu.Items.Add(listMenuPlay);
  1213. listMenu.Items.Add(listMenuQueue);
  1214. listMenu.Items.Add(new Separator());
  1215. listMenu.Items.Add(listMenuAddToPlaylist);
  1216. listMenu.Items.Add(listMenuRemoveFromPlaylist);
  1217. listMenu.Items.Add(listMenuRemove);
  1218. listMenu.Items.Add(listMenuDelete);
  1219. listMenu.Items.Add(new Separator());
  1220. listMenu.Items.Add(listMenuWatchOnYouTube);
  1221. listMenu.Items.Add(listMenuInfo);
  1222. PlaylistTrackLists = new Hashtable();
  1223. //// TODO: remove all these lines
  1224. ////FileTracks.ParentWindow = this;
  1225. ////QueueTracks.ParentWindow = this;
  1226. ////HistoryTracks.ParentWindow = this;
  1227. ControlPanel.ParentWindow = this;
  1228. NavigationPane.ParentWindow = this;
  1229. PlaybackControls.ParentWindow = this;
  1230. FileTracks.ContextMenu = listMenu;
  1231. HistoryTracks.ContextMenu = listMenu;
  1232. QueueTracks.ContextMenu = listMenu;
  1233. YouTubeContainer.YouTubeTracks.ContextMenu = listMenu;
  1234. YouTubeContainer.YouTubeTracks.MouseDoubleClick += new MouseButtonEventHandler(TrackList_MouseDoubleClick);
  1235. YouTubeContainer.YouTubeTracks.SelectionChanged += new SelectionChangedEventHandler(TrackList_SelectionChanged);
  1236. YouTubeContainer.YouTubeTracks.ContextMenuOpening += new ContextMenuEventHandler(TrackList_ContextMenuOpening);
  1237. YouTubeContainer.YouTubeTracks.MoveItem += new MoveItemEventHandler(TrackList_MoveItem);
  1238. sourceModifiedDelay.Tick += new EventHandler(SourceModifiedDelay_Tick);
  1239. sourceModifiedDelay.Interval = new TimeSpan(0, 0, 0, 1, 500);
  1240. SettingsManager.PropertyChanged += new PropertyChangedWithValuesEventHandler(SettingsManager_PropertyChanged);
  1241. NavigationPane.CreateNewPlaylistETB.EnteredEditMode += new EventHandler(EditableTextBlock_EnteredEditMode);
  1242. U.ListenForShortcut = true;
  1243. SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
  1244. String defaultAlbumArt = "/GUI/Images/AlbumArt/Default.jpg";
  1245. //// rough detection of aero vs classic
  1246. //// you'll se a lot more of these around the code
  1247. if (System.Windows.Forms.VisualStyles.VisualStyl