Author: jflesch
Date: 2007-08-25 16:15:52 +0000 (Sat, 25 Aug 2007)
New Revision: 14878
Added:
trunk/apps/Thaw/src/thaw/plugins/IndexWebGrapher.java
trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/
trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphBuilder.java
trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphPanel.java
trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/Node.java
Modified:
trunk/apps/Thaw/src/thaw/core/PluginManager.java
trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
trunk/apps/Thaw/src/thaw/i18n/thaw.properties
trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
trunk/apps/Thaw/src/thaw/plugins/index/Index.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
Log:
Implement an index web grapher plugin (Graph must still be optimized)
Modified: trunk/apps/Thaw/src/thaw/core/PluginManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/PluginManager.java 2007-08-25 02:17:41 UTC
(rev 14877)
+++ trunk/apps/Thaw/src/thaw/core/PluginManager.java 2007-08-25 16:15:52 UTC
(rev 14878)
@@ -37,6 +37,7 @@
"thaw.plugins.Restarter",
"thaw.plugins.TransferLogs",
"thaw.plugins.MDns",
+ "thaw.plugins.IndexWebGrapher",
"thaw.plugins.SqlConsole",
"thaw.plugins.LogConsole"
};
Modified: trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties 2007-08-25
02:17:41 UTC (rev 14877)
+++ trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties 2007-08-25
16:15:52 UTC (rev 14878)
@@ -639,5 +639,15 @@
## Index web grapher
-thaw.plugin.indexWebGrapher=Dessinateur de toile d'index
+thaw.plugin.indexWebGrapher=Toile d'indexes
+thaw.plugin.indexWebGrapher.shortName=Toile d'indexes
+thaw.plugin.indexWebGrapher.compute=Calculer
+thaw.plugin.indexWebGrapher.computing=En cours ...
+thaw.plugin.indexWebGrapher.waiting=En attente
+thaw.plugin.indexWebGrapher.fanFan.0=H?h?, facile !
+thaw.plugin.indexWebGrapher.fanFan.1=C'est fait !
+thaw.plugin.indexWebGrapher.fanFan.2=Mouahah, je suis trop g?nial !
+thaw.plugin.indexWebGrapher.fanFan.3=C'?tait du gateau !
+thaw.plugin.indexWebGrapher.fanFan.4=Joli, n'est-ce pas ? :)
+
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-08-25 02:17:41 UTC
(rev 14877)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-08-25 16:15:52 UTC
(rev 14878)
@@ -657,4 +657,14 @@
## index web grapher
-thaw.plugin.indexWebGrapher=Dessinateur de toile d'index
+thaw.plugin.indexWebGrapher=Index web grapher
+thaw.plugin.indexWebGrapher.shortName=Index web
+thaw.plugin.indexWebGrapher.compute=Compute
+thaw.plugin.indexWebGrapher.computing=Computing
+thaw.plugin.indexWebGrapher.waiting=Waiting
+
+thaw.plugin.indexWebGrapher.fanFan.0=Hehe, easy !
+thaw.plugin.indexWebGrapher.fanFan.1=All done !
+thaw.plugin.indexWebGrapher.fanFan.2=Mooahah, I'm so good !
+thaw.plugin.indexWebGrapher.fanFan.3=Piece of cake !
+thaw.plugin.indexWebGrapher.fanFan.4=Nice, isn't it ? :)
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-08-25 02:17:41 UTC
(rev 14877)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-08-25 16:15:52 UTC
(rev 14878)
@@ -639,5 +639,15 @@
## Index web grapher
-thaw.plugin.indexWebGrapher=Dessinateur de toile d'index
+thaw.plugin.indexWebGrapher=Toile d'indexes
+thaw.plugin.indexWebGrapher.shortName=Toile d'indexes
+thaw.plugin.indexWebGrapher.compute=Calculer
+thaw.plugin.indexWebGrapher.computing=En cours ...
+thaw.plugin.indexWebGrapher.waiting=En attente
+thaw.plugin.indexWebGrapher.fanFan.0=H\u00e9h\u00e9, facile !
+thaw.plugin.indexWebGrapher.fanFan.1=C'est fait !
+thaw.plugin.indexWebGrapher.fanFan.2=Mouahah, je suis trop g\u00e9nial !
+thaw.plugin.indexWebGrapher.fanFan.3=C'\u00e9tait du gateau !
+thaw.plugin.indexWebGrapher.fanFan.4=Joli, n'est-ce pas ? :)
+
Added: trunk/apps/Thaw/src/thaw/plugins/IndexWebGrapher.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/IndexWebGrapher.java
(rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/IndexWebGrapher.java 2007-08-25
16:15:52 UTC (rev 14878)
@@ -0,0 +1,154 @@
+package thaw.plugins;
+
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.JButton;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.util.Random;
+
+
+import thaw.core.Core;
+import thaw.core.I18n;
+import thaw.core.Logger;
+
+import thaw.plugins.indexWebGrapher.*;
+
+
+
+public class IndexWebGrapher implements thaw.core.Plugin, ActionListener {
+ public final static int NMB_STEPS = 10;
+
+ private Core core;
+
+ private Hsqldb db;
+
+ private JPanel tabPanel;
+
+ private JScrollPane scrollPane;
+ private GraphPanel graphPanel;
+
+ private JButton compute;
+ private JButton zoomIn;
+ private JButton zoomOut;
+ private JProgressBar progressBar;
+
+ private Random random;
+
+ public boolean run(Core core) {
+ this.core = core;
+
+ this.random = new Random();
+
+ /** dep **/
+
+ if(core.getPluginManager().getPlugin("thaw.plugins.Hsqldb") ==
null) {
+ Logger.info(this, "Loading Hsqldb plugin");
+
+
if(core.getPluginManager().loadPlugin("thaw.plugins.Hsqldb") == null
+ ||
!core.getPluginManager().runPlugin("thaw.plugins.Hsqldb")) {
+ Logger.error(this, "Unable to load
thaw.plugins.Hsqldb !");
+ return false;
+ }
+ }
+
+ db =
(Hsqldb)core.getPluginManager().getPlugin("thaw.plugins.Hsqldb");
+ db.registerChild(this);
+
+
+ /** graphics **/
+
+ tabPanel = new JPanel(new BorderLayout(5, 5));
+
+ JPanel southPanel = new JPanel(new BorderLayout(5, 5));
+
+ compute = new
JButton(I18n.getMessage("thaw.plugin.indexWebGrapher.compute"));
+ compute.addActionListener(this);
+
+ progressBar = new JProgressBar(0, 100);
+
progressBar.setString(I18n.getMessage("thaw.plugin.indexWebGrapher.waiting"));
+ progressBar.setStringPainted(true);
+
+ JPanel zoomPanel = new JPanel(new GridLayout(1, 2));
+ zoomPanel.add( (zoomOut = new JButton("-")) );
+ zoomPanel.add( (zoomIn = new JButton("+")) );
+
+ zoomOut.addActionListener(this);
+ zoomIn.addActionListener(this);
+
+ southPanel.add(compute, BorderLayout.WEST);
+ southPanel.add(progressBar, BorderLayout.CENTER);
+ southPanel.add(zoomPanel, BorderLayout.EAST);
+
+
+ graphPanel = new GraphPanel(this);
+ scrollPane = new JScrollPane(graphPanel,
+
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ scrollPane.getVerticalScrollBar().setUnitIncrement(15);
+
+ tabPanel.add(scrollPane, BorderLayout.CENTER);
+ tabPanel.add(southPanel, BorderLayout.SOUTH);
+
+
core.getMainWindow().addTab(I18n.getMessage("thaw.plugin.indexWebGrapher.shortName"),
+ thaw.gui.IconBox.web,
+ tabPanel);
+
+ return true;
+ }
+
+
+ public JScrollPane getScrollPane() {
+ return scrollPane;
+ }
+
+
+ public void setProgress(int step) {
+ String txt = "";
+
+ if (step == NMB_STEPS) {
+ int fanFan = random.nextInt(5);
+ txt =
I18n.getMessage("thaw.plugin.indexWebGrapher.fanFan."+Integer.toString(fanFan));
+ } else {
+ txt =
I18n.getMessage("thaw.plugin.indexWebGrapher.computing")
+ +
"("+Integer.toString(step)+"/"+Integer.toString(NMB_STEPS)+")";
+ }
+
+ progressBar.setString(txt);
+ progressBar.setValue( (step * 100) / NMB_STEPS );
+ }
+
+
+ public boolean stop() {
+ core.getMainWindow().removeTab(tabPanel);
+
+ return true;
+ }
+
+ public String getNameForUser() {
+ return I18n.getMessage("thaw.plugin.indexWebGrapher");
+ }
+
+ public javax.swing.ImageIcon getIcon() {
+ return thaw.gui.IconBox.web;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == compute) {
+ GraphBuilder builder = new GraphBuilder(this,
graphPanel, db);
+ Thread th = new Thread(builder);
+ th.start();
+ } else if (e.getSource() == zoomIn) {
+ graphPanel.zoomIn();
+ } else if (e.getSource() == zoomOut) {
+ graphPanel.zoomOut();
+ }
+ }
+}
Modified: trunk/apps/Thaw/src/thaw/plugins/index/Index.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/index/Index.java 2007-08-25 02:17:41 UTC
(rev 14877)
+++ trunk/apps/Thaw/src/thaw/plugins/index/Index.java 2007-08-25 16:15:52 UTC
(rev 14878)
@@ -1448,12 +1448,6 @@
}
public boolean setNewCommentFlagInMem(boolean flag) {
- try {
- throw new Exception("bleh");
- } catch(Exception e) {
- e.printStackTrace();
- }
-
newComment = flag;
return true;
}
Added: trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphBuilder.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphBuilder.java
(rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphBuilder.java
2007-08-25 16:15:52 UTC (rev 14878)
@@ -0,0 +1,176 @@
+package thaw.plugins.indexWebGrapher;
+
+import java.sql.*;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+
+import thaw.plugins.IndexWebGrapher;
+import thaw.plugins.Hsqldb;
+
+import thaw.fcp.FreenetURIHelper;
+import thaw.core.Logger;
+
+
+public class GraphBuilder implements Runnable {
+
+ private IndexWebGrapher plugin;
+ private GraphPanel graphPanel;
+ private Hsqldb db;
+
+ public GraphBuilder(IndexWebGrapher plugin,
+ GraphPanel panel,
+ Hsqldb db) {
+ this.plugin = plugin;
+ this.graphPanel = panel;
+ this.db = db;
+ }
+
+ public void run() {
+ Logger.info(this, "=== Starting ===");
+
+ /* === */
+
+ plugin.setProgress(0);
+ Logger.info(this, "0) Loading all the nodes ...");
+
+ graphPanel.reinit();
+
+ try {
+ synchronized(db.dbLock) {
+ PreparedStatement st;
+
+ st =
db.getConnection().prepareStatement("SELECT id, displayName, publicKey "+
+ "FROM
indexes");
+
+ ResultSet set = st.executeQuery();
+
+ int nmb = 0;
+
+ while(set.next()) {
+ /* will register itself in the
graphPanel */
+ new Node(nmb,
+ set.getInt("id") /* index id
*/,
+ set.getString("displayName"),
+ set.getString("publicKey"),
+ graphPanel);
+ nmb++;
+ }
+
+ Logger.info(this, Integer.toString(nmb)+" nodes
loaded");
+ }
+ } catch(SQLException e) {
+ Logger.error(this, "Can't load the nodes because :
"+e.toString());
+ return;
+ }
+
+ /* === */
+
+ plugin.setProgress(1);
+ Logger.info(this, "1) Loading links ...");
+
+ try {
+ synchronized(db.dbLock) {
+ PreparedStatement st;
+
+ st =
db.getConnection().prepareStatement("SELECT publicKey FROM links WHERE
indexParent = ?");
+
+ for (Iterator it = (new
Vector(graphPanel.getNodeList())).iterator();
+ it.hasNext(); ) {
+ Node node = (Node)it.next();
+
+ st.setInt(1, node.getIndexId());
+
+ ResultSet set = st.executeQuery();
+
+ while(set.next()) {
+ String lnk =
set.getString("publicKey");
+
+ Node target =
graphPanel.getNode(lnk);
+
+ if (target == null) {
+ target = new
Node(graphPanel.getLastUsedId()+1,
+ -1 /*
indexId */,
+
FreenetURIHelper.getFilenameFromKey(lnk).replaceAll(".frdx", ""),
+ lnk,
+
graphPanel);
+ }
+
+ node.setLinkTo(target);
+ }
+ }
+ }
+ } catch(SQLException e) {
+ Logger.error(this, "Can't load the links because :
"+e.toString());
+ return;
+ }
+
+
+ /* === */
+
+ plugin.setProgress(2);
+ Logger.info(this, "2) Sorting the nodes according to their
number of links ...");
+
+ Vector nodes = new Vector(graphPanel.getNodeList());
+ java.util.Collections.sort(nodes);
+
+
+ /* === */
+
+ plugin.setProgress(3);
+ Logger.info(this, "3) Initial placing of the nodes ...");
+
+ double x = 0.0;
+
+ for (Iterator it = nodes.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+ if (!node.isPositionSet()) {
+ node.setPosition(x, 0.0);
+ node.setInitialNeightboorPositions();
+ x += (node.getLinkCount()+1);
+ }
+ }
+
+ /* === */
+
+ plugin.setProgress(4);
+ Logger.info(this, "4) Optimizing placement ...");
+
+ for (int i = 0 ; i < 100 ; i++) {
+ for (Iterator it = nodes.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+ node.computeVelocity(nodes);
+ }
+
+ boolean move = false;
+
+ for (Iterator it = nodes.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+ move |= node.applyVelocity();
+ }
+
+ if (!move) {
+ Logger.info(this, "Wow, fully optimized ?!");
+ break;
+ }
+ }
+
+ /* === */
+
+ plugin.setProgress(9);
+ Logger.info(this, "Drawing ...");
+
+ graphPanel.guessZoom();
+ graphPanel.refresh();
+
+ /* === */
+
+ plugin.setProgress(10);
+ Logger.info(this, "== Pouf, done ==");
+ } /* /run */
+
+}
Added: trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphPanel.java
(rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/GraphPanel.java
2007-08-25 16:15:52 UTC (rev 14878)
@@ -0,0 +1,203 @@
+package thaw.plugins.indexWebGrapher;
+
+import javax.swing.JPanel;
+import javax.swing.JComponent;
+import java.awt.Graphics;
+import java.awt.Dimension;
+
+import java.awt.event.MouseListener;
+import java.awt.event.MouseEvent;
+
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Iterator;
+
+import thaw.plugins.IndexWebGrapher;
+
+
+public class GraphPanel extends JComponent implements MouseListener {
+
+ public final static int BORDER = 50;
+
+ private Hashtable nodeHashtable;
+ private Vector nodeList;
+
+ private int lastId;
+
+ private double zoom;
+
+ private IndexWebGrapher plugin;
+
+ private Node lastSelectedNode;
+
+ public GraphPanel(IndexWebGrapher plugin) {
+ super();
+ this.plugin = plugin;
+ nodeHashtable = null;
+ nodeList = null;
+ lastId = 0;
+ setPreferredSize(new Dimension(10, 10));
+ this.addMouseListener(this);
+ }
+
+ public void reinit() {
+ lastSelectedNode = null;
+ nodeHashtable = new Hashtable();
+ nodeList = new Vector();
+ lastId = 0;
+ }
+
+ public void registerNode(Node node) {
+ nodeHashtable.put(node.getIndexKey().substring(4, 40),
+ node);
+ nodeList.add(node);
+
+ if (node.getId() > lastId)
+ lastId = node.getId();
+ }
+
+ public Node getNode(String key) {
+ return (Node)nodeHashtable.get(key.substring(4, 40));
+ }
+
+ public Vector getNodeList() {
+ return nodeList;
+ }
+
+ public int getLastUsedId() {
+ return lastId;
+ }
+
+
+ public void setZoom(double zoom) {
+ this.zoom = zoom;
+ }
+
+ private double minX = 0;
+ private double maxX = 0;
+ private double minY = 0;
+ private double maxY = 0;
+
+
+ public void guessZoom() {
+ minX = 0;
+ maxX = 0;
+ minY = 0;
+ maxY = 0;
+
+ for (Iterator it = nodeList.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (node.getX() < minX) minX = node.getX();
+ if (node.getX() > maxX) maxX = node.getX();
+ if (node.getY() < minY) minY = node.getY();
+ if (node.getY() > maxY) maxY = node.getY();
+ }
+
+ Dimension size = plugin.getScrollPane().getSize();
+
+ double zoomX = (size.getWidth()-(2*BORDER)) / (maxX - minX);
+ double zoomY = (size.getHeight()-(2*BORDER)) / (maxY - minY);
+
+ zoom = ((zoomX > zoomY) ? zoomY : zoomX);
+ }
+
+ public void zoomIn() {
+ zoom = zoom * 2.0;
+ refresh();
+ }
+
+ public void zoomOut() {
+ zoom = zoom / 2.0;
+ refresh();
+ }
+
+ public void refresh() {
+ Dimension dim = new Dimension((int)((maxX - minX) * zoom) +
(2*BORDER),
+ (int)((maxY - minY) * zoom) +
(2*BORDER));
+
+ this.setPreferredSize(dim);
+ this.setSize((int)((maxX - minX) * zoom) + (2*BORDER),
+ (int)((maxY - minY) * zoom) + (2*BORDER));
+ plugin.getScrollPane().revalidate();
+ repaint();
+ }
+
+
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ Dimension d = getSize();
+ g.setColor(java.awt.Color.WHITE);
+ g.fillRect(0, 0, (int)d.getWidth(), (int)d.getHeight());
+
+ if (nodeList == null)
+ return;
+
+ int zeroX = (-1 * (int)(minX * zoom)) + BORDER;
+ int zeroY = (-1 * (int)(minY * zoom)) + BORDER;
+
+ for (Iterator it = nodeList.iterator();
+ it.hasNext();) {
+ ((Node)it.next()).paintTaNodeFaceDeNoeud(g, zoom,
zeroX, zeroY);
+ }
+ }
+
+
+ public void clicked(int x, int y) {
+ int zeroX = (-1 * (int)(minX * zoom)) + BORDER;
+ int zeroY = (-1 * (int)(minY * zoom)) + BORDER;
+
+ if (lastSelectedNode != null)
+ lastSelectedNode.setSelected(false);
+
+ Node bestPlaced = null;
+ double bestDist = 0.0;
+
+ for (Iterator it = nodeList.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (bestPlaced == null) {
+ bestPlaced = node;
+ double diffBestX =
Math.abs(bestPlaced.getXPixel(zoom, zeroX)-x);
+ double diffBestY =
Math.abs(bestPlaced.getYPixel(zoom, zeroY)-y);
+
+ bestDist = Math.sqrt(Math.pow(diffBestX,
2)+Math.pow(diffBestY, 2));
+ } else {
+ double diffNodeX =
Math.abs(node.getXPixel(zoom, zeroX)-x);
+ double diffNodeY =
Math.abs(node.getYPixel(zoom, zeroY)-y);
+
+ double distNode = Math.sqrt(Math.pow(diffNodeX,
2) + Math.pow(diffNodeY, 2));
+
+ if (distNode < bestDist) {
+ bestPlaced = node;
+ bestDist = distNode;
+ }
+ }
+ }
+
+ if (bestPlaced != null) {
+ bestPlaced.setSelected(true);
+ lastSelectedNode = bestPlaced;
+ }
+
+ repaint();
+ }
+
+ public void mouseClicked(final MouseEvent e) {
+ clicked(e.getX(), e.getY());
+ }
+
+ public void mouseEntered(final MouseEvent e) { }
+ public void mouseExited(final MouseEvent e) { }
+
+ public void mousePressed(final MouseEvent e) {
+ clicked(e.getX(), e.getY());
+ }
+
+ public void mouseReleased(final MouseEvent e) {
+ clicked(e.getX(), e.getY());
+ }
+}
Added: trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/Node.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/Node.java
(rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/indexWebGrapher/Node.java 2007-08-25
16:15:52 UTC (rev 14878)
@@ -0,0 +1,316 @@
+package thaw.plugins.indexWebGrapher;
+
+import java.util.Vector;
+import java.util.Iterator;
+
+import java.awt.Graphics;
+import java.awt.Color;
+
+import thaw.core.Logger;
+
+
+public class Node implements Comparable {
+
+ public final static int RADIUS = 4;
+
+ private int id;
+ private int indexId;
+ private String indexName;
+ private String indexKey;
+ private GraphPanel graphPanel;
+
+ private Vector linkTo;
+ private Vector linkedFrom;
+
+ /**
+ * @param indexId -1 if none
+ */
+ public Node(int id,
+ int indexId,
+ String indexName,
+ String indexKey,
+ GraphPanel graphPanel) {
+ this.id = id;
+ this.indexId = indexId;
+ this.indexName = indexName;
+ this.indexKey = indexKey;
+ this.graphPanel = graphPanel;
+
+ linkTo = new Vector();
+ linkedFrom = new Vector();
+
+ graphPanel.registerNode(this);
+ }
+
+
+ public int getId() {
+ return id;
+ }
+
+ public int getIndexId() {
+ return indexId;
+ }
+
+ public String getIndexKey() {
+ return indexKey;
+ }
+
+ public String getIndexName() {
+ return indexName;
+ }
+
+ public void setLinkTo(Node node) {
+ linkTo.add(node);
+ node.setLinkedFrom(this);
+ }
+
+ private void setLinkedFrom(Node node) {
+ linkedFrom.add(node);
+ }
+
+ public Vector getLinkList() {
+ return linkTo;
+ }
+
+ public int getLinkCount() {
+ return linkTo.size() + linkedFrom.size();
+ }
+
+ /**
+ * we want the nodes with the higher number of
+ * links first => we consider them smaller
+ */
+ public int compareTo(final Object o) {
+ final Node node = (Node)o;
+
+ if (node.getLinkCount() < getLinkCount())
+ return -1;
+ if (node.getLinkCount() > getLinkCount())
+ return 1;
+
+ return 0;
+ }
+
+
+ private boolean posSet = false;
+ private double x = -1;
+ private double y = -1;
+
+ public boolean isPositionSet() {
+ return posSet;
+ }
+
+
+ public void setPosition(double x, double y) {
+ posSet = true;
+ this.x = x;
+ this.y = y;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+
+ private double velocityX = 0.0;
+ private double velocityY = 0.0;
+
+ public final static double TIMESTEP = 0.1;
+
+ private double[] attraction(Node node) {
+ return new double[] {0, 0};
+ }
+
+ private double[] repulsion(Node node) {
+ return new double[] {0, 0};
+ }
+
+ /**
+ * see http://en.wikipedia.org/wiki/Force-based_algorithms
+ */
+ public void computeVelocity(Vector nodeList) {
+ double netForceX = 0.0;
+ double netForceY = 0.0;
+
+ /* repulsion */
+ for (Iterator it = nodeList.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (node == this
+ || linkTo.indexOf(node) >= 0
+ || linkedFrom.indexOf(node) >= 0)
+ continue;
+
+ double[] repuls = repulsion(node);
+ netForceX += repuls[0];
+ netForceY += repuls[1];
+ }
+
+ /* attraction */
+ for (Iterator it = linkTo.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (node == this)
+ continue;
+
+ double[] attr = attraction(node);
+ netForceX += attr[0];
+ netForceY += attr[1];
+ }
+
+ /* attraction */
+ for (Iterator it = linkedFrom.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (node == this)
+ continue;
+
+ double[] attr = attraction(node);
+ netForceX += attr[0];
+ netForceY += attr[1];
+ }
+
+ velocityX += netForceX;
+ velocityY += netForceY;
+ }
+
+ /**
+ * @return true if moved
+ */
+ public boolean applyVelocity() {
+ if (velocityX == 0 && velocityY == 0)
+ return false;
+
+ x += velocityX * TIMESTEP;
+ y += velocityY * TIMESTEP;
+
+ return true;
+ }
+
+
+ /**
+ * Recursivity : Dirty, but easier :P
+ */
+ public void setInitialNeightboorPositions() {
+ int unplaced = 0;
+
+ for (Iterator it = linkTo.iterator();
+ it.hasNext(); ) {
+ Node node = (Node)it.next();
+
+ if (!node.isPositionSet())
+ unplaced++;
+ }
+
+ if (unplaced == 0)
+ return;
+
+ double step = (2*Math.PI) / unplaced;
+
+ double current = 0;
+
+ for (Iterator it = linkTo.iterator();
+ it.hasNext();) {
+ Node node = (Node)it.next();
+
+ if (!node.isPositionSet()) {
+ double diffX = Math.cos(current) * (unplaced+1);
+ double diffY = Math.sin(current) * (unplaced+1);
+
+ node.setPosition(x + diffX,
+ y + diffY);
+
+ node.setInitialNeightboorPositions();
+
+ current += step;
+ }
+ }
+
+ return;
+ }
+
+
+ public boolean linkTo(Node node) {
+ return (linkTo.indexOf(node) >= 0);
+ }
+
+ private boolean selected = false;
+
+ public void setSelected(boolean sel) {
+ this.selected = sel;
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ public double getXPixel(double zoom, int zeroX) {
+ return (double)((int)(x*zoom) + zeroX);
+ }
+
+ public double getYPixel(double zoom, int zeroY) {
+ return (double)((int)(y*zoom) + zeroY);
+ }
+
+
+ public void paintTaNodeFaceDeNoeud(Graphics g, double zoom,
+ int zeroX, int zeroY) {
+
+ int realX = (int)(x*zoom);
+ int realY = (int)(y*zoom);
+
+ if (selected)
+ g.setColor(Color.ORANGE);
+ else
+ g.setColor(Color.GRAY);
+
+ for (Iterator it = linkTo.iterator();
+ it.hasNext();) {
+ Node target = (Node)it.next();
+
+ int targetX = (int)(target.getX()*zoom);
+ int targetY = (int)(target.getY()*zoom);
+
+ if (target.isSelected()) {
+ g.setColor(Color.CYAN);
+ }
+
+ if ( (target.isSelected() || selected)
+ && target.linkTo(this) ) {
+ g.setColor(Color.PINK);
+ }
+
+ g.drawLine(realX+zeroX, realY+zeroY, targetX+zeroX,
targetY+zeroY);
+
+ if (target.isSelected())
+ g.setColor(Color.GRAY);
+ }
+
+
+ if (selected)
+ g.setColor(Color.RED);
+ else
+ g.setColor(Color.GREEN);
+
+ g.fillOval( realX - RADIUS + zeroX,
+ realY - RADIUS + zeroY,
+ 2*RADIUS,
+ 2*RADIUS);
+
+
+ if (selected) {
+ g.setColor(Color.BLACK);
+
+ g.drawString(indexName,
+ realX + zeroX,
+ realY + zeroY - 10);
+ }
+ }
+}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
2007-08-25 02:17:41 UTC (rev 14877)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
2007-08-25 16:15:52 UTC (rev 14878)
@@ -534,38 +534,41 @@
}
protected void endOfRefresh() {
- Logger.info(this, "End of refresh");
+ synchronized(this) {
+ Logger.info(this, "End of refresh");
- try {
- Hsqldb db = factory.getDb();
+ try {
+ Hsqldb db = factory.getDb();
- synchronized(db.dbLock) {
- PreparedStatement st;
+ synchronized(db.dbLock) {
+ PreparedStatement st;
- st =
db.getConnection().prepareStatement("UPDATE frostKSKBoards "+
- "SET
lastUpdate = ? "+
- "WHERE
id = ?");
- st.setDate(1, new java.sql.Date(new
java.util.Date().getTime()));
- st.setInt(2, id);
- st.execute();
+ st =
db.getConnection().prepareStatement("UPDATE frostKSKBoards "+
+
"SET lastUpdate = ? "+
+
"WHERE id = ?");
+ st.setDate(1, new java.sql.Date(new
java.util.Date().getTime()));
+ st.setInt(2, id);
+ st.execute();
+ }
+ } catch(SQLException e) {
+ Logger.error(this, "Unable to update the
lastUpdate date :"+e.toString());
}
- } catch(SQLException e) {
- Logger.error(this, "Unable to update the lastUpdate
date :"+e.toString());
- }
- int newMsgs = getNewMessageNumber();
+ int newMsgs = getNewMessageNumber();
- if (newMsgs > 0) {
- String announce =
I18n.getMessage("thaw.plugin.miniFrost.newMsgAnnounce");
- announce = announce.replaceAll("X",
Integer.toString(newMsgs));
- announce = announce.replaceAll("Y", toString());
+ if (newMsgs > 0) {
+ String announce =
I18n.getMessage("thaw.plugin.miniFrost.newMsgAnnounce");
+ announce = announce.replaceAll("X",
Integer.toString(newMsgs));
+ announce = announce.replaceAll("Y", toString());
-
thaw.plugins.TrayIcon.popMessage(factory.getCore().getPluginManager(),
- "MiniFrost",
- announce);
+
thaw.plugins.TrayIcon.popMessage(factory.getCore().getPluginManager(),
+ "MiniFrost",
+ announce);
+ }
+
+ refreshing = false;
}
- refreshing = false;
notifyChange();
}
@@ -744,7 +747,11 @@
this.maxDaysInThePast = maxDaysInThePast;
- refreshing = true;
+ synchronized(this) {
+ lastDate = getNextRefreshDate(null);
+ lastRev = -1;
+ refreshing = true;
+ }
notifyChange();
@@ -756,8 +763,6 @@
//lastDate = new Date((new Date()).getTime()
// + (MIN_DAYS_IN_THE_FUTURE * (24 * 60 * 60 *
1000 /* 1 day */)));
- lastDate = getNextRefreshDate(null);
- lastRev = -1;
synchronized(runningDownloads) {
lastSuccessfulRev = getLastDownloadedRev(lastDate);
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
2007-08-25 02:17:41 UTC (rev 14877)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
2007-08-25 16:15:52 UTC (rev 14878)
@@ -205,7 +205,7 @@
|| (board.getCurrentlyRefreshedDate() != null
&&
(KSKBoard.getMidnight(board.getCurrentlyRefreshedDate()).getTime()
< KSKBoard.getMidnight(date).getTime()) )) {
- Logger.info(this, "Board:
"+Long.toString(KSKBoard.getMidnight(board.getCurrentlyRefreshedDate()).getTime()));
+ //Logger.info(this, "Board:
"+Long.toString(KSKBoard.getMidnight(board.getCurrentlyRefreshedDate()).getTime()));
Logger.info(this, "Draft:
"+KSKBoard.getMidnight(date).getTime());
return true;
}