changeset 333:495fb632840c

brief and no header options for messages displayed in the list view; also Tools->View->Snowl tweaked, new submenu Layouts which includes layout group, header toggle group, toolbars checkbox toggle. List and sidebar toolbars can be toggled off. Contextual enable/disable of menuitems. New snowl toolbarbutton, mirrors the statusbar button. Layout button removed.
author alta88 <alta88@gmail.com>
date Mon, 20 Oct 2008 02:05:26 -0700
parents e08a381e3ff7
children 7d9cdc7e5a41
files chrome.manifest content/browser.js content/browser.xul content/list.css content/list.js content/list.xul content/message/message.css content/message/message.js content/message/message.xul content/stream.js content/toolbar.xul defaults/preferences/snowl.js locale/en-US/browser.dtd locale/en-US/list.dtd
diffstat 14 files changed, 376 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/chrome.manifest	Mon Oct 20 01:38:56 2008 -0700
+++ b/chrome.manifest	Mon Oct 20 02:05:26 2008 -0700
@@ -8,6 +8,9 @@
 # the list view sidebar.
 overlay chrome://browser/content/browser.xul chrome://snowl/content/list.xul
 
+# For Customize to display our buttons correctly.
+style chrome://global/content/customizeToolbar.xul chrome://snowl/content/browser.css
+
 # Add the collections view to the list view sidebar.  We overlay it onto both
 # the list view sidebar and the river view, but for the river view we overlay it
 # dynamically via document.loadOverlay instead of an entry here because we
--- a/content/browser.js	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/browser.js	Mon Oct 20 02:05:26 2008 -0700
@@ -19,6 +19,7 @@
  *
  * Contributor(s):
  *   Myk Melez <myk@mozilla.org>
+ *   alta88 <alta88@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -72,6 +73,11 @@
     }
 
     this._prefs.set("lastVersion", this._version);
+
+    // Listen for tab selected, to toggle preferred header view
+    gBrowser.tabContainer.addEventListener("TabSelect",
+        function() { Snowl._toggleHeader("TabSelect"); }, false);
+
   },
 
   //**************************************************************************//
@@ -85,17 +91,39 @@
   onStatusbarButtonMouseDown: function(event) {
     let menuPopup = document.getElementById('snowlMenuPopup');
     let statusbarButton = document.getElementById("snowlStatusbarButton");
+    let toolbarButton = document.getElementById("snowlToolbarButton");
 
-    // If the menu popup isn't on the statusbar button, then move the popup
+    // If the menu popup isn't on the statusbar or toolbar button, then move it
     // onto the button so the popup appears when the user clicks the button.
     // We'll move the popup back to the Tools > Snowl menu when the popup hides.
-    if (menuPopup.parentNode != statusbarButton)
+    if (event.target.id == "snowlToolbarButton" &&
+        menuPopup.parentNode != toolbarButton)
+      toolbarButton.appendChild(menuPopup);
+    if (event.target.id == "snowlStatusbarButton" &&
+        menuPopup.parentNode != statusbarButton)
       statusbarButton.appendChild(menuPopup);
   },
 
