diff --git a/CHANGELOG b/CHANGELOG index 17231b5b13..14343e683a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Re-position buttons on Binary/Image widget * Set focus on first visible input when modal is shown * Improve treeview headers * Add keyboard shortcuts diff --git a/src/view/form.js b/src/view/form.js index d5af77562b..66ef0eeb3d 100644 --- a/src/view/form.js +++ b/src/view/form.js @@ -3153,24 +3153,6 @@ function eval_pyson(value){ 'role': 'group' }); - this.but_select = jQuery('', { - 'class': 'btn btn-default', - 'type': 'button' - }).append(jQuery('', { - 'class': 'glyphicon glyphicon-search' - })).appendTo(group); - this.but_select.click(this.select.bind(this)); - - if (this.filename) { - this.but_open = jQuery('', { - 'class': 'btn btn-default', - 'type': 'button' - }).append(jQuery('', { - 'class': 'glyphicon glyphicon-folder-open' - })).appendTo(group); - this.but_open.click(this.open.bind(this)); - } - this.but_save_as = jQuery('', { 'class': 'btn btn-default', 'type': 'button' @@ -3179,6 +3161,14 @@ function eval_pyson(value){ })).appendTo(group); this.but_save_as.click(this.save_as.bind(this)); + this.but_select = jQuery('', { + 'class': 'btn btn-default', + 'type': 'button' + }).append(jQuery('', { + 'class': 'glyphicon glyphicon-search' + })).appendTo(group); + this.but_select.click(this.select.bind(this)); + this.but_clear = jQuery('', { 'class': 'btn btn-default', 'type': 'button' @@ -3195,6 +3185,17 @@ function eval_pyson(value){ return record.model.fields[this.filename]; } }, + update_buttons: function(value) { + if (value) { + this.but_save_as.show(); + this.but_select.hide(); + this.but_clear.show(); + } else { + this.but_save_as.hide(); + this.but_select.show(); + this.but_clear.hide(); + } + }, select: function() { var record = this.record(); @@ -3279,7 +3280,7 @@ function eval_pyson(value){ }.bind(this)); }, clear: function() { - var filename_field = this.filename_field(); + var filename_field = this.filename_field(); if (filename_field) { filename_field.set_client(this.record(), null); } @@ -3297,39 +3298,48 @@ function eval_pyson(value){ this.el = jQuery('
', { 'class': this.class_ }); - - if (this.filename && attributes.filename_visible) { - this.text = jQuery('', { - type: 'input', - 'class': 'form-control input-sm' - }).appendTo(this.el); - this.text.change(this.focus_out.bind(this)); - // Use keydown to not receive focus-in TAB - this.text.on('keydown', this.key_press.bind(this)); - } - var group = jQuery('', { 'class': 'input-group input-group-sm' }).appendTo(this.el); + this.size = jQuery('', { type: 'input', 'class': 'form-control input-sm', 'readonly': true }).appendTo(group); + if (this.filename && attributes.filename_visible) { + this.text = jQuery('', { + type: 'input', + 'class': 'form-control input-sm' + }).prependTo(group); + this.text.change(this.focus_out.bind(this)); + // Use keydown to not receive focus-in TAB + this.text.on('keydown', this.key_press.bind(this)); + this.text.css('width', '50%'); + this.size.css('width', '50%'); + + this.but_open = jQuery('', { + 'class': 'btn btn-default', + 'type': 'button' + }).append(jQuery('', { + 'class': 'glyphicon glyphicon-folder-open' + })).appendTo(jQuery('', { + 'class': 'input-group-btn', + }).prependTo(group)); + this.but_open.click(this.open.bind(this)); + } + this.toolbar('input-group-btn').appendTo(group); }, display: function(record, field) { Sao.View.Form.Binary._super.display.call(this, record, field); if (!field) { - this.size.val(''); - if (this.filename) { - this.but_open.button('disable'); - } if (this.text) { this.text.val(''); } - this.but_save_as.button('disable'); + this.size.val(''); + this.but_save_as.hide(); return; } var size; @@ -3338,21 +3348,17 @@ function eval_pyson(value){ } else { size = field.get(record).length; } - var button_sensitive; - if (size) { - button_sensitive = 'enable'; - } else { - button_sensitive = 'disable'; - } - - if (this.filename) { - if (this.text) { - this.text.val(this.filename_field().get(record) || ''); - } - this.but_open.button(button_sensitive); - } this.size.val(Sao.common.humanize(size)); - this.but_save_as.button(button_sensitive); + + if (this.text) { + this.text.val(this.filename_field().get(record) || ''); + if (size) { + this.but_open.parent().show(); + } else { + this.but_open.parent().hide(); + } + } + this.update_buttons(Boolean(size)); }, key_press: function(evt) { var editable = !this.wid_text.prop('readonly'); @@ -3371,14 +3377,8 @@ function eval_pyson(value){ } }, set_readonly: function(readonly) { - if (readonly) { - this.but_select.hide(); - this.but_clear.hide(); - - } else { - this.but_select.show(); - this.but_clear.show(); - } + this.but_select.prop('disabled', readonly); + this.but_clear.prop('disabled', readonly); if (this.wid_text) { this.wid_text.prop('readonly', readonly); } @@ -3456,12 +3456,8 @@ function eval_pyson(value){ this.update_img(); }, set_readonly: function(readonly) { - [this.but_select, this.but_open, this.but_save_as, this.but_clear] - .forEach(function(button) { - if (button) { - button.prop('disable', readonly); - } - }); + this.but_select.prop('disable', readonly); + this.but_clear.prop('disable', readonly); }, clear: function() { Sao.View.Form.Image._super.clear.call(this); @@ -3492,6 +3488,7 @@ function eval_pyson(value){ url = window.URL.createObjectURL(blob); } this.image.attr('src', url); + this.update_buttons(Boolean(data)); }.bind(this)); }, display: function(record, field) { diff --git a/src/view/tree.js b/src/view/tree.js index d47b86c60c..db2a3a01ce 100644 --- a/src/view/tree.js +++ b/src/view/tree.js @@ -1561,6 +1561,15 @@ Sao.View.Tree.BinaryColumn = Sao.class_(Sao.View.Tree.CharColumn, { class_: 'column-binary', + init: function(model, attributes) { + Sao.View.Tree.BinaryColumn._super.init.call(this, model, attributes); + this.filename = attributes.filename || null; + }, + get_cell: function() { + var cell = Sao.View.Tree.BinaryColumn._super.get_cell.call(this); + jQuery('').appendTo(cell); + return cell; + }, update_text: function(cell, record) { var size; if (this.field.get_size) { @@ -1568,8 +1577,46 @@ } else { size = this.field.get(record).length; } - cell.text(Sao.common.humanize(size)); - } + var text = size? Sao.common.humanize(size) : ''; + cell.children('span').text(text); + var button = cell.children('button'); + if (!button.length) { + button = jQuery('', { + 'class': 'btn btn-default btn-sm', + 'type': 'button', + }).append(jQuery('', { + 'class': 'glyphicon glyphicon-save', + })).appendTo(cell) + .click(record, function(event) { + // Prevent editable tree to start edition + event.stopPropagation(); + this.save_as(event.data); + }.bind(this)); + } + if (!size) { + button.hide(); + } else { + button.show(); + } + }, + save_as: function(record) { + var filename; + var mimetype = 'application/octet-binary'; + var filename_field = record.model.fields[this.filename]; + if (filename_field) { + filename = filename_field.get_client(record); + mimetype = Sao.common.guess_mimetype(filename); + } + var prm; + if (this.field.get_data) { + prm = this.field.get_data(record); + } else { + prm = jQuery.when(this.field.get(record)); + } + prm.done(function(data) { + Sao.common.download_file(data, filename); + }.bind(this)); + }, }); Sao.View.Tree.ImageColumn = Sao.class_(Sao.View.Tree.CharColumn, {