diff --git a/web/pgadmin/static/js/selection/clipboard.js b/web/pgadmin/static/js/selection/clipboard.js index a5f35ab..df077c0 100644 --- a/web/pgadmin/static/js/selection/clipboard.js +++ b/web/pgadmin/static/js/selection/clipboard.js @@ -7,6 +7,7 @@ // ////////////////////////////////////////////////////////////// + define(['sources/gettext', 'alertify'], function (gettext, alertify) { var clipboard = { copyTextToClipboard: function (text) { @@ -64,6 +65,9 @@ define(['sources/gettext', 'alertify'], function (gettext, alertify) { if (clipboardData) { clipboardData.setData('text', text); + // As there no uniform way to read data from clipboard + // storing copied data into main window object, so it is accessible from anywhere in the application + window.parent.window.clipboardData = text; // We want our data, not data from any selection, to be written to the clipboard e.preventDefault(); } @@ -83,6 +87,9 @@ define(['sources/gettext', 'alertify'], function (gettext, alertify) { document.body.removeChild(textArea); }, + getTextFromClipboard: function() { + return window.parent.window.clipboardData || ''; + }, }; return clipboard; }); diff --git a/web/pgadmin/static/js/selection/copy_data.js b/web/pgadmin/static/js/selection/copy_data.js index 29946ec..d139fa9 100644 --- a/web/pgadmin/static/js/selection/copy_data.js +++ b/web/pgadmin/static/js/selection/copy_data.js @@ -24,7 +24,6 @@ function ($, _, clipboard, RangeSelectionHelper, rangeBoundaryNavigator) { var dataView = grid.getData(); var rows = grid.getSelectedRows(); var CSVOptions = grid.CSVOptions; - if (RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges)) { self.copied_rows = rows.map(function (rowIndex) { return grid.getDataItem(rowIndex); @@ -48,6 +47,10 @@ function ($, _, clipboard, RangeSelectionHelper, rangeBoundaryNavigator) { var setPasteRowButtonEnablement = function (canEditFlag, isEnabled) { if (canEditFlag) { $('#btn-paste-row').prop('disabled', !isEnabled); + if(isEnabled && window.parent.$) { + // trigger copied event to all sessions + window.parent.$(window.parent.document).trigger('pgadmin-sqleditor:rows-copied', copyWithHeader()); + } } }; return copyData; diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js index f76bdbc..f02e3a7 100644 --- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js @@ -2363,6 +2363,8 @@ define('tools.querytool', [ // Indentation related self.on('pgadmin-sqleditor:indent_selected_code', self._indent_selected_code, self); self.on('pgadmin-sqleditor:unindent_selected_code', self._unindent_selected_code, self); + + window.parent.$(window.parent.document).on('pgadmin-sqleditor:rows-copied', self._copied_in_other_session); }, // Checks if there is any dirty data in the grid before executing a query @@ -3683,33 +3685,35 @@ define('tools.querytool', [ $('.copy-with-header').toggleClass('visibility-hidden'); }, + // This function will enable Paste button if data is copied in some other active session + _copied_in_other_session: function(e, copiedWithHeaders) { + pgAdmin.SqlEditor.copiedInOtherSessionWithHeaders = copiedWithHeaders; + $('#btn-paste-row').prop('disabled', false); + }, + // This function will paste the selected row. _paste_row: function() { - var self = this, - grid = self.slickgrid, - dataView = grid.getData(), - data = dataView.getItems(), - count = dataView.getLength(), - rows = grid.getSelectedRows().sort( - function(a, b) { - return a - b; + var self = this; + let rowsText = clipboard.getTextFromClipboard(); + let copied_rows = rowsText.split('\n'); + // Do not parse row if rows are copied with headers + if(pgAdmin.SqlEditor.copiedInOtherSessionWithHeaders) { + copied_rows = copied_rows.slice(1); + } + copied_rows = copied_rows.reduce((partial, item) => { + // split each row with "\t" + const values = item.split('\t'); + let row = {}; + for (let k in self.columns) { + let v = null; + if (values.length > k) { + v = values[k].replace(/^\"/g, '').replace(/\"$/g, ''); } - ), - copied_rows = rows.map(function(rowIndex) { - return data[rowIndex]; - }), - array_types = []; - - // for quick look up create list of array data types - for (var k in self.columns) { - if (self.columns[k].is_array) { - array_types.push(self.columns[k].name); + row[self.columns[k].name] = v; } - } - - rows = rows.length == 0 ? self.last_copied_rows : rows; - - self.last_copied_rows = rows; + partial.push(row); + return partial; + }, []); // If there are rows to paste? if (copied_rows.length > 0) { @@ -3717,10 +3721,21 @@ define('tools.querytool', [ // save newly pasted rows on server $('#btn-save-data').prop('disabled', false); - var arr_to_object = function(arr) { + var grid = self.slickgrid, + dataView = grid.getData(), + count = dataView.getLength(), + array_types = []; + // for quick look up create list of array data types + for (var k in self.columns) { + if (self.columns[k].is_array) { + array_types.push(self.columns[k].name); + } + } + + var arr_to_object = function (arr) { var obj = {}; - _.each(arr, function(val, i) { + _.each(arr, function (val, i) { if (arr[i] !== undefined) { // Do not stringify array types. if (_.isObject(arr[i]) && array_types.indexOf(i) == -1) { @@ -3742,13 +3757,13 @@ define('tools.querytool', [ // Reset selection dataView.beginUpdate(); - _.each(copied_rows, function(row) { + _.each(copied_rows, function (row) { var new_row = arr_to_object(row), _key = (self.gridView.client_primary_key_counter++).toString(); new_row.is_row_copied = true; self.temp_new_rows.push(count); new_row[self.client_primary_key] = _key; - if(self.has_oids && new_row.oid) { + if (self.has_oids && new_row.oid) { new_row.oid = null; } @@ -3761,7 +3776,9 @@ define('tools.querytool', [ count++; }); dataView.endUpdate(); + grid.invalidateRow(grid.getSelectedRows()); grid.updateRowCount(); + grid.render(); // Pasted row/s always append so bring last row in view port. grid.scrollRowIntoView(dataView.getLength()); grid.setSelectedRows([]);