Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Show notifications on each change event.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:dd23419f8b08af4f54df97aa4556164ca9987f12
User & Date: tinus 2017-02-13 19:48:52
Context
2017-02-13
20:01
Only show tray icon when TNotificationCenter is not supported. check-in: 58ee7bc51d user: tinus tags: trunk
19:48
Show notifications on each change event. check-in: dd23419f8b user: tinus tags: trunk
2017-02-11
13:30
Added a vertical splitter (unfortunately, it's the wrong way around). Also added a main menu, but it shouldn't be linked to the same actionmanager as the toolbars. check-in: c35b3e81ac user: tinus tags: trunk
Changes

Changes to src/FMain.dfm.

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    AutoSize = True
    BandBorderStyle = bsNone
    Bands = <
      item
        Control = acttbFolders
        ImageIndex = -1
        MinHeight = 26
        Width = 583
      end
      item
        Break = False
        Control = acttbWatchers
        ImageIndex = -1
        MinHeight = 23
        Width = 89
      end>
    Color = clMenuBar
    EdgeBorders = [ebBottom]
    ParentColor = False
    object acttbFolders: TActionToolBar
      Left = 11
      Top = 0
      Width = 570
      Height = 26
      ActionManager = modActions.actmgrMain
      Caption = 'Folders'
      Color = clMenuBar
      ColorMap.DisabledFontColor = 7171437
      ColorMap.HighlightColor = clWhite
      ColorMap.BtnSelectedFont = clBlack
................................................................................
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      ParentFont = False
      Spacing = 0
    end
    object acttbWatchers: TActionToolBar
      Left = 596
      Top = 1
      Width = 80
      Height = 23
      ActionManager = modActions.actmgrMain
      Caption = 'Watchers'
      Color = clMenuBar
      ColorMap.DisabledFontColor = 7171437
      ColorMap.HighlightColor = clWhite
      ColorMap.BtnSelectedFont = clBlack







|






|







|







 







|

|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    AutoSize = True
    BandBorderStyle = bsNone
    Bands = <
      item
        Control = acttbFolders
        ImageIndex = -1
        MinHeight = 26
        Width = 587
      end
      item
        Break = False
        Control = acttbWatchers
        ImageIndex = -1
        MinHeight = 23
        Width = 85
      end>
    Color = clMenuBar
    EdgeBorders = [ebBottom]
    ParentColor = False
    object acttbFolders: TActionToolBar
      Left = 11
      Top = 0
      Width = 574
      Height = 26
      ActionManager = modActions.actmgrMain
      Caption = 'Folders'
      Color = clMenuBar
      ColorMap.DisabledFontColor = 7171437
      ColorMap.HighlightColor = clWhite
      ColorMap.BtnSelectedFont = clBlack
................................................................................
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      ParentFont = False
      Spacing = 0
    end
    object acttbWatchers: TActionToolBar
      Left = 600
      Top = 1
      Width = 76
      Height = 23
      ActionManager = modActions.actmgrMain
      Caption = 'Watchers'
      Color = clMenuBar
      ColorMap.DisabledFontColor = 7171437
      ColorMap.HighlightColor = clWhite
      ColorMap.BtnSelectedFont = clBlack

Changes to src/FMain.pas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
unit FMain;
interface

uses
  // System
  SysUtils, Variants, Classes, IniFiles, Actions, ImageList, Generics.Collections,
  // Windows
  Windows, Messages,
  // VCL
  Graphics, Controls, Forms, Dialogs, ExtCtrls, WinXCtrls, ToolWin, ActnMan, ActnCtrls,
  ActnList, ImgList, PlatformDefaultStyleActnCtrls, ComCtrls, StdActns, Vcl.BandActn,
  Vcl.CustomizeDlg,
  // Own
  FileSystemWatcher, Vcl.ActnMenus;

type
  TfrmFolderWatcher = class(TForm)
    lvwFolders: TListView;
    splFoldersDetails: TSplitter;
    pnlDetails: TPanel;
    clbrMain: TCoolBar;





|




|
|

|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
unit FMain;
interface

uses
  // System
  SysUtils, Variants, Classes, IniFiles, Actions, ImageList, Generics.Collections, System.Notification,
  // Windows
  Windows, Messages,
  // VCL
  Graphics, Controls, Forms, Dialogs, ExtCtrls, WinXCtrls, ToolWin, ActnMan, ActnCtrls,
  ActnList, ImgList, PlatformDefaultStyleActnCtrls, ComCtrls, StdActns, BandActn,
  CustomizeDlg, ActnMenus,
  // Own
  FileSystemWatcher;

type
  TfrmFolderWatcher = class(TForm)
    lvwFolders: TListView;
    splFoldersDetails: TSplitter;
    pnlDetails: TPanel;
    clbrMain: TCoolBar;

Changes to src/M_Actions.dfm.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
194
195
196
197
198
199
200
201



202






    end
  end
  object imlMain: TImageList
    ColorDepth = cd32Bit
    Left = 96
    Top = 136
    Bitmap = {
      494C0101020008001C0010001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600
      0000000000003600000028000000400000001000000001002000000000000010
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000465D4E88216A
      3CF2166834FF216A3CF2465D4E88000000000000000000000000000000000000
      000000000000000000000000000000000000000000000000000045526A781D4E
      A8DF0340BAFE1A4EABE33F4F697A000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
................................................................................
      2800000040000000100000000100010000000000800000000000000000000000
      000000000000000000000000FFFFFF00FFC1FFC100000000FF80FF8000000000
      8000800000000000800080000000000080008000000000008000800000000000
      8001800100000000800180010000000080018001000000008001800100000000
      800180010000000080018001000000008001800100000000FFFFFFFF00000000
      FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000
      000000000000}
  end



end













|







 








>
>
>
|
>
>
>
>
>
>
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
    end
  end
  object imlMain: TImageList
    ColorDepth = cd32Bit
    Left = 96
    Top = 136
    Bitmap = {
      494C010102000800200010001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600
      0000000000003600000028000000400000001000000001002000000000000010
      0000000000000000000000000000000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000465D4E88216A
      3CF2166834FF216A3CF2465D4E88000000000000000000000000000000000000
      000000000000000000000000000000000000000000000000000045526A781D4E
      A8DF0340BAFE1A4EABE33F4F697A000000000000000000000000000000000000
      0000000000000000000000000000000000000000000000000000000000000000
................................................................................
      2800000040000000100000000100010000000000800000000000000000000000
      000000000000000000000000FFFFFF00FFC1FFC100000000FF80FF8000000000
      8000800000000000800080000000000080008000000000008000800000000000
      8001800100000000800180010000000080018001000000008001800100000000
      800180010000000080018001000000008001800100000000FFFFFFFF00000000
      FFFFFFFF00000000FFFFFFFF0000000000000000000000000000000000000000
      000000000000}
  end
  object ntcNotificationCenter: TNotificationCenter
    Left = 176
    Top = 136
  end
  object trayIcon: TTrayIcon
    IconIndex = -1
    Left = 264
    Top = 144
  end
end

Changes to src/M_Actions.pas.

1
2
3
4
5

6

7
8

9
10
11
12
13
14
15
..
16
17
18
19
20
21
22


23
24
25
26
27
28
29
..
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
..
88
89
90
91
92
93
94



95
96
97
98
99
100
101
...
111
112
113
114
115
116
117



118
119
120
121
122
123

124
125
126
127
128
129
130
131
132
133
134
135
136




















137
138
139
140
141
142
143
unit M_Actions;

interface

uses

  Classes, ImageList, Actions, Generics.Collections, IniFiles,

  Vcl.ImgList, Vcl.Controls, Vcl.BandActn, Vcl.ActnList, Vcl.StdActns,
  Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnMan,

  FileSystemWatcher;

type
  TFileEvent = record
    FileOperation: TFileOperation;
    FileName1, FileName2: string;
  end;
................................................................................

  TmodActions = class(TDataModule)
    actmgrMain: TActionManager;
    actFolderAdd: TBrowseForFolder;
    actFolderRemove: TAction;
    actCustomize: TCustomizeActionBars;
    imlMain: TImageList;


    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    procedure WatchersNotify(Sender: TObject; const Watcher: TFileSystemWatcher; Action: TCollectionNotification);
    procedure FileSystemChange(Sender: TFileSystemWatcher; FileOperation: TFileOperation; const FileName1, FileName2: string);
    procedure actFolderAddAccept(Sender: TObject);
  private
    { Private declarations }
................................................................................
  end;

var
  modActions: TmodActions;

implementation
uses
  SysUtils, IOUtils, ZLib,
  Vcl.Forms,
  L_SpecialFolders,
  FMain, System.TypInfo, Vcl.ComCtrls;

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

procedure TmodActions.DataModuleCreate(Sender: TObject);
var
................................................................................
    for Folder in Folders do begin
      Watcher := AddFolder(Folder);
      Watcher.Enabled := FSettings.ReadBool('Folders', Folder, False);
    end;
  finally
    Folders.Free;
  end;



end;

procedure TmodActions.DataModuleDestroy(Sender: TObject);
begin
  try
    SaveActions;
  finally
................................................................................
  ISO: TFormatSettings = (DateSeparator: '-'; TimeSeparator: ':';
                          ShortDateFormat: 'yyyy-MM-dd';
                          LongTimeFormat: 'hh:nn:ss.zzz');
var
  Path: string;
  Item: TListItem;
  i: Integer;



begin
  Path := IncludeTrailingPathDelimiter(Sender.WatchedDir);
  // TODO
  Item := frmFolderWatcher.lvwLog.Items.Add;
  Item.Caption := DateTimeToStr(Now, ISO);
  Item.SubItems.Add(GetEnumName(TypeInfo(TFileOperation), Ord(FileOperation)).Substring(2));

  if FileName1.StartsWith(Path) then
    Item.SubItems.Add(FileName1.Substring(Path.Length))
  else
    Item.SubItems.Add(FileName1);
  if FileName2.StartsWith(Path) then
    Item.SubItems.Add(FileName2.Substring(Path.Length))
  else
    Item.SubItems.Add(FileName2);
  Item.SubItems.Add(Sender.WatchedDir);
  Item.MakeVisible(False);

  for i := 0 to frmFolderWatcher.lvwLog.Columns.Count - 1 do
    frmFolderWatcher.lvwLog.Columns.Items[i].Width := -1;




















end;

procedure TmodActions.actFolderAddAccept(Sender: TObject);
begin
  AddFolder(actFolderAdd.Folder);
end;






>
|
>

|
>







 







>
>







 







|
|

|







 







>
>
>







 







>
>
>





|
>













>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
unit M_Actions;

interface

uses
  // System
  Classes, ImageList, Actions, Generics.Collections, IniFiles, System.Notification,
  // VCL
  Vcl.ImgList, Vcl.Controls, Vcl.BandActn, Vcl.ActnList, Vcl.StdActns,
  Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnMan, Vcl.ExtCtrls,
  // Common
  FileSystemWatcher;

type
  TFileEvent = record
    FileOperation: TFileOperation;
    FileName1, FileName2: string;
  end;
................................................................................

  TmodActions = class(TDataModule)
    actmgrMain: TActionManager;
    actFolderAdd: TBrowseForFolder;
    actFolderRemove: TAction;
    actCustomize: TCustomizeActionBars;
    imlMain: TImageList;
    ntcNotificationCenter: TNotificationCenter;
    trayIcon: TTrayIcon;
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
    procedure WatchersNotify(Sender: TObject; const Watcher: TFileSystemWatcher; Action: TCollectionNotification);
    procedure FileSystemChange(Sender: TFileSystemWatcher; FileOperation: TFileOperation; const FileName1, FileName2: string);
    procedure actFolderAddAccept(Sender: TObject);
  private
    { Private declarations }
................................................................................
  end;

var
  modActions: TmodActions;

implementation
uses
  SysUtils, IOUtils, ZLib, TypInfo,
  Vcl.Forms, Vcl.ComCtrls,
  L_SpecialFolders,
  FMain;

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

procedure TmodActions.DataModuleCreate(Sender: TObject);
var
................................................................................
    for Folder in Folders do begin
      Watcher := AddFolder(Folder);
      Watcher.Enabled := FSettings.ReadBool('Folders', Folder, False);
    end;
  finally
    Folders.Free;
  end;

  trayIcon.Icon := Application.Icon;
  trayIcon.BalloonTitle := Application.Title;
end;

procedure TmodActions.DataModuleDestroy(Sender: TObject);
begin
  try
    SaveActions;
  finally
................................................................................
  ISO: TFormatSettings = (DateSeparator: '-'; TimeSeparator: ':';
                          ShortDateFormat: 'yyyy-MM-dd';
                          LongTimeFormat: 'hh:nn:ss.zzz');
var
  Path: string;
  Item: TListItem;
  i: Integer;
  Notif: TNotification;
  Action: string;
  Body: string;
begin
  Path := IncludeTrailingPathDelimiter(Sender.WatchedDir);
  // TODO
  Item := frmFolderWatcher.lvwLog.Items.Add;
  Item.Caption := DateTimeToStr(Now, ISO);
  Action := GetEnumName(TypeInfo(TFileOperation), Ord(FileOperation)).Substring(2);
  Item.SubItems.Add(Action);
  if FileName1.StartsWith(Path) then
    Item.SubItems.Add(FileName1.Substring(Path.Length))
  else
    Item.SubItems.Add(FileName1);
  if FileName2.StartsWith(Path) then
    Item.SubItems.Add(FileName2.Substring(Path.Length))
  else
    Item.SubItems.Add(FileName2);
  Item.SubItems.Add(Sender.WatchedDir);
  Item.MakeVisible(False);

  for i := 0 to frmFolderWatcher.lvwLog.Columns.Count - 1 do
    frmFolderWatcher.lvwLog.Columns.Items[i].Width := -1;

  // TODO: gather up events that are in close repetition, and just display them once.
  Body := Action + ' ' + FileName1;
  if FileName2 <> '' then begin
    if SameFileName(ExtractFileDir(FileName2), ExtractFileDir(FileName2)) then
      Body := Body + ' to ' + ExtractFileName(FileName2)
    else
      Body := Body + ' to ' + FileName2;
  end;
  if ntcNotificationCenter.Supported then begin
    Notif := ntcNotificationCenter.CreateNotification;
    Notif.Title := Application.Title;
    Notif.AlertBody := Body;
    Notif.HasAction := False;
    ntcNotificationCenter.PresentNotification(Notif);
  end else begin
    trayIcon.BalloonHint := Body;
    trayIcon.BalloonFlags := bfInfo;
    trayIcon.ShowBalloonHint;
  end;
end;

procedure TmodActions.actFolderAddAccept(Sender: TObject);
begin
  AddFolder(actFolderAdd.Folder);
end;