E.g. I have file This is a very-very-very long file name and this is a very-very-very long file name and this is a very-very-very long file name and this is a very-very-very long file name and this is a very-very-very long file name.txt but in panel I see only This is a very-very-very long file name and this is a very-very-very long file name and this is a very-very-.. txt (when I hovew file by mouse I can see full name in tooltip).
Also TC have INI parameter BriefViewWidthLimit that allows to limit column width. If I set limit to e.g. 300 I see only This is a very-very-very long file name and th.. txt.
So TC truncates filename if it doesn't fit the panel width and shows ".." at the end of name. Tooltip may be used to see full name, and a hotkey may be sssigned for displaying such tooltip. Why it doesn't satisfy you?
PS. I don't think that truncating middle part of name is always better than truncating last part of name. And, as people said, in case of variable width font it may be hard to cut middle part.
filename truncation like in MC
Moderators: Hacker, petermad, Stefan2, white
Well, I've managed it. Here's my code (not perfect just enough to be proof of concept):MVV wrote:And, as people said, in case of variable width font it may be hard to cut middle part.
Code: Select all
procedure TfrmMain.Truncate;
var
TextWidth, AreaWidth, half: Integer;
S1, S2: string;
begin
TextWidth := TruncatedFilename.Canvas.TextWidth(TruncatedFilename.Caption);
AreaWidth := TruncatedFilename.Width;
while (TextWidth > AreaWidth) do
begin
half := Length(TruncatedFilename.Caption) div 2;
S1 := Copy(TruncatedFilename.Caption, 1, (half - 1));
S2 := Copy(TruncatedFilename.Caption, (half + 2), (Length(TruncatedFilename.Caption) - half - 1));
TruncatedFilename.Caption := S1 + '~' + S2;
TextWidth := TruncatedFilename.Canvas.TextWidth(TruncatedFilename.Caption);
end;
end;
I can post a link to demo application so everyone can test it. I've tested it with fonts like Arial, Courier New, MS Sans Serif and Verdana.
In case of fixed width fonts task is quite quick and easy and doesn't require any loops. But lets count processor ticks required for suggested example function...
E.g. filename length is 500 characters and column width is 50 characters, and your algo (if I understood it correctly) cuts 1 character per loop (plus previous '~' char). So you need to call Copy function ~800 times and then call Concat function ~400 times and then call TextWidth method ~400 times... And all theese functions have linear complexity.
And all this just for truncating middle part of filename... If we have just one file in panel its OK but if we have thousands of files...
BTW its much faster to use Delete function call and assign one character to '~' char instead of two Copy function calls and one Concat function call. So you need just to delete middle character and then assign new middle character to '~':
Also for large filename lengths it is much faster to use binary algo that will try to cut N/2 characters, then N/4 or N/2+N/4 etc. So for 1000 characters it will require only 10 loop passes instead of up to 950 for linear algo.
E.g. filename length is 500 characters and column width is 50 characters, and your algo (if I understood it correctly) cuts 1 character per loop (plus previous '~' char). So you need to call Copy function ~800 times and then call Concat function ~400 times and then call TextWidth method ~400 times... And all theese functions have linear complexity.
And all this just for truncating middle part of filename... If we have just one file in panel its OK but if we have thousands of files...
BTW its much faster to use Delete function call and assign one character to '~' char instead of two Copy function calls and one Concat function call. So you need just to delete middle character and then assign new middle character to '~':
Code: Select all
procedure TfrmMain.Truncate;
var
AreaWidth, half: Integer;
S: string;
begin
AreaWidth := TruncatedFilename.Width;
if (TruncatedFilename.Canvas.TextWidth(TruncatedFilename.Caption) <= AreaWidth) exit;
S := TruncatedFilename.Caption;
repeat
half := Length(TruncatedFilename.Caption) div 2;
Delete(S, half, 1);
S[half] := '~';
until (TruncatedFilename.Canvas.TextWidth(S) <= AreaWidth);
TruncatedFilename.Caption := S;
end;