Index: js/ui/status/network.js
===================================================================
--- js/ui/status/network.js.orig	2014-08-22 16:41:29.423305963 +0800
+++ js/ui/status/network.js	2014-08-25 18:20:45.904193093 +0800
@@ -20,6 +20,7 @@ const MessageTray = imports.ui.messageTr
 const ModalDialog = imports.ui.modalDialog;
 const ModemManager = imports.misc.modemManager;
 const Util = imports.misc.util;
+const Shell = imports.gi.Shell;
 
 const NMConnectionCategory = {
     INVALID: 'invalid',
@@ -218,6 +219,10 @@ const NMConnectionSection = new Lang.Cla
             this.item.label.text = '';
     },
 
+    getConnectLabel: function() {
+        return _("Connect");
+    },
+
     _getMenuIcon: function() {
         return this.getIndicatorIcon();
     },
@@ -1230,7 +1235,8 @@ const NMVPNConnectionItem = new Lang.Cla
         if (this._activeConnection == null)
             return false;
 
-        return this._activeConnection.vpn_state != NetworkManager.VPNConnectionState.DISCONNECTED;
+        return (this._activeConnection.vpn_state != NetworkManager.VPNConnectionState.DISCONNECTED
+                && this._activeConnection.vpn_state != NetworkManager.VPNConnectionState.FAILED);
     },
 
     _buildUI: function() {
@@ -1318,28 +1324,84 @@ const NMVPNSection = new Lang.Class({
 
     _init: function(client) {
         this.parent(client);
+
+        this._vpnSettings = new PopupMenu.PopupMenuItem('');
+        this.item.menu.addMenuItem(this._vpnSettings);
+        this._vpnSettings.connect('activate', Lang.bind(this, this._onSettingsActivate));
+
+        this.connect('icon-changed', Lang.bind(this, this._onBusyVPNConnection));
+
         this._sync();
     },
 
     _sync: function() {
         let nItems = this._connectionItems.size();
         this.item.actor.visible = (nItems > 0);
+
+        this._vpnSettings.label.text = "VPN " + _("Settings") + "...";
+
         this.parent();
     },
 
+    _onBusyVPNConnection: function() {
+        if (this._vpnOngoingConnection == null)
+            return;
+
+        let activeConnection = this._vpnOngoingConnection._activeConnection;
+        if (activeConnection == null)
+            return;
+
+        switch(activeConnection.vpn_state) {
+        case NetworkManager.VPNConnectionState.PREPARE:
+        case NetworkManager.VPNConnectionState.CONNECT:
+        case NetworkManager.VPNConnectionState.IP_CONFIG_GET:
+        case NetworkManager.VPNConnectionState.NEED_AUTH:
+        case NetworkManager.VPNConnectionState.ACTIVATED:
+            log ("Ongoing Connection: disable other vpn connections.")
+            for (let item of this._connectionItems.values()){
+                if (item != this._vpnOngoingConnection)
+                    item.radioItem.actor.reactive = false;
+            };
+            break;
+        default:
+            this._vpnOngoingConnection = null;
+        }
+    },
+
+    _onSettingsActivate: function() {
+        let nItems = this._connectionItems.size();
+        let connection = this._connections[0];
+        Util.spawnApp(['gnome-control-center', 'network', 'show-device',
+                       connection.get_path()]);
+    },
+
     _getDescription: function() {
         return _("VPN");
     },
 
+    _getStatus: function() {
+        let values = this._connectionItems.values();
+        for (let item of values) {
+            if (item.isActive())
+                return item.getName();
+        }
+
+        return _("Off");
+    },
+
     _getMenuIcon: function() {
         return this.getIndicatorIcon() || 'network-vpn-symbolic';
     },
 
     activateConnection: function(connection) {
+        this._vpnOngoingConnection = this._connectionItems.get(connection.get_uuid());
+
         this._client.activate_connection(connection, null, null, null);
     },
 
     deactivateConnection: function(activeConnection) {
+        this._vpnOngoingConnection = null;
+
         this._client.deactivate_connection(activeConnection);
     },
 
@@ -1746,6 +1808,12 @@ const NMApplet = new Lang.Class({
     },
 
     _updateIcon: function() {
+        this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
+        this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
+
+        if (this._vpnIndicator.visible)
+            return;
+
         if (!this._client.networking_enabled || !this._mainConnection) {
             this._primaryIndicator.icon_name = 'network-offline-symbolic';
             this._primaryIndicator.visible = true;
@@ -1755,8 +1823,5 @@ const NMApplet = new Lang.Class({
             if (dev)
                 this._primaryIndicator.icon_name = dev.getIndicatorIcon();
         }
-
-        this._vpnIndicator.icon_name = this._vpnSection.getIndicatorIcon();
-        this._vpnIndicator.visible = (this._vpnIndicator.icon_name != '');
     }
 });