-  onPopupHiding: function() {
+  onLayoutPopupShowing: function(event) {
+    let layoutmenu = document.getElementById("snowlLayoutMenu");
+    let lchecked = document.getElementById("viewSnowlList").hasAttribute("checked");
+    let schecked = document.getElementById("viewSnowlStream").hasAttribute("checked");
+    let layoutmenuitems = document.getElementsByAttribute("name", "snowlLayoutMenuitemGroup");
+
+    if (layoutmenuitems) {
+      for (var i = 0; i < layoutmenuitems.length; i++)
+        layoutmenuitems[i].setAttribute("disabled", !lchecked);
+    }
+    document.getElementById("snowlToolbarMenuitem").setAttribute("disabled",
+        (!lchecked && !schecked) ? true : false);
+    document.getElementById("snowlViewToolbarMenuitem").setAttribute("disabled",
+        (!lchecked) ? true : false)
+  },
+
+  onPopupHiding: function(event) {
     let menuPopup = document.getElementById("snowlMenuPopup");
     let menu = document.getElementById("snowlMenu");
+    event.target.parentNode.removeAttribute("open");
 
     // If the menu popup isn't on the Tools > Snowl menu, then move the popup
     // back onto that menu so the popup appears when the user selects the menu.
@@ -129,8 +157,88 @@
 
   onExportOPML: function() {
     SnowlOPML.export(window);
-  }
+  },
+
+  //**************************************************************************//
+  // Buttons
+
+  // Header toggle
+  kNoHeader: 0,
+  kBriefHeader: 1,
+  kFullHeader: 2,
+
+  _toggleHeader: function(val) {
+    let contentWindowDoc = gBrowser.selectedBrowser.contentDocument;
+    let selectedIndex = null;
+    let headerDeck = new XPCNativeWrapper(contentWindowDoc, "getElementById()")
+        .getElementById("headerDeck");
+
+    let button = document.getElementById("snowlToggleHeaderButton");
+    if (button)
+      button.setAttribute("disabled", !headerDeck ? true : false);
+
+    // Not a snowl message in the tab..
+    if (!headerDeck)
+      return;
+
+    let briefHeader = new XPCNativeWrapper(contentWindowDoc, "getElementById()")
+        .getElementById("briefHeader");
+    let fullHeader = new XPCNativeWrapper(contentWindowDoc, "getElementById()")
+        .getElementById("fullHeader");
+    let menuitems = document.getElementsByAttribute("name", "snowlHeaderMenuitemGroup");
 
+    if (val == "TabSelect")
+      // Make sure tab switch reflects header state
+      selectedIndex = this._prefs.get("message.headerView");
+    else if (val == "Toggle") {
+      // Toggled to next in 3 way
+      selectedIndex = parseInt(headerDeck.selectedIndex);
+      selectedIndex = ++selectedIndex > 2 ? 0 : selectedIndex++;
+      this._prefs.set("message.headerView", selectedIndex);
+    }
+    else {
+      // Passed an event from menuitem choice
+      selectedIndex = eval(val.target.getAttribute("headerType"));
+      val.target.setAttribute("checked", true);
+      this._prefs.set("message.headerView", selectedIndex);
+    }
+
+    headerDeck.setAttribute("selectedIndex", selectedIndex);
+    briefHeader.setAttribute("collapsed", selectedIndex == 1 ? false : true);
+    fullHeader.setAttribute("collapsed", selectedIndex == 2 ? false : true);
+
+    if (button)
+      button.setAttribute("snowlHeader", selectedIndex == 0 ?
+          "none" : (selectedIndex == 1 ? "brief" : "full"));
+    if (menuitems) {
+      menuitems[selectedIndex].setAttribute("checked", true);
+//alert("id: checked "+menuitems[selectedIndex].id+":"+menuitems[selectedIndex].getAttribute("checked"));
+    }
+  },
+
+  // Need to init onLoad due to xul structure, toolbar exists in list and stream
+  _initSnowlToolbar: function() {
+    let menuitem = document.getElementById("snowlToolbarMenuitem");
+    let doc = document.getElementById("sidebar").contentDocument;
+    let toolbar = doc.getElementById("snowlToolbar");
+
+    if (toolbar) {
+      menuitem.setAttribute("checked", !toolbar.hidden);
+    }
+  },
+
+  _toggleToolbar: function(event) {
+    let name = event.target.getAttribute("name");
+    let menuitem = document.getElementById(name+"Menuitem");
+    let doc = (name == "snowlToolbar") ?
+        document.getElementById("sidebar").contentDocument : document;
+    let toolbar = doc.getElementById(name);
+
+    if (toolbar) {
+      toolbar.hidden = !toolbar.hidden;
+      menuitem.setAttribute("checked", !toolbar.hidden);
+    }
+  },
 };
 
 Cu.import("resource://snowl/modules/Preferences.js", Snowl);
--- a/content/browser.xul	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/browser.xul	Mon Oct 20 02:05:26 2008 -0700
@@ -21,6 +21,7 @@
    -
    - Contributor(s):
    -   Myk Melez <myk@mozilla.org>
+   -   alta88 <alta88@gmail.com>
    -
    - Alternatively, the contents of this file may be used under the terms of
    - either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -36,6 +37,8 @@
    -
    - ***** END LICENSE BLOCK ***** -->
 
