From: Niki Roo Date: Sun, 2 Apr 2017 16:05:38 +0000 (+0200) Subject: Fix cover not deleted, add new UI option "Move to" X-Git-Tag: fanfix-1.5.0~2 X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=70c9b112926f1cf95b2fddd0bb504ab37d6ddd1e;p=fanfix.git Fix cover not deleted, add new UI option "Move to" Library: fix the covers that were not always removed when deleting a story UI: Sources are now editable ("Move to...") --- diff --git a/changelog.md b/changelog.md index 458c2e5..3a99d86 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,9 @@ ## Version wip - Library: perf improvement when retrieving the stories (cover not loaded when not needed) +- Library: fix the covers that were not always removed when deleting a story - UI: perf improvement when displaying books (cover resized then cached) +- UI: Sources are now editable ("Move to...") ## Version 1.4.2 diff --git a/libs/nikiroo-utils-1.4.1-sources.jar b/libs/nikiroo-utils-1.4.2-sources.jar similarity index 91% rename from libs/nikiroo-utils-1.4.1-sources.jar rename to libs/nikiroo-utils-1.4.2-sources.jar index 721f793..2a4f7d1 100644 Binary files a/libs/nikiroo-utils-1.4.1-sources.jar and b/libs/nikiroo-utils-1.4.2-sources.jar differ diff --git a/src/be/nikiroo/fanfix/Library.java b/src/be/nikiroo/fanfix/Library.java index 7819eff..f1f7121 100644 --- a/src/be/nikiroo/fanfix/Library.java +++ b/src/be/nikiroo/fanfix/Library.java @@ -17,6 +17,7 @@ import be.nikiroo.fanfix.data.MetaData; import be.nikiroo.fanfix.data.Story; import be.nikiroo.fanfix.output.BasicOutput; import be.nikiroo.fanfix.output.BasicOutput.OutputType; +import be.nikiroo.fanfix.output.InfoCover; import be.nikiroo.fanfix.supported.BasicSupport; import be.nikiroo.fanfix.supported.BasicSupport.SupportType; import be.nikiroo.fanfix.supported.InfoReader; @@ -72,7 +73,7 @@ public class Library { } /** - * List all the known types of stories. + * List all the known types (sources) of stories. * * @return the types */ @@ -143,6 +144,11 @@ public class Library { * @return the stories */ public synchronized List getListByType(String type) { + if (type != null) { + // convert the type to dir name + type = getDir(type).getName(); + } + List list = new ArrayList(); for (Entry entry : getStories(null).entrySet()) { String storyType = entry.getValue().getParentFile().getName(); @@ -372,8 +378,8 @@ public class Library { key.setLuid(luid); } - getDir(key).mkdirs(); - if (!getDir(key).exists()) { + getDir(key.getSource()).mkdirs(); + if (!getDir(key.getSource()).exists()) { throw new IOException("Cannot create library dir"); } @@ -404,63 +410,137 @@ public class Library { public synchronized boolean delete(String luid) { boolean ok = false; + List files = getFiles(luid); + if (!files.isEmpty()) { + for (File file : files) { + IOUtils.deltree(file); + } + + ok = true; + + // clear cache + stories.clear(); + } + + return ok; + } + + /** + * Change the type (source) of the given {@link Story}. + * + * @param luid + * the {@link Story} LUID + * @param newSourcethe + * new source + * + * @return TRUE if the {@link Story} was found + */ + public synchronized boolean changeType(String luid, String newType) { + MetaData meta = getInfo(luid); + if (meta != null) { + meta.setSource(newType); + File newDir = getDir(meta.getSource()); + if (!newDir.exists()) { + newDir.mkdir(); + } + + List files = getFiles(luid); + for (File file : files) { + if (file.getName().endsWith(".info")) { + try { + String name = file.getName().replaceFirst("\\.info$", + ""); + InfoCover.writeInfo(newDir, name, meta); + file.delete(); + } catch (IOException e) { + Instance.syserr(e); + } + } else { + file.renameTo(new File(newDir, file.getName())); + } + } + + // clear cache + stories.clear(); + + return true; + } + + return false; + } + + /** + * Return the list of files/dirs on disk for this {@link Story}. + *

