Menu

[r111]: / trunk / Src / USourceFileOutputMgr.pas  Maximize  Restore  History

Download this file

395 lines (362 with data), 14.2 kB

  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
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 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
104
105
106
107
108
109
110
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
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
{
* USourceFileOutputMgr.pas
*
* Implements class that manages customisation and output of source files.
*
* v1.0 of 29 Oct 2006 - Original version.
* v1.1 of 02 Jul 2007 - Changed to generate output files that contain document
* titles where relevant.
* v1.2 of 26 Sep 2007 - Added ErrorMessage parameter to
* TSourceFileNameCheckEvent.
* - Now display error message if entered file not
* acceptable.
* - Preview dialogs are now aligned over save dialog box.
* v1.3 of 29 May 2008 - Fixed bug that was always saving files of type
* selected in save dialog's highlight type regardless of
* file extension. Now bases file format on extension.
* v1.4 of 14 Dec 2008 - Changed to use ExtToFilterIndex routine from
* its new location in the UOpenDialogHelper unit.
*
*
* ***** BEGIN LICENSE BLOCK *****
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is USourceFileOutputMgr.pas
*
* The Initial Developer of the Original Code is Peter Johnson
* (http://www.delphidabbler.com/).
*
* Portions created by the Initial Developer are Copyright (C) 2006-2008 Peter
* Johnson. All Rights Reserved.
*
* Contributor(s): None
*
* ***** END LICENSE BLOCK *****
}
unit USourceFileOutputMgr;
interface
uses
// Project
USaveSourceDlg, USourceFileInfo, USourceGen;
type
{
TSourceCodeGenEvent:
Type of TSourceFileOutputMgr's OnGenerateOutput event used to get source
code to be output.
@param Sender [in] TSourceFileOutputMgr instance triggering event.
@param CommentStyle [in] Style of commenting required in generated source.
@param RawSourceCode [out] Set to raw source code in event handler.
@param DocTitle [out] Set to the document's title in event handler.
}
TSourceCodeGenEvent = procedure(Sender: TObject;
const CommentStyle: TCommentStyle;
out RawSourceCode, DocTitle: string) of object;
{
TSourceFileNameCheckEvent:
Type of TSourceFileOutputMgr's OnCheckFileName event used to check if a
file name is acceptable to caller.
@param Sender [in] TSourceFileOutputMgr instance triggering event.
@param FileName [in] File name to be checked.
@param NameOK [in/out] Defaults to true. Handler should set false if file
name not acceptable.
@param ErrorMessage [in/out] Default to ''. Handler should set to error
message if NameOK is set false. Ignored if NameOK is true. Default
message used if left as empty string.
}
TSourceFileNameCheckEvent = procedure(Sender: TObject; const FileName: string;
var NameOK: Boolean; var ErrorMessage: string) of object;
{
TSourceFileOutputMgr:
Class that manages output of source files. Gets information about file to
be output from user, validates file, enables it to be previewed, and writes
it to file with optional syntax highlighting. Owner of object must generate
the source code and provide information about supported file types.
}
TSourceFileOutputMgr = class(TObject)
private
fSaveDlg: TSaveSourceDlg;
{Customised save dialog box used to get name of source file, commenting
style and whether to use syntax highlighting from user}
fSourceFileInfo: TSourceFileInfo;
{Object providing information about supported source file types}
fOnGenerateOutput: TSourceCodeGenEvent;
{Handler for OnGenerateOutput event}
fOnCheckFileName: TSourceFileNameCheckEvent;
{Handler for OnCheckFileName event}
function GetDlgTile: string;
{Read accessor for DlgTitle property.
@return Dialog box title.
}
procedure SetDlgTitle(const Value: string);
{Write accessor for DlgTitle property.
@param Value [in] New dialog box title.
}
function GetDlgHelpKeyword: string;
{Read accessor for DlgHelpKeyword property.
@return Help keyword.
}
procedure SetDlgHelpKeyword(const Value: string);
{Write accessor for DlgHelpKeyword property.
@param Value [in] New help keyword.
}
function IsHilitingSupported(const FileType: TSourceFileType): Boolean;
{Checks if highlighting is supported for a file type.
@param FileType [in] File type to be checked.
@return True if file type supports highlighting, False if not.
}
procedure HiliteQueryHandler(Sender: TObject; const Ext: string;
var CanHilite: Boolean);
{Handles custom save dialog box's OnHiliteQuery event. Determines whether
syntax highlighting is supported for a file extension.
@param Sender [in] Not used.
@param Ext [in] Extension of selected file type.
@param CanHilite [in/out] Set true if syntax highlighting is enabled and
false (default) if not.
}
procedure PreviewHandler(Sender: TObject);
{Handles custom save dialog's OnPreview event. Displays source code
appropriately formatted in preview dialog box.
@param Sender [in] Not used.
}
procedure CanCloseHandler(Sender: TObject; var CanClose: Boolean);
{Handles custom save dialog's OnCanClose event. Permits dialog to close if
filename entered in dialog box is acceptable.
@param Sender [in] Not used.
@param CanClose [in/out] Set to true to allow dialog to close or false
to inhibit.
}
function GenerateOutput(const FileType: TSourceFileType): string;
{Generates source code in desired format.
@param FileType [in] Type of file for which source code is required.
Determines file format.
@return Formatted source code.
}
function CheckEnteredFileName: Boolean;
{Checks if file name entered in save dialog box is acceptable. Hands off
decision about file name to caller by triggering OnCheckFileName event.
Displays and error message if event handler notifies file name is not
acceptable.
@return True if filename is OK, false otherwise.
}
public
constructor Create;
{Class constructor. Sets up object.
}
destructor Destroy; override;
{Class destructor. Tears down object.
}
procedure Execute;
{Gets information about source file to be generated from user then outputs
the source file.
}
property SourceFileInfo: TSourceFileInfo
read fSourceFileInfo;
{Information about supported source file types}
property DlgTitle: string
read GetDlgTile write SetDlgTitle;
{Title of save dialog box}
property DlgHelpKeyword: string
read GetDlgHelpKeyword write SetDlgHelpKeyword;
{Help keyword identifying topic accessed when user clicks help button in
save dialog box}
property OnGenerateOutput: TSourceCodeGenEvent
read fOnGenerateOutput write fOnGenerateOutput;
{Event triggered when this object needs to output source code. Caller must
handle this event to generate the source code}
property OnCheckFileName: TSourceFileNameCheckEvent
read fOnCheckFileName write fOnCheckFileName;
{Event used to enable caller to check if entered file name is valid}
end;
implementation
uses
// Delphi
SysUtils,
// Project
FmPreviewDlg, UFileHiliter, UMessageBox, UOpenDialogHelper, UPreferences,
UUtils;
{ TSourceFileOutputMgr }
procedure TSourceFileOutputMgr.CanCloseHandler(Sender: TObject;
var CanClose: Boolean);
{Handles custom save dialog's OnCanClose event. Permits dialog to close if
filename entered in dialog box is acceptable.
@param Sender [in] Not used.
@param CanClose [in/out] Set to true to allow dialog to close or false to
inhibit.
}
begin
CanClose := CheckEnteredFileName;
end;
function TSourceFileOutputMgr.CheckEnteredFileName: Boolean;
{Checks if file name entered in save dialog box is acceptable. Hands off
decision about file name to caller by triggering OnCheckFileName event.
Displays and error message if event handler notifies file name is not
acceptable.
@return True if filename is OK, false otherwise.
}
var
ErrMsg: string; // error message displayed if name not OK
resourcestring
sDefaultErrMsg = 'Invalid file name'; // default error message
begin
// Assume file name is OK
Result := True;
ErrMsg := '';
// Ask caller about file name via event
if Assigned(fOnCheckFileName) then
fOnCheckFileName(Self, fSaveDlg.FileName, Result, ErrMsg);
if not Result then
begin
// File name not acceptable: display message aligned over dialog box
if ErrMsg = '' then
ErrMsg := sDefaultErrMsg;
TMessageBox.Error(fSaveDlg, ErrMsg);
end;
end;
constructor TSourceFileOutputMgr.Create;
{Class constructor. Sets up object.
}
begin
inherited Create;
// Create locally owned source file info object
fSourceFileInfo := TSourceFileInfo.Create;
// Create and initialize custom save dialog box
fSaveDlg := TSaveSourceDlg.Create(nil);
fSaveDlg.CommentStyle := Preferences.SourceCommentStyle;
fSaveDlg.UseSyntaxHiliting := Preferences.SourceSyntaxHilited;
fSaveDlg.OnPreview := PreviewHandler;
fSaveDlg.OnHiliteQuery := HiliteQueryHandler;
fSaveDlg.OnCanClose := CanCloseHandler;
end;
destructor TSourceFileOutputMgr.Destroy;
{Class destructor. Tears down object.
}
begin
FreeAndNil(fSaveDlg);
FreeAndNil(fSourceFileInfo);
inherited;
end;
procedure TSourceFileOutputMgr.Execute;
{Gets information about source file to be generated from user then outputs
the source file.
}
begin
// Set up dialog box
fSaveDlg.Filter := fSourceFileInfo.FilterString;
fSaveDlg.FilterIndex := ExtToFilterIndex(
fSaveDlg.Filter,
fSourceFileInfo.FileExtensions[Preferences.SourceDefaultFileType],
1
);
fSaveDlg.FileName := fSourceFileInfo.FileName;
// Display dialog box and save file if user OKs
if fSaveDlg.Execute then
StringToFile(
GenerateOutput(
fSourceFileInfo.FileTypeFromExt(ExtractFileExt(fSaveDlg.FileName))
),
fSaveDlg.FileName
);
end;
function TSourceFileOutputMgr.GenerateOutput(
const FileType: TSourceFileType): string;
{Generates optionally syntax highlighted source code. Requires that caller
generates the raw source code by handling the OnGenerateOutput event.
@param FileType [in] Type of file for which source code is required.
Determines file format.
@return Optionally highlighted source code.
}
var
RawSource: string; // raw source code
DocTitle: string; // document title
Hiliter: TFileHiliter; // object used to highlight source code
Ext: string; // extension of selected file
begin
if Assigned(fOnGenerateOutput) then
begin
// Get raw source code from caller
fOnGenerateOutput(Self, fSaveDlg.CommentStyle, RawSource, DocTitle);
// Highlight the raw source as required
Ext := ExtractFileExt(fSaveDlg.FileName);
Hiliter := TFileHiliter.Create(
fSaveDlg.UseSyntaxHiliting and IsHilitingSupported(FileType),
FileType
);
try
Result := Hiliter.Hilite(RawSource, DocTitle);
finally
FreeAndNil(Hiliter);
end;
end;
end;
function TSourceFileOutputMgr.GetDlgHelpKeyword: string;
{Read accessor for DlgHelpKeyword property.
@return Help keyword.
}
begin
Result := fSaveDlg.HelpKeyword;
end;
function TSourceFileOutputMgr.GetDlgTile: string;
{Read accessor for DlgTitle property.
@return Dialog box title.
}
begin
Result := fSaveDlg.Title;
end;
procedure TSourceFileOutputMgr.HiliteQueryHandler(Sender: TObject;
const Ext: string; var CanHilite: Boolean);
{Handles custom save dialog box's OnHiliteQuery event. Determines whether
syntax highlighting is supported for a file extension.
@param Sender [in] Not used.
@param Ext [in] Extension of selected file type.
@param CanHilite [in/out] Set true if syntax highlighting is enabled and
false (default) if not.
}
begin
CanHilite := IsHilitingSupported(fSourceFileInfo.FileTypeFromExt(Ext));
end;
function TSourceFileOutputMgr.IsHilitingSupported(
const FileType: TSourceFileType): Boolean;
{Checks if highlighting is supported for a file type.
@param FileType [in] File type to be checked.
@return True if file type supports highlighting, False if not.
}
begin
Result := TFileHiliter.IsHilitingSupported(FileType);
end;
procedure TSourceFileOutputMgr.PreviewHandler(Sender: TObject);
{Handles custom save dialog's OnPreview event. Displays source code
appropriately formatted in preview dialog box.
@param Sender [in] Not used.
}
begin
// Display preview dialog box. We use save dialog as owner to ensure preview
// dialog box is aligned over save dialog box
TPreviewDlg.Execute(
fSaveDlg,
GenerateOutput(fSourceFileInfo.FileTypeFromExt(fSaveDlg.SelectedExt))
);
end;
procedure TSourceFileOutputMgr.SetDlgHelpKeyword(const Value: string);
{Write accessor for DlgHelpKeyword property.
@param Value [in] New help keyword.
}
begin
fSaveDlg.HelpKeyword := Value;
end;
procedure TSourceFileOutputMgr.SetDlgTitle(const Value: string);
{Write accessor for DlgTitle property.
@param Value [in] New dialog box title.
}
begin
fSaveDlg.Title := Value;
end;
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.