+<?xml-stylesheet href="chrome://snowl/content/browser.css" type="text/css"?>
+
 <!DOCTYPE overlay SYSTEM "chrome://snowl/locale/browser.dtd">
 
 <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@@ -71,18 +74,106 @@
     <menu id="snowlMenu" class="menu-iconic" label="&snowlMenu.label;"
           image="chrome://snowl/content/icons/snowl-16.png"
           accesskey="&snowlMenu.accesskey;" insertafter="menu_openAddons">
-      <menupopup id="snowlMenuPopup" onpopuphiding="Snowl.onPopupHiding()">
+      <menupopup id="snowlMenuPopup" onpopuphiding="Snowl.onPopupHiding(event)">
         <menuitem observes="viewSnowlList" label="&listView.label;"
                   accesskey="&listView.accesskey;"/>
-        <menuitem label="&riverView.label;" accesskey="&riverView.accesskey;"
-                  oncommand="Snowl.onRiverView()"/>
         <menuitem observes="viewSnowlStream" label="&streamView.label;"
                   accesskey="&streamView.accesskey;"/>
         <menuseparator/>
+        <menuitem label="&riverView.label;" accesskey="&riverView.accesskey;"
+                  oncommand="Snowl.onRiverView()"/>
         <menuitem label="&checkForNewMessages.label;"
                   accesskey="&checkForNewMessages.accesskey;"
                   oncommand="Snowl.onCheckForNewMessages()"/>
         <menuseparator/>
+        <menu id="snowlLayoutMenu"
+              label="&snowlLayoutMenu.label;"
+              accesskey="&snowlLayoutMenu.accesskey;">
+          <menupopup id="snowlLayoutPopup"
+                     onpopupshowing="Snowl.onLayoutPopupShowing(event)">
+            <menuitem id="snowlLayoutMenuitemClassic"
+                      label="&layoutClassic.label;"
+                      type="radio"
+                      checked="true"
+                      accesskey="&layoutClassic.accesskey;"
+                      name="snowlLayoutMenuitemGroup"
+                      persist="checked"
+                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kClassicLayout)"/>
+            <menuitem id="snowlLayoutMenuitemVertical"
+                      label="&layoutVertical.label;"
+                      type="radio"
+                      accesskey="&layoutVertical.accesskey;"
+                      name="snowlLayoutMenuitemGroup"
+                      persist="checked"
+                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kVerticalLayout)"/>
+            <menuitem id="snowlLayoutMenuitemWideMessage"
+                      label="&layoutWideMessage.label;"
+                      type="radio"
+                      accesskey="&layoutWideMessage.accesskey;"
+                      name="snowlLayoutMenuitemGroup"
+                      persist="checked"
+                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kWideMessageLayout)"/>
+            <menuitem id="snowlLayoutMenuitemWideThread"
+                      label="&layoutWideThread.label;"
+                      type="radio"
+                      accesskey="&layoutWideThread.accesskey;"
+                      name="snowlLayoutMenuitemGroup"
+                      persist="checked"
+                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kWideThreadLayout)"/>
+            <menuitem id="snowlLayoutMenuitemStacked"
+                      label="&layoutStacked.label;"
+                      type="radio"
+                      accesskey="&layoutStacked.accesskey;"
+                      name="snowlLayoutMenuitemGroup"
+                      persist="checked"
+                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kStackedLayout)"/>
+            <menuseparator/>
+            <menuitem id="snowlHeaderMenuitemNone"
+                      label="&headerNone.label;"
+                      type="radio"
+                      accesskey="&headerNone.accesskey;"
+                      name="snowlHeaderMenuitemGroup"
+                      persist="checked"
+                      headerType="Snowl.kNoHeader"
+                      oncommand="Snowl._toggleHeader(event)"/>
+            <menuitem id="snowlHeaderMenuitemBrief"
+                      label="&headerBrief.label;"
+                      type="radio"
+                      accesskey="&headerBrief.accesskey;"
+                      name="snowlHeaderMenuitemGroup"
+                      persist="checked"
+                      headerType="Snowl.kBriefHeader"
+                      oncommand="Snowl._toggleHeader(event)"/>
+            <menuitem id="snowlHeaderMenuitemFull"
+                      label="&headerFull.label;"
+                      type="radio"
+                      accesskey="&headerFull.accesskey;"
+                      name="snowlHeaderMenuitemGroup"
+                      persist="checked"
+                      headerType="Snowl.kFullHeader"
+                      oncommand="Snowl._toggleHeader(event)"/>
+            <menuseparator/>
+            <menuitem id="snowlToolbarMenuitem"
+                      label="&toolbar.label;"
+                      type="checkbox"
+                      checked="true"
+                      autoCheck="false"
+                      accesskey="&toolbar.accesskey;"
+                      name="snowlToolbar"
+                      persist="checked"
+                      oncommand="Snowl._toggleToolbar(event)"/>
+            <menuitem id="snowlViewToolbarMenuitem"
+                      label="&viewtoolbar.label;"
+                      type="checkbox"
+                      checked="true"
+                      autoCheck="false"
+                      accesskey="&viewtoolbar.accesskey;"
+                      name="snowlViewToolbar"
+                      persist="checked"
+                      oncommand="Snowl._toggleToolbar(event)"/>
+          </menupopup>
+        </menu>
+        <menuseparator/>
         <menuitem label="&subscribe.label;" accesskey="&subscribe.accesskey;"
                   oncommand="Snowl.onSubscribe()"/>
         <menuitem label="&importOPML.label;" accesskey="&importOPML.accesskey;"
