private void NewSearchWindowExec(object sender, ExecutedRoutedEventArgs e) { IEnumerable <Album> albums; var albumParameter = e.Parameter as Album; if (albumParameter != null) { //Search for the specified album in a new search window albums = new Album[] { albumParameter }; } else { //Search for all the selected albums in new search windows albums = mQueueList.SelectedItems.Cast <Album>(); } var cascade = new Common.WindowCascade(); foreach (Album album in albums) { ArtSearchWindow searchWindow = Common.NewSearchWindow(this); cascade.Arrange(searchWindow); searchWindow.SetDefaultSaveFolderPattern(album.ArtFile, true); //Default save to the location where the image was searched for. searchWindow.Search(album.Artist, album.Name); } }
private void OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { if ((bool)e.NewValue) { //Window is being shown. Show warning Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new ThreadStart(delegate { var warning = new AutoDownloadWarning(); warning.Owner = this; if (warning.ShowDialog().GetValueOrDefault()) { //User chose to enqueue normal search windows instead. var cascade = new Common.WindowCascade(); foreach (var album in mQueueList.Albums) { ArtSearchWindow searchWindow = Common.NewSearchWindow(this); cascade.Arrange(searchWindow); searchWindow.SetDefaultSaveFolderPattern(album.ArtFile, true); //Default save to the location where the image was searched for. searchWindow.Search(album.Artist, album.Name); } Close(); } })); } }
/// <summary> /// If the specified search window is in the queue, remove it from the queue without showing it. /// Disposes of the search window, if it is removed. /// </summary> public void CancelSearchWindow(ArtSearchWindow searchWindow) { if (mQueue.Remove(searchWindow)) { searchWindow.Close(); } }
/// <summary> /// If the specified search window is in the queue, force it to be shown immediately. /// </summary> public void ForceSearchWindow(ArtSearchWindow searchWindow) { int index = mQueue.IndexOf(searchWindow); if (index >= 0) { mQueue.RemoveAt(index); ShowSearchWindow(searchWindow); } }
/// <summary> /// Shows the specified search window, and starts it searching. /// The window should have been dequeued before calling this method. /// </summary> private void ShowSearchWindow(ArtSearchWindow searchWindow) { if (!mNoLoadFromSettingsOnShow.Remove(searchWindow)) //Don't update from settings if specifically requested not to. { searchWindow.LoadSettings(); //Ensure the settings are brought up to date } searchWindow.Closed += new EventHandler(OnSearchWindowClosed); searchWindow.Show(); NumberOfOpenSearchWindows++; }
/// <summary> /// Enqueues the specified search window. This may mean that the search /// window is shown immediately, if there are less than <see cref="SimultaneousWindowsAllowed"/> /// windows open already. /// </summary> /// <param name="loadFromSettingsOnShow">If true, the window will load the current settings when it is shown.</param> public void EnqueueSearchWindow(ArtSearchWindow searchWindow, bool loadFromSettingsOnShow) { if (!loadFromSettingsOnShow) //The usual case is to load on show, but if not doing it, flag up this state so that ShowSearchWindow doesn't call LoadSettings for it { mNoLoadFromSettingsOnShow.Add(searchWindow); } if (NumberOfOpenSearchWindows < SimulataneousWindowsAllowed) { //Show the window immediately ShowSearchWindow(searchWindow); } else { //Enqueue it mQueue.Add(searchWindow); } }
/// <param name="forceShown">If true, the new search window will be immediately shown, rather than queued.</param> public static ArtSearchWindow NewSearchWindow(IAppWindow existingWindow, bool forceShown) { //Enqueue rather than opening the new window directly ArtSearchWindow newWindow = new ArtSearchWindow(); SetupNewWindow(newWindow, existingWindow); SearchQueue searchQueue = ((App)Application.Current).SearchQueue; searchQueue.EnqueueSearchWindow(newWindow, true); if (forceShown) { //Ensure the new window is shown immediately, rather than queued. searchQueue.ForceSearchWindow(newWindow); } else if (searchQueue.Queue.Count == 1) { //This is the first item enqueued, so show the queue manager window searchQueue.ShowManagerWindow(); } return(newWindow); }
private void OnQueueDoubleClick(object sender, MouseButtonEventArgs e) { FrameworkElement source = e.OriginalSource as FrameworkElement; if (source != null) { //If the source is deep in the visual tree, go up to its top level parent first while (source.Parent is FrameworkElement) { source = (FrameworkElement)source.Parent; } //Find the top level templated parent while (source.TemplatedParent is FrameworkElement) { source = (FrameworkElement)source.TemplatedParent; } ArtSearchWindow searchWindow = mQueueDisplay.ItemContainerGenerator.ItemFromContainer(source) as ArtSearchWindow; if (searchWindow != null) { ((App)Application.Current).SearchQueue.ForceSearchWindow(searchWindow); } } }
private void GetArtworkExec(object sender, ExecutedRoutedEventArgs e) { AutoDownloader autoDownloader = null; if (SelectedItems.Count > 1 && Properties.Settings.Default.FileBrowseAutoDownload) { autoDownloader = new AutoDownloader(); } else { //Warn if there are a lot of selected items if (SelectedItems.Count > Properties.Settings.Default.EnqueueWarning) { EnqueueWarning enqueueWarning = new EnqueueWarning(); enqueueWarning.Owner = Window.GetWindow(this); enqueueWarning.NumberToEnqueue = SelectedItems.Count; if (!enqueueWarning.ShowDialog().GetValueOrDefault()) { //Cancelled return; } //Trim the selection back to the number to enqueue while (SelectedItems.Count > enqueueWarning.NumberToEnqueue) { SelectedItems.RemoveAt(SelectedItems.Count - 1); } } } //The art file search pattern is used as the default path to save the found image to, but first: // *In case of alternates, use the first alternate only. string artFileSearchPattern = ImagePathPattern.Split(new[] { '|' }, 2)[0]; // *Don't substitute placeholders, but do substitute recursive path matching with the simplest solution to it, just putting saving to the immediate subfolder artFileSearchPattern = artFileSearchPattern.Replace("**\\", "").Replace("**/", ""); // *Also replace a wildcarded extension if (artFileSearchPattern.EndsWith(".*")) { artFileSearchPattern = artFileSearchPattern.Substring(0, artFileSearchPattern.Length - 2) + ".%extension%"; } // *If the pattern ends in just a wildcard, replace with %name%.%extension% else if (artFileSearchPattern.EndsWith("*")) { artFileSearchPattern = artFileSearchPattern.Substring(0, artFileSearchPattern.Length - 1) + "%name%.%extension%"; } //Replace other wildcards with the %name%, so that for local files search they become wildcards again artFileSearchPattern = artFileSearchPattern.Replace("*", "%name%"); var cascade = new Common.WindowCascade(); foreach (Album album in SelectedItems) { //If the image path is relative, get an absolute path for it. string rootedArtFileSearchPattern; if (Path.IsPathRooted(artFileSearchPattern)) { rootedArtFileSearchPattern = artFileSearchPattern; } else { rootedArtFileSearchPattern = Path.Combine(album.BasePath, artFileSearchPattern); } if (autoDownloader != null) { album.ArtFile = rootedArtFileSearchPattern; //The destination filename to download to autoDownloader.Add(album); } else { ArtSearchWindow searchWindow = Common.NewSearchWindow(Window.GetWindow(this) as IAppWindow); cascade.Arrange(searchWindow); searchWindow.SetDefaultSaveFolderPattern(rootedArtFileSearchPattern, true); //Default save to the location where the image was searched for. searchWindow.Search(album.Artist, album.Name); //Kick off the search. //Watch for the window being closed to update the status of the artwork mSearchWindowAlbumLookup.Add(searchWindow, album); searchWindow.Closed += OnSearchWindowClosed; } } if (autoDownloader != null) { autoDownloader.Show(); } }
/// <summary> /// Checks to see if a search window is ready for dequeuing, and if so, dequeues it /// </summary> private void DequeueNextSearchWindow() { if (Queue.Count > 0) { while (NumberOfOpenSearchWindows < SimulataneousWindowsAllowed) //Keep dequeueing as long as more simultaneous windows are allowed. { //Dequeue and show the next window ArtSearchWindow searchWindow = Queue[0]; mQueue.RemoveAt(0); if (NumberOfOpenSearchWindows == 0) { //Just show normally ShowSearchWindow(searchWindow); } else { //Show behind existing windows, unactivated if (!App.UsePreSP1Compatibility) { //ShowActivated not supported pre SP1. SetShowActivated(searchWindow, false); } ShowSearchWindow(searchWindow); //Send it behind the lowest existing window. IntPtr hWnd = ((HwndSource)HwndSource.FromVisual(searchWindow)).Handle; //Find the lowest existing window IntPtr bottomWindow = IntPtr.Zero; EnumWindowsProc enumWindowsProc = new EnumWindowsProc(delegate(IntPtr enumHWnd, int enumLParam) { var hwndSource = HwndSource.FromHwnd(enumHWnd); if (hwndSource != null && hwndSource.RootVisual is ArtSearchWindow) { bottomWindow = enumHWnd; } return(true); }); EnumWindows(enumWindowsProc, 0); GC.KeepAlive(enumWindowsProc); //Send it behind that one if (bottomWindow != IntPtr.Zero) { SetWindowPos(hWnd, bottomWindow, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); //HACK: Repaint all the other windows Non-Client area (as WPF screws this up) foreach (Window window in Application.Current.Windows) { if (window.IsVisible) { SendMessage(((HwndSource)HwndSource.FromVisual(window)).Handle, WM_NCPAINT, 0, 0); } } } } } if (Queue.Count == 0) { //Close the manager, if it is open if (mManagerWindow != null) { mManagerWindow.Close(); } } } }
//This method exists to isolate the ShowActivated member, which is unsupported under SP1. //This method may not be called if App.UsePreSP1Compatiblity is set false, as it will crash (before even executing the method) private void SetShowActivated(ArtSearchWindow window, bool showActivated) { window.ShowActivated = false; }
/// <summary> /// Process command args. Returns True if a new search window was shown, False if it was not. /// </summary> private bool ProcessCommandArgs(string[] args) { //valuedParameters is a list of parameters which must have values - they can not be just switches. string[] valuedParameters = { "artist", "ar", "album", "al", "path", "p", "localimagespath", "sources", "s", "exclude", "es", "include", "i", "sort", "o", "group", "g", "minsize", "mn", "maxsize", "mx", "covertype", "t" }; Arguments arguments = new Arguments(args, valuedParameters); if (arguments.Contains("?")) { ShowCommandArgs(); return(false); } bool?autoClose = null; bool showSearchWindow = false, showFileBrowser = false, showFoobarBrowser = false, showConfigFile = false; bool startFoobarBrowserSearch = false; bool showMinimized = false; bool forceNewWindow = false; string artist = null, album = null, path = null, localImagesPath = null, fileBrowser = null, sortField = null; ListSortDirection sortDirection = ListSortDirection.Ascending; Grouping? grouping = null; int?minSize = null, maxSize = null; AllowedCoverType?coverType = null; List <String> useSources = new List <string>(); List <String> excludeSources = new List <string>(); List <String> includeSources = new List <string>(); string errorMessage = null; bool skipNext = false; foreach (Parameter parameter in arguments) { if (skipNext) { skipNext = false; continue; } //Check un-named parameters if (parameter.Name == null) { showSearchWindow = true; //For un-named parameters, use compatibility mode: 3 args, "<artist>" "<album>" "<path to save image>" switch (arguments.IndexOf(parameter)) { case 0: artist = parameter.Value; break; case 1: album = parameter.Value; break; case 2: path = parameter.Value; break; default: errorMessage = "Only the first three parameters may be un-named"; break; } } else { //Check named parameters switch (parameter.Name.ToLower()) //Case insensitive parameter names { case "artist": case "ar": artist = parameter.Value; showSearchWindow = true; break; case "album": case "al": album = parameter.Value; showSearchWindow = true; break; case "path": case "p": path = PathFix(parameter.Value); //Compatibility mode: if an "f" parameter, for filename, is provided, append it to the path. string filename; if (arguments.TryGetParameterValue("f", out filename)) { path = Path.Combine(path, filename); } showSearchWindow = true; break; case "f": break; //See case "p" for handling of this parameter case "localimagespath": localImagesPath = PathFix(parameter.Value); showSearchWindow = true; break; case "autoclose": case "ac": if (parameter.Value.Equals("off", StringComparison.InvariantCultureIgnoreCase)) { autoClose = false; } else { autoClose = true; } break; case "sources": case "s": useSources.AddRange(parameter.Value.Split(',')); showSearchWindow = true; break; case "exclude": case "es": excludeSources.AddRange(parameter.Value.Split(',')); showSearchWindow = true; break; case "ae": //Compatibility: Show Existing Album Art excludeSources.Add("Local Files"); showSearchWindow = true; break; case "include": case "i": includeSources.AddRange(parameter.Value.Split(',')); showSearchWindow = true; break; case "pf": //Compatibility: Show pictures in folder break; //Not currently supported case "filebrowser": fileBrowser = PathFix(parameter.Value); showFileBrowser = true; break; case "foobarbrowser": startFoobarBrowserSearch = parameter.Value.Equals("search", StringComparison.InvariantCultureIgnoreCase); showFoobarBrowser = true; break; case "sort": case "o": string sortName = null; if (parameter.Value.EndsWith("-")) { sortDirection = ListSortDirection.Descending; } else if (parameter.Value.EndsWith("+")) { sortDirection = ListSortDirection.Ascending; } sortName = parameter.Value.TrimEnd('-', '+'); switch (sortName.ToLower()) { case "name": case "n": sortField = "ResultName"; break; case "size": case "s": sortField = "ImageWidth"; break; case "source": case "o": sortField = "SourceName"; break; case "type": case "t": sortField = "CoverType"; break; case "area": case "a": sortField = "ImageArea"; break; case "page": case "p": sortField = "InfoUri"; break; default: errorMessage = "Unexpected sort field: " + sortName; break; } break; case "group": case "g": switch (parameter.Value.ToLower()) { case "none": case "n": grouping = Grouping.None; break; case "local": case "l": grouping = Grouping.Local; break; case "source": case "o": grouping = Grouping.Source; break; case "category": case "c": grouping = Grouping.SourceCategory; break; case "type": case "t": grouping = Grouping.Type; break; case "size": case "s": grouping = Grouping.Size; break; case "page": case "p": grouping = Grouping.InfoUri; break; default: errorMessage = "Unexpected grouping: " + parameter.Value; break; } break; case "minsize": case "mn": try { minSize = Int32.Parse(parameter.Value); } catch (Exception e) { errorMessage = "The /minSize parameter must be a number: " + parameter.Value + "\n " + e.Message; } break; case "maxsize": case "mx": try { maxSize = Int32.Parse(parameter.Value); } catch (Exception e) { errorMessage = "The /maxSize parameter must be a number: " + parameter.Value + "\n " + e.Message; } break; case "covertype": case "t": coverType = default(AllowedCoverType); foreach (String allowedCoverType in parameter.Value.ToLower().Split(',')) { switch (allowedCoverType) { case "front": case "f": coverType |= AllowedCoverType.Front; break; case "back": case "b": coverType |= AllowedCoverType.Back; break; case "inside": case "i": coverType |= AllowedCoverType.Inside; break; case "cd": case "c": coverType |= AllowedCoverType.CD; break; case "unknown": case "u": coverType |= AllowedCoverType.Unknown; break; case "booklet": case "k": coverType |= AllowedCoverType.Booklet; break; case "any": case "a": coverType |= AllowedCoverType.Any; break; default: errorMessage = "Unrecognized cover type: " + parameter.Value; break; } } break; case "update": //Force an immediate check for updates Updates.CheckForUpdates(true); break; case "getscripts": //Force an immediate check for new scripts Updates.ShowNewScripts(); break; case "separateinstance": //This will already have been handled earlier, in Main() break; case "config": showConfigFile = true; break; case "minimized": showMinimized = true; break; case "new": forceNewWindow = true; break; case "minaspect": case "ma": case "orientation": case "r": case "sequence": case "seq": case "listsources": case "l": System.Diagnostics.Debug.Fail("Unexpected command line parameter (valid for aad.exe, though): " + parameter.Name); break; default: errorMessage = "Unexpected command line parameter: " + parameter.Name; break; } } if (errorMessage != null) { break; //Stop parsing args if there was an error } } if (errorMessage != null) //Problem with the command args, so display the error, and the help { ShowCommandArgs(errorMessage); return(false); } if (!String.IsNullOrEmpty(sortField)) { //Set the sort AlbumArtDownloader.Properties.Settings.Default.ResultsSorting = new SortDescription(sortField, sortDirection); } if (grouping.HasValue) { //Set the grouping AlbumArtDownloader.Properties.Settings.Default.ResultsGrouping = grouping.Value; } if (minSize.HasValue) { if (minSize.Value == 0) { //0 would have no effect, so assume it means no filtering. AlbumArtDownloader.Properties.Settings.Default.UseMinimumImageSize = false; } else { //Set the minimum size AlbumArtDownloader.Properties.Settings.Default.MinimumImageSize = minSize.Value; AlbumArtDownloader.Properties.Settings.Default.UseMinimumImageSize = true; } } if (maxSize.HasValue) { if (maxSize.Value == 0) { //0 would result in no images at all, so assume it means no filtering. AlbumArtDownloader.Properties.Settings.Default.UseMinimumImageSize = false; } else { //Set the minimum size AlbumArtDownloader.Properties.Settings.Default.MaximumImageSize = maxSize.Value; AlbumArtDownloader.Properties.Settings.Default.UseMaximumImageSize = true; } } if (coverType.HasValue) { AlbumArtDownloader.Properties.Settings.Default.AllowedCoverTypes = coverType.Value; } //If the setting for using system codepage for id3 tags is set, instruct TagLib to do so. if (AlbumArtDownloader.Properties.Settings.Default.UseSystemCodepageForID3Tags) { TagLib.ByteVector.UseBrokenLatin1Behavior = true; } if (!showFileBrowser && !showFoobarBrowser && !showSearchWindow && !showConfigFile) //If no windows will be shown, show the search window { showSearchWindow = true; } if (showFileBrowser) { FileBrowser browserWindow = new FileBrowser(); if (showMinimized) { browserWindow.WindowState = WindowState.Minimized; } browserWindow.Show(); if (!String.IsNullOrEmpty(fileBrowser)) { browserWindow.Search(fileBrowser, AlbumArtDownloader.Properties.Settings.Default.FileBrowseSubfolders, //TODO: Should the browse subfolders flag be a command line parameter? AlbumArtDownloader.Properties.Settings.Default.FileBrowseImagePath, AlbumArtDownloader.Properties.Settings.Default.FileBrowseUsePathPattern ? AlbumArtDownloader.Properties.Settings.Default.FileBrowsePathPattern : null ); } } if (showFoobarBrowser) { FoobarBrowser browserWindow = new FoobarBrowser(); if (showMinimized) { browserWindow.WindowState = WindowState.Minimized; } browserWindow.Show(); if (startFoobarBrowserSearch) { browserWindow.Search(AlbumArtDownloader.Properties.Settings.Default.FileBrowseImagePath); //TODO: Should foobar browser have a separate path setting? } } if (showSearchWindow) { ArtSearchWindow searchWindow = null; if ((artist != null || album != null) && //If doing a new search !forceNewWindow && //And not forcing a new window !AlbumArtDownloader.Properties.Settings.Default.OpenResultsInNewWindow && //And the option is to open results in the same window Windows.Count == 1) //And only one window is open { searchWindow = Windows[0] as ArtSearchWindow; //And if that window is an ArtSearchWindow, then re-use it } if (searchWindow == null) { searchWindow = new ArtSearchWindow(); if (showMinimized) { searchWindow.WindowState = WindowState.Minimized; } SearchQueue.EnqueueSearchWindow(searchWindow, false); //Don't load from settings on show, otherwise they'll override the settings specified on the command line } else { searchWindow.Activate(); //Bring the window to the foreground } if (autoClose.HasValue) { searchWindow.OverrideAutoClose(autoClose.Value); } if (path != null) { searchWindow.SetDefaultSaveFolderPattern(path); } if (localImagesPath != null) { searchWindow.SetLocalImagesPath(localImagesPath); } if (useSources.Count > 0) { searchWindow.UseSources(useSources); } if (excludeSources.Count > 0) { searchWindow.ExcludeSources(excludeSources); } if (includeSources.Count > 0) { searchWindow.IncludeSources(includeSources); } if (artist != null || album != null) { searchWindow.Search(artist, album); if (SearchQueue.Queue.Count == 1) { //This is the first item enqueued, so show the queue manager window SearchQueue.ShowManagerWindow(); } } else { //Showing a new search window without performing a search, so force show it. SearchQueue.ForceSearchWindow(searchWindow); } } if (showConfigFile) { AlbumArtDownloader.Properties.Settings.Default.Save(); string configName = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal).FilePath; System.Diagnostics.Process.Start("notepad.exe", configName); if (!showFileBrowser && !showFoobarBrowser && !showSearchWindow) //If no other windows will be shown, exit now { return(false); } } // Set up jumplist for taskbar button TaskbarHelper.CreateApplicationJumpList(); if (AlbumArtDownloader.Properties.Settings.Default.AutoUpdateEnabled) { //Check for updates if enough time has elapsed. Updates.CheckForUpdates(false); } return(true); }
private void RemoveFromQueue(ArtSearchWindow searchWindow) { ((App)Application.Current).SearchQueue.CancelSearchWindow(searchWindow); }
private void RemoveFromQueue(ArtSearchWindow searchWindow) { SearchQueue.CancelSearchWindow(searchWindow); }