DisplayAgentThreadsV3-Customize-Date-Time
From 40tude Dialog Wiki
Contents |
Display Threads in Agent-/Xnews-Style (V3) & Customize Date/Time
This is an improved version of Display Threads in Agent-/Xnews-Style (V2) & Shortening the date-column.
Changes
- 'Subject' appears just once (at the first article in the current thread),
'Name' will be displayed in an extra column, but also can be suppressed - Below first subject in thread, there will be the followups' author names only, threaded, of course (the name column will remain blank)
- Subject changes will be displayed on correct subject changes only
(to suppress invalid subject changes due to char conversions etc. - Hint: this feature can be disabled) - 'Time' and 'Date' can be formatted as you like (following the standard date format syntax)
- Today's and yesterday's time and date can be configured seperately
(i. e. the date can be replaced by e. g. 'Today' resp. 'Yesterday' or any string you like, it can even be suppressed completely) - The date of articles up to a configurable number 'n' of days back can be replaced by e. g. 'n days ago';
the text beyond and behind the 'n' is completely configurable, thus you can even have 'this article has been posted n days ago';
optionally you can display these 'n' days back with the appropriate weekday's name, too (even localized, of course)
Example
That's just one possibility (of several) of what you can get:
Installation & Setup
Header layout changes
Use Dialog's Columns Editor (Settings -> Layout -> Edit header list columns, or just right click a header title) to change the header list column's definitions as follows:
- Change Column 'Subject' to %subjectnamechange%
- Set 'Name' (resp. 'From') column to %threadindent%%fromname%
You may set attributes for 'Subject' and 'Name' like this (YMMV):
- Alignment: Left
- Colorize: Unread
- Bold: If is first in thread or subject changed
- Underline: Never
- Sort by: Subject, Date (for Subject) resp. From, Date (for Name)
- Subject: Additionally check "This column gets the remaining width"
You may set attributes for 'Date' like this (YMMV):
- Content: %datelocal%
- Alignment: Right
- Colorize: Never
- Bold: Never
- Underline: Never
- Sort by: Date
Installation
Paste the script in Event scripts -> OnArticleListPaint, save, configure (as described below), compile and run.
Setup
Have a close look at the 'const' section in the source code below. The settings and their effects are described there. Please check the configuration carefully as the script may produce unpredictable results if not properly configured - although it's very unlikely that the script will damage your installation or data. ;o)
Warning
Please read the Painting script warning page before trying out this script.
The Script
program OnArticleListPaint;
// Version : 1.5
// Date : 11.07.2006
// Dialog : 2.0.15.1 beta 38
//
// 1.2 Amended for 2.0.13.1 beta 36
// 1.3 += doesn't fail if '(' in subject (by Dirk Straka)
// 1.4 += format date string (by Dirk Straka)
// 1.4.1 += Subject_was_only() (by Dirk Straka)
// 1.4.2 += TODAYSTR <none> (by Dirk Straka)
// 1.4.3 -= bug (failed with '(<anything>)' in author's name)
// += correct subject changes without 'was: ' will be shown, too
// (by Dirk Straka)
// 1.4.4 += format date string with 'Yesterday'
// (by Maik Prinz)
// 1.5 += format date string with 'n days ago' or weekday's name
// (by Dirk Straka)
//
// Remarks: - Set subject column to "%subjectnamechange%"
// and name column to "%threadindent%%fromname%"
// It's recommended to set date column's alignment to 'right'
//
// - Subject_was_only() does not need any From column.
//
// --> adjust column indexes and date format below ... <--
//
const
//
// - configure column number of columns here.
// - if you don't have a <from> column,
// just set it's index to zero (0).
//
n_subject_column = 3; // <-- set subject column here!
n_from_column = 4; // <-- set from column here!
n_date_column = 5; // <-- set date column here!
//
// If you like to use dialog's default thread view (i. e. show
// '<subject> (<from>)' on subject changes), but want to see subjects
// of "correct" subject changes only (i. e. containing "was: "),
// then set this value to TRUE; normal FUp's display <from> only.
// BTW: Subjects containing "Re: " _and_ "was: " will be suppressed,
// too (as they seem to be incorrect replies):
//
// If set to FALSE, only <from> will be shown.
//
SHOW_SUBJECT_ON_CHANGE = TRUE; // set to TRUE or FALSE
//
// In DATEFMT you can define how to display the date.
// Hint: If you want to add normal text, use double quotes like this:
// DATEFMT = '"Date:" dd.mm.yy ("Time:" hh:nn)';
// If you want to see a single quote ('), use two, like this:
// DATEFMT = '"Date:" dd.mm.yy ("Time:" hh:nn "o''clock")';
//
DATEFMT = 'dd.mm.yy (hh:nn)'; // <-- set preferred date format
//
// TODAYSTR and TIMEFMT:
// If TODAYSTR is filled with a string,
// today's date will be replaced by this string;
// today's time will be formatted as spec. in TIMEFMT
// If TODAYSTR is set to '<none>',
// we will display no string for TODAY at all;
// today's time will be formatted as spec. in TIMEFMT
// If TODAYSTR is empty (''),
// today's date & time displays as defined in DATEFMT
// If YESTERDAYSTR is set to any non-empty string,
// handling will be the same acc. to TODAYSTR
//
TIMEFMT = '(hh:nn)'; // <-- set time format for today's msgs
TODAYSTR = 'Today '; // <-- will result in ' Today (14:23)'
//TODAYSTR = '<none>'; // <-- will result in ' (14:23)'
YESTERDAYSTR = 'Yesterday '; // <-- will result in 'Yesterday (14:23)'
//
// ORDINALDAYS
// If ORDINALDAYS is set to a value greater than 0,
// this many days back will be shown as e. g. 'n days ago'
// or with it's weekday name instead of the article's
// absolute date.
// Hint: ORDINALDAYS=1 will be overruled by YESTERDAYSTR!
//
ORDINALDAYS = 3; // <-- how many days back
// USE_ORDINALS (doesn't matter if ORDINALDAYS is set to 0)
// If USE_ORDINALS is set to ...
// TRUE: ORDINALPREFIX and -SUFFIX will be used (e. g. 'n days ago'):
// FALSE: WEEKDAY_n will be used (e. g. 'Wed' or 'Wednesday')
//
// ORDDAYPREFIX can be set to any text
// and will be shown before the count of days
// ORDDAYSUFFIX can be set to any text
// and will be shown beyond the count of days.
// Thus you can even display
// 'sent 4 days ago',
// by setting ORDDAYPREFIX to 'sent '
// and ORDDAYSUFFIX to ' days ago'
//
USE_ORDINALS = TRUE; // <-- results in ordinals e. g. 'n days ago'
//USE_ORDINALS = FALSE; // <-- results in weekday's name e. g. 'Wednesday'
//
// Settings for USE_ORDINALS = TRUE: Prefix and suffix
//
ORDDAYPREFIX = ''; // <-- text before daycount 'n' in 'n days ago'
ORDDAYSUFFIX = ' days ago '; // <-- text beyond daycount 'n' in 'n days ago'
//
// Settings for USE_ORDINALS = FALSE: Weekday's names
// You can use your own translation, too, of course.
// The number of blanks following the names depend on your font.
//
WEEKDAY_1 = 'Monday ';
WEEKDAY_2 = 'Tuesday ';
WEEKDAY_3 = 'Wednesd. ';
WEEKDAY_4 = 'Thursday ';
WEEKDAY_5 = 'Friday ';
WEEKDAY_6 = 'Saturday ';
WEEKDAY_7 = 'Sunday ';
// ------------------------------------------------------------- //
// --- No user maintainable parts below this line ------------ //
// ------------------------------------------------------------- //
//
// Is the line indented?
// Indented lines start with a space
//
function IsIndented( PaintString : WideString ) : Boolean;
var
c : WideString;
begin
c := Copy( PaintString, 1, 1 )
result := (c = ' ');
end;
//
// Is this a correctly changed subject (i. e. contains "(was: "
//
function IsSubjectChange( PaintString : WideString ) : Boolean;
begin
result := TRUE;
if not SHOW_SUBJECT_ON_CHANGE then begin
result := FALSE;
end
else begin
if IsIndented( PaintString ) then begin
if ( (Pos(' (was: ', PaintString) = 0) // ... there's no regular subject change ...
and (Pos(' (war: ', PaintString) = 0) // ... possibly in german ...
and (Pos(', was: ', PaintString) = 0) // ... or with comma ...
and (Pos(', war: ', PaintString) = 0)) // ... or with german comma. ;o)
then begin // no (correct) subject change found
result := FALSE; // thus suppress subject
end;
if result and (Pos('Re: ', Trim(PaintString)) = 1) then begin
result := FALSE; // suppress incorrect Re's.
end;
if not (Pos('Re: ', Trim(PaintString)) = 1) then begin // added 04/11/11
result := TRUE; // No "^Re: " - seems to be new (or a name), thus show it.
end;
end;
end;
end;
//
// - Prerequisite: set Subject column to '%subjectnamechange%'
// - Check if there is a subject change, i. e. if there's a "(was: "
// in the subject (and no "^Re: "),
// - If so, display "<subject> (<from>)", otherwise just "<from>".
// - Strip (<from>) from "<subject> (<from>) if there's an extra
// from column (n_from_column > 0)
//
// - Will _NOT_ fail if subject has ' (', now. ;o)
//
function Subject( PaintString : WideString ) : WideString;
var
bpos : Integer; // pos of opening bracket
pbpos : Integer; // pos of previous opening bracket
flen : Integer; // length of <from> field
ilvl : Integer; // identation level (i. e. number of leading blanks)
i : Integer; // counter
s : WideString; // copy of 2 PaintString chars
begin
bpos := 0;
pbpos := 0;
result := Copy( PaintString, 1, Length(PaintString) );
for i:=1 to Length( PaintString ) - 1 do begin // get start of <from> field
s := Copy( PaintString, i, 2 );
if s = ' (' then begin
pbpos := bpos; // remember last bracket
bpos := i; // no break, to get the last '('
end;
if s = ' ' then ilvl := ilvl + 1; // indentation levels
end;
if s = '))' then bpos := pbpos; // Author with bracket in name
flen := Length( PaintString ) - bpos-2; // length of <from>
if IsIndented( PaintString ) then begin // FollowUp -> strip subject if ...
if IsSubjectChange( PaintString) then begin // ... there's no subject change
result := Copy( PaintString, 1, Length(PaintString) ); // show complete subject
end
else begin // print <from> only
result := '';
for i:=0 to ilvl do result := result + ' ';
if bpos > 0
then result := result + Copy( PaintString, bpos+2, flen )
else result := Copy( PaintString, 1, Length(PaintString) );
end;
end;
if (n_from_column > 0) and (bpos > 0) // have to strip from
and IsSubjectChange( PaintString )
and not IsIndented( PaintString )
then begin
result := Copy( PaintString, 1, bpos-1 )
end;
end;
//
// From column = %threadindent%%fromname%
// Blank the column if it has a threadindent char at start
//
function From( PaintString : WideString ) : WideString;
begin
if IsIndented( PaintString )
then result := ''
else result := PaintString;
end;
//
// Format date column following const DATEFMT (resp. TODAYSTR + TIMEFMT)
//
function Date( const PaintString : WideString ) : WideString;
var
daysago : Integer;
daystr : String;
y : Word;
m : Word;
d : Word;
dow : Word;
begin
result := FormatDateTime( DATEFMT, StrToDateTime(PaintString) ); // default
daysago := Trunc(Now()) - Trunc(StrToDateTime(PaintString));
case daysago of
0: // Today
daystr := TODAYSTR;
1: // Yesterday
daystr := YESTERDAYSTR;
else // 2 or more days ago
if daysago <= ORDINALDAYS then begin
if USE_ORDINALS = TRUE then begin
daystr := ORDDAYPREFIX + IntToStr(daysago) + ORDDAYSUFFIX;
end
else begin
DecodeDateFully( StrToDateTime(PaintString), y, m, d, dow );
case dow of
2: daystr := WEEKDAY_1;
3: daystr := WEEKDAY_2;
4: daystr := WEEKDAY_3;
5: daystr := WEEKDAY_4;
6: daystr := WEEKDAY_5;
7: daystr := WEEKDAY_6;
1: daystr := WEEKDAY_7;
end;
end;
end;
end;
if not (daystr = '') then begin
if (daystr = '<none>') then begin
result := FormatDateTime( TIMEFMT, StrToDateTime(PaintString) );
end
else begin
result := daystr + ' ' + FormatDateTime( TIMEFMT, StrToDateTime(PaintString) );
end;
end;
// result := IntToStr(daysago) + ' | ' + result // uncomment for adjustment purposes
end;
function OnArticleListPaint(
PaintString : WideString;
ColumnIndex : Integer
) : Widestring;
begin
case ColumnIndex of
n_subject_column:
result := Subject( PaintString );
n_from_column:
result := From( PaintString );
n_date_column:
result := Date( PaintString );
else
result := PaintString;
end;
end;
begin
end.
Have fun! ;o)
Dirk Straka