@@ -93,11 +184,26 @@
     </menu>
   </menupopup>
 
+  <toolbarpalette id="BrowserToolbarPalette">
+    <toolbarbutton id="snowlToolbarButton"
+                   type="menu"
+                   label="&snowlMenu.label;"
+                   tooltiptext="&snowlMenu.label;"
+                   onmousedown="Snowl.onStatusbarButtonMouseDown(event)"/>
+
+    <toolbarbutton id="snowlToggleHeaderButton"
+                   class="toolbarbutton-1"
+                   oncommand="Snowl._toggleHeader('Toggle')"
+                   label="&toggleHeader.label;"
+                   snowlHeader="full"
+                   tooltiptext="&toggleHeader.tooltip;"/>
+  </toolbarpalette>>
+
   <statusbar id="status-bar">
     <statusbarpanel id="snowlStatusbarButton" class="statusbarpanel-menu-iconic"
                     insertbefore="statusbar-display"
                     src="chrome://snowl/content/icons/snowl-16.png"
-                    onmousedown="Snowl.onStatusbarButtonMouseDown()">
+                    onmousedown="Snowl.onStatusbarButtonMouseDown(event)">
     </statusbarpanel>
   </statusbar>
 
--- a/content/list.css	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/list.css	Mon Oct 20 02:05:26 2008 -0700
@@ -53,10 +53,6 @@
   display: none;
 }
 
-#snowlLayoutButton {
-  list-style-image: url("chrome://snowl/content/icons/application_tile_horizontal.png");
-}
-
 #snowlView {
   height: 12em;
 }
--- a/content/list.js	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/list.js	Mon Oct 20 02:05:26 2008 -0700
@@ -200,6 +200,8 @@
 
     this._snowlViewContainer.hidden = false;
     this._snowlViewSplitter.hidden = false;
+
+    Snowl._initSnowlToolbar();
   },
 
   hide: function() {
--- a/content/list.xul	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/list.xul	Mon Oct 20 02:05:26 2008 -0700
@@ -58,7 +58,7 @@
   
   <vbox id="sidebar-box"
         flex="1"/>
-           
+
   <browser id="sidebar"
            style="min-width: 14em; width: 18em; max-width: none;"/>
 
@@ -71,48 +71,8 @@
           hidden="true">
       <toolbar id="snowlViewToolbar"
                pack="end"
-               align="center">
-        <toolbarbutton id="snowlLayoutButton"
-                       class="snowlToolbarButton"
-                       type="menu"
-                       tooltiptext="Change Layout">
-          <menupopup id="snowlLayoutPopup">
-            <menuitem id="snowlLayoutMenuitemClassic"
-                      label="&layoutClassic.label;"
-                      type="radio"
-                      checked="true"
-                      name="snowlLayoutMenuitemGroup"
-                      persist="checked"
-                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kClassicLayout)"/>
-            <menuitem id="snowlLayoutMenuitemVertical"
-                      label="&layoutVertical.label;"
-                      type="radio"
-                      name="snowlLayoutMenuitemGroup"
-                      persist="checked"
-                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kVerticalLayout)"/>
-            <menuitem id="snowlLayoutMenuitemWideMessage"
-                      label="&layoutWideMessage.label;"
-                      type="radio"
-                      name="snowlLayoutMenuitemGroup"
-                      persist="checked"
-                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kWideMessageLayout)"/>
-            <menuitem id="snowlLayoutMenuitemWideThread"
-                      label="&layoutWideThread.label;"
-                      type="radio"
-                      name="snowlLayoutMenuitemGroup"
-                      persist="checked"
-                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kWideThreadLayout)"/>
-            <menuitem id="snowlLayoutMenuitemStacked"
-                      label="&layoutStacked.label;"
-                      type="radio"
-                      name="snowlLayoutMenuitemGroup"
-                      persist="checked"
-                      oncommand="SnowlMessageView.switchLayout(SnowlMessageView.kStackedLayout)"/>
-          </menupopup>
-        </toolbarbutton>
-
-        <toolbarspring/>
-
+               align="center"
+               persist="hidden">
         <toolbarbutton id="snowlCurrentButton" class="snowlToolbarButton"
                        type="checkbox"
                        image="chrome://snowl/content/icons/newspaper.png"
--- a/content/message/message.css	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/message/message.css	Mon Oct 20 02:05:26 2008 -0700
@@ -46,6 +46,14 @@
   font-weight: bold;
 }
 
+.briefHeaderBox {
+  -moz-box-align: baseline;
+}
+
+#briefSubject[href] .textbox-input {
+  cursor: pointer;
+}
+
 #body {
   -moz-box-flex: 1;
   -moz-user-focus: normal;
--- a/content/message/message.js	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/message/message.js	Mon Oct 20 02:05:26 2008 -0700
@@ -19,6 +19,7 @@
  *
  * Contributor(s):
  *   Myk Melez <myk@mozilla.org>
+ *   alta88 <alta88@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -47,6 +48,13 @@
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
+let gBrowserWindow = window.QueryInterface(Ci.nsIInterfaceRequestor).
+                     getInterface(Ci.nsIWebNavigation).
+                     QueryInterface(Ci.nsIDocShellTreeItem).
+                     rootTreeItem.
+                     QueryInterface(Ci.nsIInterfaceRequestor).
+                     getInterface(Ci.nsIDOMWindow);
+
 // Parse URL parameters
 let params = {};
 let query = window.location.search.substr(1);
@@ -75,9 +83,18 @@
     body.appendChild(docFragment);
 }
 
+// Brief headers
+document.getElementById("briefAuthor").value = message.author;
+document.getElementById("briefSubject").value = message.subject;
+document.getElementById("briefSubject").setAttribute("href", message.link);
+document.getElementById("briefTimestamp").value = SnowlUtils._formatDate(message.timestamp);
+
+// Full headers
 document.getElementById("author").value = message.author;
 document.getElementById("subject").value = message.subject;
 document.documentElement.setAttribute("title", message.subject);
 document.getElementById("timestamp").value = SnowlUtils._formatDate(message.timestamp);
 document.getElementById("link").href = message.link;
 document.getElementById("link").value = message.link;
+
+gBrowserWindow.Snowl._toggleHeader("TabSelect");
--- a/content/message/message.xul	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/message/message.xul	Mon Oct 20 02:05:26 2008 -0700
@@ -21,6 +21,7 @@
    -
    - Contributor(s):
    -   Myk Melez <myk@mozilla.org>
+   -   alta88 <alta88@gmail.com>
    -
    - Alternatively, the contents of this file may be used under the terms of
    - either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -37,6 +38,7 @@
    - ***** END LICENSE BLOCK ***** -->
 
 <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+<?xml-stylesheet href="chrome://global/skin/formatting.css" type="text/css"?>
 <?xml-stylesheet href="chrome://snowl/content/message/message.css" type="text/css"?>
 
 <!DOCTYPE page SYSTEM "chrome://snowl/locale/message.dtd">
@@ -44,38 +46,86 @@
 <page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <vbox id="head">
-    <grid>
-      <columns>
-        <column id="labelColumn"/>
-        <column id="valueColumn" flex="1"/>
-      </columns>
-      <rows>
-        <row id="authorRow">
-          <hbox class="labelBox">
-            <label class="label" value="&author.label;"/>
-          </hbox>
-          <label id="author" crop="end"/>
-        </row>
-        <row id="subjectRow">
-          <hbox class="labelBox">
-            <label class="label" value="&subject.label;"/>
-          </hbox>
-          <label id="subject" crop="end"/>
-        </row>
-        <row id="timestampRow">
-          <hbox class="labelBox">
-            <label class="label" value="&timestamp.label;"/>
-          </hbox>
-          <label id="timestamp" crop="end"/>
-        </row>
-        <row id="linkRow">
-          <hbox class="labelBox">
-            <label class="label" value="&link.label;"/>
-          </hbox>
-          <label id="link" class="text-link" crop="end"/>
-        </row>
-      </rows>
-    </grid>
+    <deck id="headerDeck" flex="1">
+
+      <hbox id="noHeader"/>
+
+      <grid id="briefHeader">
+        <columns>
+          <column id="briefSubjectColumn" flex="1">
+            <hbox class="briefHeaderBox">
+              <label class="label"
+                     value="&subject.label;"/>
+              <textbox id="briefSubject"
+                       class="text-link plain"
+                       readonly="true"
+                       crop="end"
+                       flex="1"/>
+            </hbox>
+          </column>
+          <column id="briefAuthorColumn" flex="1">
+            <hbox class="briefHeaderBox">
+              <label class="label"
+                     value="&author.label;"/>
+              <textbox id="briefAuthor"
+                       class="plain"
+                       readonly="true"
+                       crop="end"
+                       flex="1"/>
+            </hbox>
+          </column>
+          <column id="briefTimestampColumn">
+            <hbox class="briefHeaderBox">
+              <label class="label"
+                     value="&timestamp.label;"/>
+              <textbox id="briefTimestamp"
+                       class="plain"
+                       readonly="true"
+                       crop="end"
+                       flex="1"/>
+            </hbox>
+          </column>
+        </columns>
+        <rows>
+          <row id="briefRow"/>
+        </rows>
+      </grid>
+
+      <grid id="fullHeader">
+        <columns>
+          <column id="labelColumn"/>
+          <column id="valueColumn" flex="1"/>
+        </columns>
+        <rows>
+          <row id="authorRow">
+            <hbox class="labelBox">
+              <label class="label" value="&author.label;"/>
+            </hbox>
+            <label id="author" crop="end"/>
+          </row>
+          <row id="subjectRow">
+            <hbox class="labelBox">
+              <label class="label" value="&subject.label;"/>
+            </hbox>
+            <label id="subject" crop="end"/>
+          </row>
+          <row id="timestampRow">
+            <hbox class="labelBox">
+              <label class="label" value="&timestamp.label;"/>
+            </hbox>
+            <label id="timestamp" crop="end"/>
+          </row>
+          <row id="linkRow">
+            <hbox class="labelBox">
+              <label class="label" value="&link.label;"/>
+            </hbox>
+            <label id="link" class="text-link" crop="end"/>
+          </row>
+        </rows>
+      </grid>
+
+    </deck>
+
   </vbox>
 
   <vbox id="body"/>
--- a/content/stream.js	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/stream.js	Mon Oct 20 02:05:26 2008 -0700
@@ -172,6 +172,8 @@
     this._rebuildView();
 
     this._setMidnightTimout();
