Implement actions/history in the browser


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7710 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
index 2e7b341..ed1538c 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/BuySellPopup.java
@@ -35,7 +35,22 @@
  */
 public class BuySellPopup extends DialogBox {
 
-  private StockQuote quote;
+
+  private static final int TICKER = 0;
+  private static final int NAME = 1;
+  private static final int PRICE = 2;
+  private static final int MAX_QUANTITY = 3;
+  private static final int QUANTITY = 4;
+  private static final int TOTAL = 5;
+  private static final int AVAILABLE = 6;
+  private static final int BUTTONS = 7;
+
+  private int cash;
+
+  /**
+   * True if we are buying, false if hiding.
+   */
+  private boolean isBuying;
 
   /**
    * The table used for layout.
@@ -43,19 +58,16 @@
   private FlexTable layout = new FlexTable();
 
   /**
-   * The box used to change the quantity.
-   */
-  private TextBox quantityBox = new TextBox();
-
-  /**
    * The button used to buy or sell.
    */
   private Button opButton;
 
   /**
-   * True if we are buying, false if hiding.
+   * The box used to change the quantity.
    */
-  private boolean isBuying;
+  private TextBox quantityBox = new TextBox();
+
+  private StockQuote quote;
 
   /**
    * The last transaction.
@@ -67,24 +79,26 @@
     setGlassEnabled(true);
     setWidget(layout);
 
-    layout.setHTML(0, 0, "<b>Ticker:</b>");
-    layout.setHTML(1, 0, "<b>Name:</b>");
-    layout.setHTML(2, 0, "<b>Price:</b>");
-    layout.setHTML(3, 0, "<b>Quantity:</b>");
-    layout.setWidget(3, 1, quantityBox);
-    layout.setHTML(4, 0, "<b>Total:</b>");
-    layout.setHTML(5, 0, "<b>Available:</b>");
+    layout.setHTML(TICKER, 0, "<b>Ticker:</b>");
+    layout.setHTML(NAME, 0, "<b>Name:</b>");
+    layout.setHTML(PRICE, 0, "<b>Price:</b>");
+    layout.setHTML(MAX_QUANTITY, 0, "<b>Max Quantity:</b>");
+    layout.setHTML(QUANTITY, 0, "<b>Quantity:</b>");
+    layout.setWidget(QUANTITY, 1, quantityBox);
+    layout.setHTML(TOTAL, 0, "<b>Total:</b>");
+    layout.setHTML(AVAILABLE, 0, "<b>Available:</b>");
 
     // Update total price when the quantity changes.
     quantityBox.addKeyUpHandler(new KeyUpHandler() {
       public void onKeyUp(KeyUpEvent event) {
         try {
-          int quantity = Integer.parseInt(quantityBox.getText());
+          String text = quantityBox.getText();
+          int quantity = text.length() == 0 ? 0 : Integer.parseInt(text);
           double totalPrice = quantity * quote.getPrice() / 100.0;
-          layout.setText(4, 1, NumberFormat.getCurrencyFormat("USD").format(
+          layout.setText(TOTAL, 1, NumberFormat.getCurrencyFormat("USD").format(
               totalPrice));
         } catch (NumberFormatException e) {
-          layout.setText(4, 1, "Invalid quantity");
+          layout.setText(TOTAL, 1, "Invalid quantity");
         }
       }
     });
@@ -101,7 +115,7 @@
         }
       }
     });
-    layout.setWidget(6, 0, opButton);
+    layout.setWidget(BUTTONS, 0, opButton);
 
     // Cancel Button.
     Button cancelButton = new Button("Cancel", new ClickHandler() {
@@ -109,7 +123,7 @@
         hide();
       }
     });
-    layout.setWidget(6, 1, cancelButton);
+    layout.setWidget(BUTTONS, 1, cancelButton);
   }
 
   public StockQuote getStockQuote() {
@@ -119,7 +133,7 @@
   /**
    * Get the last transaction.
    * 
-   * @return the last transaction, or null if cancelled
+   * @return the last transaction, or null if canceled
    */
   public Transaction getTransaction() {
     return transaction;
@@ -132,7 +146,8 @@
    */
   public void setAvailableCash(int cash) {
     // TODO: Bind the available cash field.
-    layout.setText(5, 1, NumberFormat.getCurrencyFormat("USD").format(cash / 100.0));
+    this.cash = cash;
+    layout.setText(AVAILABLE, 1, NumberFormat.getCurrencyFormat("USD").format(cash / 100.0));
   }
 
   /**
@@ -145,10 +160,15 @@
     this.quote = quote;
     String op = isBuying ? "Buy" : "Sell";
     setText(op + " " + quote.getTicker() + " (" + quote.getName() + ")");
-    layout.setText(0, 1, quote.getTicker());
-    layout.setText(1, 1, quote.getName());
-    layout.setText(2, 1, quote.getDisplayPrice());
-    layout.setText(4, 1, NumberFormat.getCurrencyFormat("USD").format(0.0));
+    layout.setText(TICKER, 1, quote.getTicker());
+    layout.setText(NAME, 1, quote.getName());
+    layout.setText(PRICE, 1, quote.getDisplayPrice());
+    if (isBuying) {
+      layout.setText(MAX_QUANTITY, 1, "" + (int) Math.floor(cash / quote.getPrice()));
+    } else {
+      layout.setText(MAX_QUANTITY, 1, "" + quote.getSharesOwned());
+    }
+    layout.setText(TOTAL, 1, NumberFormat.getCurrencyFormat("USD").format(0.0));
     quantityBox.setText("0");
     opButton.setText(op);
     this.isBuying = isBuying;
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockQueryWidget.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockQueryWidget.java
index 9ddfaf0..9636868 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockQueryWidget.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockQueryWidget.java
@@ -82,7 +82,6 @@
     output = output.replaceAll("^[\\| ]+", "");
     output = output.replaceAll("[\\| ]+$", "");
     output = output.replaceAll("[ ]+", "|");
-    System.out.println("Replaced \"" + input + "\" with \"" + output + "\"");
     return output;
   }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
index be7e403..93d87df 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/StockSample.java
@@ -97,6 +97,11 @@
     }
   };
 
+  public void buy(StockQuote stockQuote) {
+    buySellPopup.setStockQuote(stockQuote, true);
+    buySellPopup.center();
+  }
+
   /**
    * This is the entry point method.
    */
@@ -134,16 +139,14 @@
     });
 
     Columns.buyColumn.setFieldUpdater(new FieldUpdater<StockQuote, String>() {
-      public void update(StockQuote object, String value) {
-        buySellPopup.setStockQuote(object, true);
-        buySellPopup.center();
+      public void update(StockQuote quote, String value) {
+        buy(quote);
       }
     });
 
     Columns.sellColumn.setFieldUpdater(new FieldUpdater<StockQuote, String>() {
-      public void update(StockQuote object, String value) {
-        buySellPopup.setStockQuote(object, false);
-        buySellPopup.center();
+      public void update(StockQuote quote, String value) {
+        sell(quote);
       }
     });
 
@@ -186,6 +189,11 @@
     updateTimer.schedule(UPDATE_DELAY);
   }
 
+  public void sell(StockQuote stockQuote) {
+    buySellPopup.setStockQuote(stockQuote, false);
+    buySellPopup.center();
+  }
+
   /**
    * Set or unset a ticker symbol as a 'favorite'.
    *
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
index 2a57bd0..5bb44db 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/TransactionTreeViewModel.java
@@ -15,8 +15,10 @@
  */
 package com.google.gwt.bikeshed.sample.stocks.client;
 
+import com.google.gwt.bikeshed.cells.client.ButtonCell;
 import com.google.gwt.bikeshed.cells.client.Cell;
 import com.google.gwt.bikeshed.cells.client.TextCell;
+import com.google.gwt.bikeshed.cells.client.ValueUpdater;
 import com.google.gwt.bikeshed.list.shared.AsyncListModel;
 import com.google.gwt.bikeshed.list.shared.ListListModel;
 import com.google.gwt.bikeshed.list.shared.ListModel;
@@ -92,7 +94,7 @@
   }
   
   @SuppressWarnings("unused")
