|
@@ -64,6 +64,8 @@ $(document).ready(function() {
|
|
|
headRowHeight: [32],
|
|
headRowHeight: [32],
|
|
|
defaultRowHeight: 21,
|
|
defaultRowHeight: 21,
|
|
|
headColWidth: [25],
|
|
headColWidth: [25],
|
|
|
|
|
+ frozenColCount: 1,
|
|
|
|
|
+ frozenLineColor: '#d9d9d9',
|
|
|
headerFont: '12px 微软雅黑',
|
|
headerFont: '12px 微软雅黑',
|
|
|
font: '12px 微软雅黑',
|
|
font: '12px 微软雅黑',
|
|
|
readOnly: false,
|
|
readOnly: false,
|
|
@@ -212,20 +214,16 @@ $(document).ready(function() {
|
|
|
* 根据目录区域宽度调整树表列宽,拖动分隔条时保持 SpreadJS 填满容器。
|
|
* 根据目录区域宽度调整树表列宽,拖动分隔条时保持 SpreadJS 填满容器。
|
|
|
*/
|
|
*/
|
|
|
resizeSpreadColumns() {
|
|
resizeSpreadColumns() {
|
|
|
- const containerWidth = Math.floor($('#filing-spread').innerWidth() || 0);
|
|
|
|
|
- if (containerWidth <= 0) return;
|
|
|
|
|
-
|
|
|
|
|
- const rowHeaderWidth = 25;
|
|
|
|
|
- const fileCountWidth = 70;
|
|
|
|
|
- const scrollbarWidth = 18;
|
|
|
|
|
- const borderWidth = 2;
|
|
|
|
|
- const nameWidth = Math.max(
|
|
|
|
|
- containerWidth - rowHeaderWidth - fileCountWidth - scrollbarWidth - borderWidth,
|
|
|
|
|
- 60
|
|
|
|
|
- );
|
|
|
|
|
- this.sheet.setColumnWidth(0, nameWidth);
|
|
|
|
|
- this.sheet.setColumnWidth(1, fileCountWidth);
|
|
|
|
|
|
|
+ if (!this.spread.getHost().clientWidth) return;
|
|
|
this.spread.refresh();
|
|
this.spread.refresh();
|
|
|
|
|
+ const sheet = this.sheet;
|
|
|
|
|
+ // 分栏骤然变窄时,旧的冻结列可能占满视口;先缩小它,才能量到实际可用宽度。
|
|
|
|
|
+ if (sheet.getViewportWidth(1) === 0) sheet.setColumnWidth(0, 1);
|
|
|
|
|
+ const viewportWidth = sheet.getViewportWidth(0) + sheet.getViewportWidth(1);
|
|
|
|
|
+ const fileCountWidth = this.spreadSetting.cols[1].width;
|
|
|
|
|
+ const nameWidth = Math.max(1, Math.floor(viewportWidth / sheet.zoom()) - fileCountWidth);
|
|
|
|
|
+ if (sheet.getColumnWidth(0) !== nameWidth) sheet.setColumnWidth(0, nameWidth);
|
|
|
|
|
+ if (sheet.getColumnWidth(1) !== fileCountWidth) sheet.setColumnWidth(1, fileCountWidth);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -294,18 +292,19 @@ $(document).ready(function() {
|
|
|
// 分类右键菜单
|
|
// 分类右键菜单
|
|
|
$.contextMenu({
|
|
$.contextMenu({
|
|
|
selector: '#filing-spread',
|
|
selector: '#filing-spread',
|
|
|
- build: function ($trigger, e) {
|
|
|
|
|
- const hit = SpreadJsObj.getHitTest($trigger, e, self.sheet);
|
|
|
|
|
- if (!hit || hit.row < 0 || hit.row >= self.filingTree.nodes.length) return false;
|
|
|
|
|
- const target = SpreadJsObj.safeRightClickSelection($trigger, e, self.spread);
|
|
|
|
|
- return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ build: ($trigger, e) => self._prepareNameMenu($trigger, e, self.spread),
|
|
|
items: {
|
|
items: {
|
|
|
|
|
+ 'copy-name': {
|
|
|
|
|
+ name: '复制名称',
|
|
|
|
|
+ icon: 'fa-copy',
|
|
|
|
|
+ callback: function() { self._copySelectedNames(self.spread); },
|
|
|
|
|
+ disabled: function() { return !self.sheet.getSelections().some(range => range.col <= 0); },
|
|
|
|
|
+ },
|
|
|
'paste-name': {
|
|
'paste-name': {
|
|
|
name: '粘贴名称',
|
|
name: '粘贴名称',
|
|
|
icon: 'fa-paste',
|
|
icon: 'fa-paste',
|
|
|
callback: function() { self._showNamePastePreview(); },
|
|
callback: function() { self._showNamePastePreview(); },
|
|
|
- disabled: function() { return !self._referenceNameClipboard || self._namePasteSaving || self._nameSaving; },
|
|
|
|
|
|
|
+ disabled: function() { return !self._nameClipboard || self._namePasteSaving || self._nameSaving; },
|
|
|
},
|
|
},
|
|
|
'delete': {
|
|
'delete': {
|
|
|
name: '删除',
|
|
name: '删除',
|
|
@@ -991,30 +990,31 @@ $(document).ready(function() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
_initNameClipboard() {
|
|
_initNameClipboard() {
|
|
|
- this._referenceNameClipboard = null;
|
|
|
|
|
|
|
+ this._nameClipboard = null;
|
|
|
this._namePasteItems = [];
|
|
this._namePasteItems = [];
|
|
|
this._namePasteSaving = false;
|
|
this._namePasteSaving = false;
|
|
|
const container = $('#filing-spread')[0];
|
|
const container = $('#filing-spread')[0];
|
|
|
|
|
+ this._bindNameCopy(this.spread);
|
|
|
// 先于 SpreadJS 的只读单元格处理,保留浏览器原生粘贴事件以读取本次剪贴板。
|
|
// 先于 SpreadJS 的只读单元格处理,保留浏览器原生粘贴事件以读取本次剪贴板。
|
|
|
container.addEventListener('keydown', e => {
|
|
container.addEventListener('keydown', e => {
|
|
|
- if (!(e.ctrlKey || e.metaKey) || e.altKey || e.keyCode !== 86 || this._isRenaming) return;
|
|
|
|
|
|
|
+ if (!(e.ctrlKey || e.metaKey) || e.altKey || e.keyCode !== 86 || this._isRenaming || this.sheet.isEditing()) return;
|
|
|
e.stopImmediatePropagation();
|
|
e.stopImmediatePropagation();
|
|
|
- if (!this._referenceNameClipboard || this._namePasteSaving) {
|
|
|
|
|
|
|
+ if (!this._nameClipboard || this._namePasteSaving) {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
- if (!this._namePasteSaving) toastr.warning('请先从右侧参考文件复制名称');
|
|
|
|
|
|
|
+ if (!this._namePasteSaving) toastr.warning('请先从左侧分类或右侧参考文件复制名称');
|
|
|
}
|
|
}
|
|
|
}, true);
|
|
}, true);
|
|
|
container.addEventListener('paste', e => {
|
|
container.addEventListener('paste', e => {
|
|
|
- if (this._isRenaming) return;
|
|
|
|
|
|
|
+ if (this._isRenaming || this.sheet.isEditing()) return;
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
e.stopImmediatePropagation();
|
|
e.stopImmediatePropagation();
|
|
|
const text = e.clipboardData ? e.clipboardData.getData('text/plain') : '';
|
|
const text = e.clipboardData ? e.clipboardData.getData('text/plain') : '';
|
|
|
- this._pasteReferenceText(text);
|
|
|
|
|
|
|
+ this._pasteCopiedNames(text);
|
|
|
}, true);
|
|
}, true);
|
|
|
this.sheet.bind(spreadNS.Events.ClipboardPasting, (e, info) => {
|
|
this.sheet.bind(spreadNS.Events.ClipboardPasting, (e, info) => {
|
|
|
if (this._isRenaming || this.sheet.isEditing()) return;
|
|
if (this._isRenaming || this.sheet.isEditing()) return;
|
|
|
info.cancel = true;
|
|
info.cancel = true;
|
|
|
- this._pasteReferenceText(info.pasteData ? info.pasteData.text : '');
|
|
|
|
|
|
|
+ this._pasteCopiedNames(info.pasteData ? info.pasteData.text : '');
|
|
|
});
|
|
});
|
|
|
$('#filing-name-paste-ok').on('click.filesjsNames', () => { this._savePastedNames(); });
|
|
$('#filing-name-paste-ok').on('click.filesjsNames', () => { this._savePastedNames(); });
|
|
|
$('#filing-name-paste').on('hide.bs.modal.filesjsNames', e => {
|
|
$('#filing-name-paste').on('hide.bs.modal.filesjsNames', e => {
|
|
@@ -1026,60 +1026,43 @@ $(document).ready(function() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
initReferenceNameClipboard(spread) {
|
|
initReferenceNameClipboard(spread) {
|
|
|
- const container = $('#std-reference-spread')[0];
|
|
|
|
|
const sheet = spread.getActiveSheet();
|
|
const sheet = spread.getActiveSheet();
|
|
|
- container.addEventListener('keydown', e => {
|
|
|
|
|
- if (!(e.ctrlKey || e.metaKey) || e.altKey || e.keyCode !== 67 || sheet.isEditing()) return;
|
|
|
|
|
- e.preventDefault();
|
|
|
|
|
- e.stopImmediatePropagation();
|
|
|
|
|
- this._copyReferenceNames(spread);
|
|
|
|
|
- }, true);
|
|
|
|
|
- container.addEventListener('copy', e => {
|
|
|
|
|
- if (sheet.isEditing()) return;
|
|
|
|
|
- e.preventDefault();
|
|
|
|
|
- e.stopImmediatePropagation();
|
|
|
|
|
- this._copyReferenceNames(spread, e.clipboardData);
|
|
|
|
|
- }, true);
|
|
|
|
|
|
|
+ this._bindNameCopy(spread);
|
|
|
$.contextMenu({
|
|
$.contextMenu({
|
|
|
selector: '#std-reference-spread',
|
|
selector: '#std-reference-spread',
|
|
|
- build: function($trigger, e) {
|
|
|
|
|
- const hit = SpreadJsObj.getHitTest($trigger, e, sheet);
|
|
|
|
|
- if (!hit || hit.row < 0 || !sheet.zh_tree || hit.row >= sheet.zh_tree.nodes.length) return false;
|
|
|
|
|
- if (hit.hitTestType !== spreadNS.SheetArea.viewport && hit.hitTestType !== spreadNS.SheetArea.rowHeader) return false;
|
|
|
|
|
- SpreadJsObj.safeRightClickSelection($trigger, e, spread);
|
|
|
|
|
- return true;
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ build: ($trigger, e) => this._prepareNameMenu($trigger, e, spread),
|
|
|
items: {
|
|
items: {
|
|
|
'copy-name': {
|
|
'copy-name': {
|
|
|
name: '复制名称',
|
|
name: '复制名称',
|
|
|
icon: 'fa-copy',
|
|
icon: 'fa-copy',
|
|
|
- callback: () => { this._copyReferenceNames(spread); },
|
|
|
|
|
|
|
+ callback: () => { this._copySelectedNames(spread); },
|
|
|
|
|
+ disabled: () => !sheet.getSelections().some(range => range.col <= 0),
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- _copyReferenceNames(spread, clipboardData) {
|
|
|
|
|
|
|
+ _copySelectedNames(spread, clipboardData) {
|
|
|
const sheet = spread.getActiveSheet();
|
|
const sheet = spread.getActiveSheet();
|
|
|
|
|
+ if (sheet.isEditing()) return false;
|
|
|
const tree = sheet.zh_tree;
|
|
const tree = sheet.zh_tree;
|
|
|
const rows = new Set();
|
|
const rows = new Set();
|
|
|
for (const selection of sheet.getSelections()) {
|
|
for (const selection of sheet.getSelections()) {
|
|
|
if (selection.col > 0) continue;
|
|
if (selection.col > 0) continue;
|
|
|
const first = Math.max(0, selection.row);
|
|
const first = Math.max(0, selection.row);
|
|
|
- const last = selection.row < 0 ? sheet.getRowCount() : first + selection.rowCount;
|
|
|
|
|
|
|
+ const last = selection.row < 0 ? sheet.getRowCount() : Math.min(sheet.getRowCount(), first + selection.rowCount);
|
|
|
for (let row = first; row < last; row++) {
|
|
for (let row = first; row < last; row++) {
|
|
|
if (tree && tree.nodes[row] && sheet.getRowVisible(row)) rows.add(row);
|
|
if (tree && tree.nodes[row] && sheet.getRowVisible(row)) rows.add(row);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if (!rows.size) {
|
|
if (!rows.size) {
|
|
|
- this._referenceNameClipboard = null;
|
|
|
|
|
- toastr.warning('请先选中参考文件的名称列');
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ this._nameClipboard = null;
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
const names = [...rows].sort((a, b) => a - b).map(row => String(tree.nodes[row].name || ''));
|
|
const names = [...rows].sort((a, b) => a - b).map(row => String(tree.nodes[row].name || ''));
|
|
|
const text = names.join('\r\n');
|
|
const text = names.join('\r\n');
|
|
|
// 保留原始数组,名称内的换行仍属于同一个分类。
|
|
// 保留原始数组,名称内的换行仍属于同一个分类。
|
|
|
- this._referenceNameClipboard = { names, text };
|
|
|
|
|
|
|
+ this._nameClipboard = { names, text };
|
|
|
SpreadJsObj.Clipboard.setCopyData(text);
|
|
SpreadJsObj.Clipboard.setCopyData(text);
|
|
|
if (clipboardData) {
|
|
if (clipboardData) {
|
|
|
clipboardData.setData('text/plain', text);
|
|
clipboardData.setData('text/plain', text);
|
|
@@ -1088,12 +1071,14 @@ $(document).ready(function() {
|
|
|
}
|
|
}
|
|
|
spread.focus();
|
|
spread.focus();
|
|
|
toastr.success(`已复制 ${names.length} 条名称`);
|
|
toastr.success(`已复制 ${names.length} 条名称`);
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- _pasteReferenceText(text) {
|
|
|
|
|
- const clipboard = this._referenceNameClipboard;
|
|
|
|
|
|
|
+ _pasteCopiedNames(text) {
|
|
|
|
|
+ if (this._namePasteItems.length || this._namePasteSaving) return;
|
|
|
|
|
+ const clipboard = this._nameClipboard;
|
|
|
if (!clipboard || String(text || '').replace(/\r\n?/g, '\n') !== clipboard.text.replace(/\r\n?/g, '\n')) {
|
|
if (!clipboard || String(text || '').replace(/\r\n?/g, '\n') !== clipboard.text.replace(/\r\n?/g, '\n')) {
|
|
|
- toastr.warning('请重新从右侧参考文件复制名称后粘贴');
|
|
|
|
|
|
|
+ toastr.warning('请重新从左侧分类或右侧参考文件复制名称后粘贴');
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
this._showNamePastePreview();
|
|
this._showNamePastePreview();
|
|
@@ -1131,8 +1116,8 @@ $(document).ready(function() {
|
|
|
|
|
|
|
|
_showNamePastePreview() {
|
|
_showNamePastePreview() {
|
|
|
if (this._namePasteSaving || this._nameSaving || $('#filing-name-paste').hasClass('show')) return;
|
|
if (this._namePasteSaving || this._nameSaving || $('#filing-name-paste').hasClass('show')) return;
|
|
|
- const clipboard = this._referenceNameClipboard;
|
|
|
|
|
- if (!clipboard) { toastr.warning('请先从右侧参考文件复制名称'); return; }
|
|
|
|
|
|
|
+ const clipboard = this._nameClipboard;
|
|
|
|
|
+ if (!clipboard) { toastr.warning('请先从左侧分类或右侧参考文件复制名称'); return; }
|
|
|
if (this._isRenaming) return;
|
|
if (this._isRenaming) return;
|
|
|
const row = this.sheet.getActiveRowIndex();
|
|
const row = this.sheet.getActiveRowIndex();
|
|
|
if (row < 0 || !this.filingTree.nodes[row] || !this.sheet.getRowVisible(row)) {
|
|
if (row < 0 || !this.filingTree.nodes[row] || !this.sheet.getRowVisible(row)) {
|
|
@@ -1332,6 +1317,34 @@ $(document).ready(function() {
|
|
|
this.sheet.setValue(range.row, 0, '');
|
|
this.sheet.setValue(range.row, 0, '');
|
|
|
this.renameFiling(node, '');
|
|
this.renameFiling(node, '');
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ _bindNameCopy(spread) {
|
|
|
|
|
+ // 在表格复制命令中取得原选区,避免默认复制把文件数或备注拼进名称。
|
|
|
|
|
+ const commands = spread.commandManager();
|
|
|
|
|
+ const key = GC.Spread.Commands.Key.c;
|
|
|
|
|
+ const copy = () => this._copySelectedNames(spread);
|
|
|
|
|
+ commands.register('filesjsCopyNames', copy, key, true, false, false, false);
|
|
|
|
|
+ commands.register('filesjsCopyNamesMac', copy, key, false, false, false, true);
|
|
|
|
|
+ spread.getHost().addEventListener('copy', e => {
|
|
|
|
|
+ if (!e.clipboardData || !this._copySelectedNames(spread, e.clipboardData)) return;
|
|
|
|
|
+ e.preventDefault();
|
|
|
|
|
+ e.stopImmediatePropagation();
|
|
|
|
|
+ }, true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _prepareNameMenu($trigger, e, spread) {
|
|
|
|
|
+ const sheet = spread.getActiveSheet();
|
|
|
|
|
+ if (sheet.isEditing()) return false;
|
|
|
|
|
+ const hit = SpreadJsObj.getHitTest($trigger, e, sheet);
|
|
|
|
|
+ if (!hit || !sheet.zh_tree || hit.row < 0 || hit.row >= sheet.zh_tree.nodes.length) return false;
|
|
|
|
|
+ const area = spreadNS.SheetArea;
|
|
|
|
|
+ if (hit.hitTestType !== area.viewport && hit.hitTestType !== area.rowHeader) return false;
|
|
|
|
|
+ // 在选中名称行的行号上右键,也保留原来的多行选区。
|
|
|
|
|
+ if (hit.hitTestType === area.rowHeader && sheet.getSelections().some(range =>
|
|
|
|
|
+ range.col <= 0 && range.row >= 0 && hit.row >= range.row && hit.row < range.row + range.rowCount)) return true;
|
|
|
|
|
+ SpreadJsObj.safeRightClickSelection($trigger, e, spread);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 初始化
|
|
// 初始化
|