diff --git a/htdocs/css/admin.css b/htdocs/css/admin.css
index c9df225c..1079c548 100644
--- a/htdocs/css/admin.css
+++ b/htdocs/css/admin.css
@@ -82,7 +82,8 @@ h1 {
/* col-1 */
.bookmarks table [data-editor="name"] {
- width: 35%;
+ white-space: nowrap;
+ width: 29%;
}
/* col-2 */
@@ -101,15 +102,28 @@ h1 {
}
/* col-4 */
-.bookmarks table [data-editor="description"] {
- width: 35%;
+.bookmarks table [data-editor="underlying"] {
+ white-space: nowrap;
+ min-width: 160px;
+ width: 10%;
}
/* col-5 */
+.bookmarks table [data-editor="description"] {
+ width: 29%;
+}
+
+/* col-6 */
+.bookmarks table [data-editor="scannable"] {
+ width: 2%;
+ text-align: center;
+}
+
+/* col-7 */
.bookmarks table tr td:last-child, .bookmarks table tr th:last-child {
text-align: right;
width: 10%;
- }
+}
.bookmarks table input, .bookmarks table select {
text-align: inherit;
diff --git a/htdocs/css/openwebrx.css b/htdocs/css/openwebrx.css
index 76e46fff..a38f0bb6 100644
--- a/htdocs/css/openwebrx.css
+++ b/htdocs/css/openwebrx.css
@@ -1512,17 +1512,16 @@ img.openwebrx-mirror-img
}
.openwebrx-dialog {
- background-color: #575757;
- padding: 10px;
- color: white;
- position: fixed;
- font-size: 10pt;
- border-radius: 15px;
- -moz-border-radius: 15px;
+ background-color: #575757;
+ padding: 10px;
+ color: white;
+ font-size: 10pt;
+ border-radius: 15px;
+ -moz-border-radius: 15px;
position: fixed;
left: 50%;
top: 50%;
- transform: translate(-50%, 0);
+ transform: translate(-50%, -50%);
}
.openwebrx-dialog .form-field {
diff --git a/htdocs/index.html b/htdocs/index.html
index d1dc8301..73b90cc6 100644
--- a/htdocs/index.html
+++ b/htdocs/index.html
@@ -384,7 +384,7 @@
Modulation:
-
+
Underlying:
diff --git a/htdocs/lib/BookmarkBar.js b/htdocs/lib/BookmarkBar.js
index 85adcd87..2532ea5f 100644
--- a/htdocs/lib/BookmarkBar.js
+++ b/htdocs/lib/BookmarkBar.js
@@ -108,13 +108,13 @@ BookmarkBar.prototype.showEditDialog = function(bookmark) {
if (!bookmark) {
var mode1 = this.getDemodulator().get_secondary_demod()
var mode2 = this.getDemodulator().get_modulation();
+ // if no secondary demod, use the primary one
if (!mode1) { mode1 = mode2; mode2 = ''; }
- if (!mode2) mode2 = '';
bookmark = {
name: '',
frequency: center_freq + this.getDemodulator().get_offset_frequency(),
modulation: mode1,
- underlying: mode2,
+ underlying: this.verifyUnderlying(mode2, mode1),
description: '',
scannable : this.modesToScan.indexOf(mode1) >= 0
}
@@ -124,12 +124,32 @@ BookmarkBar.prototype.showEditDialog = function(bookmark) {
this.$dialog.find('#name').focus();
};
+BookmarkBar.prototype.verifyUnderlying = function(underlying, modulation) {
+ if (!underlying) return '';
+
+ // check that underlying demod is valid and NOT the default one
+ var mode = Modes.findByModulation(modulation);
+ if (!mode || !mode.underlying || mode.underlying.indexOf(underlying) <= 0) {
+ return '';
+ }
+
+ return underlying;
+};
+
BookmarkBar.prototype.storeBookmark = function() {
var me = this;
var bookmark = this.$dialog.bookmarkDialog().getValues();
if (!bookmark) return;
+
+ // parse bookmark frequency to a number
bookmark.frequency = Number(bookmark.frequency);
+ // make sure underlying demod, if present, is valid
+ bookmark.underlying = this.verifyUnderlying(
+ bookmark.modulation,
+ bookmark.underlying
+ );
+
var bookmarks = me.localBookmarks.getBookmarks();
if (!bookmark.id) {
diff --git a/htdocs/lib/BookmarkDialog.js b/htdocs/lib/BookmarkDialog.js
index ef039352..55226e76 100644
--- a/htdocs/lib/BookmarkDialog.js
+++ b/htdocs/lib/BookmarkDialog.js
@@ -10,7 +10,7 @@ $.fn.bookmarkDialog = function() {
return this;
},
setUnderlying: function(modes) {
- $el.find('#underlying').html('
None ' +
+ $el.find('#underlying').html('
' +
modes.filter(function(m) {
return m.isAvailable() && !m.underlying && m.type === 'analog';
}).map(function(m) {
diff --git a/htdocs/lib/settings/BookmarkTable.js b/htdocs/lib/settings/BookmarkTable.js
index 4dc4b292..007a1780 100644
--- a/htdocs/lib/settings/BookmarkTable.js
+++ b/htdocs/lib/settings/BookmarkTable.js
@@ -188,6 +188,27 @@ ModulationEditor.prototype.getHtml = function() {
return $option.html();
};
+function UnderlyingEditor(table) {
+ Editor.call(this, table);
+ this.modes = table.data('modes');
+}
+
+UnderlyingEditor.prototype = new Editor();
+
+UnderlyingEditor.prototype.getInputHtml = function() {
+ return '
' +
+ ' ' +
+ $.map(this.modes, function(name, modulation) {
+ return '' + name + ' ';
+ }).join('') +
+ ' ';
+};
+
+UnderlyingEditor.prototype.getHtml = function() {
+ var $option = this.input.find('option:selected')
+ return $option? $option.html() : '';
+};
+
function DescriptionEditor(table) {
Editor.call(this, table);
}
@@ -220,20 +241,8 @@ ScannableEditor.prototype.getHtml = function() {
return this.getValue()? '✓' : '';
};
-var renderModulation = function(b, modes) {
- var modulation = b.modulation;
- if (modulation in modes) {
- modulation = modes[modulation];
- }
- var underlying = b.underlying;
- if (underlying in modes) {
- underlying = modes[underlying];
- }
- // add underlying modulation, if present
- if (underlying) {
- modulation += ' (' + underlying + ')';
- }
- return modulation;
+var renderModulation = function(m, modes) {
+ return m in modes? modes[m] : m;
}
$.fn.bookmarktable = function() {
@@ -241,6 +250,7 @@ $.fn.bookmarktable = function() {
name: NameEditor,
frequency: FrequencyEditor,
modulation: ModulationEditor,
+ underlying: UnderlyingEditor,
description: DescriptionEditor,
scannable: ScannableEditor
};
@@ -393,7 +403,8 @@ $.fn.bookmarktable = function() {
'
' +
'
' + b.name + ' ' +
'
' + renderFrequency(b.frequency) + ' ' +
- '
' + renderModulation(b, modes) + ' ' +
+ '
' + renderModulation(b.modulation, modes) + ' ' +
+ '
' + renderModulation(b.underlying, modes) + ' ' +
''
);
row.data('bookmark', b);
@@ -424,22 +435,23 @@ $.fn.bookmarktable = function() {
var modes = $table.data('modes');
if (data.length && data.length == selected.length) {
$table.append(data.map(function(obj, index) {
- var bookmark = selected[index];
+ var b = selected[index];
// provide reasonable default for missing fields
- if (!('description' in bookmark)) {
- bookmark.description = '';
+ if (!('description' in b)) {
+ b.description = '';
}
- if (!('scannable' in bookmark)) {
+ if (!('scannable' in b)) {
var modesToScan = ['lsb', 'usb', 'cw', 'am', 'sam', 'nfm'];
- bookmark.scannable = modesToScan.indexOf(bookmark.modulation) >= 0;
+ b.scannable = modesToScan.indexOf(b.modulation) >= 0;
}
return $(
'
' +
- '' + bookmark.name + ' ' +
- '' + renderFrequency(bookmark.frequency) +' ' +
- '' + renderModulation(bookmark, modes) + ' ' +
- '' + bookmark.description + ' ' +
- '' + (bookmark.scannable? '✓':'') + ' ' +
+ '' + b.name + ' ' +
+ '' + renderFrequency(b.frequency) +' ' +
+ '' + renderModulation(b.modulation, modes) + ' ' +
+ '' + renderModulation(b.underlying, modes) + ' ' +
+ '' + b.description + ' ' +
+ '' + (b.scannable? '✓':'') + ' ' +
'' +
'delete ' +
' ' +
diff --git a/owrx/controllers/settings/bookmarks.py b/owrx/controllers/settings/bookmarks.py
index a2e66abe..3db40a91 100644
--- a/owrx/controllers/settings/bookmarks.py
+++ b/owrx/controllers/settings/bookmarks.py
@@ -24,7 +24,7 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
def render_table(self):
bookmarks = Bookmarks.getSharedInstance().getEditableBookmarks()
emptyText = """
-
+
No bookmarks in storage. You can add new bookmarks using the buttons below.
"""
@@ -35,6 +35,7 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
Name
Frequency
Modulation
+
Underlying
Description
Scan
Actions
@@ -66,17 +67,17 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
return "{num:g} {suffix}Hz".format(num=num, suffix=suffix)
scan = bookmark.isScannable()
- mode1 = Modes.findByModulation(bookmark.getModulation())
- mode2 = Modes.findByModulation(bookmark.getUnderlying())
- name1 = bookmark.getModulation() if mode1 is None else mode1.name
- name2 = bookmark.getUnderlying() if mode2 is None else mode2.name
- if name2:
- name1 += " (" + name2 + ")"
+ name1 = bookmark.getModulation()
+ name2 = bookmark.getUnderlying()
+ mode1 = Modes.findByModulation(name1)
+ mode2 = Modes.findByModulation(name2)
+
return """
{name}
{rendered_frequency}
{modulation_name}
+ {underlying_name}
{description}
{scannable_check}
@@ -89,8 +90,10 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
# TODO render frequency in si units
frequency=bookmark.getFrequency(),
rendered_frequency=render_frequency(bookmark.getFrequency()),
- modulation=bookmark.getModulation() if mode1 is None else mode1.modulation,
- modulation_name=name1,
+ modulation=name1 if mode1 is None else mode1.modulation,
+ underlying=name2 if mode2 is None else mode2.modulation,
+ modulation_name=name1 if mode1 is None else mode1.name,
+ underlying_name=name2 if mode2 is None else mode2.name,
description=bookmark.getDescription(),
scannable="true" if scan else "false",
scannable_check="✓" if scan else "",