Files
system-taskbar/ding/app/symLinkIcon.js

179 lines
6.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Adw-DING Copyright (C) 2022, 2025 Sundeep Mediratta (smedius@gmail.com)
* Based on code original (C) Carlos Soriano and (c) Sergio Costas
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import {Gio} from '../dependencies/gi.js';
import {_} from '../dependencies/gettext.js';
export {SymLinkIcon};
const SymLinkIcon = class {
constructor(
Basetype,
ddesktopManager,
ffile,
ffileInfo,
ffileTypeEnum,
ggioMount
) {
const SymLinkSuperClass = class extends Basetype {
constructor(
desktopManager,
file,
fileInfo,
fileTypeEnum,
gioMount
) {
super(desktopManager, file, fileInfo, fileTypeEnum, gioMount);
this._isSymlink = fileInfo.get_attribute_boolean(
Gio.FILE_ATTRIBUTE_STANDARD_IS_SYMLINK
);
/*
* This is a glib trick to detect broken symlinks. If a file is a
* symlink, the filetype points to the final file, unless it is broken;
* thus if the file type is SYMBOLIC_LINK, it must be a broken link.
* https://developer.gnome.org/gio/stable/GFile.html#g-file-query-info
*/
this._isBrokenSymlink =
this._isSymlink &&
this._fileType === Gio.FileType.SYMBOLIC_LINK;
if (this._isSymlink && !this._symlinkFileMonitor)
this._monitorSymlink();
}
_updateMetadataFromFileInfo(fileInfo) {
this._isSymlink = fileInfo.get_attribute_boolean(
Gio.FILE_ATTRIBUTE_STANDARD_IS_SYMLINK
);
/*
* This is a glib trick to detect broken symlinks. If a file is a
* symlink, the filetype points to the final file, unless it is broken;
* thus if the file type is SYMBOLIC_LINK, it must be a broken link.
* https://developer.gnome.org/gio/stable/GFile.html#g-file-query-info
*/
this._isBrokenSymlink =
this._isSymlink &&
this._fileType === Gio.FileType.SYMBOLIC_LINK;
super._updateMetadataFromFileInfo(fileInfo);
}
_destroy() {
super._destroy();
if (this._symlinkFileMonitorId) {
this._symlinkFileMonitor.disconnect(this._symlinkFileMonitorId);
this._symlinkFileMonitor.cancel();
this._symlinkFileMonitorId = 0;
}
}
async _doOpenContext(context, fileList) {
if (!fileList)
fileList = [];
if (this._isBrokenSymlink) {
try {
console.log(
`Error: Cant open ${this.file.get_uri()}` +
' because it is a broken symlink.'
);
const title = _('Broken Link');
const error =
_('Can not open this File because it is a Broken Symlink');
this._showerrorpopup(title, error);
} catch (e) {}
return;
}
await super._doOpenContext(context, fileList);
}
_monitorSymlink() {
let symlinkTarget = this._fileInfo.get_symlink_target();
let symlinkTargetGioFile = Gio.File.new_for_path(symlinkTarget);
this._symlinkFileMonitor = symlinkTargetGioFile.monitor(
Gio.FileMonitorFlags.WATCH_MOVES,
null
);
this._symlinkFileMonitor.set_rate_limit(1000);
this._symlinkFileMonitorId = this._symlinkFileMonitor.connect(
'changed',
this._updateSymlinkIcon.bind(this)
);
}
async _updateSymlinkIcon() {
await this._reloadIcon().catch(e => {
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
console.error(
e,
`Exception while updating ${
this._getVisibleName()
? this._getVisibleName()
: 'symlink icon'
}: ${e.message}`);
}
});
}
_addEmblemsToIconIfNeeded(iconPaintable, position = 0) {
let emblem = null;
let newIconPaintable = iconPaintable;
if (this._isSymlink && this.Prefs.showLinkEmblem) {
emblem = Gio.ThemedIcon.new('icon-emblem-symbolic-link');
newIconPaintable =
this._addEmblem(newIconPaintable, emblem, position);
position += 1;
}
if (this._isBrokenSymlink) {
emblem = Gio.ThemedIcon.new('icon-emblem-unreadable');
newIconPaintable =
this._addEmblem(newIconPaintable, emblem, position);
position += 1;
}
return super._addEmblemsToIconIfNeeded(newIconPaintable, position);
}
};
return new SymLinkSuperClass(
ddesktopManager,
ffile,
ffileInfo,
ffileTypeEnum,
ggioMount
);
}
};