diff --git a/src/latmod/cursegraph/Curse.java b/src/latmod/cursegraph/Curse.java index 192d96f..1b17409 100644 --- a/src/latmod/cursegraph/Curse.java +++ b/src/latmod/cursegraph/Curse.java @@ -52,22 +52,25 @@ public static class Project implements Comparable @Expose public Integer typeID; @Expose public String title; - @Expose public String game; - @Expose public String category; @Expose public String url; @Expose public String thumbnail; @Expose public String[] authors; @Expose public Map downloads; @Expose public Integer favorites; @Expose public Integer likes; - @Expose public String updated_at; - @Expose public String created_at; @Expose public String project_url; - @Expose public String release_type; - @Expose public String license; @Expose public Version download; @Expose public Map versions; + public boolean checkValid() + { + if(title == null) return false; + if(url == null) return false; + if(download == null) return false; + if(versions == null) return false; + return true; + } + private int totalDownloads = -1; public String toString() diff --git a/src/latmod/cursegraph/CurseGraphFrame.java b/src/latmod/cursegraph/CurseGraphFrame.java index 768ed65..edb67a4 100644 --- a/src/latmod/cursegraph/CurseGraphFrame.java +++ b/src/latmod/cursegraph/CurseGraphFrame.java @@ -2,6 +2,7 @@ import java.awt.*; import java.awt.event.*; +import java.util.*; import javax.swing.*; @@ -10,104 +11,155 @@ public class CurseGraphFrame extends JFrame private static final long serialVersionUID = 1L; public static final CurseGraphFrame inst = new CurseGraphFrame(); - public final JTabbedPane pane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); + public final JTabbedPane pane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT); public CurseGraphFrame() { setTitle("CurseGraph v" + Main.version); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); add(pane); + this.setSize(700, 500); pane.setSize(700, 500); setResizable(true); refresh(); pack(); setLocationRelativeTo(null); + + setVisible(!Main.config.startMinimized.booleanValue()); + setIconImage(Main.imageReady); } public void refresh() { pane.removeAll(); + pane.setTabLayoutPolicy(Main.config.scrollTabs.booleanValue() ? JTabbedPane.SCROLL_TAB_LAYOUT : JTabbedPane.WRAP_TAB_LAYOUT); + + ArrayList componentsAdded = new ArrayList(); + componentsAdded.add("Settings"); JPanel settingsPanel = new JPanel(false); - //settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.Y_AXIS)); - BorderLayout layout = new BorderLayout(); - layout.setHgap(40); - layout.setVgap(50); + GridLayout layout = new GridLayout(); + layout.setColumns(1); + layout.setRows(0); + layout.setVgap(5); settingsPanel.setLayout(layout); + { + JButton b = new JButton("Add"); + b.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + try + { + String types[] = Curse.Type.getAllNames(); + String type0 = (String)JOptionPane.showInputDialog(null, "Select the mod:", "Add new Project", JOptionPane.PLAIN_MESSAGE, null, types, Curse.Type.MOD.name); + if(type0 == null || type0.isEmpty()) return; + Curse.Type t = Curse.Type.getFromName(type0); + + String input = JOptionPane.showInputDialog("Enter " + t.name + "'s ProjectID here:", ""); + if(input != null && !input.trim().isEmpty()) + { + Projects.add(t, input.trim(), false); + Main.refresh(); + } + } + catch(Exception ex) + { ex.printStackTrace(); } + } + }); + + settingsPanel.add(b); + } + { JButton b = new JButton("Refresh"); - b.setAlignmentX(Component.CENTER_ALIGNMENT); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) - { try { refresh(); Graph.logData(); } catch(Exception ex) + { try { Main.refresh(); Graph.logData(); } catch(Exception ex) { ex.printStackTrace(); } } }); - settingsPanel.add(b, BorderLayout.LINE_END); + settingsPanel.add(b); } { - JButton b = new JButton("Set refresh interval"); - b.setAlignmentX(Component.CENTER_ALIGNMENT); + JButton b = new JButton("Set graph type"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - String input = JOptionPane.showInputDialog("Set refresh minutes:", "" + Main.config.refreshMinutes); - if(input != null && !input.isEmpty()) + try { - try + int times[] = { -1, 1, 24, 24 * 7, 24 * 30 }; + String types[] = { "None", "Hour", "Day", "Week", "Month" }; + + String type0 = (String)JOptionPane.showInputDialog(null, "Select graph type:", "Graph type", JOptionPane.PLAIN_MESSAGE, null, types, types[0]); + if(type0 == null || type0.isEmpty()) return; + + for(int i = 0; i < types.length; i++) { - int i = Integer.parseInt(input); - Main.config.refreshMinutes = Math.max(1, i); - Main.config.save(); - - Graph.checker.start(); + if(type0.equals(types[i])) + { + Main.config.graphLimit = times[i]; + Main.refresh(); + } } - catch(Exception ex) - { Main.error("Invalid number!"); } } + catch(Exception ex) + { ex.printStackTrace(); } } }); - settingsPanel.add(b, BorderLayout.LINE_START); + //settingsPanel.add(b); } { - JButton b = new JButton("Add"); - b.setAlignmentX(Component.CENTER_ALIGNMENT); + final boolean scrollTabs = Main.config.scrollTabs.booleanValue(); + final JButton b = new JButton("Scrolling Tabs " + (scrollTabs ? "[ON]" : "[OFF]")); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - try + Main.config.scrollTabs = !Main.config.scrollTabs.booleanValue(); + Main.config.save(); + refresh(); + } + }); + + settingsPanel.add(b); + } + + { + JButton b = new JButton("Set refresh interval"); + b.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + String input = JOptionPane.showInputDialog("Set refresh minutes:", "" + Main.config.refreshMinutes); + if(input != null && !input.isEmpty()) { - String types[] = Curse.Type.getAllNames(); - String type0 = (String)JOptionPane.showInputDialog(null, "Select the mod:", "Add new Project", JOptionPane.PLAIN_MESSAGE, null, types, Curse.Type.MOD.name); - if(type0 == null || type0.isEmpty()) return; - Curse.Type t = Curse.Type.getFromName(type0); - - String input = JOptionPane.showInputDialog("Enter " + t.name + "'s ProjectID here:", ""); - if(input != null && !input.isEmpty()) + try { - Projects.add(t, input, false); - refresh(); + int i = Integer.parseInt(input); + Main.config.refreshMinutes = Math.max(1, i); + Main.config.save(); + + Graph.checker.start(); } + catch(Exception ex) + { Main.error("Invalid number!", false); } } - catch(Exception ex) - { ex.printStackTrace(); } } }); - settingsPanel.add(b, BorderLayout.CENTER); + settingsPanel.add(b); } { JButton b = new JButton("Open data folder"); - b.setAlignmentX(Component.CENTER_ALIGNMENT); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -115,24 +167,106 @@ public void actionPerformed(ActionEvent e) catch(Exception ex) { ex.printStackTrace(); } } }); - settingsPanel.add(b, BorderLayout.PAGE_START); + settingsPanel.add(b); } + /* + { + PopupMenu m1 = new PopupMenu("Clear older than..."); + + { + MenuItem m2 = new MenuItem("Month"); + + m2.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { Graph.clearData(getH(24 * 30)); } + }); + + m1.add(m2); + } + + { + MenuItem m2 = new MenuItem("Week"); + + m2.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { Graph.clearData(getH(24 * 7)); } + }); + + m1.add(m2); + } + + { + MenuItem m2 = new MenuItem("Day"); + + m2.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { Graph.clearData(getH(24)); } + }); + + m1.add(m2); + } + + { + MenuItem m2 = new MenuItem("Hour"); + + m2.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { Graph.clearData(getH(1)); } + }); + + m1.add(m2); + } + + { + MenuItem m2 = new MenuItem("X Minues"); + + m2.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + String input = JOptionPane.showInputDialog("X Minutes:", "10"); + if(input != null && !input.isEmpty()) + { + try + { + int i = Integer.parseInt(input); + i = Math.max(1, i); + Graph.clearData(i * 60000L); + } + catch(Exception ex) + { error("Invalid number!", false); } + } + } + }); + + m1.add(m2); + } + + menu.add(m1); + } + */ { JButton b = new JButton("Exit"); - b.setAlignmentX(Component.CENTER_ALIGNMENT); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); - settingsPanel.add(b, BorderLayout.PAGE_END); + settingsPanel.add(b); } addPanel("Settings", settingsPanel); - for(final Curse.Project p : Projects.list) + Curse.Project[] projectsList = Projects.list.toArray(new Curse.Project[0]); + Arrays.sort(projectsList); + + for(final Curse.Project p : projectsList) { final JPanel panel = new JPanel(false); @@ -247,7 +381,7 @@ public void actionPerformed(ActionEvent e) { Projects.list.remove(p); Projects.save(); - refresh(); + Main.refresh(); } } }); @@ -259,9 +393,32 @@ public void actionPerformed(ActionEvent e) panel.add(new JCurseGraph(panel, p)); addPanel(p.title, panel); + componentsAdded.add(p.title); + } + + JPopupMenu menuAll = new JPopupMenu(); + + for(int i = 0; i < componentsAdded.size(); i++) + { + final JMenuItem item = new JMenuItem(componentsAdded.get(i)); + final int index = i; + item.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + pane.setSelectedIndex(index); + } + }); + + menuAll.add(item); } + + pane.setComponentPopupMenu(menuAll); } + //private static long getH(int i) + //{ return 1000L * 60L * 60L * i; } + public void addPanel(String title, JComponent c) { pane.addTab(title, null, c, title); } } \ No newline at end of file diff --git a/src/latmod/cursegraph/Graph.java b/src/latmod/cursegraph/Graph.java index 9792ab6..8068f13 100644 --- a/src/latmod/cursegraph/Graph.java +++ b/src/latmod/cursegraph/Graph.java @@ -68,13 +68,25 @@ public void run() } } + public static class TimedDown implements Comparable + { + public long time; + public int down; + + public TimedDown(long t, int v) + { time = t; down = v; } + + public int compareTo(TimedDown o) + { return new Long(time).compareTo(o.time); } + } + public static File dataFile; public static GraphData graphData; public static Checker checker; public static void init() throws Exception { - dataFile = new File(Main.folder, "data.json"); + dataFile = new File(Main.config.dataFileLocation); graphData = Utils.fromJsonFile(dataFile, GraphData.class); if(!dataFile.exists()) dataFile.createNewFile(); @@ -117,14 +129,50 @@ public static String getTimeString(long time) private static String formNum(int i) { return (i < 10) ? ("0" + i) : ("" + i); } + public static ArrayList getAllKeys(String mod) + { + ArrayList alist = new ArrayList(); + + Map map = graphData.projects.get(mod); + + if(map == null || map.isEmpty()) return alist; + + TimedDown[] list = new TimedDown[map.size()]; + + Iterator keys = map.keySet().iterator(); + Iterator values = map.values().iterator(); + + int i = -1; while(keys.hasNext()) + list[++i] = new TimedDown(keys.next(), values.next()); + + Arrays.sort(list); + + for(i = 0; i < list.length; i++) + alist.add(list[i]); + + return alist; + } + + public static ArrayList getKeys(String mod, long min, long max) + { + ArrayList al = getAllKeys(mod); + + for(int i = 0; i < al.size(); i++) + { + long v = al.get(i).time; + if(v < min && v > max) + al.remove(i); + } + + return al; + } + public static void logData() throws Exception { if(graphData == null) graphData = new GraphData(); long ms = System.currentTimeMillis(); - //System.out.println("Data logged with ID " + ms + "!"); - checkNull(); if(Projects.hasProjects()) for(Curse.Project p : Projects.list) @@ -189,7 +237,7 @@ public static void clearData(long l) Main.refresh(); } - Main.info("Removed " + i + " values!"); + Main.info("Removed " + i + " values!", false); } catch(Exception e) { e.printStackTrace(); } diff --git a/src/latmod/cursegraph/JCurseGraph.java b/src/latmod/cursegraph/JCurseGraph.java index 6146c5b..d2fab02 100644 --- a/src/latmod/cursegraph/JCurseGraph.java +++ b/src/latmod/cursegraph/JCurseGraph.java @@ -4,6 +4,7 @@ import java.awt.event.*; import java.awt.image.BufferedImage; import java.util.*; +import java.util.List; import javax.swing.*; @@ -11,18 +12,6 @@ public class JCurseGraph extends JLabel implements MouseMotionListener, MouseLis { private static final long serialVersionUID = 1L; - private static class TimedValue implements Comparable - { - public Long time; - public Integer down; - - public TimedValue(Long t, Integer v) - { time = t; down = v; } - - public int compareTo(TimedValue o) - { return time.compareTo(o.time); } - } - private static class GraphPoint { public final int x; @@ -91,53 +80,61 @@ public void paint(Graphics g) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - Map map = Graph.graphData.projects.get(project.projectID); - - TimedValue values[] = new TimedValue[map.size()]; + List values = Graph.getAllKeys(project.projectID); long minTime = -1; long maxTime = -1; int minDown = -1; int maxDown = -1; - int index = -1; - for(Long l : map.keySet()) - values[++index] = new TimedValue(l, map.get(l)); + //values.add(new Graph.TimedDown(System.currentTimeMillis(), project.getTotalDownloads())); - //values[values.length - 1] = new TimedValue(System.currentTimeMillis(), mod.getTotalDownloads()); - - Arrays.sort(values); - - for(int i = 0; i < values.length; i++) + for(int i = 0; i < values.size(); i++) { - if(minTime == -1 || values[i].time < minTime) minTime = values[i].time; - if(maxTime == -1 || values[i].time > maxTime) maxTime = values[i].time; - if(minDown == -1 || values[i].down < minDown) minDown = values[i].down; - if(maxDown == -1 || values[i].down > maxDown) maxDown = values[i].down; + Graph.TimedDown t = values.get(i); + if(minTime == -1 || t.time < minTime) minTime = t.time; + if(maxTime == -1 || t.time > maxTime) maxTime = t.time; + if(minDown == -1 || t.down < minDown) minDown = t.down; + if(maxDown == -1 || t.down > maxDown) maxDown = t.down; } ArrayList points = new ArrayList(); - for(int i = 0; i < values.length; i++) + if(Main.config.graphLimit.intValue() > 0) { - long time = values[i].time.longValue(); - int downs = values[i].down.intValue(); + int pc = Main.config.graphLimit.intValue() * 4; - double x=0, y=0; + long currentTime = System.currentTimeMillis(); + long h24 = (24000L * 3600L); - if(Main.config.graphRelative.booleanValue()) + for(int i = 0; i < pc; i++) { - x = Utils.map(time, minTime, maxTime, 0D, w); - y = Utils.map(downs, minDown, maxDown, h, 0D); + long time = currentTime - h24 + (i * 3600000L); + + //long time = values[i].time.longValue(); + //int downs = values[i].down.intValue(); + + double x = Utils.map(minTime, minTime, maxTime, 0D, w); + double y = Utils.map(minDown, minDown, maxDown, h, 0D); + + y = Math.max(2, Math.min(y, h - 2)); + points.add(new GraphPoint(x, y, time, 0)); } - else + + } + else + { + for(int i = 0; i < values.size(); i++) { - x = Utils.map(time, minTime, maxTime, 0D, w); - y = Utils.map(downs, minDown, maxDown, h, 0D); + Graph.TimedDown t = values.get(i); + + double x = Utils.map(t.time, minTime, maxTime, 0D, w); + double y = Utils.map(t.down, minDown, maxDown, h, 0D); + + y = Math.max(2, Math.min(y, h - 2)); + points.add(new GraphPoint(x, y, t.time, t.down)); } - y = Math.max(2, Math.min(y, h - 2)); - points.add(new GraphPoint(x, y, time, downs)); } boolean isOver = false; diff --git a/src/latmod/cursegraph/Main.java b/src/latmod/cursegraph/Main.java index 0f6d126..3dc3bc9 100644 --- a/src/latmod/cursegraph/Main.java +++ b/src/latmod/cursegraph/Main.java @@ -13,7 +13,7 @@ public class Main { - public static final int version = 5; + public static final int version = 6; public static int latestVersion = -1; public static TrayIcon trayIcon = null; @@ -23,19 +23,19 @@ public class Main public static File projectsFile, configFile; public static Config config; + private static boolean firstRefresh; + public static void main(String[] args) throws Exception { - if(!SystemTray.isSupported() || !Desktop.isDesktopSupported()) + if(!Desktop.isDesktopSupported()) { - System.out.println("Invalid system!"); + System.out.println("Desktop not supported!"); System.exit(1); return; } System.out.println("Loading CurseGraph, Version: " + version + " @ " + Graph.getTimeString(System.currentTimeMillis())); - projectsFile = new File(folder, "projects.json"); configFile = new File(folder, "config.json"); - config = Utils.fromJsonFile(configFile, Config.class); if(!configFile.exists()) configFile.createNewFile(); @@ -43,6 +43,8 @@ public static void main(String[] args) throws Exception config.setDefaults(); config.save(); + projectsFile = new File(config.projectsFileLocation); + try { String s = Utils.toString(new URL("http://pastebin.com/raw.php?i=RyuQPm4f").openStream()); @@ -54,24 +56,36 @@ public static void main(String[] args) throws Exception imageReady = loadImage("trayIcon.png"); imageBusy = loadImage("trayIconBusy.png"); + firstRefresh = true; + trayIcon = new TrayIcon(imageReady); trayIcon.setImageAutoSize(true); trayIcon.setToolTip("Curse Graph"); - SystemTray.getSystemTray().add(trayIcon); - trayIcon.addActionListener(new ActionListener() + if(!Utils.contains(args, "notray")) { - public void actionPerformed(ActionEvent e) - { CurseGraphFrame.inst.setVisible(!CurseGraphFrame.inst.isVisible()); } - }); + if(!SystemTray.isSupported()) + { + System.out.println("System tray not supported!"); + System.exit(1); return; + } + + SystemTray.getSystemTray().add(trayIcon); + + trayIcon.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { CurseGraphFrame.inst.setVisible(!CurseGraphFrame.inst.isVisible()); } + }); + } refresh(); Projects.save(); Graph.init(); - if(latestVersion > version) info("Update available!"); + if(latestVersion > version) info("Update available!", false); - CurseGraphFrame.inst.setVisible(!config.startMinimized.booleanValue()); + firstRefresh = false; } private static File getFolder() @@ -87,6 +101,7 @@ public static BufferedImage loadImage(String s) throws Exception public static void refresh() { trayIcon.setImage(imageBusy); + if(!firstRefresh) CurseGraphFrame.inst.setIconImage(imageBusy); Projects.load(); PopupMenu menu = new PopupMenu(); @@ -105,85 +120,6 @@ public void actionPerformed(ActionEvent e) menu.addSeparator(); - { - PopupMenu m1 = new PopupMenu("Clear older than..."); - - { - MenuItem m2 = new MenuItem("Month"); - - m2.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { Graph.clearData(getH(24 * 30)); } - }); - - m1.add(m2); - } - - { - MenuItem m2 = new MenuItem("Week"); - - m2.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { Graph.clearData(getH(24 * 7)); } - }); - - m1.add(m2); - } - - { - MenuItem m2 = new MenuItem("Day"); - - m2.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { Graph.clearData(getH(24)); } - }); - - m1.add(m2); - } - - { - MenuItem m2 = new MenuItem("Hour"); - - m2.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { Graph.clearData(getH(1)); } - }); - - m1.add(m2); - } - - { - MenuItem m2 = new MenuItem("X Minues"); - - m2.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) - { - String input = JOptionPane.showInputDialog("X Minutes:", "10"); - if(input != null && !input.isEmpty()) - { - try - { - int i = Integer.parseInt(input); - i = Math.max(1, i); - Graph.clearData(i * 60000L); - } - catch(Exception ex) - { error("Invalid number!"); } - } - } - }); - - m1.add(m2); - } - - menu.add(m1); - } - { MenuItem m1 = new MenuItem("Exit"); @@ -201,21 +137,19 @@ public void actionPerformed(ActionEvent e) trayIcon.setPopupMenu(menu); trayIcon.setImage(imageReady); + if(!firstRefresh) CurseGraphFrame.inst.setIconImage(imageReady); CurseGraphFrame.inst.refresh(); } - private static long getH(int i) - { return 1000L * 60L * 60L * i; } - - public static void info(String string) + public static void info(String string, boolean silent) { - JOptionPane.showMessageDialog(null, string, "Info", JOptionPane.INFORMATION_MESSAGE); + if(!silent) JOptionPane.showMessageDialog(null, string, "Info", JOptionPane.INFORMATION_MESSAGE); System.out.println(string); } - public static void error(String string) + public static void error(String string, boolean silent) { - JOptionPane.showMessageDialog(null, string, "Error!", JOptionPane.ERROR_MESSAGE); + if(!silent) JOptionPane.showMessageDialog(null, string, "Error!", JOptionPane.ERROR_MESSAGE); System.out.println(string); } @@ -232,18 +166,20 @@ public static void openURL(String s) public static class Config { @Expose public Integer refreshMinutes; - @Expose public String lastProjectID; - @Expose public Boolean graphRelative; @Expose public Integer graphLimit; @Expose public Boolean startMinimized; + @Expose public String dataFileLocation; + @Expose public String projectsFileLocation; + @Expose public Boolean scrollTabs; public void setDefaults() { if(refreshMinutes == null) refreshMinutes = 30; - if(lastProjectID == null) lastProjectID = ""; - if(graphRelative == null) graphRelative = false; if(graphLimit == null) graphLimit = -1; if(startMinimized == null) startMinimized = true; + if(dataFileLocation == null) dataFileLocation = new File(folder, "data.json").getAbsolutePath(); + if(projectsFileLocation == null) projectsFileLocation = new File(folder, "projects.json").getAbsolutePath(); + if(scrollTabs == null) scrollTabs = true; } public void save() diff --git a/src/latmod/cursegraph/Projects.java b/src/latmod/cursegraph/Projects.java index 013ea8e..1d4b78c 100644 --- a/src/latmod/cursegraph/Projects.java +++ b/src/latmod/cursegraph/Projects.java @@ -65,7 +65,7 @@ public static boolean load() if(!loadOld()) addedAll = false; - if(!addedAll) Main.error("Some projects failed to load!"); + if(!addedAll) Main.error("Some projects failed to load!", false); return hasProjects(); } @@ -99,35 +99,35 @@ public static boolean add(Curse.Type t, String id, boolean silent) String s = sc.useDelimiter("\\A").next(); sc.close(); Curse.Project m = Utils.fromJson(s, Curse.Project.class); - if(m != null) + if(m != null && m.checkValid()) { m.projectID = id; m.typeID = t.ordinal(); - if(!list.contains(m)) list.add(m); - else + if(list.contains(m)) { - if(!silent) Main.error("Duplicate ProjectID!"); + Main.error("Duplicate ProjectID '" + id + "'!", silent); return false; } + + list.add(m); + + if(!silent) + { + save(); + Graph.logData(); + } + + Main.info("Added '" + m.title + "'!", silent); + + return true; } - - if(!silent) - { - save(); - Main.info("Added '" + m.title + "'!"); - Graph.logData(); - } - - return true; } catch(Exception ex) - { - ex.printStackTrace(); - if(!silent) Main.error("Mod '" + id + "' failed to load!"); - else System.out.println("Failed to load " + id + " as " + t.name); - return false; - } + { ex.printStackTrace(); } + + Main.error("Project with ID '" + id + "' failed to load!", silent); + return false; } public static void save() diff --git a/src/latmod/cursegraph/Utils.java b/src/latmod/cursegraph/Utils.java index 696a7f0..e49c5bd 100644 --- a/src/latmod/cursegraph/Utils.java +++ b/src/latmod/cursegraph/Utils.java @@ -88,4 +88,17 @@ public static double distSq(double x1, double y1, double x2, double y2) public static double dist(double x1, double y1, double x2, double y2) { return Math.sqrt(distSq(x1, y1, x2, y2)); } + + public static boolean contains(Object[] oa, Object o) + { + if(oa == null || oa.length == 0 || o == null) return false; + + for(int i = 0; i < oa.length; i++) + { + if(oa[i] != null && (oa[i] == o || oa[i].equals(o))) + return true; + } + + return false; + } } \ No newline at end of file