PageRenderTime 96ms CodeModel.GetById 20ms app.highlight 65ms RepoModel.GetById 1ms app.codeStats 1ms

/Settings Migrator/Migrator.cs

http://yet-another-music-application.googlecode.com/
C# | 1543 lines | 875 code | 258 blank | 410 comment | 258 complexity | 2faef0fe08d404b4c5efcb7ecc9b5cc4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/**
   2 * Migrator.cs
   3 * 
   4 * Creates a modified version of a settings file for migration
   5 * between two versions of Stoffi Music Player.
   6 * 
   7 * * * * * * * * *
   8 * 
   9 * Copyright 2012 Simplare
  10 * 
  11 * This code is part of the Stoffi Music Player Project.
  12 * Visit our website at: stoffiplayer.com
  13 *
  14 * This program is free software; you can redistribute it and/or
  15 * modify it under the terms of the GNU General Public License
  16 * as published by the Free Software Foundation; either version
  17 * 3 of the License, or (at your option) any later version.
  18 * 
  19 * See stoffiplayer.com/license for more information.
  20 **/
  21
  22using System;
  23using System.Collections.Generic;
  24using System.Collections.Specialized;
  25using System.Collections.ObjectModel;
  26using System.Globalization;
  27using System.IO;
  28using System.Linq;
  29using System.Text;
  30using System.Xml;
  31using System.Xml.Serialization;
  32
  33namespace Stoffi
  34{
  35    /// <summary>
  36    /// Migrates settings between two versions of Stoffi.
  37    /// </summary>
  38    public class SettingsMigrator : IMigrator
  39    {
  40        #region Members
  41
  42        private Utility utility;
  43
  44        #endregion
  45
  46        #region Methods
  47
  48        #region Public
  49
  50        /// <summary>
  51        /// Migrates a settings file.
  52        /// </summary>
  53        /// <param name="fromFile">The original file</param>
  54        /// <param name="toFile">The output file</param>
  55        public void Migrate(String fromFile, String toFile)
  56        {
  57			utility = new Utility();
  58			utility.LogFile = "migrator.log";
  59			utility.Mode = LogMode.Debug;
  60
  61			NewSettings settings = new NewSettings();
  62
  63			utility.LogMessageToFile(LogMode.Information, "Reading configuration");
  64			ReadConfig(settings, fromFile);
  65
  66			utility.LogMessageToFile(LogMode.Information, "Modifying configuration");
  67
  68			foreach (SourceData source in settings.Sources)
  69				FixSource(source);
  70
  71			utility.LogMessageToFile(LogMode.Information, "Writing configuration");
  72			WriteConfig(settings, toFile);
  73		}
  74
  75        #endregion
  76
  77        #region Private
  78
  79		private void FixSource(SourceData item)
  80		{
  81			item.Icon = item.Icon.Replace(
  82				"pack://application:,,,/GUI/Images/Icons/",
  83				"pack://application:,,,/Platform/Windows 7/GUI/Images/Icons/"
  84			);
  85		}
  86
  87		private KeyboardShortcut GetKeyboardShortcut(KeyboardShortcutProfile profile, String keysAsText)
  88		{
  89			foreach (KeyboardShortcut s in profile.Shortcuts)
  90				if (s.Keys == keysAsText)
  91					return s;
  92			return null;
  93		}
  94
  95		private KeyboardShortcut GetKeyboardShortcut(KeyboardShortcutProfile profile, String category, String name)
  96		{
  97			foreach (KeyboardShortcut s in profile.Shortcuts)
  98				if (s.Name == name && s.Category == category)
  99					return s;
 100			return null;
 101		}
 102
 103		private void SetKeyboardShortcut(KeyboardShortcut sc, String keysAsText, String isGlobal = "false")
 104		{
 105			sc.Keys = keysAsText;
 106			sc.IsGlobal = isGlobal;
 107		}
 108
 109		private void SetKeyboardShortcut(KeyboardShortcutProfile profile, String category, String name, String keysAsText, String isGlobal = "false")
 110		{
 111			KeyboardShortcut sc = GetKeyboardShortcut(profile, category, name);
 112			if (sc == null)
 113			{
 114				sc = new KeyboardShortcut();
 115				sc.Category = category;
 116				sc.Name = name;
 117				profile.Shortcuts.Add(sc);
 118			}
 119			SetKeyboardShortcut(sc, keysAsText, isGlobal);
 120		}
 121
 122		private void InitShortcutProfile(KeyboardShortcutProfile profile, String name, String isprotected)
 123		{
 124			profile.Name = name;
 125			profile.IsProtected = isprotected;
 126			profile.Shortcuts = new List<KeyboardShortcut>();
 127
 128			// set the default shortcuts
 129			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Add track", IsGlobal = "false", Keys = "Ctrl+T" });
 130			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Add folder", IsGlobal = "false", Keys = "Ctrl+F" });
 131			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Open playlist", IsGlobal = "false", Keys = "Ctrl+O" });
 132			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Minimize", IsGlobal = "false", Keys = "Ctrl+M" });
 133			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Restore", IsGlobal = "true", Keys = "Ctrl+Shift+R" });
 134			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Help", IsGlobal = "false", Keys = "F1" });
 135			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Application", Name = "Close", IsGlobal = "false", Keys = "Ctrl+W" });
 136			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Library", IsGlobal = "false", Keys = "Alt+L" });
 137			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Queue", IsGlobal = "false", Keys = "Alt+Q" });
 138			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "History", IsGlobal = "false", Keys = "Alt+H" });
 139			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Playlists", IsGlobal = "false", Keys = "Alt+P" });
 140			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Now playing", IsGlobal = "false", Keys = "Alt+W" });
 141			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Tracklist", IsGlobal = "false", Keys = "Alt+T" });
 142			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Search", IsGlobal = "false", Keys = "Alt+F" });
 143			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "General preferences", IsGlobal = "false", Keys = "Alt+G" });
 144			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Services", IsGlobal = "false", Keys = "Alt+V" });
 145			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Library sources", IsGlobal = "false", Keys = "Alt+S" });
 146			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Keyboard shortcuts", IsGlobal = "false", Keys = "Alt+K" });
 147			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "About", IsGlobal = "false", Keys = "Alt+A" });
 148			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Toggle details pane", IsGlobal = "false", Keys = "Alt+D" });
 149			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Toggle menu bar", IsGlobal = "false", Keys = "Alt+M" });
 150			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MainWindow", Name = "Create playlist", IsGlobal = "false", Keys = "Alt+N" });
 151			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Play or pause", IsGlobal = "false", Keys = "Alt+5 (numpad)" });
 152			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Next", IsGlobal = "false", Keys = "Alt+6 (numpad)" });
 153			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Previous", IsGlobal = "false", Keys = "Alt+4 (numpad)" });
 154			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Toggle shuffle", IsGlobal = "false", Keys = "Alt+7 (numpad)" });
 155			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Toggle repeat", IsGlobal = "false", Keys = "Alt+9 (numpad)" });
 156			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Increase volume", IsGlobal = "false", Keys = "Alt+8 (numpad)" });
 157			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Decrease volume", IsGlobal = "false", Keys = "Alt+2 (numpad)" });
 158			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Seek forward", IsGlobal = "false", Keys = "Alt+3 (numpad)" });
 159			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Seek backward", IsGlobal = "false", Keys = "Alt+1 (numpad)" });
 160			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Add bookmark", IsGlobal = "false", Keys = "Alt+B" });
 161			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to previous bookmark", IsGlobal = "false", Keys = "Alt+Left" });
 162			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to next bookmark", IsGlobal = "false", Keys = "Alt+Right" });
 163			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to first bookmark", IsGlobal = "false", Keys = "Alt+Home" });
 164			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to last bookmark", IsGlobal = "false", Keys = "Alt+End" });
 165			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 1", IsGlobal = "false", Keys = "Alt+1" });
 166			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 2", IsGlobal = "false", Keys = "Alt+2" });
 167			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 3", IsGlobal = "false", Keys = "Alt+3" });
 168			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 4", IsGlobal = "false", Keys = "Alt+4" });
 169			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 5", IsGlobal = "false", Keys = "Alt+5" });
 170			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 6", IsGlobal = "false", Keys = "Alt+6" });
 171			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 7", IsGlobal = "false", Keys = "Alt+7" });
 172			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 8", IsGlobal = "false", Keys = "Alt+8" });
 173			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 9", IsGlobal = "false", Keys = "Alt+9" });
 174			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to bookmark 10", IsGlobal = "false", Keys = "Alt+0" });
 175			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to current track", IsGlobal = "false", Keys = "Alt+C" });
 176			profile.Shortcuts.Add(new KeyboardShortcut { Category = "MediaCommands", Name = "Jump to selected track", IsGlobal = "false", Keys = "Alt+X" });
 177			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Track", Name = "Queue and dequeue", IsGlobal = "false", Keys = "Shift+Q" });
 178			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Track", Name = "Remove track", IsGlobal = "false", Keys = "Delete" });
 179			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Track", Name = "Play track", IsGlobal = "false", Keys = "Enter" });
 180			profile.Shortcuts.Add(new KeyboardShortcut { Category = "Track", Name = "View information", IsGlobal = "false", Keys = "Shift+I" });
 181		}
 182
 183		/// <summary>
 184		/// Creates a ViewDetailsConfig with default values
 185		/// </summary>
 186		/// <returns>The newly created config</returns>
 187		public static ViewDetailsConfig CreateListConfig()
 188		{
 189			Stoffi.ViewDetailsConfig config = new Stoffi.ViewDetailsConfig();
 190			config.HasNumber = true;
 191			config.IsNumberVisible = false;
 192			config.Filter = "";
 193			config.IsClickSortable = true;
 194			config.IsDragSortable = true;
 195			config.LockSortOnNumber = false;
 196			config.SelectedIndices = new List<int>();
 197			config.UseIcons = true;
 198			config.AcceptFileDrops = true;
 199			config.Columns = new ObservableCollection<Stoffi.ViewDetailsColumn>();
 200			config.NumberColumn = CreateListColumn("#", "#", "Number", "Number", 60, "Right", false);
 201			return config;
 202		}
 203
 204		/// <summary>
 205		/// Creates a ViewDetailsColumn
 206		/// </summary>
 207		/// <param name="name">The name of the column</param>
 208		/// <param name="text">The displayed text</param>
 209		/// <param name="binding">The value to bind to</param>
 210		/// <param name="width">The width</param>
 211		/// <param name="isVisible">Whether the column is visible</param>
 212		/// <param name="alignment">The alignment of the text</param>
 213		/// <param name="isAlwaysVisible">Whether the column is always visible</param>
 214		/// <param name="isSortable">Whether the column is sortable</param>
 215		/// <returns>The newly created column</returns>
 216		public static ViewDetailsColumn CreateListColumn(string name, string text, string binding, int width,
 217														 string alignment = "Left",
 218														 bool isVisible = true,
 219														 bool isAlwaysVisible = false,
 220														 bool isSortable = true)
 221		{
 222
 223			ViewDetailsColumn column = new ViewDetailsColumn();
 224			column.Name = name;
 225			column.Text = text;
 226			column.Binding = binding;
 227			column.Width = width;
 228			column.Alignment = alignment;
 229			column.IsAlwaysVisible = isAlwaysVisible;
 230			column.IsSortable = isSortable;
 231			column.IsVisible = isVisible;
 232			column.SortField = binding;
 233			return column;
 234		}
 235
 236		/// <summary>
 237		/// Creates a ViewDetailsColumn
 238		/// </summary>
 239		/// <param name="name">The name of the column</param>
 240		/// <param name="text">The displayed text</param>
 241		/// <param name="binding">The value to bind to</param>
 242		/// <param name="sortField">The column to sort on</param>
 243		/// <param name="width">The width</param>
 244		/// <param name="isVisible">Whether the column is visible</param>
 245		/// <param name="alignment">The alignment of the text</param>
 246		/// <param name="isAlwaysVisible">Whether the column is always visible</param>
 247		/// <param name="isSortable">Whether the column is sortable</param>
 248		/// <returns>The newly created column</returns>
 249		public static ViewDetailsColumn CreateListColumn(string name, string text, string binding, string sortField, int width,
 250														 string alignment = "Left",
 251														 bool isVisible = true,
 252														 bool isAlwaysVisible = false,
 253														 bool isSortable = true)
 254		{
 255
 256			ViewDetailsColumn column = new ViewDetailsColumn();
 257			column.Name = name;
 258			column.Text = text;
 259			column.Binding = binding;
 260			column.Width = width;
 261			column.Alignment = alignment;
 262			column.IsAlwaysVisible = isAlwaysVisible;
 263			column.IsSortable = isSortable;
 264			column.IsVisible = isVisible;
 265			column.SortField = sortField;
 266			return column;
 267		}
 268
 269
 270		private void ReadConfig(NewSettings settings, String file)
 271		{
 272			utility.LogMessageToFile(LogMode.Debug, "Reading config");
 273			if (File.Exists(file) == false)
 274			{
 275				utility.LogMessageToFile(LogMode.Error, "Could not find data file " + file);
 276				return;
 277			}
 278
 279
 280			XmlTextReader xmlReader = new XmlTextReader(file);
 281			xmlReader.WhitespaceHandling = WhitespaceHandling.None;
 282			xmlReader.Read();
 283
 284			while (xmlReader.Read())
 285			{
 286				if (xmlReader.NodeType == XmlNodeType.Element)
 287				{
 288					if (xmlReader.Name == "setting")
 289					{
 290						String name = "";
 291						for (int i = 0; i < xmlReader.AttributeCount; xmlReader.MoveToAttribute(i), i++)
 292							if (xmlReader.Name == "name") name = xmlReader.Value;
 293
 294						xmlReader.Read();
 295						if (!xmlReader.IsEmptyElement)
 296							xmlReader.Read();
 297
 298						utility.LogMessageToFile(LogMode.Debug, "Parsing attribute '" + name + "'");
 299
 300						if (name == "WinHeight")
 301							settings.WinHeight = xmlReader.Value;
 302
 303						else if (name == "WinWidth")
 304							settings.WinWidth = xmlReader.Value;
 305
 306						else if (name == "WinTop")
 307							settings.WinTop = xmlReader.Value;
 308
 309						else if (name == "WinLeft")
 310							settings.WinLeft = xmlReader.Value;
 311
 312						else if (name == "WinState")
 313							settings.WinState = xmlReader.Value;
 314
 315						else if (name == "EqualizerHeight")
 316							settings.EqualizerHeight = xmlReader.Value;
 317
 318						else if (name == "EqualizerWidth")
 319							settings.EqualizerWidth = xmlReader.Value;
 320
 321						else if (name == "EqualizerTop")
 322							settings.EqualizerTop = xmlReader.Value;
 323
 324						else if (name == "EqualizerLeft")
 325							settings.EqualizerLeft = xmlReader.Value;
 326
 327						else if (name == "MediaState")
 328							settings.MediaState = xmlReader.Value;
 329
 330						else if (name == "Language")
 331							settings.Language = xmlReader.Value;
 332
 333						else if (name == "NavigationPaneWidth")
 334							settings.NavigationPaneWidth = xmlReader.Value;
 335
 336						else if (name == "DetailsPaneHeight")
 337							settings.DetailsPaneHeight = xmlReader.Value;
 338
 339						else if (name == "Repeat")
 340							settings.Repeat = xmlReader.Value;
 341
 342						else if (name == "Shuffle")
 343							settings.Shuffle = xmlReader.Value;
 344
 345						else if (name == "Volume")
 346							settings.Volume = xmlReader.Value;
 347
 348						else if (name == "EqualizerProfiles")
 349							settings.EqualizerProfiles = ReadSetting<List<EqualizerProfile>>(xmlReader);
 350
 351						else if (name == "CurrentEqualizerProfile")
 352							settings.CurrentEqualizerProfile = ReadSetting<EqualizerProfile>(xmlReader);
 353
 354						else if (name == "Seek")
 355							settings.Seek = xmlReader.Value;
 356
 357						else if (name == "CurrentTrack")
 358							settings.CurrentTrack = ReadSetting<TrackData>(xmlReader);
 359
 360						else if (name == "HistoryIndex")
 361							settings.HistoryIndex = xmlReader.Value;
 362
 363						else if (name == "CurrentSelectedNavigation")
 364							settings.CurrentSelectedNavigation = xmlReader.Value;
 365
 366						else if (name == "CurrentActiveNavigation")
 367							settings.CurrentActiveNavigation = xmlReader.Value;
 368
 369						else if (name == "CurrentVisualizer")
 370							settings.CurrentVisualizer = xmlReader.Value;
 371
 372						else if (name == "MenuBarVisibility" || name == "MenuBarVisible")
 373							settings.MenuBarVisible = xmlReader.Value;
 374
 375						else if (name == "DetailsPaneVisibility" || name == "DetailsPaneVisible")
 376							settings.DetailsPaneVisible = xmlReader.Value;
 377
 378						else if (name == "FirstRun")
 379							settings.FirstRun = xmlReader.Value;
 380
 381						else if (name == "PluginSettings")
 382							settings.PluginSettings = ReadSetting<List<PluginSettings>>(xmlReader);
 383
 384						else if (name == "PluginListConfig")
 385							settings.PluginListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 386
 387						else if (name == "Sources")
 388							settings.Sources = ReadSetting<List<SourceData>>(xmlReader);
 389
 390						else if (name == "SourceListConfig")
 391							settings.SourceListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 392
 393						else if (name == "LibraryListConfig")
 394							settings.LibraryListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 395
 396						else if (name == "RadioListConfig")
 397							settings.RadioListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 398
 399						else if (name == "DiscListConfig")
 400							settings.DiscListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 401
 402						else if (name == "HistoryListConfig")
 403							settings.HistoryListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 404
 405						else if (name == "QueueListConfig")
 406							settings.QueueListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 407
 408						else if (name == "YouTubeListConfig")
 409							settings.YouTubeListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 410
 411						else if (name == "SoundCloudListConfig")
 412							settings.SoundCloudListConfig = ReadSetting<ViewDetailsConfig>(xmlReader);
 413
 414						else if (name == "LibraryTracks")
 415							settings.LibraryTracks = ReadSetting<List<TrackData>>(xmlReader);
 416
 417						else if (name == "RadioTracks")
 418							settings.RadioTracks = ReadSetting<List<TrackData>>(xmlReader);
 419
 420						else if (name == "HistoryTracks")
 421							settings.HistoryTracks = ReadSetting<List<TrackData>>(xmlReader);
 422
 423						else if (name == "QueueTracks")
 424							settings.QueueTracks = ReadSetting<List<TrackData>>(xmlReader);
 425
 426						else if (name == "Playlists")
 427							settings.Playlists = ReadSetting<List<PlaylistData>>(xmlReader);
 428
 429						else if (name == "OpenAddPolicy")
 430							settings.OpenAddPolicy = xmlReader.Value;
 431
 432						else if (name == "OpenPlayPolicy")
 433							settings.OpenPlayPolicy = xmlReader.Value;
 434
 435						else if (name == "UpgradePolicy")
 436							settings.UpgradePolicy = xmlReader.Value;
 437
 438						else if (name == "SearchPolicy")
 439							settings.SearchPolicy = xmlReader.Value;
 440
 441						else if (name == "ShowOSD")
 442							settings.ShowOSD = xmlReader.Value;
 443
 444						else if (name == "MinimizeToTray")
 445							settings.MinimizeToTray = xmlReader.Value;
 446
 447						else if (name == "ID")
 448							settings.ID = xmlReader.Value;
 449
 450						else if (name == "UpgradeCheck")
 451							settings.UpgradeCheck = xmlReader.Value;
 452
 453						else if (name == "ShortcutProfiles")
 454							settings.ShortcutProfiles = ReadSetting<List<KeyboardShortcutProfile>>(xmlReader);
 455
 456						else if (name == "OAuthToken")
 457							settings.OAuthToken = xmlReader.Value;
 458
 459						else if (name == "OAuthSecret")
 460							settings.OAuthSecret = xmlReader.Value;
 461
 462						else if (name == "SubmitSongs")
 463							settings.SubmitSongs = xmlReader.Value;
 464
 465						else if (name == "SubmitPlaylists")
 466							settings.SubmitPlaylists = xmlReader.Value;
 467
 468						else if (name == "PauseWhenLocked" || name == "PauseWhileLocked")
 469							settings.PauseWhenLocked = xmlReader.Value;
 470
 471						else if (name == "PauseWhenSongEnds")
 472							settings.PauseWhenSongEnds = xmlReader.Value;
 473
 474						else if (name == "CloudIdentities")
 475							settings.CloudIdentities = ReadSetting<List<CloudIdentity>>(xmlReader);
 476
 477						utility.LogMessageToFile(LogMode.Debug, "Done");
 478					}
 479				}
 480			}
 481
 482			xmlReader.Close();
 483		}
 484
 485		private void WriteConfig(NewSettings settings, String file)
 486		{
 487			utility.LogMessageToFile(LogMode.Debug, "Writing config");
 488			XmlTextWriter xmlWriter = new XmlTextWriter(file, Encoding.UTF8);
 489			xmlWriter.WriteStartDocument();
 490			xmlWriter.WriteWhitespace("\n");
 491			xmlWriter.WriteStartElement("configuration");
 492			xmlWriter.WriteWhitespace("\n    ");
 493
 494			xmlWriter.WriteStartElement("configSections");
 495			xmlWriter.WriteWhitespace("\n        ");
 496			xmlWriter.WriteStartElement("sectionGroup");
 497			xmlWriter.WriteStartAttribute("name");
 498			xmlWriter.WriteString("userSettings");
 499			xmlWriter.WriteEndAttribute();
 500
 501			xmlWriter.WriteWhitespace("\n            ");
 502			xmlWriter.WriteStartElement("section");
 503			xmlWriter.WriteStartAttribute("name");
 504			xmlWriter.WriteString("Stoffi.Properties.Settings");
 505			xmlWriter.WriteEndAttribute();
 506			xmlWriter.WriteStartAttribute("type");
 507			xmlWriter.WriteString("System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
 508			xmlWriter.WriteEndAttribute();
 509			xmlWriter.WriteStartAttribute("allowExeDefinition");
 510			xmlWriter.WriteString("MachineToLocalUser");
 511			xmlWriter.WriteEndAttribute();
 512			xmlWriter.WriteStartAttribute("requirePermission");
 513			xmlWriter.WriteString("false");
 514			xmlWriter.WriteEndAttribute();
 515			xmlWriter.WriteEndElement();
 516
 517			xmlWriter.WriteWhitespace("\n        ");
 518			xmlWriter.WriteEndElement();
 519
 520			xmlWriter.WriteWhitespace("\n    ");
 521			xmlWriter.WriteEndElement();
 522
 523
 524			xmlWriter.WriteWhitespace("\n    ");
 525			xmlWriter.WriteStartElement("userSettings");
 526			xmlWriter.WriteWhitespace("\n        ");
 527			xmlWriter.WriteStartElement("Stoffi.Properties.Settings");
 528
 529			WriteSetting(xmlWriter, "WinWidth", 3, settings.WinWidth);
 530			WriteSetting(xmlWriter, "WinHeight", 3, settings.WinHeight);
 531			WriteSetting(xmlWriter, "WinTop", 3, settings.WinTop);
 532			WriteSetting(xmlWriter, "WinLeft", 3, settings.WinLeft);
 533			WriteSetting(xmlWriter, "WinWidth", 3, settings.EqualizerWidth);
 534			WriteSetting(xmlWriter, "WinState", 3, settings.WinState);
 535			WriteSetting(xmlWriter, "EqualizerHeight", 3, settings.EqualizerHeight);
 536			WriteSetting(xmlWriter, "EqualizerTop", 3, settings.EqualizerTop);
 537			WriteSetting(xmlWriter, "EqualizerLeft", 3, settings.EqualizerLeft);
 538			WriteSetting(xmlWriter, "MediaState", 3, settings.MediaState);
 539			WriteSetting(xmlWriter, "Language", 3, settings.Language);
 540			WriteSetting(xmlWriter, "NavigationPaneWidth", 3, settings.NavigationPaneWidth);
 541			WriteSetting(xmlWriter, "DetailsPaneHeight", 3, settings.DetailsPaneHeight);
 542			WriteSetting(xmlWriter, "Repeat", 3, settings.Repeat);
 543			WriteSetting(xmlWriter, "Shuffle", 3, settings.Shuffle);
 544			WriteSetting(xmlWriter, "Volume", 3, settings.Volume);
 545			WriteSetting<List<EqualizerProfile>>(xmlWriter, "EqualizerProfiles", "Xml", 3, settings.EqualizerProfiles);
 546			WriteSetting<EqualizerProfile>(xmlWriter, "CurrentEqualizerProfile", "Xml", 3, settings.CurrentEqualizerProfile);
 547			WriteSetting(xmlWriter, "Seek", 3, settings.Seek);
 548			WriteSetting<TrackData>(xmlWriter, "CurrentTrack", "Xml", 3, settings.CurrentTrack);
 549			WriteSetting(xmlWriter, "HistoryIndex", 3, settings.HistoryIndex);
 550			WriteSetting(xmlWriter, "CurrentSelectedNavigation", 3, settings.CurrentSelectedNavigation);
 551			WriteSetting(xmlWriter, "CurrentActiveNavigation", 3, settings.CurrentActiveNavigation);
 552			WriteSetting(xmlWriter, "CurrentVisualizer", 3, settings.CurrentVisualizer);
 553			WriteSetting(xmlWriter, "MenuBarVisible", 3, settings.MenuBarVisible);
 554			WriteSetting(xmlWriter, "DetailsPaneVisibile", 3, settings.DetailsPaneVisible);
 555			WriteSetting(xmlWriter, "FirstRun", 3, settings.FirstRun);
 556			WriteSetting<List<PluginSettings>>(xmlWriter, "PluginSettings", "Xml", 3, settings.PluginSettings);
 557			WriteSetting<ViewDetailsConfig>(xmlWriter, "PluginListConfig", "Xml", 3, settings.PluginListConfig);
 558			WriteSetting<List<SourceData>>(xmlWriter, "Sources", "Xml", 3, settings.Sources);
 559			WriteSetting<ViewDetailsConfig>(xmlWriter, "SourceListConfig", "Xml", 3, settings.SourceListConfig);
 560			WriteSetting<ViewDetailsConfig>(xmlWriter, "LibraryListConfig", "Xml", 3, settings.LibraryListConfig);
 561			WriteSetting<ViewDetailsConfig>(xmlWriter, "RadioListConfig", "Xml", 3, settings.RadioListConfig);
 562			WriteSetting<ViewDetailsConfig>(xmlWriter, "DiscListConfig", "Xml", 3, settings.DiscListConfig);
 563			WriteSetting<ViewDetailsConfig>(xmlWriter, "HistoryListConfig", "Xml", 3, settings.HistoryListConfig);
 564			WriteSetting<ViewDetailsConfig>(xmlWriter, "QueueListConfig", "Xml", 3, settings.QueueListConfig);
 565			WriteSetting<ViewDetailsConfig>(xmlWriter, "YouTubeListConfig", "Xml", 3, settings.YouTubeListConfig);
 566			WriteSetting<ViewDetailsConfig>(xmlWriter, "SoundCloudListConfig", "Xml", 3, settings.SoundCloudListConfig);
 567			WriteSetting<List<TrackData>>(xmlWriter, "LibraryTracks", "Xml", 3, settings.LibraryTracks);
 568			WriteSetting<List<TrackData>>(xmlWriter, "RadioTracks", "Xml", 3, settings.RadioTracks);
 569			WriteSetting<List<TrackData>>(xmlWriter, "HistoryTracks", "Xml", 3, settings.HistoryTracks);
 570			WriteSetting<List<TrackData>>(xmlWriter, "QueueTracks", "Xml", 3, settings.QueueTracks);
 571			WriteSetting<List<PlaylistData>>(xmlWriter, "Playlists", "Xml", 3, settings.Playlists);
 572			WriteSetting(xmlWriter, "OpenAddPolicy", 3, settings.OpenAddPolicy);
 573			WriteSetting(xmlWriter, "OpenPlayPolicy", 3, settings.OpenPlayPolicy);
 574			WriteSetting(xmlWriter, "UpgradePolicy", 3, settings.UpgradePolicy);
 575			WriteSetting(xmlWriter, "SearchPolicy", 3, settings.SearchPolicy);
 576			WriteSetting(xmlWriter, "ShowOSD", 3, settings.ShowOSD);
 577			WriteSetting(xmlWriter, "MinimizeToTray", 3, settings.MinimizeToTray);
 578			WriteSetting(xmlWriter, "ID", 3, settings.ID);
 579			WriteSetting(xmlWriter, "UpgradeCheck", 3, settings.UpgradeCheck);
 580			WriteSetting<List<KeyboardShortcutProfile>>(xmlWriter, "ShortcutProfiles", "Xml", 3, settings.ShortcutProfiles);
 581			WriteSetting(xmlWriter, "CurrentShortcutProfile", 3, settings.CurrentShortcutProfile);
 582			WriteSetting(xmlWriter, "OAuthToken", 3, settings.OAuthToken);
 583			WriteSetting(xmlWriter, "OAuthSecret", 3, settings.OAuthSecret);
 584			WriteSetting(xmlWriter, "SubmitSongs", 3, settings.SubmitSongs);
 585			WriteSetting(xmlWriter, "SubmitPlaylists", 3, settings.SubmitPlaylists);
 586			WriteSetting(xmlWriter, "PauseWhenLocked", 3, settings.PauseWhenLocked);
 587			WriteSetting(xmlWriter, "PauseWhenSongEnds", 3, settings.PauseWhenSongEnds);
 588			WriteSetting<List<CloudIdentity>>(xmlWriter, "CloudIdentities", "Xml", 3, settings.CloudIdentities);
 589
 590			xmlWriter.WriteWhitespace("\n        ");
 591			xmlWriter.WriteEndElement();
 592			xmlWriter.WriteWhitespace("\n    ");
 593			xmlWriter.WriteEndElement();
 594			xmlWriter.WriteWhitespace("\n");
 595			xmlWriter.WriteEndElement();
 596			xmlWriter.WriteEndDocument();
 597			utility.LogMessageToFile(LogMode.Debug, "Write done");
 598			xmlWriter.Close();
 599		}
 600
 601		/// <summary>
 602		/// Writes a settings to the XML settings file
 603		/// </summary>
 604		/// <typeparam name="T">The type of the settings</typeparam>
 605		/// <param name="xmlWriter">The XmlWriter</param>
 606		/// <param name="setting">The name of the setting</param>
 607		/// <param name="serializeAs">A string describing how the setting is serialized</param>
 608		/// <param name="indent">The number of spaces used for indentation</param>
 609		/// <param name="value">The value</param>
 610		private void WriteSetting<T>(XmlWriter xmlWriter, String setting, String serializeAs, int indent, T value)
 611		{
 612			String indentString = "";
 613			for (int i = 0; i < indent; i++)
 614				indentString += "    ";
 615
 616			xmlWriter.WriteWhitespace("\n" + indentString);
 617			xmlWriter.WriteStartElement("setting");
 618			xmlWriter.WriteStartAttribute("name");
 619			xmlWriter.WriteString(setting);
 620			xmlWriter.WriteEndAttribute();
 621			xmlWriter.WriteStartAttribute("serializeAs");
 622			xmlWriter.WriteString(serializeAs);
 623			xmlWriter.WriteEndAttribute();
 624
 625			xmlWriter.WriteWhitespace("\n" + indentString + "    ");
 626			xmlWriter.WriteStartElement("value");
 627
 628			if (value != null)
 629			{
 630				XmlSerializer ser = new XmlSerializer(typeof(T));
 631				ser.Serialize(xmlWriter, value);
 632			}
 633
 634			xmlWriter.WriteEndElement();
 635
 636			xmlWriter.WriteWhitespace("\n" + indentString);
 637			xmlWriter.WriteEndElement();
 638		}
 639
 640		/// <summary>
 641		/// Reads a setting from the XML settings file
 642		/// </summary>
 643		/// <typeparam name="T">The type of the setting</typeparam>
 644		/// <param name="xmlReader">The xml reader</param>
 645		/// <returns>The deserialized setting</returns>
 646		private T ReadSetting<T>(XmlTextReader xmlReader)
 647		{
 648			try
 649			{
 650				XmlSerializer ser = new XmlSerializer(typeof(T));
 651				return (T)ser.Deserialize(xmlReader);
 652			}
 653			catch (Exception e)
 654			{
 655				utility.LogMessageToFile(LogMode.Error, e.Message);
 656				return (T)(null as object);
 657			}
 658		}
 659
 660		/// <summary>
 661		/// Reads an old list data structure and uses it to populate
 662		/// a list of tracks and a config structure.
 663		/// </summary>
 664		/// <param name="data">The old list data structure</param>
 665		/// <param name="tracks">The track list to populate</param>
 666		/// <param name="config">The config to populate</param>
 667		private void ListDataToListAndConfig(TrackListData data, List<TrackData> tracks, ViewDetailsConfig config)
 668		{
 669			tracks.AddRange(data.Tracks);
 670
 671			config.SelectedIndices = new List<int>();
 672			foreach (string index in data.SelectedIndices)
 673				config.SelectedIndices.Add(Convert.ToInt32(index));
 674
 675			config.Filter = data.SearchText;
 676
 677			Dictionary<string, string> columnIndices = StringToDictionary(data.ColumnIndices);
 678			Dictionary<string, string> columnWidths = StringToDictionary(data.ColumnWidths);
 679			Dictionary<string, string> columnVisibilities = StringToDictionary(data.ColumnVisibilities);
 680
 681			int artistWidth = columnWidths.ContainsKey("Artist") ? Convert.ToInt32(columnWidths["Artist"]) : 150;
 682			int albumWidth = columnWidths.ContainsKey("Album") ? Convert.ToInt32(columnWidths["Album"]) : 150;
 683			int titleWidth = columnWidths.ContainsKey("Title") ? Convert.ToInt32(columnWidths["Title"]) : 150;
 684			int genreWidth = columnWidths.ContainsKey("Genre") ? Convert.ToInt32(columnWidths["Genre"]) : 100;
 685			int lengthWidth = columnWidths.ContainsKey("Length") ? Convert.ToInt32(columnWidths["Length"]) : 100;
 686			int lpWidth = columnWidths.ContainsKey("LastPlayed") ? Convert.ToInt32(columnWidths["LastPlayed"]) : 150;
 687			int pcWidth = columnWidths.ContainsKey("PlayCount") ? Convert.ToInt32(columnWidths["PlayCount"]) : 100;
 688			int pathWidth = columnWidths.ContainsKey("Path") ? Convert.ToInt32(columnWidths["Path"]) : 300;
 689
 690			bool artistVis = columnVisibilities.ContainsKey("Artist") && columnVisibilities["Artist"] == "visible";
 691			bool albumVis = columnVisibilities.ContainsKey("Album") && columnVisibilities["Album"] == "visible";
 692			bool titleVis = columnVisibilities.ContainsKey("Title") && columnVisibilities["Title"] == "visible";
 693			bool genreVis = columnVisibilities.ContainsKey("Genre") && columnVisibilities["Genre"] == "visible";
 694			bool lengthVis = columnVisibilities.ContainsKey("Length") && columnVisibilities["Length"] == "visible";
 695			bool lpVis = columnVisibilities.ContainsKey("LastPlayed") && columnVisibilities["LastPlayed"] == "visible";
 696			bool pcVis = columnVisibilities.ContainsKey("PlayCount") && columnVisibilities["PlayCount"] == "visible";
 697			bool pathVis = columnVisibilities.ContainsKey("Path") && columnVisibilities["Path"] == "visible";
 698
 699			config.Columns = new ObservableCollection<ViewDetailsColumn>();
 700			Dictionary<string, ViewDetailsColumn> columns = new Dictionary<string, ViewDetailsColumn>();
 701			columns.Add("Artist", CreateListColumn("Artist", "Artist", "Artist", artistWidth, "Left", artistVis));
 702			columns.Add("Album", CreateListColumn("Album", "Album", "Album", albumWidth, "Left", albumVis));
 703			columns.Add("Title", CreateListColumn("Title", "Title", "Title", titleWidth, "Left", titleVis));
 704			columns.Add("Genre", CreateListColumn("Genre", "Genre", "Genre", genreWidth, "Left", genreVis));
 705			columns.Add("Length", CreateListColumn("Length", "Length", "Length", "RawLength", lengthWidth, "Right", lengthVis));
 706			columns.Add("Year", CreateListColumn("Year", "Year", "Year", "Year", 100, "Right", false));
 707			columns.Add("Last Played", CreateListColumn("LastPlayed", "Last played", "LastPlayed", lpWidth, "Left", lpVis));
 708			columns.Add("Play Count", CreateListColumn("PlayCount", "Play count", "PlayCount", pcWidth, "Right", pcVis));
 709			columns.Add("Track", CreateListColumn("Track", "Track", "Track", 100, "Right", false));
 710			columns.Add("Path", CreateListColumn("Path", "Path", "Path", pathWidth, "Left", pathVis));
 711
 712			foreach (string column in columnIndices.Keys)
 713			{
 714				config.Columns.Add(columns[column]);
 715				columns.Remove(column);
 716			}
 717
 718			foreach (ViewDetailsColumn column in columns.Values)
 719				config.Columns.Add(column);
 720
 721			config.AcceptFileDrops = true;
 722			config.HasNumber = true;
 723			config.UseIcons = true;
 724			config.IsClickSortable = true;
 725			config.IsDragSortable = true;
 726			config.IsNumberVisible = false;
 727			config.LockSortOnNumber = false;
 728			config.Sorts = new List<string>();
 729			foreach (string sortPair in data.ColumnSorts)
 730			{
 731				string[] s = sortPair.Split(':');
 732				string dir = s[1] == "Ascending" ? "asc" : "dsc";
 733				string name = s[0];
 734				if (name == "Last Played") name = "LastPlayed";
 735				if (name == "Play Count") name = "PlayCount";
 736				config.Sorts.Add(dir + ":" + name);
 737			}
 738		}
 739
 740		private Dictionary<string,string> StringToDictionary(string str)
 741		{
 742			Dictionary<string, string> ret = new Dictionary<string, string>();
 743			foreach (string pair in str.Split(';'))
 744			{
 745				string[] s = pair.Split(':');
 746				if (ret.ContainsKey(s[0]))
 747					ret.Remove(s[0]);
 748				ret.Add(s[0], s[1]);
 749			}
 750			return ret;
 751		}
 752
 753		private void WriteSetting(XmlWriter xmlWriter, String setting, int indent, String value)
 754		{
 755			if (value == "" || value == null) return;
 756			String indentString = "";
 757			for (int i = 0; i < indent; i++)
 758				indentString += "    ";
 759
 760			xmlWriter.WriteWhitespace("\n" + indentString);
 761			xmlWriter.WriteStartElement("setting");
 762			xmlWriter.WriteStartAttribute("name");
 763			xmlWriter.WriteString(setting);
 764			xmlWriter.WriteEndAttribute();
 765			xmlWriter.WriteStartAttribute("serializeAs");
 766			xmlWriter.WriteString("String");
 767			xmlWriter.WriteEndAttribute();
 768
 769			xmlWriter.WriteWhitespace("\n" + indentString + "    ");
 770			xmlWriter.WriteStartElement("value");
 771			xmlWriter.WriteString(value);
 772			xmlWriter.WriteEndElement();
 773
 774			xmlWriter.WriteWhitespace("\n" + indentString);
 775			xmlWriter.WriteEndElement();
 776		}
 777
 778        #endregion
 779
 780        #endregion
 781    }
 782
 783    /// <summary>
 784    /// 
 785    /// </summary>
 786	public class TrackData : ViewDetailsItemData
 787    {
 788        #region Properties
 789
 790        /// <summary>
 791        /// 
 792        /// </summary>
 793        public String Artist { get; set; }
 794
 795        /// <summary>
 796        /// 
 797        /// </summary>
 798        public String Album { get; set; }
 799
 800        /// <summary>
 801        /// 
 802        /// </summary>
 803        public String Title { get; set; }
 804
 805        /// <summary>
 806        /// 
 807        /// </summary>
 808        public String Genre { get; set; }
 809
 810        /// <summary>
 811        /// 
 812        /// </summary>
 813        public String Length { get; set; }
 814
 815        /// <summary>
 816        /// 
 817        /// </summary>
 818		public String RawLength { get; set; }
 819
 820		/// <summary>
 821		/// Gets the amount of views on YouTube in a localized,
 822		/// human readable format.
 823		/// </summary>
 824		public string Views { get; set; }
 825
 826		/// <summary>
 827		/// Gets or sets the amount of views on YouTube.
 828		/// </summary>
 829		public int RawViews { get; set; }
 830
 831		/// <summary>
 832		/// 
 833		/// </summary>
 834		public String LastPlayed { get; set; }
 835
 836		/// <summary>
 837		/// 
 838		/// </summary>
 839		public String RawLastPlayed { get; set; }
 840
 841		/// <summary>
 842		/// 
 843		/// </summary>
 844		public String PlayCount { get; set; }
 845
 846        /// <summary>
 847        /// 
 848        /// </summary>
 849        public String LastWrite { get; set; }
 850
 851        /// <summary>
 852        /// 
 853        /// </summary>
 854        public String Processed { get; set; }
 855
 856        /// <summary>
 857        /// 
 858        /// </summary>
 859        public String Track { get; set; }
 860
 861        /// <summary>
 862        /// 
 863        /// </summary>
 864        public String Path { get; set; }
 865
 866        /// <summary>
 867        /// 
 868        /// </summary>
 869		public String Year { get; set; }
 870
 871		/// <summary>
 872		/// Gets or sets the bitrate of the track
 873		/// </summary>
 874		public int Bitrate { get; set; }
 875
 876		/// <summary>
 877		/// Gets or sets the number of channels of the track
 878		/// </summary>
 879		public int Channels { get; set; }
 880
 881		/// <summary>
 882		/// Gets or sets the sample rate of the track
 883		/// </summary>
 884		public int SampleRate { get; set; }
 885
 886		/// <summary>
 887		/// Gets or sets the codecs of the track
 888		/// </summary>
 889		public string Codecs { get; set; }
 890
 891        /// <summary>
 892        /// 
 893        /// </summary>
 894		public String Source { get; set; }
 895
 896        /// <summary>
 897        /// 
 898        /// </summary>
 899		public List<String> Bookmarks { get; set; }
 900
 901        #endregion
 902    }
 903
 904	/// <summary>
 905	/// Describes an equalizer profile
 906	/// </summary>
 907	public class EqualizerProfile
 908	{
 909		/// <summary>
 910		/// Get or sets the name of the profile
 911		/// </summary>
 912		public String Name { get; set; }
 913
 914		/// <summary>
 915		/// Get or sets whether the user can modify the profile
 916		/// </summary>
 917		public Boolean IsProtected { get; set; }
 918
 919		/// <summary>
 920		/// Get or sets the levels.
 921		/// </summary>
 922		/// <remarks>
 923		/// Is a list with 10 floats between 0 and 10,
 924		/// where each float represents the maximum level
 925		/// on a frequency band going from lower to higher.
 926		/// </remarks>
 927		public float[] Levels;
 928
 929		/// <summary>
 930		/// Get or sets the echo level.
 931		/// A float ranging from 0 to 10 going from
 932		/// dry to wet.
 933		/// </summary>
 934		public string EchoLevel;
 935	}
 936
 937	/// <summary>
 938	/// 
 939	/// </summary>
 940	public class TrackListData
 941	{
 942		#region Properties
 943
 944		/// <summary>
 945		/// 
 946		/// </summary>
 947		public String ColumnWidths { get; set; }
 948
 949		/// <summary>
 950		/// 
 951		/// </summary>
 952		public String ColumnIndices { get; set; }
 953
 954		/// <summary>
 955		/// 
 956		/// </summary>
 957		public String ColumnVisibilities { get; set; }
 958
 959		/// <summary>
 960		/// 
 961		/// </summary>
 962		public List<String> SelectedIndices { get; set; }
 963
 964		/// <summary>
 965		/// 
 966		/// </summary>
 967		public List<String> ColumnSorts { get; set; }
 968
 969		/// <summary>
 970		/// 
 971		/// </summary>
 972		public String SearchText { get; set; }
 973
 974		/// <summary>
 975		/// 
 976		/// </summary>
 977		public List<TrackData> Tracks { get; set; }
 978
 979		#endregion
 980	}
 981
 982    /// <summary>
 983    /// 
 984    /// </summary>
 985	public class PlaylistData
 986    {
 987        #region Properites
 988
 989        /// <summary>
 990        /// 
 991        /// </summary>
 992        public String Name { get; set; }
 993
 994        /// <summary>
 995        /// 
 996        /// </summary>
 997        public String Time { get; set; }
 998
 999        /// <summary>
1000        /// 
1001        /// </summary>
1002		public List<TrackData> Tracks { get; set; }
1003
1004		/// <summary>
1005		/// Get or sets the configuration of the list view
1006		/// </summary>
1007		public ViewDetailsConfig ListConfig { get; set; }
1008
1009		/// <summary>
1010		/// Deprecated!
1011		/// </summary>
1012		public TrackListData ListData { get; set; }
1013
1014        #endregion
1015    }
1016
1017    /// <summary>
1018    /// 
1019    /// </summary>
1020	public class SourceData : ViewDetailsItemData
1021    {
1022		#region Properties
1023
1024		/// <summary>
1025		/// 
1026		/// </summary>
1027		public String Include { get; set; }
1028
1029		/// <summary>
1030		/// 
1031		/// </summary>
1032		public String Ignore { get; set; }
1033
1034        /// <summary>
1035        /// 
1036        /// </summary>
1037		public String Type { get; set; }
1038
1039		/// <summary>
1040		/// 
1041		/// </summary>
1042		public String HumanType { get; set; }
1043
1044        /// <summary>
1045        /// 
1046        /// </summary>
1047		public String Data { get; set; }
1048
1049        #endregion
1050    }
1051
1052    /// <summary>
1053    /// 
1054    /// </summary>
1055	public class KeyboardShortcut
1056    {
1057        #region Properties
1058
1059        /// <summary>
1060        /// 
1061        /// </summary>
1062        public String Name { get; set; }
1063
1064        /// <summary>
1065        /// 
1066        /// </summary>
1067		public String Category { get; set; }
1068
1069        /// <summary>
1070        /// 
1071        /// </summary>
1072		public String Keys { get; set; }
1073
1074        /// <summary>
1075        /// 
1076        /// </summary>
1077		public String IsGlobal { get; set; }
1078
1079        #endregion
1080    }
1081
1082    /// <summary>
1083    /// 
1084    /// </summary>
1085	public class KeyboardShortcutProfile
1086    {
1087        #region Members
1088
1089        public List<KeyboardShortcut> Shortcuts; // TODO: rename to shortcuts
1090
1091        #endregion
1092
1093        #region Properties
1094
1095        /// <summary>
1096        /// 
1097        /// </summary>
1098        public String Name { get; set; }
1099
1100        /// <summary>
1101        /// 
1102        /// </summary>
1103		public String IsProtected { get; set; }
1104
1105        #endregion
1106    }
1107
1108	public class PluginSettings
1109	{
1110		public String PluginID { get; set; }
1111		public List<Setting> Settings { get; set; }
1112		public String Enabled { get; set; }
1113		public String Installed { get; set; }
1114	}
1115
1116	public class Setting
1117	{
1118		public String ID { get; set; }
1119		public String Type { get; set; }
1120		public String Value { get; set; }
1121		public String Maximum { get; set; }
1122		public String Minimum { get; set; }
1123		public List<String> PossibleValues { get; set; }
1124		public String IsVisible { get; set; }
1125	}
1126
1127	public class CloudIdentity
1128	{
1129		public String UserID { get; set; }
1130		public String ConfigurationID { get; set; }
1131		public String Synchronize { get; set; }
1132		public String SynchronizePlaylists { get; set; }
1133		public String SynchronizeConfig { get; set; }
1134		public String SynchronizeQueue { get; set; }
1135		public String SynchronizeFiles { get; set; }
1136		public String DeviceID { get; set; }
1137	}
1138
1139	/// <summary>
1140	/// The settings after the migration
1141	/// </summary>
1142	public class NewSettings
1143	{
1144		#region Properties
1145
1146		public String WinHeight { get; set; }
1147		public String WinWidth { get; set; }
1148		public String WinTop { get; set; }
1149		public String WinLeft { get; set; }
1150		public String WinState { get; set; }
1151		public String EqualizerHeight { get; set; }
1152		public String EqualizerWidth { get; set; }
1153		public String EqualizerTop { get; set; }
1154		public String EqualizerLeft { get; set; }
1155		public String MediaState { get; set; }
1156		public String Language { get; set; }
1157		public String NavigationPaneWidth { get; set; }
1158		public String DetailsPaneHeight { get; set; }
1159		public String Shuffle { get; set; }
1160		public String Repeat { get; set; }
1161		public String Volume { get; set; }
1162		public List<EqualizerProfile> EqualizerProfiles { get; set; }
1163		public EqualizerProfile CurrentEqualizerProfile { get; set; }
1164		public String Seek { get; set; }
1165		public TrackData CurrentTrack { get; set; }
1166		public String HistoryIndex { get; set; }
1167		public String CurrentSelectedNavigation { get; set; }
1168		public String CurrentActiveNavigation { get; set; }
1169		public String CurrentVisualizer { get; set; }
1170		public String MenuBarVisible { get; set; }
1171		public String DetailsPaneVisible { get; set; }
1172		public String FirstRun { get; set; }
1173		public List<PluginSettings> PluginSettings { get; set; }
1174		public ViewDetailsConfig PluginListConfig { get; set; }
1175		public List<SourceData> Sources { get; set; }
1176		public ViewDetailsConfig SourceListConfig { get; set; }
1177		public ViewDetailsConfig LibraryListConfig { get; set; }
1178		public ViewDetailsConfig RadioListConfig { get; set; }
1179		public ViewDetailsConfig DiscListConfig { get; set; }
1180		public ViewDetailsConfig HistoryListConfig { get; set; }
1181		public ViewDetailsConfig QueueListConfig { get; set; }
1182		public ViewDetailsConfig YouTubeListConfig { get; set; }
1183		public ViewDetailsConfig SoundCloudListConfig { get; set; }
1184		public List<TrackData> LibraryTracks { get; set; }
1185		public List<TrackData> RadioTracks { get; set; }
1186		public List<TrackData> HistoryTracks { get; set; }
1187		public List<TrackData> QueueTracks { get; set; }
1188		public List<PlaylistData> Playlists { get; set; }
1189		public String OpenAddPolicy { get; set; }
1190		public String OpenPlayPolicy { get; set; }
1191		public String UpgradePolicy { get; set; }
1192		public String SearchPolicy { get; set; }
1193		public String ShowOSD { get; set; }
1194		public String MinimizeToTray { get; set; }
1195		public String ID { get; set; }
1196		public String UpgradeCheck { get; set; }
1197		public List<KeyboardShortcutProfile> ShortcutProfiles { get; set; }
1198		public String CurrentShortcutProfile { get; set; }
1199		public String OAuthToken { get; set; }
1200		public String OAuthSecret { get; set; }
1201		public String SubmitSongs { get; set; }
1202		public String SubmitPlaylists { get; set; }
1203		public String PauseWhenLocked { get; set; }
1204		public String PauseWhenSongEnds { get; set; }
1205		public List<CloudIdentity> CloudIdentities { get; set; }
1206
1207		#endregion
1208	}
1209
1210	/// <summary>
1211	/// Describes the data source of an item inside the ViewDetails list
1212	/// </summary>
1213	public class ViewDetailsItemData
1214	{
1215		#region Properties
1216
1217		/// <summary>
1218		/// Gets or sets the index number of the item
1219		/// </summary>
1220		public int Number { get; set; }
1221
1222		/// <summary>
1223		/// Gets or sets whether the item is marked as active or not
1224		/// </summary>
1225		public bool IsActive { get; set; }
1226
1227		/// <summary>
1228		/// Gets or sets the icon of the item
1229		/// </summary>
1230		public string Icon { get; set; }
1231
1232		/// <summary>
1233		/// Gets or sets whether the items should feature a strikethrough
1234		/// </summary>
1235		public bool Strike { get; set; }
1236
1237		#endregion
1238	}
1239
1240	/// <summary>
1241	/// Describes a configuration for the ViewDetails class
1242	/// </summary>
1243	public class ViewDetailsConfig
1244	{
1245		#region Properties
1246
1247		/// <summary>
1248		/// Gets or sets the columns
1249		/// </summary>
1250		public ObservableCollection<ViewDetailsColumn> Columns { get; set; }
1251
1252		/// <summary>
1253		/// Gets or sets the number column configuration
1254		/// </summary>
1255		public ViewDetailsColumn NumberColumn { get; set; }
1256
1257		/// <summary>
1258		/// Gets or sets the indices of the selected items
1259		/// </summary>
1260		public List<int> SelectedIndices { get; set; }
1261
1262		/// <summary>
1263		/// Gets or sets the the sort orders
1264		/// Each sort is represented as a string on the format
1265		/// "asc/dsc:ColumnName"
1266		/// </summary>
1267		public List<string> Sorts { get; set; }
1268
1269		/// <summary>
1270		/// Gets or sets text used to filter the list
1271		/// </summary>
1272		public string Filter { get; set; }
1273
1274		/// <summary>
1275		/// Gets or sets whether the number column should be enabled
1276		/// </summary>
1277		public bool HasNumber { get; set; }
1278
1279		/// <summary>
1280		/// Gets or sets whether the number column should be visible
1281		/// </summary>
1282		public bool IsNumberVisible { get; set; }
1283
1284		/// <summary>
1285		/// Gets or sets the position of the number column
1286		/// </summary>
1287		public int NumberIndex { get; set; }
1288
1289		/// <summary>
1290		/// Gets or sets whether to display icons or not
1291		/// </summary>
1292		public bool UseIcons { get; set; }
1293
1294		/// <summary>
1295		/// Gets or sets whether files can be dropped onto the list
1296		/// </summary>
1297		public bool AcceptFileDrops { get; set; }
1298
1299		/// <summary>
1300		/// Gets or sets whether the list can be resorted via drag and drop
1301		/// </summary>
1302		public bool IsDragSortable { get; set; }
1303
1304		/// <summary>
1305		/// Gets or sets whether the list can be resorted by clicking on a column
1306		/// </summary>
1307		public bool IsClickSortable { get; set; }
1308
1309		/// <summary>
1310		/// Gets or sets whether only the number column can be used to sort the list
1311		/// </summary>
1312		public bool LockSortOnNumber { get; set; }
1313
1314		#endregion
1315	}
1316
1317	/// <summary>
1318	/// Represents a column of a details list
1319	/// </summary>
1320	public class ViewDetailsColumn
1321	{
1322		#region Properties
1323
1324		/// <summary>
1325		/// Gets or sets the name of the column
1326		/// </summary>
1327		public string Name { get; set; }
1328
1329		/// <s…

Large files files are truncated, but you can click here to view the full file