diff --git a/build.xml b/build.xml
index e11177db..64e14ff4 100644
--- a/build.xml
+++ b/build.xml
@@ -195,7 +195,7 @@
-
+
diff --git a/source/net/sourceforge/filebot/Main.java b/source/net/sourceforge/filebot/Main.java
index ad56a1c7..3c426ba6 100644
--- a/source/net/sourceforge/filebot/Main.java
+++ b/source/net/sourceforge/filebot/Main.java
@@ -3,8 +3,8 @@ package net.sourceforge.filebot;
import static javax.swing.JFrame.*;
+import static net.sourceforge.tuned.ui.TunedUtilities.*;
-import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.security.CodeSource;
@@ -96,16 +96,19 @@ public class Main {
}
- private static void restoreWindowBounds(Window window, final Settings settings) {
+ private static void restoreWindowBounds(final JFrame window, final Settings settings) {
// store bounds on close
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
- settings.put("window.x", String.valueOf(e.getWindow().getX()));
- settings.put("window.y", String.valueOf(e.getWindow().getY()));
- settings.put("window.width", String.valueOf(e.getWindow().getWidth()));
- settings.put("window.height", String.valueOf(e.getWindow().getHeight()));
+ // don't save window bounds if window is maximized
+ if (!isMaximized(window)) {
+ settings.put("window.x", String.valueOf(window.getX()));
+ settings.put("window.y", String.valueOf(window.getY()));
+ settings.put("window.width", String.valueOf(window.getWidth()));
+ settings.put("window.height", String.valueOf(window.getHeight()));
+ }
}
});
diff --git a/source/net/sourceforge/filebot/ui/panel/rename/MovieFormatter.java b/source/net/sourceforge/filebot/ui/panel/rename/MovieFormatter.java
index e9f718df..0a2c37dd 100644
--- a/source/net/sourceforge/filebot/ui/panel/rename/MovieFormatter.java
+++ b/source/net/sourceforge/filebot/ui/panel/rename/MovieFormatter.java
@@ -2,15 +2,16 @@
package net.sourceforge.filebot.ui.panel.rename;
+import java.util.Formatter;
+
import net.sourceforge.filebot.similarity.Match;
-import net.sourceforge.filebot.web.MovieDescriptor;
class MovieFormatter implements MatchFormatter {
@Override
public boolean canFormat(Match, ?> match) {
- return match.getValue() instanceof MovieDescriptor;
+ return match.getValue() instanceof MoviePart;
}
@@ -22,8 +23,15 @@ class MovieFormatter implements MatchFormatter {
@Override
public String format(Match, ?> match) {
- // use default format for the time being
- return match.getValue().toString();
+ MoviePart video = (MoviePart) match.getValue();
+ Formatter name = new Formatter(new StringBuilder());
+
+ // format as single-file or multi-part movie
+ name.format("%s (%d)", video.getMovie().getName(), video.getMovie().getYear());
+
+ if (video.getPartCount() > 1)
+ name.format(" CD%d", video.getPartIndex() + 1);
+
+ return name.out().toString();
}
-
}
diff --git a/source/net/sourceforge/filebot/ui/panel/rename/MovieHashMatcher.java b/source/net/sourceforge/filebot/ui/panel/rename/MovieHashMatcher.java
index c1ede12a..01e750e6 100644
--- a/source/net/sourceforge/filebot/ui/panel/rename/MovieHashMatcher.java
+++ b/source/net/sourceforge/filebot/ui/panel/rename/MovieHashMatcher.java
@@ -11,10 +11,15 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Scanner;
import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
@@ -44,18 +49,44 @@ class MovieHashMatcher implements AutoCompleteMatcher {
File[] movieFiles = filter(files, VIDEO_FILES).toArray(new File[0]);
MovieDescriptor[] movieDescriptors = service.getMovieDescriptors(movieFiles);
+ // map movies to (possibly multiple) files (in natural order)
+ Map> filesByMovie = new HashMap>();
+
+ // map all files by movie
+ for (int i = 0; i < movieFiles.length; i++) {
+ MovieDescriptor movie = movieDescriptors[i];
+
+ // unknown hash, try via imdb id from nfo file
+ if (movie == null) {
+ movie = determineMovie(movieFiles[i]);
+ }
+
+ // check if we managed to lookup the movie descriptor
+ if (movie != null) {
+ // get file list for movie
+ SortedSet movieParts = filesByMovie.get(movie);
+
+ if (movieParts == null) {
+ movieParts = new TreeSet();
+ filesByMovie.put(movie, movieParts);
+ }
+
+ movieParts.add(movieFiles[i]);
+ }
+ }
+
+ // collect all File/MoviePart matches
List> matches = new ArrayList>();
- for (int i = 0; i < movieDescriptors.length; i++) {
- if (movieDescriptors[i] != null) {
- matches.add(new Match(movieFiles[i], movieDescriptors[i]));
- } else {
- // unknown hash, try via imdb id from nfo file
- MovieDescriptor movie = determineMovie(movieFiles[i]);
-
- if (movie != null) {
- matches.add(new Match(movieFiles[i], movie));
- }
+ for (Entry> entry : filesByMovie.entrySet()) {
+ MovieDescriptor movie = entry.getKey();
+
+ int partIndex = 0;
+ int partCount = entry.getValue().size();
+
+ // add all movie parts
+ for (File file : entry.getValue()) {
+ matches.add(new Match(file, new MoviePart(movie, partIndex++, partCount)));
}
}
diff --git a/source/net/sourceforge/filebot/ui/panel/rename/MoviePart.java b/source/net/sourceforge/filebot/ui/panel/rename/MoviePart.java
new file mode 100644
index 00000000..e4455d5e
--- /dev/null
+++ b/source/net/sourceforge/filebot/ui/panel/rename/MoviePart.java
@@ -0,0 +1,45 @@
+
+package net.sourceforge.filebot.ui.panel.rename;
+
+
+import net.sourceforge.filebot.web.MovieDescriptor;
+
+
+class MoviePart {
+
+ private final MovieDescriptor movie;
+
+ private final int partIndex;
+ private final int partCount;
+
+
+ public MoviePart(MovieDescriptor movie) {
+ this(movie, 0, 1);
+ }
+
+
+ public MoviePart(MovieDescriptor movie, int partIndex, int partCount) {
+ if (partCount < 1 || partIndex >= partCount)
+ throw new IllegalArgumentException("Illegal part: " + partIndex + "/" + partCount);
+
+ this.movie = movie;
+ this.partIndex = partIndex;
+ this.partCount = partCount;
+ }
+
+
+ public MovieDescriptor getMovie() {
+ return movie;
+ }
+
+
+ public int getPartIndex() {
+ return partIndex;
+ }
+
+
+ public int getPartCount() {
+ return partCount;
+ }
+
+}
diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java
index 1692dc3a..ffc95c24 100644
--- a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java
+++ b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java
@@ -41,6 +41,7 @@ import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.EpisodeListProvider;
import net.sourceforge.filebot.web.IMDbClient;
import net.sourceforge.filebot.web.MovieDescriptor;
+import net.sourceforge.filebot.web.OpenSubtitlesClient;
import net.sourceforge.filebot.web.TMDbClient;
import net.sourceforge.filebot.web.TVDotComClient;
import net.sourceforge.filebot.web.TVRageClient;
@@ -152,6 +153,9 @@ public class RenamePanel extends JComponent {
actionPopup.addDescription(new JLabel("Movie Mode:"));
// create action for movie name completion
+ OpenSubtitlesClient osdb = new OpenSubtitlesClient(String.format("%s %s", getApplicationName(), getApplicationVersion()));
+ actionPopup.add(new AutoCompleteAction(osdb.getName(), osdb.getIcon(), new MovieHashMatcher(osdb)));
+
TMDbClient tmdb = new TMDbClient(getApplicationProperty("themoviedb.apikey"));
actionPopup.add(new AutoCompleteAction(tmdb.getName(), tmdb.getIcon(), new MovieHashMatcher(tmdb)));
diff --git a/source/net/sourceforge/tuned/ui/TunedUtilities.java b/source/net/sourceforge/tuned/ui/TunedUtilities.java
index 0b66ce2a..bc6a4386 100644
--- a/source/net/sourceforge/tuned/ui/TunedUtilities.java
+++ b/source/net/sourceforge/tuned/ui/TunedUtilities.java
@@ -5,6 +5,7 @@ package net.sourceforge.tuned.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
+import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
@@ -98,6 +99,11 @@ public final class TunedUtilities {
}
+ public static boolean isMaximized(Frame frame) {
+ return (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
+ }
+
+
public static Window getWindow(Object component) {
if (component instanceof Window)
return (Window) component;
diff --git a/test/net/sourceforge/filebot/web/TheTVDBClientTest.java b/test/net/sourceforge/filebot/web/TheTVDBClientTest.java
index 65b3cd60..e4ab5ffd 100644
--- a/test/net/sourceforge/filebot/web/TheTVDBClientTest.java
+++ b/test/net/sourceforge/filebot/web/TheTVDBClientTest.java
@@ -44,8 +44,7 @@ public class TheTVDBClientTest {
TheTVDBSearchResult first = (TheTVDBSearchResult) results.get(0);
- // test encoding (umlauts)
- assertEquals("Buffy - Im Bann der Dämonen", first.getName());
+ assertEquals("Buffy", first.getName());
assertEquals(70327, first.getSeriesId());
TheTVDBSearchResult second = (TheTVDBSearchResult) results.get(1);