Skip to content
Snippets Groups Projects
Commit 749d0821 authored by Eric Oulashin's avatar Eric Oulashin Committed by Rob Swindell
Browse files

DDFileLister: Theme configuration files can now just have the attribute...

DDFileLister: Theme configuration files can now just have the attribute characters without the control code. Refactored the code that reads the configuration.
parent 07e8506a
No related branches found
No related tags found
2 merge requests!463MRC mods by Codefenix (2024-10-20),!293DDFileLister: Theme configuration files can now just have the attribute characters without the control code. Refactored the code that reads the configuration.
......@@ -66,6 +66,12 @@
* Also, ddfilelister now checks whether the user has permission to
* download before allowing adding files to their batch download queue
* (and downloading a single file as well).
* 2023-05-14 Eric Oulashin Version 2.11
* Refactored the function that reads the configuration file. Also,
* the theme configuration file can now just contain the attribute
* characters, without the control character.
*
* Future work: Actual support for a traditional/non-lightbar user interface
*/
"use strict";
......@@ -128,8 +134,8 @@ if (system.version_num < 31900)
}
// Lister version information
var LISTER_VERSION = "2.10";
var LISTER_DATE = "2023-02-27";
var LISTER_VERSION = "2.11";
var LISTER_DATE = "2023-05-14";
///////////////////////////////////////////////////////////////////////////////
......@@ -243,6 +249,11 @@ var gErrorMsgBoxHeight = 3;
// Whether or not to pause after viewing a file
var gPauseAfterViewingFile = true;
// Whether or not to use the lightbar interface (this could be specified as false
// in the configuration file, to use the traditional interface even if the user's
// terminal supports ANSI)
var gUseLightbarInterface = true;
///////////////////////////////////////////////////////////////////////////////
// Script execution code
......@@ -265,7 +276,8 @@ parseArgs(argv);
// If the user's terminal doesn't support ANSI, then just call the standard Synchronet
// file list function and exit now
if (!console.term_supports(USER_ANSI))
// TODO: Add support in this script for a traditional/non-lightbar user interface
if (!console.term_supports(USER_ANSI) || !gUseLightbarInterface)
{
var exitCode = 0;
if (gScriptMode == MODE_SEARCH_FILENAME || gScriptMode == MODE_SEARCH_DESCRIPTION || gScriptMode == MODE_NEW_FILE_SEARCH)
......@@ -2245,6 +2257,8 @@ function createFileListMenu(pQuitKeys)
menuWidth = gListIdxes.fileSizeEnd + 1;
var menuHeight = console.screen_rows - (startRow-1) - 1;
var fileListMenu = new DDLightbarMenu(1, startRow, menuWidth, menuHeight);
// TODO: Add support for a traditional/non-lightbar user interface
//fileListMenu.allowANSI = gUseLightbarInterface;
fileListMenu.scrollbarEnabled = true;
fileListMenu.borderEnabled = false;
fileListMenu.multiSelect = true;
......@@ -2986,8 +3000,6 @@ function confirmFileActionWithUser(pFilenames, pActionName, pDefaultYes)
// Reads the configuration file and sets the settings accordingly
function readConfigFile()
{
this.cfgFileSuccessfullyRead = false;
var themeFilename = ""; // In case a theme filename is specified
// Determine the script's startup directory.
......@@ -3009,59 +3021,12 @@ function readConfigFile()
var cfgFile = new File(cfgFilenameFullPath);
if (cfgFile.open("r"))
{
this.cfgFileSuccessfullyRead = true;
var settingsObj = cfgFile.iniGetObject();
cfgFile.close();
var fileLine = null; // A line read from the file
var equalsPos = 0; // Position of a = in the line
var commentPos = 0; // Position of the start of a comment
var setting = null; // A setting name (string)
var settingUpper = null; // Upper-case setting name
var value = null; // To store a value for a setting (string)
while (!cfgFile.eof)
if (typeof(settingsObj["sortOrder"]) === "string")
{
// Read the next line from the config file.
fileLine = cfgFile.readln(2048);
// fileLine should be a string, but I've seen some cases
// where it isn't, so check its type.
if (typeof(fileLine) != "string")
continue;
// If the line starts with with a semicolon (the comment
// character) or is blank, then skip it.
if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0))
continue;
// If the line has a semicolon anywhere in it, then remove
// everything from the semicolon onward.
commentPos = fileLine.indexOf(";");
if (commentPos > -1)
fileLine = fileLine.substr(0, commentPos);
// Look for an equals sign, and if found, separate the line
// into the setting name (before the =) and the value (after the
// equals sign).
equalsPos = fileLine.indexOf("=");
if (equalsPos > 0)
{
// Read the setting & value, and trim leading & trailing spaces.
setting = trimSpaces(fileLine.substr(0, equalsPos), true, false, true);
settingUpper = setting.toUpperCase();
value = trimSpaces(fileLine.substr(equalsPos+1), true, false, true);
var valueUpper = value.toUpperCase();
// Set the appropriate valueUpper in the settings object.
if (settingUpper == "SORTORDER")
{
// FileBase.SORT properties
// Name Type Description
// NATURAL number Natural sort order (same as DATE_A)
// NAME_AI number Filename ascending, case insensitive sort order
// NAME_DI number Filename descending, case insensitive sort order
// NAME_AS number Filename ascending, case sensitive sort order
// NAME_DS number Filename descending, case sensitive sort order
// DATE_A number Import date/time ascending sort order
// DATE_D number Import date/time descending sort order
var valueUpper = settingsObj.sortOrder.toUpperCase();
if (valueUpper == "NATURAL")
gFileSortOrder = FileBase.SORT.NATURAL;
else if (valueUpper == "NAME_AI")
......@@ -3083,24 +3048,22 @@ function readConfigFile()
else // Default
gFileSortOrder = FileBase.SORT.NATURAL;
}
else if (settingUpper == "PAUSEAFTERVIEWINGFILE")
gPauseAfterViewingFile = (value.toUpperCase() == "TRUE");
else if (settingUpper == "THEMEFILENAME")
if (typeof(settingsObj["pauseAfterViewingFile"]) === "boolean")
gPauseAfterViewingFile = settingsObj.pauseAfterViewingFile;
if (typeof(settingsObj["useLightbarInterface"]) === "boolean")
gUseLightbarInterface = settingsObj.useLightbarInterface;
if (typeof(settingsObj["themeFilename"]) === "string")
{
// First look for the theme config file in the sbbs/mods
// directory, then sbbs/ctrl, then the same directory as
// this script.
themeFilename = system.mods_dir + value;
themeFilename = system.mods_dir + settingsObj.themeFilename;
if (!file_exists(themeFilename))
themeFilename = system.ctrl_dir + value;
themeFilename = system.ctrl_dir + settingsObj.themeFilename;
if (!file_exists(themeFilename))
themeFilename = startupPath + value;
themeFilename = startupPath + settingsObj.themeFilename;
}
}
}
cfgFile.close();
}
else
{
// Was unable to read the configuration file. Output a warning to the user
......@@ -3117,62 +3080,35 @@ function readConfigFile()
// from it.
if (themeFilename.length > 0)
{
var onlySyncAttrsRegexWholeWord = new RegExp("^[\x01krgybmcw01234567hinq,;\.dtlasz]+$", 'i');
var themeFile = new File(themeFilename);
if (themeFile.open("r"))
{
var fileLine = null; // A line read from the file
var equalsPos = 0; // Position of a = in the line
var commentPos = 0; // Position of the start of a comment
var setting = null; // A setting name (string)
var value = null; // To store a value for a setting (string)
while (!themeFile.eof)
{
// Read the next line from the config file.
fileLine = themeFile.readln(2048);
// fileLine should be a string, but I've seen some cases
// where it isn't, so check its type.
if (typeof(fileLine) != "string")
continue;
// If the line starts with with a semicolon (the comment
// character) or is blank, then skip it.
if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0))
continue;
// If the line has a semicolon anywhere in it, then remove
// everything from the semicolon onward.
commentPos = fileLine.indexOf(";");
if (commentPos > -1)
fileLine = fileLine.substr(0, commentPos);
var themeSettingsObj = themeFile.iniGetObject();
themeFile.close();
// Look for an equals sign, and if found, separate the line
// into the setting name (before the =) and the value (after the
// equals sign).
equalsPos = fileLine.indexOf("=");
if (equalsPos > 0)
// Set any color values specified
for (var prop in gColors)
{
// Read the setting (without leading/trailing spaces) & value
setting = trimSpaces(fileLine.substr(0, equalsPos), true, false, true);
value = fileLine.substr(equalsPos+1);
if (gColors.hasOwnProperty(setting))
if (typeof(themeSettingsObj[prop]) === "string")
{
// Trim leading & trailing spaces from the value when
// setting a color. Also, replace any instances of "\x01" or "\1"
// with the Synchronet attribute control character.
gColors[setting] = trimSpaces(value, true, false, true).replace(/\\[xX]01/g, "\x01").replace(/\\1/g, "\x01");
var value = trimSpaces(themeSettingsObj[prop].toString(), true, false, true).replace(/\\[xX]01/g, "\x01").replace(/\\1/g, "\x01");
// If the value doesn't have any control characters, then add the control character
// before attribute characters
if (!/\x01/.test(value))
value = attrCodeStr(value);
if (onlySyncAttrsRegexWholeWord.test(value))
gColors[prop] = value;
}
}
}
themeFile.close();
}
else
{
// Was unable to read the theme file. Output a warning to the user
// that defaults will be used and to notify the sysop.
this.cfgFileSuccessfullyRead = false;
console.print("\x01n");
console.crlf();
console.print("\x01w\x01hUnable to open the theme file: \x01y" + themeFilename);
......@@ -4208,3 +4144,27 @@ function userCanDownloadFromFileArea_ShowErrorIfNot(pDirCode)
}
return userCanDownload;
}
// Given a string of attribute characters, this function inserts the control code
// in front of each attribute character and returns the new string.
//
// Parameters:
// pAttrCodeCharStr: A string of attribute characters (i.e., "YH" for yellow high)
//
// Return value: A string with the control character inserted in front of the attribute characters
function attrCodeStr(pAttrCodeCharStr)
{
if (typeof(pAttrCodeCharStr) !== "string")
return "";
var str = "";
// See this page for Synchronet color attribute codes:
// http://wiki.synchro.net/custom:ctrl-a_codes
for (var i = 0; i < pAttrCodeCharStr.length; ++i)
{
var currentChar = pAttrCodeCharStr.charAt(i);
if (/[krgybmcwKRGYBMCWHhIiEeFfNn01234567]/.test(currentChar))
str += "\x01" + currentChar;
}
return str;
}
\ No newline at end of file
; Default color theme
; Filename in the file list
filename=\1n\1b\1h
filename=nbh
; File size in the file list
fileSize=\1n\1m\1h
fileSize=nmh
; Description in the file list
desc=\1n\1w
desc=nw
; Background color for the highlighted (selected) file menu itme
bkgHighlight=\1n4
bkgHighlight=n4
; Highlight filename color for the file list
filenameHighlight=\1c\1h
filenameHighlight=ch
; Highlight file size color for the file list
fileSizeHighlight=\1c\1h
fileSizeHighlight=ch
; Highlight description color for the file list
descHighlight=\1c\1h
descHighlight=ch
; File timestamp color for showing an extended file description
fileTimestamp=\1g\1h
fileTimestamp=gh
; For the extended file information box border
fileInfoWindowBorder=\1r
fileInfoWindowBorder=r
; For the title of the extended file information box
fileInfoWindowTitle=\1g
fileInfoWindowTitle=g
; Error box border
errorBoxBorder=\1g\1h
errorBoxBorder=gh
; Error message color
errorMessage=\1y\1h
errorMessage=yh
; Success message color
successMessage=\1c
successMessage=c
; Batch download confirm/info window border color
batchDLInfoWindowBorder=\1r
batchDLInfoWindowBorder=r
; Batch download info window title color
batchDLInfoWindowTitle=\1g
batchDLInfoWindowTitle=g
; Multi-file action confirm window border color
confirmFileActionWindowBorder=\1r
confirmFileActionWindowBorder=r
; Multi-file action confirm window title color
confirmFileActionWindowWindowTitle=\1g
confirmFileActionWindowWindowTitle=g
; Colors related to moving a file
; The color of the file area menu border (for moving a file)
fileAreaMenuBorder=\1b
fileAreaMenuBorder=b
; The file area entry background color for 'normal' colors (for moving a file)
fileNormalBkg=\1n4
fileNormalBkg=n4
; The file library/directory number for 'normal' colors (for moving a file)
fileAreaNum=\1w
fileAreaNum=w
; The file library/directory description for 'normal' colors (for moving a file)
fileAreaDesc=\1w
fileAreaDesc=w
; The number of directories/files for 'normal' colors (for moving a file)
fileAreaNumItems=\1w
fileAreaNumItems=w
; The file area entry background color for 'highlight' colors (for moving a file)
fileAreaMenuHighlightBkg=\1n7
fileAreaMenuHighlightBkg=n7
; The file library/directory number for 'highlight' colors (for moving a file)
fileAreaNumHighlight=\1b
fileAreaNumHighlight=b
; The file library/directory description for 'highlight' colors (for moving a file)
fileAreaDescHighlight=\1b
fileAreaDescHighlight=b
; The number of directories/files for 'highlight' colors (for moving a file)
fileAreaNumItemsHighlight=\1b
\ No newline at end of file
fileAreaNumItemsHighlight=b
\ No newline at end of file
Digital Distortion File Lister
Version 2.10
Release date: 2023-02-27
Version 2.11
Release date: 2023-05-14
by
......
......@@ -5,6 +5,10 @@ Revision History (change log)
=============================
Version Date Description
------- ---- -----------
2.11 2023-05-14 The theme configuration file can now just contain the
attribute characters, without the control character.
Code: Refactored the function that reads the configuration
file.
2.10 2023-02-27 Now allows downloading a single selected file with the D key
2.09 2023-02-25 Now supports being used as a loadable module for Scan Dirs
and List Files (applicable for Synchronet 3.20+)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment