ONOS-6730: Lion: I18n for Topology View
- WIP : part 1
- toolbar (partial)
- quick help (partial)

Change-Id: I85b5f0d8c0042d82fda00f26e9760ba1320405c6
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
index 5ef4724..2c6a966 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/UiExtensionManager.java
@@ -118,6 +118,7 @@
             // view component localization
             "core.view.App",
             "core.view.Cluster",
+            "core.view.Topo",
 
             // TODO: More to come...
     };
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/_config/core.view.Topo.lioncfg b/web/gui/src/main/resources/org/onosproject/ui/lion/_config/core.view.Topo.lioncfg
new file mode 100644
index 0000000..e69c7c3
--- /dev/null
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/_config/core.view.Topo.lioncfg
@@ -0,0 +1,33 @@
+#
+# Copyright 2017-present Open Networking Laboratory
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+bundle core.view.Topo
+
+alias cv core.view
+alias cf core.fw
+alias cc core.common
+
+from cv.Topo import *
+
+from cf.QuickHelp import qh_hint_close_detail
+
+from cc.Ui import click, shift_click, drag, cmd_scroll, cmd_drag
+
+# TODO: clean these up to just those used...
+from cc.Props import icon, title, app_id, version, category, origin, state, role
+from cc.Action import activate, deactivate, uninstall
+from cc.State import total
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui.properties
index 59e1255..2d0b7be 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui.properties
@@ -23,6 +23,10 @@
 click=click
 click_row=click row
 scroll_down=scroll down
+shift_click=shift-click
+drag=drag
+cmd_scroll=cmd-scroll
+cmd_drag=cmd-drag
 
 # Common control button tooltips
 tt_ctl_auto_refresh=Toggle auto refresh
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_es.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_es.properties
index 2f1c7c3..48de9bf 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_es.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_es.properties
@@ -23,6 +23,10 @@
 click=click
 click_row=click row
 scroll_down=Desplazar hacia abajo
+shift_click=shift-click (es)
+drag=drag (es)
+cmd_scroll=cmd-scroll (es)
+cmd_drag=cmd-drag (es)
 
 # Common control button tooltips
 tt_ctl_auto_refresh=Activar actualización automática
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_it.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_it.properties
index a04c80b..1733740 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_it.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_it.properties
@@ -23,6 +23,10 @@
 click=click
 click_row=click sulla riga
 scroll_down=scorri verso il basso
+shift_click=shift-click (it)
+drag=drag (it)
+cmd_scroll=cmd-scroll (it)
+cmd_drag=cmd-drag (it)
 
 # Common control button tooltips
 tt_ctl_auto_refresh=Attiva aggiornamento automatico
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_ko.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_ko.properties
index f25b030..10336cf 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_ko.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_ko.properties
@@ -23,6 +23,10 @@
 click=클릭
 click_row=행 선택
 scroll_down=아래로 스크롤
+shift_click=shift-click (ko)
+drag=drag (ko)
+cmd_scroll=cmd-scroll (ko)
+cmd_drag=cmd-drag (ko)
 
 # Common control button tooltips
 tt_ctl_auto_refresh=자동 새로고침 토글
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_CN.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_CN.properties
index f847f66..1505c25 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_CN.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_CN.properties
@@ -23,6 +23,10 @@
 click=点击
 click_row=单击 行
 scroll_down=向下滚动
+shift_click=shift-click (zh_CN)
+drag=drag (zh_CN)
+cmd_scroll=cmd-scroll (zh_CN)
+cmd_drag=cmd-drag (zh_CN)
 
 # Common control button tooltips
 tt_ctl_auto_refresh=切换自动刷新
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_TW.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_TW.properties
index 037c87c..37b094b 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_TW.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/common/Ui_zh_TW.properties
@@ -23,6 +23,10 @@
 click=點擊
 click_row=click row
 scroll_down=向下滾動
+shift_click=shift-click (zh_TW)
+drag=drag (zh_TW)
+cmd_scroll=cmd-scroll (zh_TW)
+cmd_drag=cmd-drag (zh_TW)
 
 # Common control button tooltips
 tt_ctl_auto_refresh=啟用自動更新
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo.properties
index 21861cc..c06e224 100644
--- a/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo.properties
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo.properties
@@ -23,3 +23,33 @@
 # Text that appears in the navigation panel
 nav_item_topo=Topology
 
+# Message when no devices are connected
+no_devices_are_connected=No Devices Are Connected
+
+# Action Key Toolbar Tooltips ...
+tbtt_tog_instances=Toggle ONOS instances panel
+tbtt_tog_summary=Toggle ONOS summary panel
+tbtt_tog_use_detail=Disable / enable details panel
+tbtt_tog_host=Toggle host visibility
+tbtt_tog_offline=Toggle offline visibility
+tbtt_tog_porthi=Toggle port highlighting
+tbtt_bad_links=Show bad links
+tbtt_tog_map=Toggle background geo map
+tbtt_sel_map=Select background geo map
+tbtt_tog_sprite=Toggle sprite layer
+tbtt_reset_loc=Reset node locations
+tbtt_tog_oblique=Toggle oblique view (experimental)
+tbtt_cyc_layers=Cycle node layers
+tbtt_cyc_dev_labs=Cycle device labels
+tbtt_cyc_host_labs=Cycle host labels
+tbtt_unpin_node=Unpin node (hover mouse over)
+tbtt_reset_zoom=Reset pan / zoom
+tbtt_tog_toolbar=Toggle Toolbar
+tbtt_eq_master=Equalize mastership roles
+
+# Quick Help Gestures
+qh_gest_click=Select the item and show details
+qh_gest_shift_click=Toggle selection state
+qh_gest_drag=Reposition (and pin) device / host
+qh_gest_cmd_scroll=Zoom in / out
+qh_gest_cmd_drag=Pan
diff --git a/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo_it.properties b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo_it.properties
new file mode 100644
index 0000000..5e94627
--- /dev/null
+++ b/web/gui/src/main/resources/org/onosproject/ui/lion/core/view/Topo_it.properties
@@ -0,0 +1,55 @@
+#
+# Copyright 2017-present Open Networking Laboratory
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+
+
+# ==========================================
+# |  WIP -- Not Yet Ready For Translation  |
+# ==========================================
+
+# Text that appears in the navigation panel
+nav_item_topo=Topology (it)
+
+# Message when no devices are connected
+no_devices_are_connected=No Devices Are Connected (it)
+
+# Action Key Toolbar Tooltips ...
+tbtt_tog_instances=Toggle ONOS instances panel (it)
+tbtt_tog_summary=Toggle ONOS summary panel (it)
+tbtt_tog_use_detail=Disable / enable details panel (it)
+tbtt_tog_host=Toggle host visibility (it)
+tbtt_tog_offline=Toggle offline visibility (it)
+tbtt_tog_porthi=Toggle port highlighting (it)
+tbtt_bad_links=Show bad links (it)
+tbtt_tog_map=Toggle background geo map (it)
+tbtt_sel_map=Select background geo map (it)
+tbtt_tog_sprite=Toggle sprite layer (it)
+tbtt_reset_loc=Reset node locations (it)
+tbtt_tog_oblique=Toggle oblique view (experimental) (it)
+tbtt_cyc_layers=Cycle node layers (it)
+tbtt_cyc_dev_labs=Cycle device labels (it)
+tbtt_cyc_host_labs=Cycle host labels (it)
+tbtt_unpin_node=Unpin node (hover mouse over) (it)
+tbtt_reset_zoom=Reset pan / zoom (it)
+tbtt_tog_toolbar=Toggle Toolbar (it)
+tbtt_eq_master=Equalize mastership roles (it)
+
+# Quick Help Gestures
+qh_gest_click=Select the item and show details (it)
+qh_gest_shift_click=Toggle selection state (it)
+qh_gest_drag=Reposition (and pin) device / host (it)
+qh_gest_cmd_scroll=Zoom in / out (it)
+qh_gest_cmd_drag=Pan (it)
diff --git a/web/gui/src/main/webapp/app/fw/widget/tooltip.js b/web/gui/src/main/webapp/app/fw/widget/tooltip.js
index beca6f8..c7bcac5 100644
--- a/web/gui/src/main/webapp/app/fw/widget/tooltip.js
+++ b/web/gui/src/main/webapp/app/fw/widget/tooltip.js
@@ -82,7 +82,9 @@
         var elem = d3.select(el),
             mouseX = d3.event.pageX,
             mouseY = d3.event.pageY,
-            style = tipStyle(mouseX, mouseY);
+            style = tipStyle(mouseX, mouseY),
+            ttMsg = fs.isF(msg) ? msg() : msg;
+
         currElemId = elem.attr('id');
 
         tooltip.transition()
@@ -92,7 +94,7 @@
             })
             .each('end', function () {
                 d3.select(this).style(style)
-                    .text(msg);
+                    .text(ttMsg);
             });
     }
 
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 29f149f..f39d61b 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -37,36 +37,77 @@
     var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
 
     // Internal state
