mirror of
https://github.com/lxsang/antos-frontend.git
synced 2024-11-08 05:58:22 +01:00
support dnd and grid sort
This commit is contained in:
parent
079af3b0ce
commit
2cdd8f9a43
147
d.ts/antos.d.ts
vendored
147
d.ts/antos.d.ts
vendored
@ -3089,13 +3089,13 @@ declare namespace OS {
|
||||
*/
|
||||
private _onfileopen;
|
||||
/**
|
||||
* Reference to the currently selected file meta-data
|
||||
* Reference to the all selected files meta-datas
|
||||
*
|
||||
* @private
|
||||
* @type {API.FileInfoType}
|
||||
* @type {API.FileInfoType[]}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
private _selectedFile;
|
||||
private _selectedFiles;
|
||||
/**
|
||||
* Data placeholder of the current working directory
|
||||
*
|
||||
@ -3116,7 +3116,7 @@ declare namespace OS {
|
||||
* Header definition of the widget grid view
|
||||
*
|
||||
* @private
|
||||
* @type {(GenericObject<string | number>[])}
|
||||
* @type {(GenericObject<any>[])}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
private _header;
|
||||
@ -3227,6 +3227,19 @@ declare namespace OS {
|
||||
*/
|
||||
set showhidden(v: boolean);
|
||||
get showhidden(): boolean;
|
||||
/**
|
||||
* Setter:
|
||||
*
|
||||
* Allow multiple selection on file view
|
||||
*
|
||||
* Getter:
|
||||
*
|
||||
* Check whether the multiselection is actived
|
||||
*
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
set multiselect(v: boolean);
|
||||
get multiselect(): boolean;
|
||||
/**
|
||||
* Get the current selected file
|
||||
*
|
||||
@ -3235,6 +3248,14 @@ declare namespace OS {
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
get selectedFile(): API.FileInfoType;
|
||||
/**
|
||||
* Get all selected files
|
||||
*
|
||||
* @readonly
|
||||
* @type {API.FileInfoType[]}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
get selectedFiles(): API.FileInfoType[];
|
||||
/**
|
||||
* Setter:
|
||||
*
|
||||
@ -3266,7 +3287,7 @@ declare namespace OS {
|
||||
*
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
set ondragndrop(v: TagEventCallback<DnDEventDataType<TreeViewTag | ListViewItemTag>>);
|
||||
set ondragndrop(v: TagEventCallback<DnDEventDataType<TreeViewTag | ListViewItemTag | GridCellPrototype>>);
|
||||
/**
|
||||
* Sort file by its type
|
||||
*
|
||||
@ -3593,7 +3614,7 @@ declare namespace OS {
|
||||
* @type {T}
|
||||
* @memberof DnDEventDataType
|
||||
*/
|
||||
from: T;
|
||||
from: T[];
|
||||
/**
|
||||
* Reference to the target DOM element
|
||||
*
|
||||
@ -4148,7 +4169,7 @@ declare namespace OS {
|
||||
* drag and drop on the list
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: ListViewItemTag; to: ListViewItemTag }}
|
||||
* @type {{ from: ListViewItemTag[]; to: ListViewItemTag }}
|
||||
* @memberof ListViewTag
|
||||
*/
|
||||
private _dnd;
|
||||
@ -5056,6 +5077,15 @@ declare namespace OS {
|
||||
*/
|
||||
set text(v: string | FormattedString);
|
||||
get text(): string | FormattedString;
|
||||
/**
|
||||
* Setter: Turn on/off text selection
|
||||
*
|
||||
* Getter: Check whether the label is selectable
|
||||
*
|
||||
* @memberof LabelTag
|
||||
*/
|
||||
set selectable(v: boolean);
|
||||
get swon(): boolean;
|
||||
/**
|
||||
* Lqbel layout definition
|
||||
*
|
||||
@ -5275,6 +5305,10 @@ interface Array<T> {
|
||||
declare namespace OS {
|
||||
namespace GUI {
|
||||
namespace tag {
|
||||
/**
|
||||
* Row item event data type
|
||||
*/
|
||||
type GridRowEventData = TagEventDataType<GridRowTag>;
|
||||
/**
|
||||
* A grid Row is a simple element that
|
||||
* contains a group of grid cell
|
||||
@ -5291,11 +5325,34 @@ declare namespace OS {
|
||||
* @memberof GridRowTag
|
||||
*/
|
||||
data: GenericObject<any>[];
|
||||
/**
|
||||
* placeholder for the row select event callback
|
||||
*
|
||||
* @private
|
||||
* @type {TagEventCallback<GridRowEventData>}
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
private _onselect;
|
||||
/**
|
||||
*Creates an instance of GridRowTag.
|
||||
* @memberof GridRowTag
|
||||
*/
|
||||
constructor();
|
||||
/**
|
||||
* Set item select event handle
|
||||
*
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
set onrowselect(v: TagEventCallback<GridRowEventData>);
|
||||
/**
|
||||
* Setter: select/unselect the current item
|
||||
*
|
||||
* Getter: Check whether the current item is selected
|
||||
*
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
set selected(v: boolean);
|
||||
get selected(): boolean;
|
||||
/**
|
||||
* Mount the tag, do nothing
|
||||
*
|
||||
@ -5576,11 +5633,64 @@ declare namespace OS {
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _oncelldbclick;
|
||||
/**
|
||||
* Event data passing between mouse event when performing
|
||||
* drag and drop on the list
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: GridRowTag[]; to: GridRowTag }}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _dnd;
|
||||
/**
|
||||
* placeholder of list drag and drop event handle
|
||||
*
|
||||
* @private
|
||||
* @type {TagEventCallback<DnDEventDataType<GridRowTag>>}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _ondragndrop;
|
||||
/**
|
||||
* Creates an instance of GridViewTag.
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
constructor();
|
||||
/**
|
||||
* Set drag and drop event handle
|
||||
*
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set ondragndrop(v: TagEventCallback<DnDEventDataType<GridRowTag>>);
|
||||
/**
|
||||
* Setter: Enable/disable drag and drop event in the list
|
||||
*
|
||||
* Getter: Check whether the drag and drop event is enabled
|
||||
*
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set dragndrop(v: boolean);
|
||||
get dragndrop(): boolean;
|
||||
/**
|
||||
* placeholder of drag and drop mouse down event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmousedown;
|
||||
/**
|
||||
* placeholder of drag and drop mouse up event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmouseup;
|
||||
/**
|
||||
* placeholder of drag and drop mouse move event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmousemove;
|
||||
/**
|
||||
* Init the grid view before mounting.
|
||||
* Reset all the placeholders to default values
|
||||
@ -5694,6 +5804,16 @@ declare namespace OS {
|
||||
*/
|
||||
set resizable(v: boolean);
|
||||
get resizable(): boolean;
|
||||
/**
|
||||
* Sort the grid using a sort function
|
||||
*
|
||||
* @param {context: any} context of the executed function
|
||||
* @param {(a:GenericObject<any>[], b:GenericObject<any>[]) => boolean} a sort function that compares two rows data
|
||||
* * @param {index: number} current header index
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
sort(context: any, fn: (a: GenericObject<any>[], b: GenericObject<any>[], index?: number) => number): void;
|
||||
/**
|
||||
* Delete a grid rows
|
||||
*
|
||||
@ -5732,11 +5852,18 @@ declare namespace OS {
|
||||
* This function triggers the row select event, a cell select
|
||||
* event will also trigger this event
|
||||
*
|
||||
* @param {TagEventType<CellEventData>} e
|
||||
* @param {TagEventType<GridRowEventData>} e
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private rowselect;
|
||||
/**
|
||||
* Unselect all the selected rows in the grid
|
||||
*
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
unselect(): void;
|
||||
/**
|
||||
* Check whether the grid has header
|
||||
*
|
||||
@ -6584,7 +6711,7 @@ declare namespace OS {
|
||||
* Private data object passing between dragndrop mouse event
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: TreeViewTag; to: TreeViewTag }}
|
||||
* @type {{ from: TreeViewTag[]; to: TreeViewTag }}
|
||||
* @memberof TreeViewTag
|
||||
*/
|
||||
private _dnd;
|
||||
@ -6631,7 +6758,7 @@ declare namespace OS {
|
||||
* current tree. This function should return a promise on
|
||||
* a list of [[TreeViewDataType]]
|
||||
*
|
||||
* @memberof TreeViewItemPrototype
|
||||
* @memberof TreeViewTag
|
||||
*/
|
||||
fetch: (d: TreeViewItemPrototype) => Promise<TreeViewDataType[]>;
|
||||
/**
|
||||
|
@ -264,7 +264,6 @@ namespace OS {
|
||||
*/
|
||||
main(): void {
|
||||
const win = this.scheme as tag.WindowTag;
|
||||
$(win).attr("tabindex", 0);
|
||||
$(win).on('keydown', (e) => {
|
||||
switch (e.which) {
|
||||
case 27:
|
||||
@ -672,7 +671,7 @@ namespace OS {
|
||||
}
|
||||
for (let k in this.data) {
|
||||
const v = this.data[k];
|
||||
rows.push([{ text: k }, { text: v }]);
|
||||
rows.push([{ text: k }, { text: v, selectable: true }]);
|
||||
}
|
||||
const grid = this.find("grid") as tag.GridViewTag;
|
||||
grid.header = [
|
||||
@ -1052,7 +1051,7 @@ namespace OS {
|
||||
__("Resource not found: {0}", path)
|
||||
);
|
||||
}
|
||||
return (fileview.path = path);
|
||||
fileview.path = path;
|
||||
};
|
||||
|
||||
if (!this.data || !this.data.root) {
|
||||
@ -1088,11 +1087,14 @@ namespace OS {
|
||||
}
|
||||
};
|
||||
(this.find("btnOk") as tag.ButtonTag).onbtclick = (_e) => {
|
||||
const f = fileview.selectedFile;
|
||||
let f = fileview.selectedFile;
|
||||
if (!f) {
|
||||
return this.notify(
|
||||
__("Please select a file/fofler")
|
||||
);
|
||||
const sel = location.selectedItem;
|
||||
if(!sel)
|
||||
return this.notify(
|
||||
__("Please select a file/fofler")
|
||||
);
|
||||
f = sel.data as API.FileInfoType;
|
||||
}
|
||||
if (
|
||||
this.data &&
|
||||
|
@ -28,13 +28,13 @@ namespace OS {
|
||||
private _onfileopen: TagEventCallback<API.FileInfoType>;
|
||||
|
||||
/**
|
||||
* Reference to the currently selected file meta-data
|
||||
* Reference to the all selected files meta-datas
|
||||
*
|
||||
* @private
|
||||
* @type {API.FileInfoType}
|
||||
* @type {API.FileInfoType[]}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
private _selectedFile: API.FileInfoType;
|
||||
private _selectedFiles: API.FileInfoType[];
|
||||
|
||||
/**
|
||||
* Data placeholder of the current working directory
|
||||
@ -58,10 +58,10 @@ namespace OS {
|
||||
* Header definition of the widget grid view
|
||||
*
|
||||
* @private
|
||||
* @type {(GenericObject<string | number>[])}
|
||||
* @type {(GenericObject<any>[])}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
private _header: GenericObject<string | number>[];
|
||||
private _header: GenericObject<any>[];
|
||||
|
||||
/**
|
||||
* placeholder for the user-specified meta-data fetch function
|
||||
@ -92,10 +92,37 @@ namespace OS {
|
||||
this.chdir = true;
|
||||
this.view = "list";
|
||||
this._onfileopen = this._onfileselect = (e) => { };
|
||||
this._selectedFiles = [];
|
||||
const fn = function(r1, r2, i) {
|
||||
let t1 = r1[i].text;
|
||||
let t2 = r2[i].text;
|
||||
if(!t1 || !t2) return 0;
|
||||
t1 = t1.toString().toLowerCase();
|
||||
t2 = t2.toString().toLowerCase();
|
||||
if(this.__f)
|
||||
{
|
||||
this.desc = ! this.desc;
|
||||
if(t1 < t2) { return -1; }
|
||||
if(t1 > t2) { return 1; }
|
||||
}
|
||||
else
|
||||
{
|
||||
this.desc = ! this.desc;
|
||||
if(t1 > t2) { return -1; }
|
||||
if(t1 < t2) { return 1; }
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
this._header = [
|
||||
{ text: "__(File name)" },
|
||||
{
|
||||
text: "__(File name)",
|
||||
sort: fn
|
||||
},
|
||||
{ text: "__(Type)" },
|
||||
{ text: "__(Size)" },
|
||||
{
|
||||
text: "__(Size)",
|
||||
sort: fn
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -227,6 +254,28 @@ namespace OS {
|
||||
return this.hasattr("showhidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter:
|
||||
*
|
||||
* Allow multiple selection on file view
|
||||
*
|
||||
* Getter:
|
||||
*
|
||||
* Check whether the multiselection is actived
|
||||
*
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
set multiselect(v: boolean) {
|
||||
this.attsw(v, "multiselect");
|
||||
(this.refs.listview as ListViewTag).multiselect = v;
|
||||
(this.refs.gridview as GridViewTag).multiselect = v;
|
||||
}
|
||||
get multiselect(): boolean {
|
||||
return this.hasattr("multiselect");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the current selected file
|
||||
*
|
||||
@ -235,7 +284,21 @@ namespace OS {
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
get selectedFile(): API.FileInfoType {
|
||||
return this._selectedFile;
|
||||
if(this._selectedFiles.length == 0)
|
||||
return undefined;
|
||||
return this._selectedFiles[this._selectedFiles.length - 1];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all selected files
|
||||
*
|
||||
* @readonly
|
||||
* @type {API.FileInfoType[]}
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
get selectedFiles(): API.FileInfoType[] {
|
||||
return this._selectedFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,7 +349,7 @@ namespace OS {
|
||||
*
|
||||
* @memberof FileViewTag
|
||||
*/
|
||||
set data(v: API.FileInfoType[]) {
|
||||
set data(v: API.FileInfoType[]) {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
@ -305,11 +368,21 @@ namespace OS {
|
||||
*/
|
||||
set ondragndrop(
|
||||
v: TagEventCallback<
|
||||
DnDEventDataType<TreeViewTag | ListViewItemTag>
|
||||
DnDEventDataType<TreeViewTag | ListViewItemTag | GridCellPrototype>
|
||||
>
|
||||
) {
|
||||
(this.refs.treeview as TreeViewTag).ondragndrop = v;
|
||||
(this.refs.listview as ListViewTag).ondragndrop = v;
|
||||
(this.refs.gridview as GridViewTag).ondragndrop = (e) => {
|
||||
const evt = {
|
||||
id: this.aid,
|
||||
data: {
|
||||
from: e.data.from.map(x => x.data[0].domel),
|
||||
to: e.data.to.data[0].domel
|
||||
}
|
||||
};
|
||||
v(evt);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -514,7 +587,7 @@ namespace OS {
|
||||
$(this.refs.listview).hide();
|
||||
$(this.refs.gridview).hide();
|
||||
$(this.refs.treecontainer).hide();
|
||||
this._selectedFile = undefined;
|
||||
this._selectedFiles = [];
|
||||
switch (this.view) {
|
||||
case "icon":
|
||||
$(this.refs.listview).show();
|
||||
@ -552,7 +625,6 @@ namespace OS {
|
||||
);
|
||||
}
|
||||
const evt = { id: this.aid, data: e };
|
||||
this._selectedFile = e;
|
||||
this._onfileselect(evt);
|
||||
this.observable.trigger("fileselect", evt);
|
||||
}
|
||||
@ -612,18 +684,22 @@ namespace OS {
|
||||
grid.header = this._header;
|
||||
tree.dragndrop = true;
|
||||
list.dragndrop = true;
|
||||
grid.dragndrop = true;
|
||||
// even handles
|
||||
list.onlistselect = (e) => {
|
||||
this.fileselect(e.data.item.data as API.FileInfoType);
|
||||
this._selectedFiles = e.data.items.map( x => x.data as API.FileInfoType);
|
||||
};
|
||||
grid.onrowselect = (e) => {
|
||||
this.fileselect(
|
||||
($(e.data.item).children()[0] as GridCellPrototype)
|
||||
.data as API.FileInfoType
|
||||
);
|
||||
this._selectedFiles = e.data.items.map( x => ($(x).children()[0] as GridCellPrototype).data as API.FileInfoType);
|
||||
};
|
||||
tree.ontreeselect = (e) => {
|
||||
this.fileselect(e.data.item.data as API.FileInfoType);
|
||||
this._selectedFiles = [e.data.item.data as API.FileInfoType];
|
||||
};
|
||||
// dblclick
|
||||
list.onlistdbclick = (e) => {
|
||||
|
@ -19,6 +19,10 @@ interface Array<T> {
|
||||
namespace OS {
|
||||
export namespace GUI {
|
||||
export namespace tag {
|
||||
/**
|
||||
* Row item event data type
|
||||
*/
|
||||
export type GridRowEventData = TagEventDataType<GridRowTag>;
|
||||
/**
|
||||
* A grid Row is a simple element that
|
||||
* contains a group of grid cell
|
||||
@ -36,6 +40,15 @@ namespace OS {
|
||||
*/
|
||||
data: GenericObject<any>[];
|
||||
|
||||
/**
|
||||
* placeholder for the row select event callback
|
||||
*
|
||||
* @private
|
||||
* @type {TagEventCallback<GridRowEventData>}
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
private _onselect: TagEventCallback<GridRowEventData>;
|
||||
|
||||
/**
|
||||
*Creates an instance of GridRowTag.
|
||||
* @memberof GridRowTag
|
||||
@ -44,6 +57,36 @@ namespace OS {
|
||||
super();
|
||||
|
||||
this.refs.yield = this;
|
||||
this._onselect = (e) => {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Set item select event handle
|
||||
*
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
set onrowselect(v: TagEventCallback<GridRowEventData>) {
|
||||
this._onselect = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter: select/unselect the current item
|
||||
*
|
||||
* Getter: Check whether the current item is selected
|
||||
*
|
||||
* @memberof ListViewItemTag
|
||||
*/
|
||||
set selected(v: boolean) {
|
||||
this.attsw(v, "selected");
|
||||
$(this).removeClass();
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
$(this).addClass("afx-grid-row-selected");
|
||||
this._onselect({ id: this.aid, data: this });
|
||||
}
|
||||
get selected(): boolean {
|
||||
return this.hasattr("selected");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -420,6 +463,27 @@ namespace OS {
|
||||
*/
|
||||
private _oncelldbclick: TagEventCallback<CellEventData>;
|
||||
|
||||
/**
|
||||
* Event data passing between mouse event when performing
|
||||
* drag and drop on the list
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: GridRowTag[]; to: GridRowTag }}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _dnd: { from: GridRowTag[]; to: GridRowTag };
|
||||
|
||||
/**
|
||||
* placeholder of list drag and drop event handle
|
||||
*
|
||||
* @private
|
||||
* @type {TagEventCallback<DnDEventDataType<GridRowTag>>}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _ondragndrop: TagEventCallback<
|
||||
DnDEventDataType<GridRowTag>
|
||||
>;
|
||||
|
||||
/**
|
||||
* Creates an instance of GridViewTag.
|
||||
* @memberof GridViewTag
|
||||
@ -428,6 +492,68 @@ namespace OS {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set drag and drop event handle
|
||||
*
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set ondragndrop(
|
||||
v: TagEventCallback<DnDEventDataType<GridRowTag>>
|
||||
) {
|
||||
this._ondragndrop = v;
|
||||
this.dragndrop = this.dragndrop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter: Enable/disable drag and drop event in the list
|
||||
*
|
||||
* Getter: Check whether the drag and drop event is enabled
|
||||
*
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set dragndrop(v: boolean) {
|
||||
this.attsw(v, "dragndrop");
|
||||
if(!v)
|
||||
{
|
||||
$(this.refs.container).off("mousedown", this._onmousedown);
|
||||
}
|
||||
else
|
||||
{
|
||||
$(this.refs.container).on(
|
||||
"mousedown",
|
||||
this._onmousedown
|
||||
);
|
||||
}
|
||||
}
|
||||
get dragndrop(): boolean {
|
||||
return this.hasattr("dragndrop");
|
||||
}
|
||||
|
||||
/**
|
||||
* placeholder of drag and drop mouse down event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmousedown: (e: JQuery.MouseEventBase) => void;
|
||||
|
||||
/**
|
||||
* placeholder of drag and drop mouse up event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmouseup: (e: JQuery.MouseEventBase) => void;
|
||||
|
||||
/**
|
||||
* placeholder of drag and drop mouse move event handle
|
||||
*
|
||||
* @private
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private _onmousemove: (e: JQuery.MouseEventBase) => void;
|
||||
|
||||
|
||||
/**
|
||||
* Init the grid view before mounting.
|
||||
* Reset all the placeholders to default values
|
||||
@ -444,9 +570,13 @@ namespace OS {
|
||||
this._selectedRow = undefined;
|
||||
this._rows = [];
|
||||
this.resizable = false;
|
||||
this.dragndrop = false;
|
||||
this._oncellselect = this._onrowselect = this._oncelldbclick = (
|
||||
e: TagEventType<CellEventData>
|
||||
): void => {};
|
||||
this._ondragndrop = (
|
||||
e: TagEventType<DnDEventDataType<GridRowTag>>
|
||||
) => {};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -507,7 +637,14 @@ namespace OS {
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set cellitem(v: string) {
|
||||
const currci = this.cellitem;
|
||||
$(this).attr("cellitem", v);
|
||||
if(v != currci)
|
||||
{
|
||||
// force render data
|
||||
$(this.refs.grid).empty();
|
||||
this.rows = this.rows;
|
||||
}
|
||||
}
|
||||
get cellitem(): string {
|
||||
return $(this).attr("cellitem");
|
||||
@ -539,6 +676,12 @@ namespace OS {
|
||||
element.uify(this.observable);
|
||||
element.data = item;
|
||||
item.domel = element;
|
||||
element.oncellselect = (e) => {
|
||||
if(element.data.sort)
|
||||
{
|
||||
this.sort(element.data, element.data.sort);
|
||||
}
|
||||
};
|
||||
i++;
|
||||
if (this.resizable) {
|
||||
if (i != v.length) {
|
||||
@ -604,9 +747,48 @@ namespace OS {
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
set rows(rows: GenericObject<any>[][]) {
|
||||
$(this.refs.grid).empty();
|
||||
this._rows = rows;
|
||||
rows.map((row) => this.push(row, false));
|
||||
if(!rows) return;
|
||||
// update existing row with new data
|
||||
const ndrows = rows.length;
|
||||
const ncrows = this.refs.grid.children.length;
|
||||
const nmin = ndrows < ncrows? ndrows: ncrows;
|
||||
if(this.selectedRow)
|
||||
{
|
||||
this.selectedRow.selected = false;
|
||||
this._selectedRow = undefined;
|
||||
this._selectedRows = [];
|
||||
}
|
||||
for(let i = 0; i < nmin; i++)
|
||||
{
|
||||
const rowel = (this.refs.grid.children[i] as GridRowTag);
|
||||
rowel.data = rows[i];
|
||||
rowel.data.domel = rowel;
|
||||
for(let celi = 0; celi < rowel.children.length; celi++)
|
||||
{
|
||||
const cel = (rowel.children[celi] as GridCellPrototype);
|
||||
cel.data = rows[i][celi];
|
||||
cel.data.domel = cel;
|
||||
}
|
||||
}
|
||||
// remove existing remaining rows
|
||||
if(ndrows < ncrows)
|
||||
{
|
||||
const arr = Array.prototype.slice.call(this.refs.grid.children);
|
||||
const blacklist = arr.slice(nmin, ncrows);
|
||||
for(const r of blacklist)
|
||||
{
|
||||
this.delete(r);
|
||||
}
|
||||
}
|
||||
// or add more rows
|
||||
else if(ndrows > ncrows)
|
||||
{
|
||||
for(let i = nmin; i < ndrows; i++)
|
||||
{
|
||||
this.push(rows[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
get rows(): GenericObject<any>[][] {
|
||||
return this._rows;
|
||||
@ -639,7 +821,24 @@ namespace OS {
|
||||
get resizable(): boolean {
|
||||
return this.hasattr("resizable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the grid using a sort function
|
||||
*
|
||||
* @param {context: any} context of the executed function
|
||||
* @param {(a:GenericObject<any>[], b:GenericObject<any>[]) => boolean} a sort function that compares two rows data
|
||||
* * @param {index: number} current header index
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
sort(context: any, fn: (a:GenericObject<any>[], b:GenericObject<any>[], index?: number) => number): void {
|
||||
const index = this._header.indexOf(context);
|
||||
const __fn = (a, b) => {
|
||||
return fn.call(context,a, b, index);
|
||||
}
|
||||
this._rows.sort(__fn);
|
||||
context.__f = ! context.__f;
|
||||
this.rows = this._rows;
|
||||
}
|
||||
/**
|
||||
* Delete a grid rows
|
||||
*
|
||||
@ -713,6 +912,10 @@ namespace OS {
|
||||
element.oncelldbclick = (e) => this.cellselect(e, true);
|
||||
element.data = cell;
|
||||
}
|
||||
el.onrowselect = (e) => this.rowselect({
|
||||
id: el.aid,
|
||||
data: {item: el}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -751,7 +954,10 @@ namespace OS {
|
||||
} else {
|
||||
this.observable.trigger("cellselect", e);
|
||||
this._oncellselect(e);
|
||||
return this.rowselect(e);
|
||||
const row = ($(
|
||||
e.data.item
|
||||
).parent()[0] as any) as GridRowTag;
|
||||
row.selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,11 +965,11 @@ namespace OS {
|
||||
* This function triggers the row select event, a cell select
|
||||
* event will also trigger this event
|
||||
*
|
||||
* @param {TagEventType<CellEventData>} e
|
||||
* @param {TagEventType<GridRowEventData>} e
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
private rowselect(e: TagEventType<CellEventData>): void {
|
||||
private rowselect(e: TagEventType<GridRowEventData>): void {
|
||||
if (!e.data.item) {
|
||||
return;
|
||||
}
|
||||
@ -774,39 +980,58 @@ namespace OS {
|
||||
items: [],
|
||||
},
|
||||
};
|
||||
const row = ($(
|
||||
e.data.item
|
||||
).parent()[0] as any) as GridRowTag;
|
||||
const row = e.data.item as GridRowTag;
|
||||
if (this.multiselect) {
|
||||
if (this.selectedRows.includes(row)) {
|
||||
this.selectedRows.splice(
|
||||
this.selectedRows.indexOf(row),
|
||||
1
|
||||
);
|
||||
$(row).removeClass();
|
||||
row.selected = false;
|
||||
return;
|
||||
} else {
|
||||
this.selectedRows.push(row);
|
||||
$(row)
|
||||
.removeClass()
|
||||
.addClass("afx-grid-row-selected");
|
||||
}
|
||||
evt.data.items = this.selectedRows;
|
||||
} else {
|
||||
if(this.selectedRows.length > 0)
|
||||
{
|
||||
for(const item of this.selectedRows)
|
||||
{
|
||||
if(item != row)
|
||||
{
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.selectedRow === row) {
|
||||
return;
|
||||
}
|
||||
$(this.selectedRow).removeClass();
|
||||
this._selectedRows = [row];
|
||||
evt.data.item = row;
|
||||
if(this.selectedRow)
|
||||
this.selectedRow.selected = false;
|
||||
evt.data.items = [row];
|
||||
$(row).removeClass().addClass("afx-grid-row-selected");
|
||||
this._selectedRows = [row];
|
||||
}
|
||||
evt.data.item = row;
|
||||
this._selectedRow = row;
|
||||
this._onrowselect(evt);
|
||||
return this.observable.trigger("rowselect", evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unselect all the selected rows in the grid
|
||||
*
|
||||
* @returns {void}
|
||||
* @memberof GridViewTag
|
||||
*/
|
||||
unselect(): void {
|
||||
for (let v of this.selectedRows) {
|
||||
v.selected = false;
|
||||
}
|
||||
this._selectedRows = [];
|
||||
this._selectedRow = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the grid has header
|
||||
*
|
||||
@ -904,7 +1129,6 @@ namespace OS {
|
||||
*/
|
||||
protected mount(): void {
|
||||
$(this).css("overflow", "hidden");
|
||||
|
||||
$(this.refs.grid).css("display", "grid");
|
||||
$(this.refs.header).css("display", "grid");
|
||||
this.observable.on("resize", (e) => this.calibrate());
|
||||
@ -912,6 +1136,73 @@ namespace OS {
|
||||
.css("width", "100%")
|
||||
.css("overflow-x", "hidden")
|
||||
.css("overflow-y", "auto");
|
||||
// drag and drop
|
||||
this._dnd = {
|
||||
from: undefined,
|
||||
to: undefined,
|
||||
};
|
||||
this._onmousedown = (e) => {
|
||||
if(this.multiselect || this.selectedRows == undefined || this.selectedRows.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let el: any = $(e.target).closest("afx-grid-row");
|
||||
if (el.length === 0) {
|
||||
return;
|
||||
}
|
||||
el = el[0];
|
||||
if(!this.selectedRows.includes(el))
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._dnd.from = this.selectedRows;
|
||||
this._dnd.to = undefined;
|
||||
$(window).on("mouseup", this._onmouseup);
|
||||
$(window).on("mousemove", this._onmousemove);
|
||||
};
|
||||
|
||||
this._onmouseup = (e) => {
|
||||
$(window).off("mouseup", this._onmouseup);
|
||||
$(window).off("mousemove", this._onmousemove);
|
||||
$("#systooltip").hide();
|
||||
let el: any = $(e.target).closest("afx-grid-row");
|
||||
if (el.length === 0) {
|
||||
return;
|
||||
}
|
||||
el = el[0];
|
||||
if (this._dnd.from.includes(el)) {
|
||||
return;
|
||||
}
|
||||
this._dnd.to = el;
|
||||
this._ondragndrop({ id: this.aid, data: this._dnd });
|
||||
this._dnd = {
|
||||
from: undefined,
|
||||
to: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
this._onmousemove = (e) => {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
if (!this._dnd.from) {
|
||||
return;
|
||||
}
|
||||
const data = {
|
||||
text: __("{0} selected elements", this._dnd.from.length).__(),
|
||||
items: this._dnd.from
|
||||
};
|
||||
const $label = $("#systooltip");
|
||||
const top = e.clientY + 5;
|
||||
const left = e.clientX + 5;
|
||||
$label.show();
|
||||
const label = $label[0] as LabelTag;
|
||||
label.set(data);
|
||||
return $label
|
||||
.css("top", top + "px")
|
||||
.css("left", left + "px");
|
||||
};
|
||||
|
||||
return this.calibrate();
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ namespace OS {
|
||||
this.icon = undefined;
|
||||
this.iconclass = undefined;
|
||||
this.text = undefined;
|
||||
this.selectable = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,6 +122,33 @@ namespace OS {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter: Turn on/off text selection
|
||||
*
|
||||
* Getter: Check whether the label is selectable
|
||||
*
|
||||
* @memberof LabelTag
|
||||
*/
|
||||
set selectable(v: boolean) {
|
||||
this.attsw(v, "selectable");
|
||||
if(v)
|
||||
{
|
||||
$(this.refs.text)
|
||||
.css("user-select", "text")
|
||||
.css("cursor", "text");
|
||||
}
|
||||
else
|
||||
{
|
||||
$(this.refs.text)
|
||||
.css("user-select", "none")
|
||||
.css("cursor", "default");
|
||||
}
|
||||
}
|
||||
get swon(): boolean {
|
||||
return this.hasattr("selectable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Lqbel layout definition
|
||||
*
|
||||
|
@ -444,10 +444,10 @@ namespace OS {
|
||||
* drag and drop on the list
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: ListViewItemTag; to: ListViewItemTag }}
|
||||
* @type {{ from: ListViewItemTag[]; to: ListViewItemTag }}
|
||||
* @memberof ListViewTag
|
||||
*/
|
||||
private _dnd: { from: ListViewItemTag; to: ListViewItemTag };
|
||||
private _dnd: { from: ListViewItemTag[]; to: ListViewItemTag };
|
||||
|
||||
/**
|
||||
*Creates an instance of ListViewTag.
|
||||
@ -990,6 +990,16 @@ namespace OS {
|
||||
this.selectedItems.push(e.data);
|
||||
edata.items = this.selectedItems;
|
||||
} else {
|
||||
if(this.selectedItems.length > 0)
|
||||
{
|
||||
for(const item of this.selectedItems)
|
||||
{
|
||||
if(item != e.data)
|
||||
{
|
||||
item.selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.selectedItem === e.data) {
|
||||
return;
|
||||
}
|
||||
@ -1044,14 +1054,22 @@ namespace OS {
|
||||
to: undefined,
|
||||
};
|
||||
this._onmousedown = (e) => {
|
||||
if(this.multiselect || this.selectedItems == undefined || this.selectedItems.length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let el: any = $(e.target).closest(
|
||||
"li[dataref='afx-list-item']"
|
||||
);
|
||||
if (el.length === 0) {
|
||||
return;
|
||||
}
|
||||
el = el.parent()[0] as ListViewItemTag;
|
||||
this._dnd.from = el;
|
||||
el = el.parent()[0];
|
||||
if(!this.selectedItems.includes(el))
|
||||
{
|
||||
return;
|
||||
}
|
||||
this._dnd.from = this.selectedItems;
|
||||
this._dnd.to = undefined;
|
||||
$(window).on("mouseup", this._onmouseup);
|
||||
$(window).on("mousemove", this._onmousemove);
|
||||
@ -1068,7 +1086,7 @@ namespace OS {
|
||||
return;
|
||||
}
|
||||
el = el.parent()[0];
|
||||
if (el === this._dnd.from) {
|
||||
if (this._dnd.from.includes(el)) {
|
||||
return;
|
||||
}
|
||||
this._dnd.to = el;
|
||||
@ -1086,7 +1104,18 @@ namespace OS {
|
||||
if (!this._dnd.from) {
|
||||
return;
|
||||
}
|
||||
const data = this._dnd.from.data;
|
||||
const data = {
|
||||
text: '',
|
||||
items: this._dnd.from
|
||||
};
|
||||
if(this._dnd.from.length == 1)
|
||||
{
|
||||
data.text = this._dnd.from[0].data.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.text = __("{0} selected elements", this._dnd.from.length).__();
|
||||
}
|
||||
const $label = $("#systooltip");
|
||||
const top = e.clientY + 5;
|
||||
const left = e.clientX + 5;
|
||||
|
@ -586,10 +586,10 @@ namespace OS {
|
||||
* Private data object passing between dragndrop mouse event
|
||||
*
|
||||
* @private
|
||||
* @type {{ from: TreeViewTag; to: TreeViewTag }}
|
||||
* @type {{ from: TreeViewTag[]; to: TreeViewTag }}
|
||||
* @memberof TreeViewTag
|
||||
*/
|
||||
private _dnd: { from: TreeViewTag; to: TreeViewTag };
|
||||
private _dnd: { from: TreeViewTag[]; to: TreeViewTag };
|
||||
|
||||
/**
|
||||
* Reference to parent tree of the current tree.
|
||||
@ -638,7 +638,7 @@ namespace OS {
|
||||
* current tree. This function should return a promise on
|
||||
* a list of [[TreeViewDataType]]
|
||||
*
|
||||
* @memberof TreeViewItemPrototype
|
||||
* @memberof TreeViewTag
|
||||
*/
|
||||
fetch: (
|
||||
d: TreeViewItemPrototype
|
||||
@ -920,7 +920,7 @@ namespace OS {
|
||||
*/
|
||||
protected mount(): void {
|
||||
this._dnd = {
|
||||
from: undefined,
|
||||
from: [],
|
||||
to: undefined,
|
||||
};
|
||||
this._treemousedown = (e) => {
|
||||
@ -932,7 +932,7 @@ namespace OS {
|
||||
if (el === this) {
|
||||
return;
|
||||
}
|
||||
this._dnd.from = el;
|
||||
this._dnd.from = [el];
|
||||
this._dnd.to = undefined;
|
||||
$(window).on("mouseup", this._treemouseup);
|
||||
return $(window).on("mousemove", this._treemousemove);
|
||||
@ -951,8 +951,8 @@ namespace OS {
|
||||
el = el.parent;
|
||||
}
|
||||
if (
|
||||
el === this._dnd.from ||
|
||||
el === this._dnd.from.parent
|
||||
el === this._dnd.from[0] ||
|
||||
el === this._dnd.from[0].parent
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -962,7 +962,7 @@ namespace OS {
|
||||
data: this._dnd,
|
||||
});
|
||||
this._dnd = {
|
||||
from: undefined,
|
||||
from: [],
|
||||
to: undefined,
|
||||
};
|
||||
};
|
||||
@ -974,7 +974,7 @@ namespace OS {
|
||||
if (!this._dnd.from) {
|
||||
return;
|
||||
}
|
||||
const data = this._dnd.from.data;
|
||||
const data = this._dnd.from[0].data;
|
||||
const $label = $("#systooltip");
|
||||
const top = e.clientY + 5;
|
||||
const left = e.clientX + 5;
|
||||
|
@ -306,6 +306,7 @@ namespace OS {
|
||||
.removeClass("unactive");
|
||||
this._shown = true;
|
||||
$(this.refs.win_overlay).hide();
|
||||
$(this).trigger("focus");
|
||||
});
|
||||
|
||||
this.observable.on("blur", () => {
|
||||
@ -336,6 +337,7 @@ namespace OS {
|
||||
w: this.width,
|
||||
h: this.height,
|
||||
});
|
||||
$(this).attr("tabindex", 0).css("outline", "none");
|
||||
return this.observable.trigger("rendered", {
|
||||
id: this.aid,
|
||||
});
|
||||
|
@ -233,7 +233,7 @@ namespace OS {
|
||||
* @type {T}
|
||||
* @memberof DnDEventDataType
|
||||
*/
|
||||
from: T;
|
||||
from: T[];
|
||||
|
||||
/**
|
||||
* Reference to the target DOM element
|
||||
|
@ -21,7 +21,7 @@ namespace OS {
|
||||
|
||||
interface FilesClipboardType {
|
||||
cut: boolean;
|
||||
file: API.VFS.BaseFileHandle;
|
||||
files: API.VFS.BaseFileHandle[];
|
||||
}
|
||||
interface FilesViewType {
|
||||
icon: boolean;
|
||||
@ -228,43 +228,54 @@ namespace OS {
|
||||
};
|
||||
|
||||
this.vfs_event_flag = true;
|
||||
this.view.ondragndrop = (e) => {
|
||||
this.view.ondragndrop = async (e) => {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
const src = e.data.from.data;
|
||||
const src = e.data.from;
|
||||
const des = e.data.to.data;
|
||||
if (des.type === "file") {
|
||||
return;
|
||||
}
|
||||
const file = src.path.asFileHandle();
|
||||
// ask to confirm
|
||||
const r = await this.ask({
|
||||
title: __("Move files"),
|
||||
text: __("Move selected file to {0}?", des.text)
|
||||
});
|
||||
if(!r)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// disable the vfs event on
|
||||
// we update it manually
|
||||
this.vfs_event_flag = false;
|
||||
return file
|
||||
.move(`${des.path}/${file.basename}`)
|
||||
.then(() => {
|
||||
if (this.view.view === "icon") {
|
||||
this.view.path = this.view.path;
|
||||
} else {
|
||||
this.view.update(file.parent().path);
|
||||
this.view.update(des.path);
|
||||
}
|
||||
//reenable the vfs event
|
||||
return (this.vfs_event_flag = true);
|
||||
})
|
||||
.catch((e: Error) => {
|
||||
// reenable the vfs event
|
||||
this.vfs_event_flag = true;
|
||||
return this.error(
|
||||
const promises = [];
|
||||
for(const item of src)
|
||||
{
|
||||
let file = item.data.path.asFileHandle();
|
||||
promises.push(
|
||||
file.move(`${des.path}/${file.basename}`));
|
||||
}
|
||||
try{
|
||||
await Promise.all(promises);
|
||||
if (this.view.view === "tree") {
|
||||
this.view.update(src[0].data.path.asFileHandle().parent().path);
|
||||
this.view.update(des.path);
|
||||
} else {
|
||||
this.view.path = this.view.path;
|
||||
}
|
||||
}
|
||||
catch(error)
|
||||
{
|
||||
this.error(
|
||||
__(
|
||||
"Unable to move: {0} -> {1}",
|
||||
src.path,
|
||||
"Unable to move files to: {0}",
|
||||
des.path
|
||||
),
|
||||
e
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
this.vfs_event_flag = true;
|
||||
};
|
||||
|
||||
// application setting
|
||||
@ -355,6 +366,23 @@ namespace OS {
|
||||
this.view.view = "list";
|
||||
this.viewType.list = true;
|
||||
};
|
||||
// enable or disable multi-select by CTRL key
|
||||
$(this.scheme).on("keydown", (evt)=>{
|
||||
if(evt.ctrlKey && evt.which == 17)
|
||||
{
|
||||
this.view.multiselect = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.view.multiselect = false;
|
||||
}
|
||||
});
|
||||
$(this.scheme).on("keyup", (evt)=>{
|
||||
if(!evt.ctrlKey)
|
||||
{
|
||||
this.view.multiselect = false;
|
||||
}
|
||||
});
|
||||
this.view.path = this.currdir.path;
|
||||
}
|
||||
|
||||
@ -585,20 +613,22 @@ namespace OS {
|
||||
title: "__(Delete)",
|
||||
iconclass: "fa fa-question-circle",
|
||||
text: __(
|
||||
"Do you really want to delete: {0}?",
|
||||
file.filename
|
||||
"Do you really want to delete selected files?"
|
||||
),
|
||||
}).then(async (d) => {
|
||||
if (!d) {
|
||||
return;
|
||||
}
|
||||
const promises = [];
|
||||
for(const f of this.view.selectedFiles)
|
||||
{
|
||||
promises.push(f.path.asFileHandle().remove());
|
||||
}
|
||||
try {
|
||||
return file.path
|
||||
.asFileHandle()
|
||||
.remove();
|
||||
await Promise.all(promises);
|
||||
}
|
||||
catch (e) {
|
||||
return this.error(__("Fail to delete: {0}", file.path), e);
|
||||
return this.error(__("Fail to delete selected files"), e);
|
||||
}
|
||||
});
|
||||
break;
|
||||
@ -609,9 +639,9 @@ namespace OS {
|
||||
}
|
||||
this.clipboard = {
|
||||
cut: true,
|
||||
file: file.path.asFileHandle(),
|
||||
files: this.view.selectedFiles.map(x => x.path.asFileHandle()),
|
||||
};
|
||||
return this.notify(__("File {0} cut", file.filename));
|
||||
return this.notify(__("{0} files cut", this.clipboard.files.length));
|
||||
|
||||
case `${this.name}-copy`:
|
||||
if (!file) {
|
||||
@ -619,10 +649,10 @@ namespace OS {
|
||||
}
|
||||
this.clipboard = {
|
||||
cut: false,
|
||||
file: file.path.asFileHandle(),
|
||||
files: this.view.selectedFiles.map(x => x.path.asFileHandle()),
|
||||
};
|
||||
return this.notify(
|
||||
__("File {0} copied", file.filename)
|
||||
__("{0} files copied", this.clipboard.files.length)
|
||||
);
|
||||
|
||||
case `${this.name}-paste`:
|
||||
@ -630,29 +660,33 @@ namespace OS {
|
||||
return;
|
||||
}
|
||||
if (this.clipboard.cut) {
|
||||
this.clipboard.file
|
||||
.move(
|
||||
`${this.currdir.path}/${this.clipboard.file.basename}`
|
||||
)
|
||||
const promises = [];
|
||||
for(const file of this.clipboard.files)
|
||||
{
|
||||
promises.push(file.move(
|
||||
`${this.currdir.path}/${file.basename}`
|
||||
));
|
||||
}
|
||||
Promise.all(promises)
|
||||
.then((r) => {
|
||||
return (this.clipboard = undefined);
|
||||
})
|
||||
.catch((e) => {
|
||||
return this.error(
|
||||
__(
|
||||
"Fail to paste: {0}",
|
||||
this.clipboard.file.path
|
||||
"Fail to paste to: {0}",
|
||||
this.currdir.path
|
||||
),
|
||||
e
|
||||
);
|
||||
});
|
||||
} else {
|
||||
API.VFS.copy([this.clipboard.file.path],this.currdir.path)
|
||||
API.VFS.copy(this.clipboard.files.map(x => x.path),this.currdir.path)
|
||||
.then(() => {
|
||||
return (this.clipboard = undefined);
|
||||
})
|
||||
.catch((e) => {
|
||||
return this.error(__("Fail to paste: {0}", this.clipboard.file.path), e);
|
||||
return this.error(__("Fail to paste to: {0}", this.currdir.path), e);
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
@ -6,7 +6,7 @@
|
||||
"author": "Xuan Sang LE",
|
||||
"email": "xsang.le@gmail.com"
|
||||
},
|
||||
"version":"0.1.4-b",
|
||||
"version":"0.1.5-b",
|
||||
"category":"System",
|
||||
"iconclass":"fa fa-hdd-o",
|
||||
"mimes":["dir"],
|
||||
|
@ -5,5 +5,4 @@ afx-label i.label-text{
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
margin-left: 3px;
|
||||
user-select:text;
|
||||
}
|
Loading…
Reference in New Issue
Block a user