From: David Schmidt Date: Sat, 18 Jan 2003 14:37:24 +0000 (+0000) Subject: Initial checkin of directory structure and source code of the java Activity X-Git-Tag: v_3_1_archive_branchpoint~38 X-Git-Url: http://www.privoxy.org/gitweb/?a=commitdiff_plain;h=dc5206b121c1641820bf9069222c87d2659b89c9;p=privoxy.git Initial checkin of directory structure and source code of the java Activity Console --- diff --git a/src/java/org/privoxy/activityconsole/ActivityConsole.java b/src/java/org/privoxy/activityconsole/ActivityConsole.java new file mode 100644 index 00000000..f0df73ac --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ActivityConsole.java @@ -0,0 +1,67 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Launch the Activity Console GUI with either the + * specified listen port or the default if none is + * specified on the command line. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +/** + * Launch the Activity Console GUI with either the specified listen port + * or the default if none is specified on the command line. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class ActivityConsole +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + /** + * main method; initializes the GUI. + * + * @String[] args - command line parameters. + */ + public static void main(java.lang.String[] args) + { + try + { + ActivityConsoleGui gui = new ActivityConsoleGui(args[0]); + } + catch (Throwable t) + { + ActivityConsoleGui gui = new ActivityConsoleGui("8119"); + } + } +} diff --git a/src/java/org/privoxy/activityconsole/ActivityConsoleGui.java b/src/java/org/privoxy/activityconsole/ActivityConsoleGui.java new file mode 100644 index 00000000..2f85dc39 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ActivityConsoleGui.java @@ -0,0 +1,629 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Provide the central GUI for displaying Privoxy + * statistics. It can be contacted either by the + * local machine or other machines in a network and + * display consolidated, tabular statistics. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.border.*; +import javax.swing.event.*; +import javax.swing.table.*; + +/** + * The main Activity Console GUI. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public final class ActivityConsoleGui extends JFrame implements ActionListener +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + ActivityConsoleGui parent_; + ServerThread _serverThread = null; + private ListResourceBundle resStrings = (ListResourceBundle)ListResourceBundle.getBundle("org.privoxy.activityconsole.ActivityConsoleResources"); + + JTable _table; + + SortableTableModel _model; + + Vector + _tableColumnMap = new Vector(); + + JPanel + mainPanel = new JPanel(new GridBagLayout()); + + JMenuItem _deleteItem, _quitItem, _configItem; + + private DefaultTableCellRenderer _statRenderer = null; + + int _port = 0; + + /** + * Constructor of the Activity Console GUI. + * @param arg the port to serve connections on - as an int parsed from the String + */ + public ActivityConsoleGui(String arg) + { + int i; + + addWindowListener(new WindowCloseMonitor()); + + JMenuBar menuBar = new JMenuBar(); + + JMenu menuFile = new JMenu(resStrings.getString("menuFile")); + MenuAction quitAction = new MenuAction(resStrings.getString("menuFileQuit")); + JMenu menuEdit = new JMenu(resStrings.getString("menuEdit")); + _quitItem = menuFile.add(quitAction); + menuBar.add(menuFile); + _configItem = menuEdit.add(new MenuAction(resStrings.getString("menuEditConfig"))); + menuBar.add(menuEdit); + _deleteItem = menuEdit.add(new MenuAction(resStrings.getString("menuEditDelete"))); + menuBar.add(menuEdit); + this.setJMenuBar(menuBar); + _deleteItem.setEnabled(false); + + try + { + _port = Integer.parseInt(arg); + if (_port < 0) + _port = 0; + } + catch (Throwable t) + { + _port = 0; + } + + /** + * The cell renderer for the StatWidget Component - simply returns the component + * itself. Additionally, it has the extra hack of telling the StatWidget where + * it is in the table so it can update itself again when it comes time to flash. + */ + _statRenderer = new DefaultTableCellRenderer() + { + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) + { + /* Housekeeping: keep track of the row, column and table references as we go */ + ((StatWidget)value).setRowColTable(row,column,table); + return(Component)value; + } + + public void setValue(Object value) + { + Color color = null; + try + { + color = (Color)value; + } + catch (ClassCastException e) + { + color = Color.white; + } + setBackground(color); + } + }; + + Vector data = new Vector(); + _model = new SortableTableModel(data, getColumnNames()); + _table = new JTable(_model); + _table.setPreferredScrollableViewportSize(new Dimension(800,50)); + _table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + _table.setCellSelectionEnabled(false); + _table.setRowSelectionAllowed(false); + + /* + * The first column is normal and text-ish - the host address and + * port being served (i.e. 127.0.0.1:8118). The rest need to have statistic + * renderers defined. + */ + SortButtonRenderer _headerRenderer = new SortButtonRenderer(); + TableColumnModel cm = _table.getColumnModel(); + /* Make the first column twice the width of the others. It shows bigger stuff. */ + cm.getColumn(0).setPreferredWidth(cm.getColumn(0).getPreferredWidth() * 2); + cm.getColumn(0).setHeaderRenderer(_headerRenderer); + for (i = 1;i<_model.getColumnCount();i++) + { + cm.getColumn(i).setPreferredWidth((int)(cm.getColumn(i).getPreferredWidth() * 1)); + cm.getColumn(i).setCellRenderer(_statRenderer); + cm.getColumn(i).setHeaderRenderer(_headerRenderer); + } + + JTableHeader header = _table.getTableHeader(); + header.addMouseListener(new HeaderListener(header,_headerRenderer)); + + ListSelectionModel csm = _table.getSelectionModel(); + csm.addListSelectionListener(new SelectedListener(csm)); + + ActivityConsoleGuiUtil.constrain(mainPanel, new JScrollPane(_table), + 1, 1, // X, Y Coordinates + 1, 1, // Grid width, height + GridBagConstraints.BOTH, // Fill value + GridBagConstraints.WEST, // Anchor value + 1.0,1.0, // Weight X, Y + 0, 0, 0, 0 ); // Top, left, bottom, right insets + + this.getContentPane().add(mainPanel, BorderLayout.CENTER); + + parent_ = this; + this.pack(); + _table.setPreferredScrollableViewportSize(new Dimension(_table.getWidth(),50)); + this.pack(); + + if (_port > 0) + { + _serverThread = new ServerThread(this, _port); + _serverThread.start(); + } + updateTitle(_port); + setBounds(ActivityConsoleGuiUtil.center(this.getSize())); + this.show(); + } + + /** + * Updates the title bar with the port currently being served. + * @param port the port being served + */ + public void updateTitle(int port) + { + String title = resStrings.getString("guiTitle"); + + title = StringUtil.replaceSubstring(title,"%1",""+port); + setTitle(title); + } + + public void actionPerformed(ActionEvent e) + { + } + + class MenuAction extends AbstractAction + { + public MenuAction(String text) + { + super(text,null); + } + + public MenuAction(String text, Icon icon) + { + super(text,icon); + } + + public void actionPerformed(ActionEvent e) + { + if (e.getSource() == _quitItem) + { + parent_.setVisible(false); + parent_.dispose(); + System.exit(0); + } + else if (e.getSource() == _deleteItem) + { + deleteAction(); + } + else if (e.getSource() == _configItem) + { + changeServerAction(); + } + } + } + + /** + * Asks the user to specify a new port to serve + */ + public void changeServerAction() + { + int port = -1; + String message = resStrings.getString("guiNewPortPrompt"); + message = StringUtil.replaceSubstring(message,"%1",""+_port); + + String inputValue = JOptionPane.showInputDialog(this, + message, + resStrings.getString("guiNewPortTitle"), + JOptionPane.QUESTION_MESSAGE); + if (inputValue != null) + try + { + port = Integer.parseInt(inputValue); + } + catch (Throwable t) + { + port = -1; + } + if (port < 1) + JOptionPane.showMessageDialog(null, resStrings.getString("guiNewPortErrorPrompt"), resStrings.getString("guiNewPortErrorTitle"), JOptionPane.ERROR_MESSAGE); + else + { + if (_port != port) + { + if (_serverThread != null) + { + _serverThread.doClose(); + _serverThread.interrupt(); + _serverThread = null; + } + _port = port; + _serverThread = new ServerThread(parent_, port); + _serverThread.start(); + updateTitle(_port); + } + } + } + + /** + * Deletes the "selected" row after seeking confirmation + */ + public void deleteAction() + { + int numSelections = _table.getSelectedRowCount(); + int selRow = _table.getSelectedRow(); + if (numSelections > 0) + { + if ((selRow > -1) && + (selRow < _table.getRowCount())) + { + /* Ask for confirmation */ + String message = resStrings.getString("guiDeleteConfirmPrompt"); + message = StringUtil.replaceSubstring(message,"%1",(String)_model.getValueAt(selRow,0)); + int ret = JOptionPane.showConfirmDialog(null, + message, + resStrings.getString("guiDeleteConfirmTitle"), + JOptionPane.YES_NO_OPTION); + if (ret == JOptionPane.YES_OPTION) + { + _model.removeRow(selRow); + } + } + } + } + + /** + * Retrieves the names of the column headers. This should be made to read a properties + * file. FIXME. + * @return Vector the set of column names. It also has the side-effect of adding + * entries to the global column mapping Vector where we map the staus integer identifiers + * to the column positions and names. Should probably fix that too. + */ + public Vector getColumnNames() + { + Vector names = new Vector(); + + names.addElement(resStrings.getString("guiDefaultColumn0")); + names.addElement(resStrings.getString("guiDefaultColumn1")); + names.addElement(resStrings.getString("guiDefaultColumn2")); + names.addElement(resStrings.getString("guiDefaultColumn3")); + names.addElement(resStrings.getString("guiDefaultColumn4")); + names.addElement(resStrings.getString("guiDefaultColumn5")); + names.addElement(resStrings.getString("guiDefaultColumn6")); + names.addElement(resStrings.getString("guiDefaultColumn7")); + names.addElement(resStrings.getString("guiDefaultColumn8")); + names.addElement(resStrings.getString("guiDefaultColumn9")); + names.addElement(resStrings.getString("guiDefaultColumn10")); + + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn1"),1)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn2"),2)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn3"),3)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn4"),4)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn5"),5)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn6"),6)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn7"),7)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn8"),8)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn9"),9)); + _tableColumnMap.addElement(new ColumnRef(resStrings.getString("guiDefaultColumn10"),10)); + + return names; + } + + /** + * Parses a String of statistics coming from Privoxy. + * @param line The statistics string sent from Privoxy + * @param from the hostname that sent the statistics + */ + public void updateStats(String line, String from) + { + /* + * An example line of data: + * 0:8118 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 + */ + int key, value; + String tableKey = "", key_str, value_str, token; + StringTokenizer colonToken; + StringTokenizer spaceTokens = new StringTokenizer(line); + Vector stats = new Vector(); + + while (spaceTokens.hasMoreTokens()) + { + token = spaceTokens.nextToken(); + colonToken = new StringTokenizer(token,":"); + if (colonToken.hasMoreTokens()) + { + key_str = null; value_str = null; + key = -1; value = 0; + + /* First token is the key */ + key_str = colonToken.nextToken(); + try + { + key = Integer.parseInt(key_str); + } + catch (NumberFormatException n) + { + key = -1; + } + + if ((colonToken.hasMoreTokens()) && (key > -1)) + { + /* Next token, if present, is the value */ + value_str = colonToken.nextToken(); + if (key == 0) + { + /* + * The key to the table row is the concatenation of the serving + * IP address string, a full colon, and the port string. + */ + tableKey = from + ":" + value_str; + } + try + { + value = Integer.parseInt(value_str); + stats.addElement((Object)(new Stat(key, value))); + } + catch (NumberFormatException n) + { + value = 0; + } + } + } + } + if ((tableKey.compareTo("") != 0) && (stats.size() > 0)) + { + updateTable(tableKey, stats); + stats.removeAllElements(); + } + stats = null; + } + + /** + * Updates (or creates) a line in the table representing the incoming packet of stats. + * @param tableKey Our key to a unique table row: the hostname concatenated with the Privoxy port being served. + * @param stats Vector of statistics elements + */ + public void updateTable(String tableKey, Vector stats) + { + boolean found = false; + for (int i = 0; i < _model.getRowCount(); i++) + { + if (((String)_model.getValueAt(i,_table.convertColumnIndexToView(0))).compareTo(tableKey) == 0) + { + updateTableEntry(i, stats); + found = true; + } + } + /* If we can't find one in the table already... */ + if (found == false) + createTableEntry(tableKey, stats); + } + + /** + * Creates a line in the table representing the incoming packet of stats. + * @param tableKey Our key to a unique table row: the hostname concatenated with the Privoxy port being served. + * @param stats Vector of statistics elements + */ + public void createTableEntry(String tableKey, Vector stats) + { + int i, j; + Vector row = new Vector(); + boolean added = false; + + row.addElement(tableKey); + + /* + * If we have a key (in stats) that maps to a key in the _tableColumnMap, + * then we add it to the vector destined for the table. + */ + for (i = 0; i < _tableColumnMap.size(); i ++) + { + for (j = 0; j < stats.size(); j++) + { + if (((Stat)stats.elementAt(j)).getKey() == ((ColumnRef)_tableColumnMap.elementAt(i)).getKey()) + { + row.addElement(new StatWidget(((Stat)stats.elementAt(j)).getValue(),500)); + added = true; + } + } + if (added == false) + { + row.addElement(new StatWidget(0,500)); + } + else + added = false; + } + _model.addRow(row); + } + + /** + * Updates a line in the table by tweaking the StatWidgets. + * @param row the table row if the StatWidget + * @param stats The Vector of Stat elements to update the table row with + */ + public void updateTableEntry(int row, Vector stats) + { + int i, j; + + for (i = 0; i < _tableColumnMap.size(); i ++) + { + for (j = 0; j < stats.size(); j++) + { + if (((Stat)stats.elementAt(j)).getKey() == ((ColumnRef)_tableColumnMap.elementAt(i)).getKey()) + { + ((StatWidget)_model.getValueAt(row,i+1)).updateValue(((Stat)stats.elementAt(j)).getValue()); + stats.removeElementAt(j); + break; + } + } + } + } + + /** + * Worker class to offer a clickable table header for sorting. + */ + class HeaderListener extends MouseAdapter + { + JTableHeader header; + SortButtonRenderer renderer; + + HeaderListener(JTableHeader header,SortButtonRenderer renderer) + { + this.header = header; + this.renderer = renderer; + } + + public void mousePressed(MouseEvent e) + { + Point click = e.getPoint(); + int col = header.columnAtPoint(click); + int margin1, margin2; + int sortCol = header.getTable().convertColumnIndexToModel(col); + + /* Don't perform the sort if the user is just trying to resize the columns. */ + margin1 = header.columnAtPoint(new Point(click.x+3,click.y)); + margin2 = header.columnAtPoint(new Point(click.x-3,click.y)); + if ((col == margin1) && (col == margin2)) + { + renderer.setPressedColumn(col); + renderer.setSelectedColumn(col); + header.repaint(); + + if (header.getTable().isEditing()) + { + header.getTable().getCellEditor().stopCellEditing(); + } + + boolean isAscent; + if (SortButtonRenderer.DOWN == renderer.getState(col)) + { + isAscent = true; + } + else + { + isAscent = false; + } + ((SortableTableModel)header.getTable().getModel()) + .sortByColumn(sortCol, isAscent); + } + } + + public void mouseReleased(MouseEvent e) + { + int col = header.columnAtPoint(e.getPoint()); + renderer.setPressedColumn(-1); // clear + header.repaint(); + } + } + + /** + * Worker class to tell the menu when it's OK to delete a row (i.e. when a row gets + * selected). This doesn't work reliably, but it's better than nothing. + */ + public class SelectedListener implements ListSelectionListener + { + ListSelectionModel model; + + public SelectedListener(ListSelectionModel lsm) + { + model = lsm; + } + + public void valueChanged(ListSelectionEvent lse) + { + // NOTE - keep this in sync with columnSelectionChanged below... + int numSelections = _table.getSelectedRowCount(); + int selRow = _table.getSelectedRow(); + if (numSelections > 0) + { + if ((selRow > -1) && + (selRow < _table.getRowCount())) + { + _deleteItem.setEnabled(true); + } + else + _deleteItem.setEnabled(false); + } + else + _deleteItem.setEnabled(false); + } + public void columnSelectionChanged(ListSelectionEvent lse) + { + // NOTE - keep this in sync with valueChanged above... + int numSelections = _table.getSelectedRowCount(); + int selRow = _table.getSelectedRow(); + if (numSelections > 0) + { + if ((selRow > -1) && + (selRow < _table.getRowCount())) + { + _deleteItem.setEnabled(true); + } + else + _deleteItem.setEnabled(false); + } + else + _deleteItem.setEnabled(false); + } + } + + /** + * Watch for the window closing event. Dunno why swing doesn't handle this better natively. + */ + public class WindowCloseMonitor extends WindowAdapter + { + public void windowClosing(WindowEvent e) + { + Window w = e.getWindow(); + w.setVisible(false); + w.dispose(); + System.exit(0); + } + } +} \ No newline at end of file diff --git a/src/java/org/privoxy/activityconsole/ActivityConsoleGuiUtil.java b/src/java/org/privoxy/activityconsole/ActivityConsoleGuiUtil.java new file mode 100644 index 00000000..468f8321 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ActivityConsoleGuiUtil.java @@ -0,0 +1,207 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Utility functions for GridBag layout and centering + * frames. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.awt.*; + +/** + * The ActivityConsoleGuiUtil class: Helper routines for the GridBag layout. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class ActivityConsoleGuiUtil +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + /** constrain - Helper method for setting a componets constraints in a gridbag layout; + * takes all of the possible parameters for grid constraints. + * @param container conatiner to add the component to + * @param component component that will be added + * @param grid_x x value + * @param grid_y y value + * @param grid_width grid width for the component + * @param grid_height grid height for the component + * @param fill fill value + * @param anchor anchor value + * @param weight_x weight x + * @param weight_y weight y + * @param top top inset + * @param left left inset + * @param bottom bottom inset + * @param right right inset + */ + + public static void constrain(Container container, + Component component, + int grid_x, + int grid_y, + int grid_width, + int grid_height, + int fill, + int anchor, + double weight_x, + double weight_y, + int top, + int left, + int bottom, + int right) + { + GridBagConstraints c = new GridBagConstraints(); + c.gridx = grid_x; + c.gridy = grid_y; + c.gridwidth = grid_width; + c.gridheight = grid_height; + c.fill = fill; + c.anchor = anchor; + c.weightx = weight_x; + c.weighty = weight_y; + if (top+bottom+left+right > 0) + c.insets = new Insets(top, left, bottom, right); + + ((GridBagLayout)container.getLayout()).setConstraints(component, c); + container.add(component); + } + + public static void constrain(Container container, + Component component, + int grid_x, + int grid_y, + int grid_width, + int grid_height) + { + constrain(container, + component, + grid_x, + grid_y, + grid_width, + grid_height, + GridBagConstraints.NONE, + GridBagConstraints.NORTHWEST, + 0.0, 0.0, 0, 0, 0, 0); + } + + public static void constrain(Container container, + Component component, + int grid_x, + int grid_y, + int grid_width, + int grid_height, + int top, + int left, + int bottom, + int right) + { + constrain(container, + component, + grid_x, + grid_y, + grid_width, + grid_height, + GridBagConstraints.NONE, + GridBagConstraints.NORTHWEST, + 0.0, 0.0, top, left, bottom, right); + } + + /** constrainLast - Helper method for setting a componets constraints in a gridbag layout; + * takes all of the possible parameters for grid constraints. + * @param container conatiner to add the component to + * @param component component that will be added + * @param grid_x x value + * @param grid_y y value + * @param top top inset + * @param left left inset + * @param bottom bottom inset + * @param right right inset + */ + + public static void constrainLast(Container container, + Component component, + int grid_x, + int grid_y, + int top, + int left, + int bottom, + int right) + { + constrain(container, + component, + grid_x, + grid_y, + GridBagConstraints.REMAINDER,1, + GridBagConstraints.HORIZONTAL, + GridBagConstraints.NORTHWEST, + 0.0, 0.0, top, left, bottom, right); + } + + /** constrain - Helper method for setting a componets constraints in a gridbag layout; + * takes all of the possible parameters for grid constraints. + * @param container conatiner to add the component to + * @param component component that will be added + * @param int x value + * @param int y value + * @param int top inset + * @param int left inset + * @param int bottom inset + * @param int right inset + */ + + public static void constrain(Container container, Component component, + int grid_x, int grid_y,int top, int left, int bottom, int right) + { + constrain(container, + component, + grid_x, + grid_y, + 1, 1, + GridBagConstraints.NONE, + GridBagConstraints.NORTHWEST, + 0.0, 0.0, top, left, bottom, right); + } + + public static Rectangle center(Dimension dim) + { + final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + final Rectangle centeredRect = + new Rectangle( (screenSize.width - dim.width) /2, + (screenSize.height - dim.height) /2, + dim.width, + dim.height); + return centeredRect; + } +} diff --git a/src/java/org/privoxy/activityconsole/ActivityConsoleResources.java b/src/java/org/privoxy/activityconsole/ActivityConsoleResources.java new file mode 100644 index 00000000..a614fad8 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ActivityConsoleResources.java @@ -0,0 +1,107 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Default English text for all translatable strings. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.io.Serializable; + +/** + * The default (English) language resources file for the Activity Console. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class ActivityConsoleResources extends java.util.ListResourceBundle implements Serializable +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + static final Object[][] contents = + { + {"guiTitle", "Activity Console - serving port %1"}, + {"menuFile", "File"}, + {"menuFileQuit", "Quit"}, + {"menuEdit", "Edit"}, + {"menuEditDelete", "Delete selected row"}, + {"menuEditConfig", "Set port"}, + {"guiNewPortTitle", "New port"}, + {"guiNewPortPrompt", "Currently serving port %1.\n\nPlease enter the new port to serve:"}, + {"guiNewPortErrorTitle", "Alert"}, + {"guiNewPortErrorPrompt", "New port must be positive."}, + {"guiDeleteConfirmTitle","Are you sure?"}, + {"guiDeleteConfirmPrompt","Are you sure you want to delete stats from host %1?"}, + + /* Headers and descriptions for statistics columns */ + {"guiDefaultColumn0","Host:Port"}, + {"guiDefaultColumn0Description","The host and port that statistics are coming from"}, + {"guiDefaultColumn1","Request"}, + {"guiDefaultColumn1Description","The number of requests that flow through the proxy"}, + {"guiDefaultColumn2","Filter"}, + {"guiDefaultColumn2Description","The number of filters that have been applied"}, + {"guiDefaultColumn3","Image"}, + {"guiDefaultColumn3Description","The number of images that have been blocked"}, + {"guiDefaultColumn4","De-anim"}, + {"guiDefaultColumn4Description","The number of GIF images that have been de-animated"}, + {"guiDefaultColumn5","Cookie"}, + {"guiDefaultColumn5Description","The number of cookies that have been blocked"}, + {"guiDefaultColumn6","Referer"}, + {"guiDefaultColumn6Description","The number of referers blocked"}, + {"guiDefaultColumn7","ACL"}, + {"guiDefaultColumn7Description","The number of blocks due to ACL restrictions"}, + {"guiDefaultColumn8","UA"}, + {"guiDefaultColumn8Description","The number of times user-agent header was removed"}, + {"guiDefaultColumn9","FROM"}, + {"guiDefaultColumn9Description","The number of times the from: header was removed"}, + {"guiDefaultColumn10","FORWARD"}, + {"guiDefaultColumn10Description","The number of times the forward header was removed"}, + }; + + /** Returns the contents of this ListBundleResources class. + * @see java.util.ListBundleResource + * @return Object an Object array containing this classes resources. + */ + protected Object[][] getContents() + { + return contents; + } + + /** Returns the name of the language this class represents. + * @return String the name of the language this class represents. + */ + + public String toString() + { + return "English"; + } +} diff --git a/src/java/org/privoxy/activityconsole/BevelArrowIcon.java b/src/java/org/privoxy/activityconsole/BevelArrowIcon.java new file mode 100644 index 00000000..c430c9aa --- /dev/null +++ b/src/java/org/privoxy/activityconsole/BevelArrowIcon.java @@ -0,0 +1,202 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Painting details for rendering the beveled arrow icon. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.awt.*; +import javax.swing.*; + +/** + * Painting details for rendering the beveled arrow icon. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class BevelArrowIcon implements Icon +{ + + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + public static final int UP = 0; // direction + public static final int DOWN = 1; + + private static final int DEFAULT_SIZE = 11; + + private Color edge1; + private Color edge2; + private Color fill; + private int size; + private int direction; + + public BevelArrowIcon(int direction, boolean isRaisedView, boolean isPressedView) + { + if (isRaisedView) + { + if (isPressedView) + { + init( UIManager.getColor("controlLtHighlight"), + UIManager.getColor("controlDkShadow"), + UIManager.getColor("controlShadow"), + DEFAULT_SIZE, direction); + } + else + { + init( UIManager.getColor("controlHighlight"), + UIManager.getColor("controlShadow"), + UIManager.getColor("control"), + DEFAULT_SIZE, direction); + } + } + else + { + if (isPressedView) + { + init( UIManager.getColor("controlDkShadow"), + UIManager.getColor("controlLtHighlight"), + UIManager.getColor("controlShadow"), + DEFAULT_SIZE, direction); + } + else + { + init( UIManager.getColor("controlShadow"), + UIManager.getColor("controlHighlight"), + UIManager.getColor("control"), + DEFAULT_SIZE, direction); + } + } + } + + public BevelArrowIcon(Color edge1, Color edge2, Color fill, + int size, int direction) + { + init(edge1, edge2, fill, size, direction); + } + + + public void paintIcon(Component c, Graphics g, int x, int y) + { + switch (direction) + { + case DOWN: drawDownArrow(g, x, y); break; + case UP: drawUpArrow(g, x, y); break; + } + } + + public int getIconWidth() + { + return size; + } + + public int getIconHeight() + { + return size; + } + + + private void init(Color edge1, Color edge2, Color fill, + int size, int direction) + { + this.edge1 = edge1; + this.edge2 = edge2; + this.fill = fill; + this.size = size; + this.direction = direction; + } + + private void drawDownArrow(Graphics g, int xo, int yo) + { + g.setColor(edge1); + g.drawLine(xo, yo, xo+size-1, yo); + g.drawLine(xo, yo+1, xo+size-3, yo+1); + g.setColor(edge2); + g.drawLine(xo+size-2, yo+1, xo+size-1, yo+1); + int x = xo+1; + int y = yo+2; + int dx = size-6; + while (y+1 < yo+size) + { + g.setColor(edge1); + g.drawLine(x, y, x+1, y); + g.drawLine(x, y+1, x+1, y+1); + if (0 < dx) + { + g.setColor(fill); + g.drawLine(x+2, y, x+1+dx, y); + g.drawLine(x+2, y+1, x+1+dx, y+1); + } + g.setColor(edge2); + g.drawLine(x+dx+2, y, x+dx+3, y); + g.drawLine(x+dx+2, y+1, x+dx+3, y+1); + x += 1; + y += 2; + dx -= 2; + } + g.setColor(edge1); + g.drawLine(xo+(size/2), yo+size-1, xo+(size/2), yo+size-1); + } + + private void drawUpArrow(Graphics g, int xo, int yo) + { + g.setColor(edge1); + int x = xo+(size/2); + g.drawLine(x, yo, x, yo); + x--; + int y = yo+1; + int dx = 0; + while (y+3 < yo+size) + { + g.setColor(edge1); + g.drawLine(x, y, x+1, y); + g.drawLine(x, y+1, x+1, y+1); + if (0 < dx) + { + g.setColor(fill); + g.drawLine(x+2, y, x+1+dx, y); + g.drawLine(x+2, y+1, x+1+dx, y+1); + } + g.setColor(edge2); + g.drawLine(x+dx+2, y, x+dx+3, y); + g.drawLine(x+dx+2, y+1, x+dx+3, y+1); + x -= 1; + y += 2; + dx += 2; + } + g.setColor(edge1); + g.drawLine(xo, yo+size-3, xo+1, yo+size-3); + g.setColor(edge2); + g.drawLine(xo+2, yo+size-2, xo+size-1, yo+size-2); + g.drawLine(xo, yo+size-1, xo+size, yo+size-1); + } +} diff --git a/src/java/org/privoxy/activityconsole/BlankIcon.java b/src/java/org/privoxy/activityconsole/BlankIcon.java new file mode 100644 index 00000000..a2b5859d --- /dev/null +++ b/src/java/org/privoxy/activityconsole/BlankIcon.java @@ -0,0 +1,84 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Painting details for rendering a blank icon. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.awt. *; +import javax.swing. *; + +/** + * Painting details for rendering a blank icon. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class BlankIcon implements Icon +{ + + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + private Color fillColor; + private int size; + + public BlankIcon() + { + this(null, 11); + } + + public BlankIcon(Color color, int size) + { + fillColor = color; + this.size = size; + } + + public void paintIcon(Component c, Graphics g, int x, int y) + { + if (fillColor != null) + { + g.setColor(fillColor); + g.drawRect(x, y, size-1, size-1); + } + } + + public int getIconWidth() + { + return size; + } + + public int getIconHeight() + { + return size; + } +} diff --git a/src/java/org/privoxy/activityconsole/ColumnRef.java b/src/java/org/privoxy/activityconsole/ColumnRef.java new file mode 100644 index 00000000..a7743caf --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ColumnRef.java @@ -0,0 +1,67 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Provides a mapping between a column's key and its + * description. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +/** + * Provides a mapping between a column's key and its description. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class ColumnRef +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + int _key = -1; + String _description = ""; + + public ColumnRef(String description, int key) + { + _description = description; + _key = key; + } + + public String getDescription() + { + return _description; + } + + public int getKey() + { + return _key; + } +} diff --git a/src/java/org/privoxy/activityconsole/Copyright.java b/src/java/org/privoxy/activityconsole/Copyright.java new file mode 100644 index 00000000..8fd79353 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/Copyright.java @@ -0,0 +1,48 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Houses the static text of the copyright statement. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +/** + * Houses the static text of the copyright statement. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class Copyright +{ + public static final String COPYRIGHT = + "Written by and Copyright (C) 2003 the SourceForge" + +"Privoxy team. http://www.privoxy.org/"; +} diff --git a/src/java/org/privoxy/activityconsole/ServerThread.java b/src/java/org/privoxy/activityconsole/ServerThread.java new file mode 100644 index 00000000..2748e7bb --- /dev/null +++ b/src/java/org/privoxy/activityconsole/ServerThread.java @@ -0,0 +1,130 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Listen on a specified port for status updates from + * Privoxy. If we get a suitable update, pass it along + * to the GUI for processing. We need to handle getting + * shut down and restarting on another port gracefully. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.net.*; +import java.io.*; +import java.text.*; +import java.util.*; +import javax.swing.*; + +/** + * Listens on a specified port for status updates from Privoxy. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class ServerThread extends Thread +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + static ActivityConsoleGui _parent; + static int _port; + static ServerSocket _serverSocket; + + public ServerThread(ActivityConsoleGui parent, int thePort) + { + _parent = parent; + _port = thePort; + } + + public void run() + { + try + { + _serverSocket = new ServerSocket(_port); + try + { + // System.out.println( "ServerThread serving port "+_port+"." ); + boolean shouldRun = true; + while (shouldRun) + { + Socket theSocket = _serverSocket.accept(); + if (!Thread.currentThread().interrupted()) + { + BufferedReader in = + new BufferedReader(new InputStreamReader(theSocket.getInputStream())); + String line = in.readLine(); + /* Ensure the line isn't null and it's not way, way too long... */ + if ((line != null) && (line.length() < 65536)) + { + _parent.updateStats(line,theSocket.getInetAddress().getHostName()); + } + in.close(); + theSocket.close(); + } + else + { + shouldRun = false; + } + } + _serverSocket.close(); + _serverSocket = null; + } + catch (IOException io) + { + try + { + _serverSocket.close(); + _serverSocket = null; + } + catch (IOException fred) + { + _serverSocket = null; + } + } + } + catch (IOException io) + { + System.err.println(io); + JOptionPane.showMessageDialog(null, io, "Alert: port "+_port, JOptionPane.ERROR_MESSAGE); + } + } + + public void doClose() + { + try + { + _serverSocket.close(); + } + catch (IOException fred) + { + } + } +} diff --git a/src/java/org/privoxy/activityconsole/SortButtonRenderer.java b/src/java/org/privoxy/activityconsole/SortButtonRenderer.java new file mode 100644 index 00000000..8c759775 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/SortButtonRenderer.java @@ -0,0 +1,158 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Swing details of rendering a column header as a button. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.util.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.table.*; + +/** + * Swing details of rendering a column header as a button. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class SortButtonRenderer extends JButton implements TableCellRenderer +{ + + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + public static final int NONE = 0; + public static final int DOWN = 1; + public static final int UP = 2; + + int pushedColumn; + Hashtable state; + JButton downButton,upButton; + + public SortButtonRenderer() + { + pushedColumn = -1; + state = new Hashtable(); + + setMargin(new Insets(0,0,0,0)); + setHorizontalTextPosition(LEFT); + setIcon(new BlankIcon()); + + downButton = new JButton(); + downButton.setMargin(new Insets(0,0,0,0)); + downButton.setHorizontalTextPosition(LEFT); + downButton.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false)); + downButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, true)); + + upButton = new JButton(); + upButton.setMargin(new Insets(0,0,0,0)); + upButton.setHorizontalTextPosition(LEFT); + upButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false)); + upButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, true)); + + } + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) + { + JButton button = this; + Object obj = state.get(new Integer(column)); + if (obj != null) + { + if (((Integer)obj).intValue() == DOWN) + { + button = downButton; + } + else + { + button = upButton; + } + } + button.setText((value ==null) ? "" : value.toString()); + boolean isPressed = (column == pushedColumn); + button.getModel().setPressed(isPressed); + button.getModel().setArmed(isPressed); + return button; + } + + public void setPressedColumn(int col) + { + pushedColumn = col; + } + + public void setSelectedColumn(int col) + { + if (col < 0) return; + Integer value = null; + Object obj = state.get(new Integer(col)); + if (obj == null) + { + value = new Integer(DOWN); + } + else + { + if (((Integer)obj).intValue() == DOWN) + { + value = new Integer(UP); + } + else + { + value = new Integer(DOWN); + } + } + state.clear(); + state.put(new Integer(col), value); + } + + public int getState(int col) + { + int retValue; + Object obj = state.get(new Integer(col)); + if (obj == null) + { + retValue = NONE; + } + else + { + if (((Integer)obj).intValue() == DOWN) + { + retValue = DOWN; + } + else + { + retValue = UP; + } + } + return retValue; + } +} diff --git a/src/java/org/privoxy/activityconsole/SortableTableModel.java b/src/java/org/privoxy/activityconsole/SortableTableModel.java new file mode 100644 index 00000000..87a14ec9 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/SortableTableModel.java @@ -0,0 +1,112 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Sorting JTable model. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.util.*; +import java.awt.*; +import javax.swing.*; +import javax.swing.table.*; + +/** + * Sorting JTable table model. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class SortableTableModel extends DefaultTableModel +{ + + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + int[] indexes; + TableSorter sorter; + + public SortableTableModel() + { + } + + public SortableTableModel(Vector data, Vector columnNames) + { + super(data, columnNames); + } + public Object getValueAt(int row, int col) + { + int rowIndex = row; + if (indexes != null) + { + rowIndex = indexes[row]; + } + return super.getValueAt(rowIndex, col); + } + + public void setValueAt(Object value, int row, int col) + { + int rowIndex = row; + if (indexes != null) + { + rowIndex = indexes[row]; + } + super.setValueAt(value, rowIndex, col); + } + + public void sortByColumn(int column, boolean isAscent) + { + if (sorter == null) + { + sorter = new TableSorter(this); + } + sorter.sort(column, isAscent); + fireTableDataChanged(); + } + + public int[] getIndexes() + { + int n = getRowCount(); + if (indexes != null) + { + if (indexes.length == n) + { + return indexes; + } + } + indexes = new int[n]; + for (int i=0; i -1 && + index < previousFind + ) + { + previousFind = index; + + finalString = originalString.substring(0,index) + + postValue + + finalString.substring(index+preValue.length()); + + index = finalString.lastIndexOf(preValue,previousFind); + if (!recursive) + { + if (index == previousFind) + previousFind--; + index = finalString.lastIndexOf(preValue,previousFind); + } + } + + return finalString; + } + + /**************************************************************************** + * This method replaces the preValue with the postValue in the originalString. + * + * @param originalString the string to have replacements + * @param preValue The substring value that the string currently contains + * @param postValue The substring value to replace the preValue + * + * @return String representing the substituted value(s) + ****************************************************************************/ + public static final String replaceSubstring( String originalString + , String preValue + , String postValue + ) + { + return(replaceSubstring(originalString, preValue, postValue, false)); + } +} diff --git a/src/java/org/privoxy/activityconsole/TableSorter.java b/src/java/org/privoxy/activityconsole/TableSorter.java new file mode 100644 index 00000000..8b61f3ca --- /dev/null +++ b/src/java/org/privoxy/activityconsole/TableSorter.java @@ -0,0 +1,195 @@ +/********************************************************************* + * + * File : $Source$ + * + * Purpose : Sorts JTable rows. + * + * Copyright : Written by and Copyright (C) 2003 the SourceForge + * Privoxy team. http://www.privoxy.org/ + * + * Based on the Internet Junkbuster originally written + * by and Copyright (C) 1997 Anonymous Coders and + * Junkbusters Corporation. http://www.junkbusters.com + * + * This program is free software; you can redistribute it + * and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will + * be useful, but WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public + * License for more details. + * + * The GNU General Public License should be included with + * this file. If not, you can view it at + * http://www.gnu.org/copyleft/gpl.html + * or write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Revisions : + * $Log$ + *********************************************************************/ + +package org.privoxy.activityconsole; + +import java.awt.*; +import java.util.*; +import javax.swing.*; +import javax.swing.table.*; + + +/** + * Sorts JTable rows. + * @author Last Modified By: $Author$ + * @version $Rev$-$Date$$State$ + */ +public class TableSorter +{ + private static final String + COPYRIGHT = org.privoxy.activityconsole.Copyright.COPYRIGHT; + + SortableTableModel model; + + public TableSorter(SortableTableModel model) + { + this.model = model; + } + + + //n2 selection + public void sort(int column, boolean isAscent) + { + int n = model.getRowCount(); + int[] indexes = model.getIndexes(); + + for (int i=0; i 0) + { + k = j; + } + } + } + int tmp = indexes[i]; + indexes[i] = indexes[k]; + indexes[k] = tmp; + } + } + + + // comparators + public int compare(int column, int row1, int row2) + { + Object o1 = model.getValueAt(row1, column); + Object o2 = model.getValueAt(row2, column); + if (o1 == null && o2 == null) + { + return 0; + } + else if (o1 == null) + { + return -1; + } + else if (o2 == null) + { + return 1; + } + else + { + Class type = model.getColumnClass(column); + if (type.getSuperclass() == Number.class) + { + return compare((Number)o1, (Number)o2); + } + else if (type == String.class) + { + return((String)o1).compareTo((String)o2); + } + else if (type == Date.class) + { + return compare((Date)o1, (Date)o2); + } + else if (type == Boolean.class) + { + return compare((Boolean)o1, (Boolean)o2); + } + else if (o1 instanceof StatWidget) + { + return((StatWidget)o1).compareTo((StatWidget)o2); + } + else + { + return((String)o1).compareTo((String)o2); + } + } + } + + public int compare(Number o1, Number o2) + { + double n1 = o1.doubleValue(); + double n2 = o2.doubleValue(); + if (n1 < n2) + { + return -1; + } + else if (n1 > n2) + { + return 1; + } + else + { + return 0; + } + } + + public int compare(Date o1, Date o2) + { + long n1 = o1.getTime(); + long n2 = o2.getTime(); + if (n1 < n2) + { + return -1; + } + else if (n1 > n2) + { + return 1; + } + else + { + return 0; + } + } + + public int compare(Boolean o1, Boolean o2) + { + boolean b1 = o1.booleanValue(); + boolean b2 = o2.booleanValue(); + if (b1 == b2) + { + return 0; + } + else if (b1) + { + return 1; + } + else + { + return -1; + } + } +} \ No newline at end of file diff --git a/src/java/org/privoxy/activityconsole/acon.bat b/src/java/org/privoxy/activityconsole/acon.bat new file mode 100755 index 00000000..69b18c79 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/acon.bat @@ -0,0 +1,40 @@ +@REM /********************************************************************* +@REM * +@REM * File : $Source$ +@REM * +@REM * Purpose : Start the Privoxy statistics viewer on Win32 platforms +@REM * +@REM * Copyright : Written by and Copyright (C) 2003 the SourceForge +@REM * Privoxy team. http://www.privoxy.org/ +@REM * +@REM * Based on the Internet Junkbuster originally written +@REM * by and Copyright (C) 1997 Anonymous Coders and +@REM * Junkbusters Corporation. http://www.junkbusters.com +@REM * +@REM * This program is free software; you can redistribute it +@REM * and/or modify it under the terms of the GNU General +@REM * Public License as published by the Free Software +@REM * Foundation; either version 2 of the License, or (at +@REM * your option) any later version. +@REM * +@REM * This program is distributed in the hope that it will +@REM * be useful, but WITHOUT ANY WARRANTY; without even the +@REM * implied warranty of MERCHANTABILITY or FITNESS FOR A +@REM * PARTICULAR PURPOSE. See the GNU General Public +@REM * License for more details. +@REM * +@REM * The GNU General Public License should be included with +@REM * this file. If not, you can view it at +@REM * http://www.gnu.org/copyleft/gpl.html +@REM * or write to the Free Software Foundation, Inc., 59 +@REM * Temple Place - Suite 330, Boston, MA 02111-1307, USA. +@REM * +@REM *********************************************************************/ +@REM +@REM Syntax: +@REM +@REM acon [port_to_serve] +@REM +@REM - Requires Java 1.2+ +@REM +@start /B java -classpath "%CLASSPATH%";ActivityConsole.jar org.privoxy.activityconsole.ActivityConsole %1 diff --git a/src/java/org/privoxy/activityconsole/acon.cmd b/src/java/org/privoxy/activityconsole/acon.cmd new file mode 100755 index 00000000..9e2cdf59 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/acon.cmd @@ -0,0 +1,40 @@ +@REM /********************************************************************* +@REM * +@REM * File : $Source$ +@REM * +@REM * Purpose : Start the Privoxy statistics viewer on OS/2 platforms +@REM * +@REM * Copyright : Written by and Copyright (C) 2003 the SourceForge +@REM * Privoxy team. http://www.privoxy.org/ +@REM * +@REM * Based on the Internet Junkbuster originally written +@REM * by and Copyright (C) 1997 Anonymous Coders and +@REM * Junkbusters Corporation. http://www.junkbusters.com +@REM * +@REM * This program is free software; you can redistribute it +@REM * and/or modify it under the terms of the GNU General +@REM * Public License as published by the Free Software +@REM * Foundation; either version 2 of the License, or (at +@REM * your option) any later version. +@REM * +@REM * This program is distributed in the hope that it will +@REM * be useful, but WITHOUT ANY WARRANTY; without even the +@REM * implied warranty of MERCHANTABILITY or FITNESS FOR A +@REM * PARTICULAR PURPOSE. See the GNU General Public +@REM * License for more details. +@REM * +@REM * The GNU General Public License should be included with +@REM * this file. If not, you can view it at +@REM * http://www.gnu.org/copyleft/gpl.html +@REM * or write to the Free Software Foundation, Inc., 59 +@REM * Temple Place - Suite 330, Boston, MA 02111-1307, USA. +@REM * +@REM *********************************************************************/ +@REM +@REM Syntax: +@REM +@REM acon [port_to_serve] +@REM +@REM - Requires Swing (i.e. swingall.jar) in CLASSPATH or Java 1.3+ +@REM +@start /MIN /C java -classpath %CLASSPATH%;ActivityConsole.jar org.privoxy.activityconsole.ActivityConsole %1 diff --git a/src/java/org/privoxy/activityconsole/acon.manifest b/src/java/org/privoxy/activityconsole/acon.manifest new file mode 100644 index 00000000..a742cc4e --- /dev/null +++ b/src/java/org/privoxy/activityconsole/acon.manifest @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 1.3.1 (IBM Corporation) +Main-Class: org.privoxy.activityconsole.ActivityConsole diff --git a/src/java/org/privoxy/activityconsole/acon.sh b/src/java/org/privoxy/activityconsole/acon.sh new file mode 100644 index 00000000..9bba5557 --- /dev/null +++ b/src/java/org/privoxy/activityconsole/acon.sh @@ -0,0 +1,40 @@ +# /********************************************************************* +# * +# * File : $Source$ +# * +# * Purpose : Start the Privoxy statistics viewer on *NIX platforms +# * +# * Copyright : Written by and Copyright (C) 2003 the SourceForge +# * Privoxy team. http://www.privoxy.org/ +# * +# * Based on the Internet Junkbuster originally written +# * by and Copyright (C) 1997 Anonymous Coders and +# * Junkbusters Corporation. http://www.junkbusters.com +# * +# * This program is free software; you can redistribute it +# * and/or modify it under the terms of the GNU General +# * Public License as published by the Free Software +# * Foundation; either version 2 of the License, or (at +# * your option) any later version. +# * +# * This program is distributed in the hope that it will +# * be useful, but WITHOUT ANY WARRANTY; without even the +# * implied warranty of MERCHANTABILITY or FITNESS FOR A +# * PARTICULAR PURPOSE. See the GNU General Public +# * License for more details. +# * +# * The GNU General Public License should be included with +# * this file. If not, you can view it at +# * http://www.gnu.org/copyleft/gpl.html +# * or write to the Free Software Foundation, Inc., 59 +# * Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# * +# *********************************************************************/ +# +# Syntax: +# +# ./acon.sh [port_to_serve] +# +# - Requires Swing (i.e. swingall.jar) in CLASSPATH or Java 1.2+ +# +java -classpath $CLASSPATH:ActivityConsole.jar org.privoxy.activityconsole.ActivityConsole $1