From 054be60531583eb7a78cae70cfeb35447a3a5fc9 Mon Sep 17 00:00:00 2001 From: FelisCatus Date: Mon, 27 Oct 2014 21:16:57 +0800 Subject: [PATCH] Add migrate function to virtual profile. --- omega-i18n/en/messages.json | 50 ++++++++++++++ omega-i18n/zh_CN/messages.json | 59 ++++++++++++++++- omega-i18n/zh_HK/messages.json | 59 ++++++++++++++++- omega-i18n/zh_TW/messages.json | 59 ++++++++++++++++- .../omega_target_web.coffee | 2 + omega-target/src/options.coffee | 65 ++++++++++++++----- omega-web/src/coffee/omega_decoration.coffee | 36 +++++++++- omega-web/src/coffee/popup.coffee | 8 ++- omega-web/src/less/common.less | 6 ++ omega-web/src/less/popup.less | 5 -- omega-web/src/omega/controllers/master.coffee | 48 +++++++++----- .../src/omega/controllers/profile.coffee | 31 +++++++-- .../omega/controllers/switch_profile.coffee | 6 +- .../omega/controllers/virtual_profile.coffee | 9 --- omega-web/src/omega/filters.coffee | 5 +- .../src/partials/omega_profile_icon.jade | 2 - omega-web/src/partials/profile_rule_list.jade | 4 +- omega-web/src/partials/profile_switch.jade | 6 +- omega-web/src/partials/profile_virtual.jade | 12 +++- omega-web/src/partials/replace_profile.jade | 17 +++++ omega-web/src/partials/ui.jade | 2 +- omega-web/src/popup.jade | 2 +- 22 files changed, 409 insertions(+), 84 deletions(-) delete mode 100644 omega-web/src/omega/controllers/virtual_profile.coffee delete mode 100644 omega-web/src/partials/omega_profile_icon.jade create mode 100644 omega-web/src/partials/replace_profile.jade diff --git a/omega-i18n/en/messages.json b/omega-i18n/en/messages.json index 87df7ba..c7a321e 100644 --- a/omega-i18n/en/messages.json +++ b/omega-i18n/en/messages.json @@ -343,6 +343,21 @@ "options_virtualProfileTargetHelp": { "message": "When this profile is applied, it acts exactly the same as the profile selected below." }, + "options_group_virtualProfileReplace": { + "message": "Migrate to Virtual Profile" + }, + "options_virtualProfileReplace": { + "message": "Replace target profile" + }, + "options_virtualProfileReplaceHelp": { + "message": "You can migrate existing options to use this virtual profile instead of $PROFILE$. Doing so will update all existing rules concerning $PROFILE$ and point them to this virtual profile, so that their result profile can be controlled here.", + "placeholders": { + "PROFILE": { + "content": "$1", + "example": "direct" + } + } + }, "options_group_ruleListConfig": { "message": "Rule List Config" }, @@ -445,6 +460,41 @@ "options_profileNameHidden": { "message": "Profiles with names starting with underscore will be hidden on the popup menu. However, they can still be used in places like switch profile results." }, + "options_modalHeader_replaceProfile": { + "message": "Replace Profile" + }, + "options_replaceProfile": { + "message": "Replace Profile" + }, + "options_replaceProfileConfirm": { + "message": "Do you really want to replace $FromProfile$ with $ToProfile$?", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, + "options_replaceProfileHelp": { + "message": "If you proceed, all rules pointing to $FromProfile$ will be updated to use $ToProfile$ instead. Other options, such as startup profile and Quick Switch will also be modified as appropriate. However, the two profile themselves will NOT be changed or deleted.", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, + "options_replaceProfileSuccess": { + "message": "Options updated." + }, "options_modalHeader_deleteProfile": { "message": "Delete Profile" }, diff --git a/omega-i18n/zh_CN/messages.json b/omega-i18n/zh_CN/messages.json index 753f914..6f8cb17 100644 --- a/omega-i18n/zh_CN/messages.json +++ b/omega-i18n/zh_CN/messages.json @@ -334,15 +334,36 @@ "options_group_pacScript": { "message": "PAC 脚本" }, + "options_group_virtualProfile": { + "message": "虚情景模式" + }, + "options_virtualProfileTarget": { + "message": "目标" + }, + "options_virtualProfileTargetHelp": { + "message": "当使用此情景模式时,相当于使用了以下情景模式:" + }, + "options_group_virtualProfileReplace": { + "message": "迁移到虚情景模式" + }, + "options_virtualProfileReplace": { + "message": "取代目标情景模式" + }, + "options_virtualProfileReplaceHelp": { + "message": "通过此功能可以更改现有的选项,使用此虚情景模式来取代 $PROFILE$ 。此功能会把所有和 $PROFILE$ 相关的切换规则改为使用此虚情景模式。这样一来,就可以通过此虚情景模式来控制那些切换条件对应的结果。", + "placeholders": { + "PROFILE": { + "content": "$1", + "example": "direct" + } + } + }, "options_group_ruleListConfig": { "message": "规则列表设置" }, "options_ruleListFormat": { "message": "规则列表格式" }, - "options_virtualProfileTargetHelp": { - "message": "当使用此情景模式时,相当于使用了以下情景模式:" - }, "options_group_ruleListResult": { "message": "规则列表结果情景模式" }, @@ -439,6 +460,38 @@ "options_profileNameHidden": { "message": "以下划线开头的情景模式不会在弹出菜单中显示,但仍可被用作切换的结果等。" }, + "options_modalHeader_replaceProfile": { + "message": "替换情景模式" + }, + "options_replaceProfile": { + "message": "替换" + }, + "options_replaceProfileConfirm": { + "message": "您确定要使用 $ToProfile 来代替 $FromProfile$ 吗?", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, + "options_replaceProfileHelp": { + "message": "如果继续操作,则和 $FromProfile$ 有关的切换规则将改为使用 $ToProfile$ 来代替。此外,启动情景模式、快速切换等设置也会做相应调整。但请注意,此操作不影响这两个情景模式本身。", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, "options_modalHeader_deleteProfile": { "message": "删除情景模式" }, diff --git a/omega-i18n/zh_HK/messages.json b/omega-i18n/zh_HK/messages.json index 22b9976..0c8c8fb 100644 --- a/omega-i18n/zh_HK/messages.json +++ b/omega-i18n/zh_HK/messages.json @@ -334,15 +334,36 @@ "options_group_pacScript": { "message": "PAC 腳本" }, + "options_group_virtualProfile": { + "message": "虛情景模式" + }, + "options_virtualProfileTarget": { + "message": "目標" + }, + "options_virtualProfileTargetHelp": { + "message": "當使用此情景模式時,相當於使用了以下情景模式:" + }, + "options_group_virtualProfileReplace": { + "message": "遷移到虛情景模式" + }, + "options_virtualProfileReplace": { + "message": "取代目標情景模式" + }, + "options_virtualProfileReplaceHelp": { + "message": "通過此功能可以更改現有的選項,使用此虛情景模式來取代 $PROFILE$ 。此功能會把所有和 $PROFILE$ 相關的切換規則改為使用此虛情景模式。這樣一來,就可以通過此虛情景模式來控制那些切換條件對應的結果。", + "placeholders": { + "PROFILE": { + "content": "$1", + "example": "direct" + } + } + }, "options_group_ruleListConfig": { "message": "規則列表設置" }, "options_ruleListFormat": { "message": "規則列表格式" }, - "options_virtualProfileTargetHelp": { - "message": "當使用此情景模式時,相當於使用了以下情景模式:" - }, "options_group_ruleListResult": { "message": "規則列表結果情景模式" }, @@ -439,6 +460,38 @@ "options_profileNameHidden": { "message": "以下劃線開頭的情景模式不會在彈出菜單中顯示,但仍可被用作切換的結果等。" }, + "options_modalHeader_replaceProfile": { + "message": "替換情景模式" + }, + "options_replaceProfile": { + "message": "替換" + }, + "options_replaceProfileConfirm": { + "message": "您確定要使用 $ToProfile 來代替 $FromProfile$ 嗎?", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, + "options_replaceProfileHelp": { + "message": "如果繼續操作,則和 $FromProfile$ 有關的切換規則將改為使用 $ToProfile$ 來代替。此外,啟動情景模式、快速切換等設定也會做相應調整。但請注意,此操作不影響這兩個情景模式本身。", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, "options_modalHeader_deleteProfile": { "message": "刪除情景模式" }, diff --git a/omega-i18n/zh_TW/messages.json b/omega-i18n/zh_TW/messages.json index f4f3dcb..6bf4c27 100644 --- a/omega-i18n/zh_TW/messages.json +++ b/omega-i18n/zh_TW/messages.json @@ -334,15 +334,36 @@ "options_group_pacScript": { "message": "PAC 指令碼" }, + "options_group_virtualProfile": { + "message": "虛情景模式" + }, + "options_virtualProfileTarget": { + "message": "目標" + }, + "options_virtualProfileTargetHelp": { + "message": "當使用此情景模式時,相當於使用了以下情景模式:" + }, + "options_group_virtualProfileReplace": { + "message": "遷移到虛情景模式" + }, + "options_virtualProfileReplace": { + "message": "取代目標情景模式" + }, + "options_virtualProfileReplaceHelp": { + "message": "通過此功能可以更改現有的選項,使用此虛情景模式來取代 $PROFILE$ 。此功能會把所有和 $PROFILE$ 相關的切換規則改為使用此虛情景模式。這樣一來,就可以通過此虛情景模式來控制那些切換條件對應的結果。", + "placeholders": { + "PROFILE": { + "content": "$1", + "example": "direct" + } + } + }, "options_group_ruleListConfig": { "message": "規則列表設定" }, "options_ruleListFormat": { "message": "規則列表格式" }, - "options_virtualProfileTargetHelp": { - "message": "當使用此情景模式時,相當於使用了以下情景模式:" - }, "options_group_ruleListResult": { "message": "規則列表結果情景模式" }, @@ -439,6 +460,38 @@ "options_profileNameHidden": { "message": "以下劃線開頭的情景模式不會在彈出選單中顯示,但仍可被用作切換的結果等。" }, + "options_modalHeader_replaceProfile": { + "message": "替換情景模式" + }, + "options_replaceProfile": { + "message": "替換" + }, + "options_replaceProfileConfirm": { + "message": "您確定要使用 $ToProfile 來代替 $FromProfile$ 嗎?", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, + "options_replaceProfileHelp": { + "message": "如果繼續操作,則和 $FromProfile$ 有關的切換規則將改為使用 $ToProfile$ 來代替。此外,啟動情景模式、快速切換等設定也會做相應調整。但請注意,此操作不影響這兩個情景模式本身。", + "placeholders": { + "FromProfile": { + "content": "$1", + "example": "autoswitch" + }, + "ToProfile": { + "content": "$2", + "example": "direct" + } + } + }, "options_modalHeader_deleteProfile": { "message": "刪除情景模式" }, diff --git a/omega-target-chromium-extension/omega_target_web.coffee b/omega-target-chromium-extension/omega_target_web.coffee index f6ec12d..d686524 100644 --- a/omega-target-chromium-extension/omega_target_web.coffee +++ b/omega-target-chromium-extension/omega_target_web.coffee @@ -58,6 +58,8 @@ angular.module('omegaTarget', []).factory 'omegaTarget', ($q) -> return args renameProfile: (fromName, toName) -> callBackground('renameProfile', fromName, toName).then omegaTarget.refresh + replaceRef: (fromName, toName) -> + callBackground('replaceRef', fromName, toName).then omegaTarget.refresh optionsPatch: (patch) -> callBackground('patch', patch).then omegaTarget.refresh resetOptions: (opt) -> diff --git a/omega-target/src/options.coffee b/omega-target/src/options.coffee index 2c52a89..9cc9530 100644 --- a/omega-target/src/options.coffee +++ b/omega-target/src/options.coffee @@ -462,25 +462,11 @@ class Options fetchUrl: (url, opt_bypass_cache) -> Promise.reject new Error('not implemented') - ###* - # Rename a profile and update references and options - # @param {String} fromName The original profile name - # @param {String} toname The target profile name - # @returns {Promise} The updated options - ### - renameProfile: (fromName, toName) -> - @log.method('Options#renameProfile', this, arguments) - if OmegaPac.Profiles.byName(toName, @_options) - return Promise.reject new Error("Target name #{name} already taken!") - profile = OmegaPac.Profiles.byName(fromName, @_options) - if not profile - return Promise.reject new ProfileNotExistError(name) - - profile.name = toName - changes = {} - changes[OmegaPac.Profiles.nameAsKey(profile)] = profile + _replaceRefChanges: (fromName, toName, changes) -> + changes ?= {} OmegaPac.Profiles.each @_options, (key, p) -> + return if p.name == fromName or p.name == toName if OmegaPac.Profiles.replaceRef(p, fromName, toName) OmegaPac.Profiles.updateRevision(p) changes[OmegaPac.Profiles.nameAsKey(p)] = p @@ -493,6 +479,51 @@ class Options quickSwitch[i] = toName changes['-quickSwitchProfiles'] = quickSwitch + return changes + + ###* + # Replace all references of profile fromName to toName. + # @param {String} fromName The original profile name + # @param {String} toname The target profile name + # @returns {Promise} The updated options + ### + replaceRef: (fromName, toName) -> + @log.method('Options#replaceRef', this, arguments) + profile = OmegaPac.Profiles.byName(fromName, @_options) + if not profile + return Promise.reject new ProfileNotExistError(fromName) + + changes = @_replaceRefChanges(fromName, toName) + for own key, value of changes + @_options[key] = value + + fromKey = OmegaPac.Profiles.nameAsKey(fromName) + if @_watchingProfiles[fromKey] + if @_currentProfileName == fromName + @_currentProfileName = toName + @applyProfile(@_currentProfileName) + + @_setOptions(changes) + + ###* + # Rename a profile and update references and options + # @param {String} fromName The original profile name + # @param {String} toname The target profile name + # @returns {Promise} The updated options + ### + renameProfile: (fromName, toName) -> + @log.method('Options#renameProfile', this, arguments) + if OmegaPac.Profiles.byName(toName, @_options) + return Promise.reject new Error("Target name #{name} already taken!") + profile = OmegaPac.Profiles.byName(fromName, @_options) + if not profile + return Promise.reject new ProfileNotExistError(fromName) + + profile.name = toName + changes = {} + changes[OmegaPac.Profiles.nameAsKey(profile)] = profile + + @_replaceRefChanges(fromName, toName, changes) for own key, value of changes @_options[key] = value diff --git a/omega-web/src/coffee/omega_decoration.coffee b/omega-web/src/coffee/omega_decoration.coffee index c2bcc16..5948b3f 100644 --- a/omega-web/src/coffee/omega_decoration.coffee +++ b/omega-web/src/coffee/omega_decoration.coffee @@ -25,13 +25,43 @@ angular.module('omegaDecoration', []).value('profileIcons', { 1 ).directive('omegaProfileIcon', (profileIcons) -> restrict: 'A' - templateUrl: 'partials/omega_profile_icon.html' + template: ''' + + + ''' scope: 'profile': '=?omegaProfileIcon' 'icon': '=?icon' 'color': '=?color' link: (scope, element, attrs, ngModel) -> scope.profileIcons = profileIcons + scope.getIcon = (profile) -> + (scope.icon || scope.profileIcons[profile.virtualType] || + profileIcons[profile.profileType]) +).directive('omegaProfileInline', -> + restrict: 'A' + template: ''' + + {{dispName ? dispName(profile) : profile.name}} + ''' + scope: + 'profile': '=omegaProfileInline' + 'dispName': '=?dispName' +).directive('omegaHtml', ($compile) -> + restrict: 'A' + link: (scope, element, attrs, ngModel) -> + locals = + $profile: (profile = 'profile', dispName = 'dispNameFilter') -> + """ + + """ + getHtml = -> scope.$eval(attrs.omegaHtml, locals) + scope.$watch getHtml, (html) -> + element.html(html) + $compile(element.contents())(scope) ).directive('omegaProfileSelect', ($timeout, profileIcons) -> restrict: 'A' templateUrl: 'partials/omega_profile_select.html' @@ -39,7 +69,7 @@ angular.module('omegaDecoration', []).value('profileIcons', { scope: 'profiles': '&omegaProfileSelect' 'defaultText': '@?defaultText' - 'dispName': '&?dispName' + 'dispName': '=?dispName' link: (scope, element, attrs, ngModel) -> scope.profileIcons = profileIcons scope.currentProfiles = [] @@ -75,5 +105,5 @@ angular.module('omegaDecoration', []).value('profileIcons', { scope.getName = (profile) -> if profile - scope.dispName?({$profile: profile}) || profile?.name + scope.dispName(profile) || profile.name ) diff --git a/omega-web/src/coffee/popup.coffee b/omega-web/src/coffee/popup.coffee index 53b7c0b..c9c953d 100644 --- a/omega-web/src/coffee/popup.coffee +++ b/omega-web/src/coffee/popup.coffee @@ -3,10 +3,13 @@ module = angular.module('omegaPopup', ['omegaTarget', 'omegaDecoration', module.filter 'tr', (omegaTarget) -> omegaTarget.getMessage module.filter 'dispName', (omegaTarget) -> - (name) -> omegaTarget.getMessage('profile_' + name) || name + (name) -> + if typeof name == 'object' + name = name.name + omegaTarget.getMessage('profile_' + name) || name module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget, - profileIcons, profileOrder) -> + profileIcons, profileOrder, dispNameFilter) -> refreshOnProfileChange = false refresh = -> @@ -16,6 +19,7 @@ module.controller 'PopupCtrl', ($scope, $window, $q, omegaTarget, else $window.close() $scope.profileIcons = profileIcons + $scope.dispNameFilter = dispNameFilter $scope.isActive = (profileName) -> if $scope.isSystemProfile profileName == 'system' diff --git a/omega-web/src/less/common.less b/omega-web/src/less/common.less index 2a79578..f2897df 100644 --- a/omega-web/src/less/common.less +++ b/omega-web/src/less/common.less @@ -42,6 +42,12 @@ a[role="button"] { margin: -1px; } +.profile-inline { + background-color: #eee; + color: #333; + padding: 0 5px; +} + /* omega-profile-select */ .omega-profile-select { diff --git a/omega-web/src/less/popup.less b/omega-web/src/less/popup.less index f80b73d..b8fd84a 100644 --- a/omega-web/src/less/popup.less +++ b/omega-web/src/less/popup.less @@ -15,11 +15,6 @@ body.with-condition-form { min-width: 360px; } -.profile-inline { - background-color: #eee; - padding: 0 5px; -} - .nav { margin-bottom: 0; } diff --git a/omega-web/src/omega/controllers/master.coffee b/omega-web/src/omega/controllers/master.coffee index 4b08853..edc1ba0 100644 --- a/omega-web/src/omega/controllers/master.coffee +++ b/omega-web/src/omega/controllers/master.coffee @@ -1,24 +1,10 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window, $modal, $state, builtinProfiles, profileColors, profileIcons, omegaTarget, $q, $timeout, $location, $filter, getAttachedName, isProfileNameReserved, - isProfileNameHidden) -> + isProfileNameHidden, dispNameFilter) -> tr = $filter('tr') - # This method allows watchers to change the value without recursively firing - # itself. Usage: $scope.omegaWatchAndChange - # coffeelint: disable=missing_fat_arrows - $rootScope.omegaWatchAndChange = (expression, listener, objectEquality) -> - scope = this - # coffeelint: enable=missing_fat_arrows - handler = (newValue, oldValue) -> - modified = listener(newValue, oldValue) - return if newValue == oldValue and newValue == modified - for watcher in scope.$$watchers - if watcher.exp == expression - watcher.last = modified - return scope.$watch(expression, handler, objectEquality) - $rootScope.options = null omegaTarget.addOptionsChangeCallback (newOptions) -> @@ -128,6 +114,37 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window, $rootScope.options[OmegaPac.Profiles.nameAsKey(profile)] = profile $state.go('profile', {name: profile.name}) + $rootScope.replaceProfile = (fromName, toName) -> + $rootScope.applyOptionsConfirm().then -> + scope = $rootScope.$new('isolate') + scope.options = $rootScope.options + scope.fromName = fromName + scope.toName = toName + scope.profileByName = $rootScope.profileByName + scope.dispNameFilter = dispNameFilter + scope.profileSelect = (model) -> + """ +
+
+ """ + $modal.open( + templateUrl: 'partials/replace_profile.html' + scope: scope + ).result.then ({fromName, toName}) -> + omegaTarget.replaceRef(fromName, toName).then(-> + $rootScope.showAlert( + type: 'success' + i18n: 'options_replaceProfileSuccess' + ) + ).catch (err) -> + $rootScope.showAlert( + type: 'error' + message: err + ) + + $rootScope.renameProfile = (fromName) -> $rootScope.applyOptionsConfirm().then -> profile = $rootScope.profileByName(fromName) @@ -228,6 +245,7 @@ angular.module('omega').controller 'MasterCtrl', ($scope, $rootScope, $window, ), false $scope.profileIcons = profileIcons + $scope.dispNameFilter = dispNameFilter for own type of OmegaPac.Profiles.formatByType $scope.profileIcons[type] = $scope.profileIcons['RuleListProfile'] diff --git a/omega-web/src/omega/controllers/profile.coffee b/omega-web/src/omega/controllers/profile.coffee index d3fe9f7..346fdf9 100644 --- a/omega-web/src/omega/controllers/profile.coffee +++ b/omega-web/src/omega/controllers/profile.coffee @@ -1,6 +1,6 @@ angular.module('omega').controller 'ProfileCtrl', ($scope, $stateParams, - $location, $rootScope, $state, $modal, profileColorPalette, getAttachedName, - getParentName) -> + $location, $rootScope, $timeout, $state, $modal, profileColorPalette, + getAttachedName, getParentName) -> name = $stateParams.name profileTemplates = 'FixedProfile': 'profile_fixed.html' @@ -83,9 +83,26 @@ angular.module('omega').controller 'ProfileCtrl', ($scope, $stateParams, $scope.profileTemplate = 'partials/' + templ $scope.scriptable = true - onProfileChange = (profile, oldProfile) -> - return profile if profile == oldProfile - OmegaPac.Profiles.updateRevision(profile) - return profile + $scope.watchAndUpdateRevision = (expression) -> + revisionChanged = false + onChange = (profile, oldProfile) -> + return profile if profile == oldProfile or not profile or not oldProfile + if revisionChanged and profile.revision != oldProfile.revision + revisionChanged = false + else + OmegaPac.Profiles.updateRevision(profile) + revisionChanged = true + $scope.$watch expression, onChange, true - $scope.omegaWatchAndChange 'profile', onProfileChange, true + onProfileChange = (profile, oldProfile) -> + return if profile == oldProfile + if profile.virtualType + target = $scope.profileByName(profile.defaultProfileName) + profile.color = target.color + profile.virtualType = target.profileType + OmegaPac.Profiles.each $scope.options, (key, p) -> + if p.virtualType and p.defaultProfileName == profile.name + onProfileChange(p, null) + + $scope.watchAndUpdateRevision 'profile' + $scope.$watch 'profile', onProfileChange, true diff --git a/omega-web/src/omega/controllers/switch_profile.coffee b/omega-web/src/omega/controllers/switch_profile.coffee index 0044034..e4f2b54 100644 --- a/omega-web/src/omega/controllers/switch_profile.coffee +++ b/omega-web/src/omega/controllers/switch_profile.coffee @@ -154,11 +154,7 @@ angular.module('omega').controller 'SwitchProfileCtrl', ($scope, $location, $scope.$watch 'options[attachedKey]', (attached) -> $scope.attached = attached - onAttachedChange = (profile, oldProfile) -> - return profile if profile == oldProfile or not profile or not oldProfile - OmegaPac.Profiles.updateRevision(profile) - return profile - $scope.omegaWatchAndChange 'options[attachedKey]', onAttachedChange, true + $scope.watchAndUpdateRevision 'options[attachedKey]' $scope.attachedOptions = {enabled: false} $scope.$watch 'profile.defaultProfileName', (name) -> diff --git a/omega-web/src/omega/controllers/virtual_profile.coffee b/omega-web/src/omega/controllers/virtual_profile.coffee deleted file mode 100644 index 7709ac3..0000000 --- a/omega-web/src/omega/controllers/virtual_profile.coffee +++ /dev/null @@ -1,9 +0,0 @@ -angular.module('omega').controller 'VirtualProfileCtrl', ($scope, $location, - $modal, profileIcons, getAttachedName) -> - - onProfileChange = (profile, oldProfile) -> - return if profile == oldProfile or not profile or not oldProfile - target = $scope.profileByName(profile.defaultProfileName) - profile.color = target.color - profile.virtualType = target.profileType - $scope.$watch 'profile', onProfileChange, true diff --git a/omega-web/src/omega/filters.coffee b/omega-web/src/omega/filters.coffee index d69bc6d..b95c188 100644 --- a/omega-web/src/omega/filters.coffee +++ b/omega-web/src/omega/filters.coffee @@ -23,4 +23,7 @@ angular.module('omega').filter 'profiles', (builtinProfiles, profileOrder, angular.module('omega').filter 'tr', (omegaTarget) -> omegaTarget.getMessage angular.module('omega').filter 'dispName', (omegaTarget) -> - (name) -> omegaTarget.getMessage('profile_' + name) || name + (name) -> + if typeof name == 'object' + name = name.name + omegaTarget.getMessage('profile_' + name) || name diff --git a/omega-web/src/partials/omega_profile_icon.jade b/omega-web/src/partials/omega_profile_icon.jade deleted file mode 100644 index 6a6f658..0000000 --- a/omega-web/src/partials/omega_profile_icon.jade +++ /dev/null @@ -1,2 +0,0 @@ -span.glyphicon(class='{{icon || profileIcons[profile.virtualType] || profileIcons[profile.profileType]}}' - ng-style='{color: color || profile.color}' ng-class='{"virtual-profile-icon": profile.profileType == "VirtualProfile"}') diff --git a/omega-web/src/partials/profile_rule_list.jade b/omega-web/src/partials/profile_rule_list.jade index 24adcb0..a375a26 100644 --- a/omega-web/src/partials/profile_rule_list.jade +++ b/omega-web/src/partials/profile_rule_list.jade @@ -5,12 +5,12 @@ div(ng-controller='RuleListProfileCtrl') label {{'options_ruleListMatchProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.matchProfileName' - disp-name='$profile.name | dispName' style='display: inline-block;') + disp-name='dispNameFilter' style='display: inline-block;') .form-group label {{'options_ruleListDefaultProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName' - disp-name='$profile.name | dispName' style='display: inline-block;') + disp-name='dispNameFilter' style='display: inline-block;') form.form-group label {{'options_ruleListFormat' | tr}} .radio.inline-form-control.no-min-width(ng-repeat='format in ruleListFormats') diff --git a/omega-web/src/partials/profile_switch.jade b/omega-web/src/partials/profile_switch.jade index 4f75ee0..086c2b7 100644 --- a/omega-web/src/partials/profile_switch.jade +++ b/omega-web/src/partials/profile_switch.jade @@ -52,7 +52,7 @@ div(ng-controller='SwitchProfileCtrl') ui-validate='{pattern: "validateCondition(rule.condition, $value)"}') td div(omega-profile-select='options | profiles:profile' ng-model='rule.profileName' - disp-name='$profile.name | dispName' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}') + disp-name='dispNameFilter' ng-class='{disabled: rule.condition.conditionType == "NeverCondition"}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteRule' | tr}}" ng-click='removeRule($index)') span.glyphicon.glyphicon-trash @@ -80,7 +80,7 @@ div(ng-controller='SwitchProfileCtrl') | {{'options_switchAttachedProfileInConditionDisabled' | tr}} td div(omega-profile-select='options | profiles:profile' ng-model='attached.matchProfileName' - disp-name='$profile.name | dispName' ng-class='{disabled: !attachedOptions.enabled}') + disp-name='dispNameFilter' ng-class='{disabled: !attachedOptions.enabled}') td button.btn.btn-danger.btn-sm(title="{{'options_deleteAttached' | tr}}" ng-click='removeAttached()') span.glyphicon.glyphicon-trash @@ -90,7 +90,7 @@ div(ng-controller='SwitchProfileCtrl') td(colspan='2') {{'options_switchDefaultProfile' | tr}} td div(omega-profile-select='options | profiles:profile' ng-model='defaultProfileName' - disp-name='$profile.name | dispName') + disp-name='dispNameFilter') td button.btn.btn-info.btn-sm(title="{{'options_resetRules_help' | tr}}" ng-click='resetRules()') span.glyphicon.glyphicon-chevron-up diff --git a/omega-web/src/partials/profile_virtual.jade b/omega-web/src/partials/profile_virtual.jade index a5b38c4..d8dbd09 100644 --- a/omega-web/src/partials/profile_virtual.jade +++ b/omega-web/src/partials/profile_virtual.jade @@ -1,4 +1,4 @@ -div(ng-controller='VirtualProfileCtrl') +div section.settings-group h3 {{'options_group_virtualProfile' | tr}} p.help-block @@ -7,4 +7,12 @@ div(ng-controller='VirtualProfileCtrl') label {{'options_virtualProfileTarget' | tr}} = ' ' div(omega-profile-select='options | profiles:profile' ng-model='profile.defaultProfileName' - disp-name='$profile.name | dispName' style='display: inline-block;') + disp-name='dispNameFilter' style='display: inline-block;') + section.settings-group + h3 {{'options_group_virtualProfileReplace' | tr}} + p.help-block(omega-html='"options_virtualProfileReplaceHelp" | tr:[$profile("profileByName(profile.defaultProfileName)")]') + .form-group + button.btn.btn-default(ng-click='replaceProfile(profile.defaultProfileName, profile.name)') + span.glyphicon.glyphicon-search + = ' ' + | {{'options_virtualProfileReplace' | tr}} diff --git a/omega-web/src/partials/replace_profile.jade b/omega-web/src/partials/replace_profile.jade new file mode 100644 index 0000000..ac6d09c --- /dev/null +++ b/omega-web/src/partials/replace_profile.jade @@ -0,0 +1,17 @@ +.modal-header + button.close(type='button' ng-click='$dismiss()') + span(aria-hidden='true') × + span.sr-only {{'dialog_close' | tr}} + h4.modal-title {{'options_modalHeader_replaceProfile' | tr}} +.modal-body + p(omega-html='"options_replaceProfileConfirm" | tr:[profileSelect("fromName"), profileSelect("toName")]') + .well + span(omega-profile-inline='profileByName(fromName)') + = ' ' + span.glyphicon.glyphicon-chevron-right + = ' ' + span(omega-profile-inline='profileByName(toName)') + .help-block(omega-html="'options_replaceProfileHelp' | tr:[$profile('profileByName(fromName)'), $profile('profileByName(toName)')]") +.modal-footer + button.btn.btn-default(ng-click='$dismiss()') {{'dialog_cancel' | tr}} + button.btn.btn-warning(type='button' ng-click='$close({fromName: fromName, toName: toName})') {{'options_replaceProfile' | tr}} diff --git a/omega-web/src/partials/ui.jade b/omega-web/src/partials/ui.jade index 873a5ba..5bd5fbe 100644 --- a/omega-web/src/partials/ui.jade +++ b/omega-web/src/partials/ui.jade @@ -16,7 +16,7 @@ section.settings-group label {{'options_startupProfile' | tr}} = ' ' div(omega-profile-select='options | profiles:"all"' ng-model='options["-startupProfileName"]' - default-text="{{'options_startupProfile_none' | tr}}" disp-name='$profile.name | dispName' + default-text="{{'options_startupProfile_none' | tr}}" disp-name='dispNameFilter' style='display: inline-block;') div.checkbox label diff --git a/omega-web/src/popup.jade b/omega-web/src/popup.jade index cda7b79..aab14dd 100644 --- a/omega-web/src/popup.jade +++ b/omega-web/src/popup.jade @@ -123,7 +123,7 @@ html(lang='en' ng-app='omegaPopup' ng-controller='PopupCtrl' ng-csp) div.form-group label {{'options_resultProfile' | tr}} div(omega-profile-select='validResultProfiles' ng-model='rule.profileName' - disp-name='$profile.name | dispName') + disp-name='dispNameFilter') div.condition-controls button.btn.btn-default(type='button' ng-click='showConditionForm = false') | {{'dialog_cancel' | tr}}