-    var zoomer, actionMap;
+    var zoomer,
+        actionMap,
+        topoLion = function (x) { return '#' + x + '#'}; // func replaced later
 
     // --- Short Cut Keys ------------------------------------------------
 
     function setUpKeys(overlayKeys) {
         // key bindings need to be made after the services have been injected
         // thus, deferred to here...
+
+        // we need functions that can be invoked after LION bundle loaded
+        function togInst() {return topoLion('tbtt_tog_instances')}
+        function togSumm() {return topoLion('tbtt_tog_summary')}
+        function togUseDet() {return topoLion('tbtt_tog_use_detail')}
+
+        function togHost() {return topoLion('tbtt_tog_host')}
+        function togOff() {return topoLion('tbtt_tog_offline')}
+        function togPortHi() {return topoLion('tbtt_tog_porthi')}
+
+        function showBad() {return topoLion('tbtt_bad_links')}
+        function togMap() {return topoLion('tbtt_tog_map')}
+        function selMap() {return topoLion('tbtt_sel_map')}
+        function togSpr() {return topoLion('tbtt_tog_sprite')}
+
+        function rstLoc() {return topoLion('tbtt_reset_loc')}
+        function togOb() {return topoLion('tbtt_tog_oblique')}
+        function cycLayer() {return topoLion('tbtt_cyc_layers')}
+        function cycDev() {return topoLion('tbtt_cyc_dev_labs')}
+        function cycHost() {return topoLion('tbtt_cyc_host_labs')}
+
+        function unpin() {return topoLion('tbtt_unpin_node')}
+        function rzoom() {return topoLion('tbtt_reset_zoom')}
+        function togtb() {return topoLion('tbtt_tog_toolbar')}
+        function eqmaster() {return topoLion('tbtt_eq_master')}
+
+        function uiClick() {return topoLion('click')}
+        function uiShClick() {return topoLion('shift_click')}
+        function uiDrag() {return topoLion('drag')}
+        function uiCmdScr() {return topoLion('cmd_scroll')}
+        function uiCmdDrag() {return topoLion('cmd_drag')}
+
+        function uiClickTxt() {return topoLion('qh_gest_click')}
+        function uiShClickTxt() {return topoLion('qh_gest_shift_click')}
+        function uiDragTxt() {return topoLion('qh_gest_drag')}
+        function uiCmdScrTxt() {return topoLion('qh_gest_cmd_scroll')}
+        function uiCmdDragTxt() {return topoLion('qh_gest_cmd_drag')}
+
         actionMap = {
-            I: [toggleInstances, 'Toggle ONOS instances panel'],
-            O: [toggleSummary, 'Toggle ONOS summary panel'],
-            D: [toggleUseDetailsFlag, 'Disable / enable details panel'],
+            I: [toggleInstances, togInst],
+            O: [toggleSummary, togSumm],
+            D: [toggleUseDetailsFlag, togUseDet],
 
-            H: [toggleHosts, 'Toggle host visibility'],
-            M: [toggleOffline, 'Toggle offline visibility'],
-            P: [togglePorts, 'Toggle Port Highlighting'],
-            dash: [tfs.showBadLinks, 'Show bad links'],
-            B: [toggleMap, 'Toggle background geo map'],
-            G: [openMapSelection, 'Select background geo map'],
-            S: [toggleSprites, 'Toggle sprite layer'],
+            H: [toggleHosts, togHost],
+            M: [toggleOffline, togOff],
+            P: [togglePorts, togPortHi],
 
-            X: [tfs.resetAllLocations, 'Reset node locations'],
-            Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'],
-            N: [fltr.clickAction, 'Cycle node layers'],
-            L: [tfs.cycleDeviceLabels, 'Cycle device labels'],
-            'shift-L': [tfs.cycleHostLabels, 'Cycle host labels'],
-            U: [tfs.unpin, 'Unpin node (hover mouse over)'],
-            R: [resetZoom, 'Reset pan / zoom'],
-            dot: [ttbs.toggleToolbar, 'Toggle Toolbar'],
+            dash: [tfs.showBadLinks, showBad],
+            B: [toggleMap, togMap],
+            G: [openMapSelection, selMap],
+            S: [toggleSprites, togSpr],
 
-            E: [equalizeMasters, 'Equalize mastership roles'],
+            X: [tfs.resetAllLocations, rstLoc],
+            Z: [tos.toggleOblique, togOb],
+            N: [fltr.clickAction, cycLayer],
+            L: [tfs.cycleDeviceLabels, cycDev],
+            'shift-L': [tfs.cycleHostLabels, cycHost],
+
+            U: [tfs.unpin, unpin],
+            R: [resetZoom, rzoom],
+            dot: [ttbs.toggleToolbar, togtb],
+            E: [equalizeMasters, eqmaster],
 
             //-- instance color palette debug
             // 9: function () { sus.cat7().testCard(svg); },
@@ -96,11 +137,11 @@
         ks.keyBindings(actionMap);
 
         ks.gestureNotes([
-            ['click', 'Select the item and show details'],
-            ['shift-click', 'Toggle selection state'],
-            ['drag', 'Reposition (and pin) device / host'],
-            ['cmd-scroll', 'Zoom in / out'],
-            ['cmd-drag', 'Pan']
+            [uiClick, uiClickTxt],
+            [uiShClick, uiShClickTxt],
+            [uiDrag, uiDragTxt],
+            [uiCmdScr, uiCmdScrTxt],
+            [uiCmdDrag, uiCmdDragTxt]
         ]);
     }
 
@@ -535,22 +576,28 @@
     // --- Controller Definition -----------------------------------------
 
     angular.module('ovTopo', moduleDependencies)
-        .controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout',
-            '$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
+        .controller('OvTopoCtrl',
+            ['$scope', '$log', '$location', '$timeout', '$cookies',
+            'FnService', 'MastService', 'KeyService', 'ZoomService',
             'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
             'WebSocketService', 'PrefsService', 'ThemeService',
-            'TopoDialogService', 'TopoD3Service',
-            'TopoEventService', 'TopoForceService', 'TopoPanelService',
-            'TopoInstService', 'TopoSelectService', 'TopoLinkService',
-            'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
-            'TopoToolbarService', 'TopoMapService', 'TopoSpriteService',
-            'TooltipService', 'TopoOverlayService',
+            'TopoDialogService', 'TopoD3Service', 'TopoEventService',
+            'TopoForceService', 'TopoPanelService', 'TopoInstService',
+            'TopoSelectService', 'TopoLinkService', 'TopoTrafficService',
+            'TopoObliqueService', 'TopoFilterService', 'TopoToolbarService',
+            'TopoMapService', 'TopoSpriteService', 'TooltipService',
+            'TopoOverlayService', 'LionService',
 
-        function (_$scope_, _$log_, _$loc_, _$timeout_, _$cookies_, _fs_, mast, _ks_,
-                  _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _th_,
+                function (_$scope_, _$log_, _$loc_, _$timeout_, _$cookies_,
+                  _fs_, mast, _ks_, _zs_,
+                  _gs_, _ms_, _sus_, _flash_,
+                  _wss_, _ps_, _th_,
                   _tds_, _t3s_, _tes_,
-                  _tfs_, _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_,
-                  _ttbs_, _tms_, _tspr_, _ttip_, _tov_) {
+                  _tfs_, _tps_, _tis_,
+                  _tss_, _tls_, _tts_,
+                  _tos_, _fltr_, _ttbs_,
+                  _tms_, _tspr_, _ttip_,
+                  _tov_, lion) {
 
             var params = _$loc_.search(),
                 selOverlay = params.overlayId,
@@ -660,6 +707,12 @@
                     flash.enable(true);
                     mapShader(true);
 
+                    // piggyback off the deferred map loading to load the
+                    // localization bundle after the uber bundle has arrived...
+                    $scope.lion = lion.bundle('core.view.Topo');
+                    topoLion = $scope.lion;
+                    $log.debug('Loaded Topo LION Bundle:', topoLion);
+
                     // now we have the map projection, we are ready for
                     //  the server to send us device/host data...
                     tes.start();
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
index 82d14ac..f9661aa 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -127,20 +127,34 @@
         keyData = d3.map(k2b);
         keyData.forEach(function(key, value) {
             var data = api.getActionEntry(key);
-            value.cb = data[0];                     // on-click callback
-            value.tt = data[1] + ' (' + key + ')';  // tooltip
+
+            value.key = key;
+            value.cb = data[0];     // on-click callback
+            value.tt = data[1];     // tooltip (may be a function)
         });
     }
 
+    // returns a no-args function that returns the tooltip text
+    function deferredText(v) {
+        // this function will get invoked at the time the tooltip is displayed:
+        return function () {
+            if (!v.ttText) {
+                // haven't cached the value yet
+                v.ttText = (fs.isF(v.tt) ? v.tt() : v.tt) + ' (' + v.key + ')';
+            }
+            return v.ttText;
+        };
+    }
+
     function addButton(key) {
         var v = keyData.get(key);
-        v.btn = toolbar.addButton(v.id, v.gid, v.cb, v.tt);
+        v.btn = toolbar.addButton(v.id, v.gid, v.cb, deferredText(v));
     }
 
     function addToggle(key, suppressIfMobile) {
         var v = keyData.get(key);
         if (suppressIfMobile && fs.isMobile()) { return; }
-        v.tog = toolbar.addToggle(v.id, v.gid, v.isel, v.cb, v.tt);
+        v.tog = toolbar.addToggle(v.id, v.gid, v.isel, v.cb, deferredText(v));
     }
 
     function addFirstRow() {