+
+    gBrowserWindow.Snowl._initSnowlToolbar();
   },
 
   _setMidnightTimout: function() {
--- a/content/toolbar.xul	Mon Oct 20 01:38:56 2008 -0700
+++ b/content/toolbar.xul	Mon Oct 20 02:05:26 2008 -0700
@@ -44,7 +44,8 @@
 
   <script type="application/x-javascript" src="chrome://snowl/content/toolbar.js"/>
 
-  <toolbar id="snowlToolbar">
+  <toolbar id="snowlToolbar"
+           persist="hidden">
     <toolbarbutton id="snowlSubscribeButton"
                    image="chrome://snowl/content/icons/add.png"
                    oncommand="SnowlToolbar.subscribe()"
--- a/defaults/preferences/snowl.js	Mon Oct 20 01:38:56 2008 -0700
+++ b/defaults/preferences/snowl.js	Mon Oct 20 02:05:26 2008 -0700
@@ -0,0 +1,2 @@
+// Header view pref: 0 = none, 1 = brief, 2= full
+pref("extensions.snowl.message.headerView", 1);
--- a/locale/en-US/browser.dtd	Mon Oct 20 01:38:56 2008 -0700
+++ b/locale/en-US/browser.dtd	Mon Oct 20 02:05:26 2008 -0700
@@ -10,7 +10,7 @@
 
 <!ENTITY listView.label                       "List">
 <!ENTITY listView.accesskey                   "l">
-<!ENTITY riverView.label                      "River">
+<!ENTITY riverView.label                      "Open River in New Tab">
 <!ENTITY riverView.accesskey                  "r">
 <!ENTITY streamView.label                     "Stream">
 <!ENTITY streamView.accesskey                 "t">
@@ -37,3 +37,35 @@
 <!ENTITY streamViewSidebarMenuItem.label      "Message Stream">
 <!ENTITY streamViewSidebarMenuItem.accesskey  "t">
 <!ENTITY streamViewSidebar.label              "Message Stream">
+
+<!-- These labels and access keys are for items in the Tools > Snowl menu,
+   - where the user doesn't need to be reminded that these are Snowl commands,
+   - since it is obvious from their placement in the Snowl menu. -->
+
+<!ENTITY snowlLayoutMenu.label                "Layouts">
+<!ENTITY snowlLayoutMenu.accesskey            "y">
+<!ENTITY layoutClassic.label                  "Classic">
+<!ENTITY layoutClassic.accesskey              "C">
+<!ENTITY layoutVertical.label                 "Vertical">
+<!ENTITY layoutVertical.accesskey             "V">
+<!ENTITY layoutWideMessage.label              "Wide Message">
+<!ENTITY layoutWideMessage.accesskey          "M">
+<!ENTITY layoutWideThread.label               "Wide List">
+<!ENTITY layoutWideThread.accesskey           "L">
+<!ENTITY layoutStacked.label                  "Stacked">
+<!ENTITY layoutStacked.accesskey              "S">
+
+<!ENTITY headerNone.label                     "No Header">
+<!ENTITY headerNone.accesskey                 "N">
+<!ENTITY headerBrief.label                    "Brief Header">
+<!ENTITY headerBrief.accesskey                "B">
+<!ENTITY headerBrief.label                    "Brief Header">
+<!ENTITY headerFull.label                     "Full Header">
+<!ENTITY headerFull.accesskey                 "F">
+<!ENTITY toolbar.label                        "Sidebar Toolbar">
+<!ENTITY toolbar.accesskey                    "d">
+<!ENTITY viewtoolbar.label                    "List Toolbar">
+<!ENTITY viewtoolbar.accesskey                "i">
+
+<!ENTITY toggleHeader.tooltip                 "Toggle message header to none, brief, or full">
+<!ENTITY toggleHeader.label                   "Snowl Toggle Header">
--- a/locale/en-US/list.dtd	Mon Oct 20 01:38:56 2008 -0700
+++ b/locale/en-US/list.dtd	Mon Oct 20 02:05:26 2008 -0700
@@ -7,10 +7,3 @@
 <!ENTITY authorCol.label              "Author">
 <!ENTITY subjectCol.label             "Subject">
 <!ENTITY timestampCol.label           "Date">
-
-<!ENTITY layoutClassic.label          "Classic">
-<!ENTITY layoutVertical.label         "Vertical">
-<!ENTITY layoutWideMessage.label      "Wide Message">
-<!ENTITY layoutWideThread.label       "Wide Thread">
-<!ENTITY layoutStacked.label          "Stacked">
-