From 2a2d3c0fb578cde276f4868b1daba2d24204b3fb Mon Sep 17 00:00:00 2001
From: mathiasdm <mathiasdm@mail.i2p>
Date: Fri, 10 Apr 2009 18:56:56 +0000
Subject: [PATCH] Added log viewer. Added shutdown informational messages.

---
 apps/desktopgui/src/gui/LogViewer.form        | 101 +++++++++++
 apps/desktopgui/src/gui/LogViewer.java        | 163 ++++++++++++++++++
 apps/desktopgui/src/gui/Tray.java             |  25 ++-
 .../src/gui/resources/LogViewer.properties    |   3 +
 apps/desktopgui/src/router/RouterHelper.java  |   4 +
 5 files changed, 295 insertions(+), 1 deletion(-)
 create mode 100644 apps/desktopgui/src/gui/LogViewer.form
 create mode 100644 apps/desktopgui/src/gui/LogViewer.java
 create mode 100644 apps/desktopgui/src/gui/resources/LogViewer.properties

diff --git a/apps/desktopgui/src/gui/LogViewer.form b/apps/desktopgui/src/gui/LogViewer.form
new file mode 100644
index 0000000000..b53b410bac
--- /dev/null
+++ b/apps/desktopgui/src/gui/LogViewer.form
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="3"/>
+    <Property name="name" type="java.lang.String" value="Form" noResource="true"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="12" pref="12" max="12" attributes="0"/>
+              <Component id="explanationText" min="-2" pref="561" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+          <Component id="textScroll" alignment="1" pref="722" max="32767" attributes="0"/>
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="refreshButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="clearButton" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="587" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" max="-2" attributes="0"/>
+              <Component id="explanationText" min="-2" pref="45" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="refreshButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="clearButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
+              <Component id="textScroll" pref="330" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="textScroll">
+      <Properties>
+        <Property name="name" type="java.lang.String" value="textScroll" noResource="true"/>
+      </Properties>
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="logText">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="rows" type="int" value="5"/>
+            <Property name="name" type="java.lang.String" value="logText" noResource="true"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JLabel" name="explanationText">
+      <Properties>
+        <Property name="text" type="java.lang.String" resourceKey="explanationText.text"/>
+        <Property name="name" type="java.lang.String" value="explanationText" noResource="true"/>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="refreshButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" resourceKey="refreshButton.text"/>
+        <Property name="name" type="java.lang.String" value="refreshButton" noResource="true"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="refreshButtonActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="clearButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" resourceKey="clearButton.text"/>
+        <Property name="name" type="java.lang.String" value="clearButton" noResource="true"/>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="clearButtonActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/apps/desktopgui/src/gui/LogViewer.java b/apps/desktopgui/src/gui/LogViewer.java
new file mode 100644
index 0000000000..2dad70c1fc
--- /dev/null
+++ b/apps/desktopgui/src/gui/LogViewer.java
@@ -0,0 +1,163 @@
+/*
+ * LogViewer.java
+ *
+ * Created on 10 april 2009, 19:17
+ */
+
+package gui;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.WindowConstants;
+
+/**
+ *
+ * @author  mathias
+ */
+public class LogViewer extends javax.swing.JFrame {
+
+    /** Creates new form LogViewer */
+    public LogViewer() {
+        initComponents();
+        readLogText();
+        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        this.setVisible(true);
+    }
+    
+    private void readLogText() {
+        Thread t = new Thread(new Runnable() {
+
+            @Override
+            public void run() {
+                String s = "";
+                File f = new File(LOGLOCATION);
+                if(f.exists()) {
+                    try {
+                        BufferedReader br = new BufferedReader(new FileReader(f));
+                        while(true) {
+                            String line = br.readLine();
+                            if(line != null)
+                                s += JTEXTNEWLINE + line;
+                            else
+                                break;
+                        }
+                    }
+                    catch(Exception e) {
+                        s = "An error has occurred while loading the logfiles:" + JTEXTNEWLINE + e.getMessage();
+                    }
+                }
+                logText.setText(s);
+            }
+            
+        });
+        t.start();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        textScroll = new javax.swing.JScrollPane();
+        logText = new javax.swing.JTextArea();
+        explanationText = new javax.swing.JLabel();
+        refreshButton = new javax.swing.JButton();
+        clearButton = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+        setName("Form"); // NOI18N
+
+        textScroll.setName("textScroll"); // NOI18N
+
+        logText.setColumns(20);
+        logText.setRows(5);
+        logText.setName("logText"); // NOI18N
+        textScroll.setViewportView(logText);
+
+        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(desktopgui.Main.class).getContext().getResourceMap(LogViewer.class);
+        explanationText.setText(resourceMap.getString("explanationText.text")); // NOI18N
+        explanationText.setName("explanationText"); // NOI18N
+
+        refreshButton.setText(resourceMap.getString("refreshButton.text")); // NOI18N
+        refreshButton.setName("refreshButton"); // NOI18N
+        refreshButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                refreshButtonActionPerformed(evt);
+            }
+        });
+
+        clearButton.setText(resourceMap.getString("clearButton.text")); // NOI18N
+        clearButton.setName("clearButton"); // NOI18N
+        clearButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                clearButtonActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(12, 12, 12)
+                .addComponent(explanationText, javax.swing.GroupLayout.PREFERRED_SIZE, 561, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap())
+            .addComponent(textScroll, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 722, Short.MAX_VALUE)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(refreshButton)
+                .addGap(18, 18, 18)
+                .addComponent(clearButton)
+                .addContainerGap(587, Short.MAX_VALUE))
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(explanationText, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(refreshButton)
+                    .addComponent(clearButton))
+                .addGap(14, 14, 14)
+                .addComponent(textScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE))
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
+    File f = new File(LOGLOCATION);
+    f.delete();
+    try {
+        f.createNewFile();//GEN-LAST:event_clearButtonActionPerformed
+    } catch (IOException ex) {
+        Logger.getLogger(LogViewer.class.getName()).log(Level.SEVERE, null, ex);
+    }
+    readLogText();
+}
+
+private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
+    readLogText();
+}//GEN-LAST:event_refreshButtonActionPerformed
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton clearButton;
+    private javax.swing.JLabel explanationText;
+    private javax.swing.JTextArea logText;
+    private javax.swing.JButton refreshButton;
+    private javax.swing.JScrollPane textScroll;
+    // End of variables declaration//GEN-END:variables
+
+    private static final String LOGLOCATION = "wrapper.log";
+    private static final String JTEXTNEWLINE = "\n";
+}
diff --git a/apps/desktopgui/src/gui/Tray.java b/apps/desktopgui/src/gui/Tray.java
index 6ed5ea0d49..bf3cd28c87 100644
--- a/apps/desktopgui/src/gui/Tray.java
+++ b/apps/desktopgui/src/gui/Tray.java
@@ -24,6 +24,7 @@ import java.net.URISyntaxException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import router.RouterHandler;
+import router.RouterHelper;
 
 /**
  *
@@ -50,7 +51,12 @@ public class Tray {
                 if(Desktop.isDesktopSupported()) {
                     Desktop desktop = Desktop.getDesktop();
                     try {
-                        desktop.browse(new URI("http://localhost:7657"));
+                        if(desktop.isSupported(Desktop.Action.BROWSE)) {
+                            desktop.browse(new URI("http://localhost:7657"));
+                        }
+                        else {
+                            trayIcon.displayMessage("Browser not found", "The default browser for your system was not found.", TrayIcon.MessageType.WARNING);
+                        }
                     } catch (URISyntaxException ex) {
                         Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                     } catch(IOException ex) {
@@ -103,12 +109,27 @@ public class Tray {
                 }
             }
 
+        });
+        MenuItem viewLog = new MenuItem("View log");
+        viewLog.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                new LogViewer();
+            }
+            
         });
         MenuItem shutdown = new MenuItem("Shutdown I2P");
         shutdown.addActionListener(new ActionListener() {
 
             public void actionPerformed(ActionEvent arg0) {
                 RouterHandler.setStatus(RouterHandler.SHUTDOWN_GRACEFULLY);
+                long shutdownTime = RouterHelper.getGracefulShutdownTimeRemaining();
+                System.out.println(shutdownTime);
+                if(shutdownTime>0)
+                    trayIcon.displayMessage("Shutting down...", "Shutdown time remaining: " + shutdownTime/1000 + " seconds.", TrayIcon.MessageType.INFO);
+                else
+                    trayIcon.displayMessage("Shutting down...", "Shutting down immediately.", TrayIcon.MessageType.INFO);
             }
 
         });
@@ -121,6 +142,8 @@ public class Tray {
         config.add(advancedConfig);
         popup.add(config);
         
+        popup.add(viewLog);
+        
         popup.add(shutdown);
 
         //Add tray icon
diff --git a/apps/desktopgui/src/gui/resources/LogViewer.properties b/apps/desktopgui/src/gui/resources/LogViewer.properties
new file mode 100644
index 0000000000..8cb0e62091
--- /dev/null
+++ b/apps/desktopgui/src/gui/resources/LogViewer.properties
@@ -0,0 +1,3 @@
+refreshButton.text=Refresh
+clearButton.text=Clear
+explanationText.text=Explanation ...
diff --git a/apps/desktopgui/src/router/RouterHelper.java b/apps/desktopgui/src/router/RouterHelper.java
index c5fc78e959..6d3cddd03d 100644
--- a/apps/desktopgui/src/router/RouterHelper.java
+++ b/apps/desktopgui/src/router/RouterHelper.java
@@ -10,4 +10,8 @@ public class RouterHelper {
     public static RouterContext getContext() {
         return (RouterContext) RouterContext.listContexts().get(0);
     }
+    
+    public static long getGracefulShutdownTimeRemaining() {
+        return RouterHelper.getContext().router().getShutdownTimeRemaining();
+    }
 }
-- 
GitLab