From 70c9b112926f1cf95b2fddd0bb504ab37d6ddd1e Mon Sep 17 00:00:00 2001 From: Niki Roo Date: Sun, 2 Apr 2017 18:05:38 +0200 Subject: [PATCH] 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...") --- changelog.md | 2 + ...es.jar => nikiroo-utils-1.4.2-sources.jar} | Bin 56418 -> 56403 bytes src/be/nikiroo/fanfix/Library.java | 162 +++++++++++++----- src/be/nikiroo/fanfix/output/InfoCover.java | 2 +- src/be/nikiroo/fanfix/reader/LocalReader.java | 5 + .../fanfix/reader/LocalReaderFrame.java | 68 +++++++- 6 files changed, 196 insertions(+), 43 deletions(-) rename libs/{nikiroo-utils-1.4.1-sources.jar => nikiroo-utils-1.4.2-sources.jar} (91%) 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 721f7931413d53bac2dd29f125d5f6708f6bc1b5..2a4f7d1f6a630b4f4bee29d4d135505b783e043b 100644 GIT binary patch delta 3501 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 bxCWE(+cg3S%9F9c7Lz^P9|mU800000Sv0%~ delta 3511 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 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. * -- 2.27.0