+ * If the {@link Story} is not found, and empty list is returned. + * + * @param luid + * the {@link Story} LUID + * + * @return the list of {@link File}s + */ + private List getFiles(String luid) { + List files = new ArrayList(); + MetaData meta = getInfo(luid); File file = getStories(null).get(meta); if (file != null) { - if (file.delete()) { - String readerExt = getOutputType(meta) - .getDefaultExtension(true); - String fileExt = getOutputType(meta).getDefaultExtension(false); - - String path = file.getAbsolutePath(); - if (readerExt != null && !readerExt.equals(fileExt)) { - path = path - .substring(0, path.length() - readerExt.length()) - + fileExt; - file = new File(path); - IOUtils.deltree(file); - } + files.add(file); - File infoFile = new File(path + ".info"); - if (!infoFile.exists()) { - infoFile = new File(path.substring(0, path.length() - - fileExt.length()) - + ".info"); - } - infoFile.delete(); - - String coverExt = "." - + Instance.getConfig().getString( - Config.IMAGE_FORMAT_COVER); - File coverFile = new File(path + coverExt); - if (!coverFile.exists()) { - coverFile = new File(path.substring(0, path.length() - - fileExt.length())); + String readerExt = getOutputType(meta).getDefaultExtension(true); + String fileExt = getOutputType(meta).getDefaultExtension(false); + + String path = file.getAbsolutePath(); + if (readerExt != null && !readerExt.equals(fileExt)) { + path = path.substring(0, path.length() - readerExt.length()) + + fileExt; + file = new File(path); + + if (file.exists()) { + files.add(file); } - coverFile.delete(); + } - ok = true; + File infoFile = new File(path + ".info"); + if (!infoFile.exists()) { + infoFile = new File(path.substring(0, + path.length() - fileExt.length()) + + ".info"); } - // clear cache - stories.clear(); + if (infoFile.exists()) { + files.add(infoFile); + } + + String coverExt = "." + + Instance.getConfig().getString(Config.IMAGE_FORMAT_COVER); + File coverFile = new File(path + coverExt); + if (!coverFile.exists()) { + coverFile = new File(path.substring(0, + path.length() - fileExt.length()) + + coverExt); + } + + if (coverFile.exists()) { + files.add(coverFile); + } } - return ok; + return files; } /** * The directory (full path) where the {@link Story} related to this * {@link MetaData} should be located on disk. * - * @param key - * the {@link Story} {@link MetaData} + * @param type + * the type (source) * * @return the target directory */ - private File getDir(MetaData key) { - String source = key.getSource().replaceAll("[^a-zA-Z0-9._+-]", "_"); + private File getDir(String type) { + String source = type.replaceAll("[^a-zA-Z0-9._+-]", "_"); return new File(baseDir, source); } @@ -479,7 +559,7 @@ public class Library { title = ""; } title = title.replaceAll("[^a-zA-Z0-9._+-]", "_"); - return new File(getDir(key), key.getLuid() + "_" + title); + return new File(getDir(key.getSource()), key.getLuid() + "_" + title); } /** diff --git a/src/be/nikiroo/fanfix/output/InfoCover.java b/src/be/nikiroo/fanfix/output/InfoCover.java index 4be150c..c7c80cc 100644 --- a/src/be/nikiroo/fanfix/output/InfoCover.java +++ b/src/be/nikiroo/fanfix/output/InfoCover.java @@ -12,7 +12,7 @@ import be.nikiroo.fanfix.Instance; import be.nikiroo.fanfix.bundles.Config; import be.nikiroo.fanfix.data.MetaData; -class InfoCover { +public class InfoCover { public static void writeInfo(File targetDir, String targetName, MetaData meta) throws IOException { File info = new File(targetDir, targetName + ".info"); diff --git a/src/be/nikiroo/fanfix/reader/LocalReader.java b/src/be/nikiroo/fanfix/reader/LocalReader.java index 29a840f..a3fdcab 100644 --- a/src/be/nikiroo/fanfix/reader/LocalReader.java +++ b/src/be/nikiroo/fanfix/reader/LocalReader.java @@ -254,4 +254,9 @@ class LocalReader extends BasicReader { } } + + void changeType(String luid, String newType) { + lib.changeType(luid, newType); + Instance.getLibrary().changeType(luid, newType); + } } diff --git a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java index bb77655..03df7fb 100644 --- a/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java +++ b/src/be/nikiroo/fanfix/reader/LocalReaderFrame.java @@ -13,6 +13,7 @@ import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -142,7 +143,8 @@ class LocalReaderFrame extends JFrame { * the selected type or author. * * @param value - * the author or the type + * the author or the type, or NULL to get all the + * authors-or-types * @param type * TRUE for type, FALSE for author */ @@ -188,6 +190,7 @@ class LocalReaderFrame extends JFrame { popup.add(createMenuItemOpenBook()); popup.addSeparator(); popup.add(createMenuItemExport()); + popup.add(createMenuItemMove()); popup.add(createMenuItemClearCache()); popup.add(createMenuItemRedownload()); popup.addSeparator(); @@ -265,6 +268,7 @@ class LocalReaderFrame extends JFrame { file.add(createMenuItemOpenBook()); file.add(createMenuItemExport()); + file.add(createMenuItemMove()); file.addSeparator(); file.add(imprt); file.add(imprtF); @@ -527,6 +531,68 @@ class LocalReaderFrame extends JFrame { return refresh; } + /** + * Create the delete menu item. + * + * @return the item + */ + private JMenuItem createMenuItemMove() { + JMenu moveTo = new JMenu("Move to..."); + moveTo.setMnemonic(KeyEvent.VK_M); + + List types = new ArrayList(); + types.add(null); + types.addAll(Instance.getLibrary().getTypes()); + + for (String type : types) { + JMenuItem item = new JMenuItem(type == null ? "New type..." : type); + + moveTo.add(item); + if (type == null) { + moveTo.addSeparator(); + } + + final String ftype = type; + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (selectedBook != null) { + String type = ftype; + if (type == null) { + Object rep = JOptionPane.showInputDialog( + LocalReaderFrame.this, "Move to:", + "Moving story", + JOptionPane.QUESTION_MESSAGE, null, null, + selectedBook.getMeta().getSource()); + if (rep == null) { + return; + } else { + type = rep.toString(); + } + } + + final String ftype = type; + outOfUi(null, new Runnable() { + public void run() { + reader.changeType(selectedBook.getMeta() + .getLuid(), ftype); + + selectedBook = null; + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + setJMenuBar(createMenu()); + } + }); + } + }); + } + } + }); + } + + return moveTo; + } + /** * Create the redownload (then delete original) menu item. *