-  public <T> NodeInfo<?> getNodeInfo(T value, TreeNode<T> treeNode) {
+  public <T> NodeInfo<?> getNodeInfo(T value, final TreeNode<T> treeNode) {
     if (value == null) {
       return new TreeViewModel.DefaultNodeInfo<String>(topLevelListListModel,
           new TextCell());
@@ -104,6 +106,31 @@
           return value.getTicker();
         }
       };
+    } else if ("History".equals(value)) {
+      String ticker = ((StockQuote) treeNode.getParentNode().getValue()).getTicker();
+      ListListModel<Transaction> listModel = transactionListListModelsByTicker.get(ticker);
+      if (listModel == null) {
+        listModel = new ListListModel<Transaction>();
+        transactionListListModelsByTicker.put(ticker, listModel);
+      }
+      return new TreeViewModel.DefaultNodeInfo<Transaction>(listModel,
+          TRANSACTION_CELL);
+    } else if ("Actions".equals(value)) {
+      ListListModel<String> listModel = new ListListModel<String>();
+      List<String> list = listModel.getList();
+      list.add("Buy");
+      list.add("Sell");
+      return new TreeViewModel.DefaultNodeInfo<String>(listModel, new ButtonCell(),
+          new ValueUpdater<String>() {
+            public void update(String value) {
+              StockQuote stockQuote = (StockQuote) treeNode.getParentNode().getValue();
+              if ("Buy".equals(value)) {
+                updater.buy(stockQuote);
+              } else {
+                updater.sell(stockQuote);
+              }
+            }
+          });
     } else if (value instanceof String) {
       SectorListModel listModel = new SectorListModel(updater, (String) value);
       sectorListModels.put((String) value, listModel);
@@ -114,14 +141,11 @@
         }
       };
     } else if (value instanceof StockQuote) {
-      String ticker = ((StockQuote) value).getTicker();
-      ListListModel<Transaction> listModel = transactionListListModelsByTicker.get(ticker);
-      if (listModel == null) {
-        listModel = new ListListModel<Transaction>();
-        transactionListListModelsByTicker.put(ticker, listModel);
-      }
-      return new TreeViewModel.DefaultNodeInfo<Transaction>(listModel,
-          TRANSACTION_CELL);
+      ListListModel<String> listModel = new ListListModel<String>();
+      List<String> list = listModel.getList();
+      list.add("Actions");
+      list.add("History");
+      return new TreeViewModel.DefaultNodeInfo<String>(listModel, new TextCell());
     }
 
     throw new IllegalArgumentException(value.toString());
@@ -132,6 +156,7 @@
   }
 
   public boolean isLeaf(Object value) {
-    return value instanceof Transaction;
+    return value instanceof Transaction ||
+      "Buy".equals(value) || "Sell".equals(value);
   }
 }
diff --git a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/Updater.java b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/Updater.java
index 02562bc..e49da1b 100644
--- a/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/Updater.java
+++ b/bikeshed/src/com/google/gwt/bikeshed/sample/stocks/client/Updater.java
@@ -15,16 +15,21 @@
  */
 package com.google.gwt.bikeshed.sample.stocks.client;
 
+import com.google.gwt.bikeshed.sample.stocks.shared.StockQuote;
+
 /**
  * Bridge between StockSample and StockQueryWidget.
  */
 public interface Updater {
-  
+
+  void buy(StockQuote stock);
+
+  void sell(StockQuote stock);
+
   /**
    * Update the widget.
    * 
    * TODO - refactor this
    */
   void update();
-
 }