├── resource.bat
├── wizard2.png
├── ProjectRTF.pas
├── ProjectRes.zip
├── SynProject.ico
├── SynProject.res
├── ProjectEdit.res
├── ProjectEditor.pas
├── ProjectParser.pas
├── ProjectTypes.pas
├── ProjectCommons.pas
├── ProjectDiffUnit.pas
├── ProjectGraphEdit.pas
├── ProjectSpellCheck.pas
├── ProjectMemoExSyntax.pas
├── PasDocLight
├── PasDoc_Hashes.pas
├── PasDoc_Types.pas
├── PasDoc_HierarchyTree.pas
├── PasDoc_ObjectVector.pas
├── PasDoc_StringVector.pas
├── PasDoc_SortSettings.pas
├── pasdoc_defines.inc
├── PasDoc_StringPairVector.pas
└── PasDoc_Serialize.pas
├── ProjectRes.rc
├── .gitattributes
├── ProjectFormViewOne.dfm
├── ProjectFormViewTwo.dfm
├── ProjectVersionCompare.dfm
├── ProjectFrameViewer.dfm
├── ProjectEditMain.dfm
├── ProjectFormSelection.dfm
├── .gitignore
├── ProjectFrameRisk.dfm
├── ProjectSpellCheck.dfm
├── ProjectVersionBackup.pas
├── ProjectFrameRisk.pas
├── ProjectEditorCommit.pas
├── README.md
├── ProjectEditorCommit.dfm
├── ProjectEditorProgram.dfm
├── SynProject.dpr
├── ProjectVersionBackup.dfm
├── ProjectGraphEdit.dfm
├── ProjectFormSelection.pas
├── ProjectVersionSCR.pas
├── ProjectVersionSCR.dfm
├── ProjectEditorRelease.dfm
├── ProjectVersionCommit.pas
├── ProjectEditorRelease.pas
├── ProjectDiagrams.pas
├── ProjectVersionCommit.dfm
├── ProjectVersionMain.dfm
├── ProjectVersionPages.dfm
├── ProjectVersionCompare.pas
├── ProjectTrackerLogin.dfm
├── ProjectFormViewOne.pas
├── ProjectFormDocWizard.dfm
├── synproject.css
├── ProjectFormViewTwo.pas
├── ProjectFrameViewer.pas
├── ProjectTrackerLogin.pas
├── ProjectEditMain.pas
└── ProjectEditor.dfm
/resource.bat:
--------------------------------------------------------------------------------
1 | brcc32 ProjectRes.rc
2 | pause
--------------------------------------------------------------------------------
/wizard2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/wizard2.png
--------------------------------------------------------------------------------
/ProjectRTF.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectRTF.pas
--------------------------------------------------------------------------------
/ProjectRes.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectRes.zip
--------------------------------------------------------------------------------
/SynProject.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/SynProject.ico
--------------------------------------------------------------------------------
/SynProject.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/SynProject.res
--------------------------------------------------------------------------------
/ProjectEdit.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectEdit.res
--------------------------------------------------------------------------------
/ProjectEditor.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectEditor.pas
--------------------------------------------------------------------------------
/ProjectParser.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectParser.pas
--------------------------------------------------------------------------------
/ProjectTypes.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectTypes.pas
--------------------------------------------------------------------------------
/ProjectCommons.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectCommons.pas
--------------------------------------------------------------------------------
/ProjectDiffUnit.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectDiffUnit.pas
--------------------------------------------------------------------------------
/ProjectGraphEdit.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectGraphEdit.pas
--------------------------------------------------------------------------------
/ProjectSpellCheck.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectSpellCheck.pas
--------------------------------------------------------------------------------
/ProjectMemoExSyntax.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/ProjectMemoExSyntax.pas
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_Hashes.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/PasDocLight/PasDoc_Hashes.pas
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_Types.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/PasDocLight/PasDoc_Types.pas
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_HierarchyTree.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/PasDocLight/PasDoc_HierarchyTree.pas
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_ObjectVector.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/PasDocLight/PasDoc_ObjectVector.pas
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_StringVector.pas:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/synopse/SynProject/HEAD/PasDocLight/PasDoc_StringVector.pas
--------------------------------------------------------------------------------
/ProjectRes.rc:
--------------------------------------------------------------------------------
1 | Default TXT "Default.ini"
2 | Zip ZIP "ProjectRes.zip"
3 | wizard2 10 "wizard2.png"
4 | css TXT "synproject.css"
5 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/ProjectFormViewOne.dfm:
--------------------------------------------------------------------------------
1 | object FormViewOne: TFormViewOne
2 | Left = 667
3 | Top = 194
4 | Width = 445
5 | Height = 562
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -11
10 | Font.Name = 'MS Sans Serif'
11 | Font.Style = []
12 | FormStyle = fsStayOnTop
13 | OldCreateOrder = False
14 | PixelsPerInch = 96
15 | TextHeight = 13
16 | object Image: TImage
17 | Left = 0
18 | Top = 0
19 | Width = 437
20 | Height = 528
21 | Align = alClient
22 | Visible = False
23 | end
24 | object PopupMenu: TPopupMenu
25 | Left = 64
26 | Top = 80
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/ProjectFormViewTwo.dfm:
--------------------------------------------------------------------------------
1 | object FormViewTwo: TFormViewTwo
2 | Left = 257
3 | Top = 137
4 | Width = 522
5 | Height = 455
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -11
10 | Font.Name = 'Tahoma'
11 | Font.Style = []
12 | FormStyle = fsStayOnTop
13 | OldCreateOrder = False
14 | OnResize = FormResize
15 | PixelsPerInch = 96
16 | TextHeight = 13
17 | object Splitter1: TSplitter
18 | Left = 265
19 | Top = 0
20 | Height = 421
21 | end
22 | object PanelLeft: TPanel
23 | Left = 0
24 | Top = 0
25 | Width = 265
26 | Height = 421
27 | Align = alLeft
28 | BevelOuter = bvNone
29 | TabOrder = 0
30 | end
31 | object PanelRight: TPanel
32 | Left = 268
33 | Top = 0
34 | Width = 246
35 | Height = 421
36 | Align = alClient
37 | BevelOuter = bvNone
38 | TabOrder = 1
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/ProjectVersionCompare.dfm:
--------------------------------------------------------------------------------
1 | object ProjectVersionCompareForm: TProjectVersionCompareForm
2 | Left = 162
3 | Top = 354
4 | Width = 547
5 | Height = 393
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -11
10 | Font.Name = 'MS Sans Serif'
11 | Font.Style = []
12 | OldCreateOrder = False
13 | OnResize = FormResize
14 | OnShow = FormShow
15 | PixelsPerInch = 96
16 | TextHeight = 13
17 | object PanelLeft: TPanel
18 | Left = 225
19 | Top = 0
20 | Width = 148
21 | Height = 342
22 | Align = alLeft
23 | BevelOuter = bvNone
24 | TabOrder = 0
25 | end
26 | object PanelRight: TPanel
27 | Left = 373
28 | Top = 0
29 | Width = 203
30 | Height = 342
31 | Align = alRight
32 | BevelOuter = bvNone
33 | TabOrder = 1
34 | end
35 | object ListFilesCommit: TListView
36 | Left = 0
37 | Top = 0
38 | Width = 225
39 | Height = 342
40 | Align = alLeft
41 | Columns = <>
42 | MultiSelect = True
43 | TabOrder = 2
44 | OnSelectItem = ListFilesCommitSelectItem
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/ProjectFrameViewer.dfm:
--------------------------------------------------------------------------------
1 | object FrameViewer: TFrameViewer
2 | Left = 0
3 | Top = 0
4 | Width = 318
5 | Height = 238
6 | TabOrder = 0
7 | object MemoEx: TMemoEx
8 | Left = 0
9 | Top = 0
10 | Width = 318
11 | Height = 238
12 | Cursor = crIBeam
13 | TabOrder = 0
14 | GutterWidth = 0
15 | RightMarginColor = clSilver
16 | ReadOnly = True
17 | Completion.Separator = '='
18 | Completion.ItemHeight = 13
19 | Completion.Interval = 800
20 | Completion.ListBoxStyle = lbStandard
21 | Completion.CaretChar = '|'
22 | Completion.CRLF = '/n'
23 | TabStops = '8'
24 | SelForeColor = clHighlightText
25 | SelBackColor = clHighlight
26 | OnKeyDown = MemoExKeyDown
27 | Align = alClient
28 | Ctl3D = True
29 | Font.Charset = DEFAULT_CHARSET
30 | Font.Color = clWindowText
31 | Font.Height = -13
32 | Font.Name = 'Courier New'
33 | Font.Pitch = fpFixed
34 | Font.Style = []
35 | ParentColor = False
36 | TabStop = True
37 | UseDockManager = False
38 | WordWrap = False
39 | end
40 | object FindDialog: TFindDialog
41 | Options = [frDown, frHideWholeWord, frHideUpDown]
42 | OnFind = FindDialogFind
43 | Left = 72
44 | Top = 72
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/ProjectEditMain.dfm:
--------------------------------------------------------------------------------
1 | object ProMainForm: TProMainForm
2 | Left = 250
3 | Top = 303
4 | Width = 668
5 | Height = 436
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -11
10 | Font.Name = 'Tahoma'
11 | Font.Style = []
12 | KeyPreview = True
13 | OldCreateOrder = False
14 | ShowHint = True
15 | WindowState = wsMaximized
16 | OnCloseQuery = FormCloseQuery
17 | OnCreate = FormCreate
18 | OnDestroy = FormDestroy
19 | OnShow = FormShow
20 | PixelsPerInch = 96
21 | TextHeight = 13
22 | object Splitter2: TSplitter
23 | Left = 121
24 | Top = 0
25 | Height = 379
26 | end
27 | object Splitter1: TSplitter
28 | Left = 649
29 | Top = 0
30 | Height = 379
31 | Align = alRight
32 | end
33 | object Sections: TListBox
34 | Left = 0
35 | Top = 0
36 | Width = 121
37 | Height = 379
38 | Align = alLeft
39 | ItemHeight = 13
40 | TabOrder = 0
41 | OnClick = SectionsClick
42 | OnMouseDown = SectionsMouseDown
43 | end
44 | object StatusBar: TStatusBar
45 | Left = 0
46 | Top = 379
47 | Width = 652
48 | Height = 19
49 | AutoHint = True
50 | Panels = <
51 | item
52 | Width = 500
53 | end
54 | item
55 | Width = 50
56 | end>
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/ProjectFormSelection.dfm:
--------------------------------------------------------------------------------
1 | object SelectionForm: TSelectionForm
2 | Left = 352
3 | Top = 156
4 | Width = 571
5 | Height = 665
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -13
10 | Font.Name = 'Tahoma'
11 | Font.Style = []
12 | KeyPreview = True
13 | OldCreateOrder = False
14 | Position = poScreenCenter
15 | OnCreate = FormCreate
16 | OnDestroy = FormDestroy
17 | OnKeyDown = FormKeyDown
18 | OnShow = FormShow
19 | PixelsPerInch = 96
20 | TextHeight = 16
21 | object List: TListBox
22 | Left = 0
23 | Top = 25
24 | Width = 555
25 | Height = 602
26 | Style = lbVirtualOwnerDraw
27 | Align = alClient
28 | ItemHeight = 18
29 | TabOrder = 1
30 | OnDblClick = ListDblClick
31 | OnDrawItem = ListDrawItem
32 | end
33 | object pnlTop: TPanel
34 | Left = 0
35 | Top = 0
36 | Width = 555
37 | Height = 25
38 | Align = alTop
39 | TabOrder = 0
40 | DesignSize = (
41 | 555
42 | 25)
43 | object edtFind: TEdit
44 | Left = 0
45 | Top = 0
46 | Width = 530
47 | Height = 25
48 | Anchors = [akLeft, akTop, akRight]
49 | AutoSize = False
50 | TabOrder = 0
51 | OnChange = edtFindChange
52 | end
53 | object btnNext: TButton
54 | Left = 528
55 | Top = 0
56 | Width = 25
57 | Height = 25
58 | Hint = 'Next (F3)'
59 | Anchors = [akTop, akRight]
60 | Caption = '>'
61 | Font.Charset = DEFAULT_CHARSET
62 | Font.Color = clWindowText
63 | Font.Height = -13
64 | Font.Name = 'Tahoma'
65 | Font.Style = [fsBold]
66 | ParentFont = False
67 | ParentShowHint = False
68 | ShowHint = True
69 | TabOrder = 1
70 | TabStop = False
71 | OnClick = edtFindChange
72 | end
73 | end
74 | end
75 |
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_SortSettings.pas:
--------------------------------------------------------------------------------
1 | unit PasDoc_SortSettings;
2 |
3 | interface
4 |
5 | uses SysUtils;
6 |
7 | type
8 | EInvalidSortSetting = class(Exception);
9 |
10 | TSortSetting = (
11 | { At unit (TPasUnit) level : } { }
12 | ssCIOs, ssConstants, ssFuncsProcs, ssTypes, ssVariables, ssUsesClauses,
13 | { At CIO (TPasCio) level : } { }
14 | ssRecordFields, ssNonRecordFields, ssMethods, ssProperties);
15 | TSortSettings = set of TSortSetting;
16 |
17 | const
18 | AllSortSettings: TSortSettings = [Low(TSortSetting) .. High(TSortSetting)];
19 |
20 | { Must be lowercase.
21 | Used in @link(SortSettingsToName), @link(SortSettingFromName). }
22 | SortSettingNames: array[TSortSetting] of string = (
23 | 'structures', 'constants', 'functions', 'types', 'variables', 'uses-clauses',
24 | 'record-fields', 'non-record-fields', 'methods', 'properties' );
25 |
26 | { @raises(EInvalidSortSetting if ASortSettingName does not match
27 | (case ignored) to any SortSettingNames.) }
28 | function SortSettingFromName(const SortSettingName: string): TSortSetting;
29 |
30 | { Comma-separated list }
31 | function SortSettingsToName(const SortSettings: TSortSettings): string;
32 |
33 |
34 | implementation
35 |
36 | function SortSettingFromName(const SortSettingName: string): TSortSetting;
37 | var S: string;
38 | begin
39 | S := LowerCase(SortSettingName);
40 | for Result := Low(Result) to High(Result) do
41 | if S = SortSettingNames[Result] then
42 | Exit;
43 | raise EInvalidSortSetting.CreateFmt('Invalid sort specifier "%s"',
44 | [SortSettingName]);
45 | end;
46 |
47 | function SortSettingsToName(const SortSettings: TSortSettings): string;
48 | var SS: TSortSetting;
49 | begin
50 | Result := '';
51 | for SS := Low(SS) to High(SS) do
52 | if SS in SortSettings then
53 | begin
54 | if Result <> '' then Result := Result + ',';
55 | Result := Result + SortSettingNames[SS];
56 | end;
57 | end;
58 |
59 | end.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Uncomment these types if you want even more clean repository. But be careful.
2 | # It can make harm to an existing project source. Read explanations below.
3 | #
4 | # Resource files are binaries containing manifest, project icon and version info.
5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
6 | #*.res
7 | #
8 | # Type library file (binary). In old Delphi versions it should be stored.
9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
10 | #*.tlb
11 | #
12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
13 | # Uncomment this if you are not using diagrams or use newer Delphi version.
14 | *.ddp
15 | *.dof
16 | #
17 | # Visual LiveBindings file. Added in Delphi XE2.
18 | # Uncomment this if you are not using LiveBindings Designer.
19 | #*.vlb
20 | #
21 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
22 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
23 | #*.deployproj
24 | #
25 | # C++ object files produced when C/C++ Output file generation is configured.
26 | # Uncomment this if you are not using external objects (zlib library for example).
27 | #*.obj
28 | #
29 |
30 | # Delphi compiler-generated binaries (safe to delete)
31 | *.exe
32 | *.dll
33 | *.bpl
34 | *.bpi
35 | *.dcp
36 | *.so
37 | *.apk
38 | *.drc
39 | *.map
40 | *.dres
41 | *.rsm
42 | *.tds
43 | *.dcu
44 | *.lib
45 | *.a
46 | *.o
47 | *.ocx
48 |
49 | # FreePascal compiler
50 | *.com
51 | *.class
52 | *.ppu
53 | *.compiled
54 | *.rsj
55 | *.or
56 | *.lps
57 | *.db
58 | fpc/
59 |
60 | # Delphi autogenerated files (duplicated info)
61 | *.cfg
62 | *.hpp
63 | *Resource.rc
64 |
65 | # Delphi local files (user-specific info)
66 | *.local
67 | *.identcache
68 | *.projdata
69 | *.tvsconfig
70 | *.dsk
71 |
72 | # Delphi history and backups
73 | __history/
74 | __recovery/
75 | *.~*
76 | *.bak
77 |
78 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
79 | *.stat
80 |
81 | #other VCS
82 | _FOSSIL_
83 | .svn/
84 | # SourceCodeRep artifact
85 | *.txt
86 |
87 | backup/
88 | .idea/
89 |
--------------------------------------------------------------------------------
/ProjectFrameRisk.dfm:
--------------------------------------------------------------------------------
1 | object FrameRisk: TFrameRisk
2 | Left = 0
3 | Top = 0
4 | Width = 353
5 | Height = 171
6 | TabOrder = 0
7 | object GroupBoxRisk: TGroupBox
8 | Left = 0
9 | Top = 0
10 | Width = 353
11 | Height = 169
12 | Caption = ' Risk Assessment '
13 | TabOrder = 0
14 | DesignSize = (
15 | 353
16 | 169)
17 | object Label1: TLabel
18 | Left = 80
19 | Top = 32
20 | Width = 3
21 | Height = 13
22 | Alignment = taRightJustify
23 | end
24 | object Label2: TLabel
25 | Left = 80
26 | Top = 56
27 | Width = 3
28 | Height = 13
29 | Alignment = taRightJustify
30 | end
31 | object Label3: TLabel
32 | Left = 80
33 | Top = 80
34 | Width = 3
35 | Height = 13
36 | Alignment = taRightJustify
37 | end
38 | object ComboBox1: TComboBox
39 | Left = 88
40 | Top = 28
41 | Width = 245
42 | Height = 21
43 | Style = csDropDownList
44 | Anchors = [akLeft, akTop, akRight]
45 | ItemHeight = 13
46 | TabOrder = 0
47 | end
48 | object ComboBox2: TComboBox
49 | Left = 88
50 | Top = 52
51 | Width = 245
52 | Height = 21
53 | Style = csDropDownList
54 | Anchors = [akLeft, akTop, akRight]
55 | ItemHeight = 13
56 | TabOrder = 1
57 | end
58 | object ComboBox3: TComboBox
59 | Left = 88
60 | Top = 76
61 | Width = 245
62 | Height = 21
63 | Style = csDropDownList
64 | Anchors = [akLeft, akTop, akRight]
65 | ItemHeight = 13
66 | TabOrder = 2
67 | end
68 | object LabeledEditEvaluatedBy: TLabeledEdit
69 | Left = 88
70 | Top = 104
71 | Width = 245
72 | Height = 21
73 | Hint = 'Put the SW risk evaluation team names, separated with +'
74 | Anchors = [akLeft, akTop, akRight]
75 | EditLabel.Width = 62
76 | EditLabel.Height = 13
77 | EditLabel.Caption = 'Evaluated by'
78 | LabelPosition = lpLeft
79 | ParentShowHint = False
80 | ShowHint = True
81 | TabOrder = 3
82 | OnKeyPress = LabeledEditEvaluatedByKeyPress
83 | end
84 | object LabeledEditJustif: TLabeledEdit
85 | Left = 88
86 | Top = 130
87 | Width = 245
88 | Height = 21
89 | Anchors = [akLeft, akTop, akRight]
90 | EditLabel.Width = 55
91 | EditLabel.Height = 13
92 | EditLabel.Caption = 'Justification'
93 | LabelPosition = lpLeft
94 | TabOrder = 4
95 | end
96 | end
97 | end
98 |
--------------------------------------------------------------------------------
/ProjectSpellCheck.dfm:
--------------------------------------------------------------------------------
1 | object SpellCheckForm: TSpellCheckForm
2 | Left = 453
3 | Top = 413
4 | BorderStyle = bsSingle
5 | Caption = 'Spell Check'
6 | ClientHeight = 219
7 | ClientWidth = 452
8 | Color = clBtnFace
9 | Font.Charset = DEFAULT_CHARSET
10 | Font.Color = clWindowText
11 | Font.Height = -11
12 | Font.Name = 'Tahoma'
13 | Font.Style = []
14 | KeyPreview = True
15 | OldCreateOrder = False
16 | OnCreate = FormCreate
17 | OnDestroy = FormDestroy
18 | OnKeyUp = FormKeyUp
19 | PixelsPerInch = 96
20 | TextHeight = 13
21 | object Label1: TLabel
22 | Left = 19
23 | Top = 15
24 | Width = 78
25 | Height = 13
26 | Alignment = taRightJustify
27 | Caption = '&Not in dictionary'
28 | FocusControl = Edit
29 | end
30 | object Label2: TLabel
31 | Left = 56
32 | Top = 46
33 | Width = 39
34 | Height = 13
35 | Alignment = taRightJustify
36 | Caption = 'Suggest'
37 | end
38 | object Edit: TEdit
39 | Left = 104
40 | Top = 13
41 | Width = 151
42 | Height = 21
43 | TabOrder = 0
44 | end
45 | object btnSkip: TButton
46 | Left = 280
47 | Top = 8
48 | Width = 73
49 | Height = 33
50 | Caption = '&Skip'
51 | TabOrder = 1
52 | OnClick = btnClick
53 | end
54 | object btnSkipAll: TButton
55 | Left = 360
56 | Top = 8
57 | Width = 73
58 | Height = 33
59 | Caption = 'Skip &All'
60 | TabOrder = 2
61 | OnClick = btnClick
62 | end
63 | object ListBox: TListBox
64 | Left = 104
65 | Top = 40
66 | Width = 153
67 | Height = 161
68 | ItemHeight = 13
69 | TabOrder = 3
70 | OnClick = ListBoxClick
71 | end
72 | object btnAddDictionary: TButton
73 | Left = 280
74 | Top = 56
75 | Width = 105
76 | Height = 33
77 | Caption = 'Add to &Dictionary'
78 | TabOrder = 4
79 | OnClick = btnClick
80 | end
81 | object btnReplace: TButton
82 | Left = 280
83 | Top = 104
84 | Width = 73
85 | Height = 33
86 | Caption = '&Replace'
87 | TabOrder = 5
88 | OnClick = btnClick
89 | end
90 | object btnReplaceAll: TButton
91 | Left = 360
92 | Top = 104
93 | Width = 73
94 | Height = 33
95 | Caption = 'Replace A&ll'
96 | TabOrder = 6
97 | OnClick = btnClick
98 | end
99 | object btnClose: TButton
100 | Left = 280
101 | Top = 168
102 | Width = 73
103 | Height = 33
104 | Caption = '&Close'
105 | Default = True
106 | TabOrder = 7
107 | OnClick = btnClick
108 | end
109 | end
110 |
--------------------------------------------------------------------------------
/ProjectVersionBackup.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning Backup form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectVersionBackup;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, Buttons, CheckLst, ProjectCommons;
31 |
32 | type
33 | TProjectVersionBackupForm = class(TForm)
34 | CheckListBox: TCheckListBox;
35 | Label1: TLabel;
36 | BtnSelected: TBitBtn;
37 | BtnAll: TBitBtn;
38 | BtnCancel: TBitBtn;
39 | procedure FormKeyDown(Sender: TObject; var Key: Word;
40 | Shift: TShiftState);
41 | procedure BtnAllClick(Sender: TObject);
42 | procedure BtnSelectedClick(Sender: TObject);
43 | procedure FormShow(Sender: TObject);
44 | private
45 | { Private declarations }
46 | public
47 | Selected: TIntegerDynArray;
48 | end;
49 |
50 | var
51 | ProjectVersionBackupForm: TProjectVersionBackupForm;
52 |
53 | implementation
54 |
55 | {$R *.dfm}
56 |
57 | procedure TProjectVersionBackupForm.FormKeyDown(Sender: TObject;
58 | var Key: Word; Shift: TShiftState);
59 | begin
60 | if byte(Shift)=0 then
61 | case Key of
62 | vk_F3: BtnSelected.Click;
63 | vk_F4: BtnAll.Click;
64 | end;
65 | end;
66 |
67 | procedure TProjectVersionBackupForm.BtnAllClick(Sender: TObject);
68 | var i: integer;
69 | begin
70 | SetLength(Selected,CheckListBox.Count);
71 | with CheckListBox.Items do
72 | for i := 0 to Count-1 do
73 | Selected[i] := integer(Objects[i]);
74 | end;
75 |
76 | procedure TProjectVersionBackupForm.BtnSelectedClick(Sender: TObject);
77 | var n,i: integer;
78 | begin
79 | SetLength(Selected,CheckListBox.Count);
80 | n := 0;
81 | with CheckListBox.Items do
82 | for i := 0 to Count-1 do
83 | if CheckListBox.Checked[i] then begin
84 | Selected[n] := integer(Objects[i]);
85 | inc(n);
86 | end;
87 | Setlength(Selected,n);
88 | end;
89 |
90 | procedure TProjectVersionBackupForm.FormShow(Sender: TObject);
91 | begin
92 | BtnSelected.SetFocus;
93 | end;
94 |
95 | end.
96 |
--------------------------------------------------------------------------------
/ProjectFrameRisk.pas:
--------------------------------------------------------------------------------
1 | /// Risk assessment setting visual frame
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectFrameRisk;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, ExtCtrls;
31 |
32 | type
33 | TFrameRisk = class(TFrame)
34 | GroupBoxRisk: TGroupBox;
35 | Label1: TLabel;
36 | Label2: TLabel;
37 | Label3: TLabel;
38 | ComboBox1: TComboBox;
39 | ComboBox2: TComboBox;
40 | ComboBox3: TComboBox;
41 | LabeledEditEvaluatedBy: TLabeledEdit;
42 | LabeledEditJustif: TLabeledEdit;
43 | procedure LabeledEditEvaluatedByKeyPress(Sender: TObject; var Key: Char);
44 | public
45 | constructor Create(AOwner: TComponent); override;
46 | procedure Init(const RiskValue: string);
47 | function Risk: string;
48 | end;
49 |
50 | implementation
51 |
52 | {$R *.dfm}
53 |
54 | uses
55 | ProjectTypes; // for RISKDEFS_ENGLISH[]
56 |
57 | { TFrameRisk }
58 |
59 | constructor TFrameRisk.Create(AOwner: TComponent);
60 | procedure One(const Risk: TRiskOneDef; L: TLabel; C: TComboBox);
61 | begin
62 | with Risk do begin
63 | L.Caption := Name;
64 | C.Hint := Name+': '+Description;
65 | with C.Items do begin
66 | Clear;
67 | Add('0 - Not evaluated');
68 | Add('1 - '+Level[1]);
69 | Add('2 - '+Level[2]);
70 | Add('3 - '+Level[3]);
71 | end;
72 | end;
73 | C.ShowHint := true;
74 | C.ItemIndex := 0;
75 | end;
76 | begin
77 | inherited;
78 | One(RISKDEFS[0],Label1,ComboBox1);
79 | One(RISKDEFS[1],Label2,ComboBox2);
80 | One(RISKDEFS[2],Label3,ComboBox3);
81 | end;
82 |
83 | procedure TFrameRisk.Init(const RiskValue: string);
84 | var R: TRisk;
85 | begin
86 | fillchar(R,sizeof(R),0);
87 | R.FromString(RiskValue);
88 | LabeledEditEvaluatedBy.Text := R.EvaluatedBy;
89 | LabeledEditJustif.Text := R.Comment;
90 | ComboBox1.ItemIndex := R.Risk[0];
91 | ComboBox2.ItemIndex := R.Risk[1];
92 | ComboBox3.ItemIndex := R.Risk[2];
93 | end;
94 |
95 | function TFrameRisk.Risk: string;
96 | begin
97 | result := format('%s,%s,%s,%s,%s',[
98 | ComboBox1.Text[1],ComboBox2.Text[1],ComboBox3.Text[1],
99 | trim(LabeledEditEvaluatedBy.Text),trim(LabeledEditJustif.Text)]);
100 | if result='0,0,0,,' then
101 | result := '';
102 | end;
103 |
104 | procedure TFrameRisk.LabeledEditEvaluatedByKeyPress(Sender: TObject; var Key: Char);
105 | begin
106 | if Key=',' then
107 | Key := '+';
108 | end;
109 |
110 | end.
111 |
112 |
--------------------------------------------------------------------------------
/ProjectEditorCommit.pas:
--------------------------------------------------------------------------------
1 | /// Commit parameters setting form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectEditorCommit;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, Buttons, ExtCtrls;
31 |
32 | type
33 | /// Commit parameters setting form
34 | TProjectEditorCommitForm = class(TForm)
35 | DisplayName: TLabeledEdit;
36 | Path: TLabeledEdit;
37 | BtnOK: TBitBtn;
38 | BtnCancel: TBitBtn;
39 | FilterDefault: TCheckBox;
40 | Filters: TLabeledEdit;
41 | BtnPath: TButton;
42 | procedure BtnPathClick(Sender: TObject);
43 | private
44 | FDefPath: string;
45 | public
46 | end;
47 |
48 | function EditorCommitForm(const Title, DefPath, FilterDefault: string; var Value: string): boolean;
49 |
50 |
51 | implementation
52 |
53 | uses
54 | ProjectCommons, ProjectRTF, ProjectFormDocWizard, ProjectVersioning;
55 |
56 | {$R *.dfm}
57 |
58 |
59 | function EditorCommitForm(const Title, DefPath, FilterDefault: string; var Value: string): boolean;
60 | // Value = 'Display Name;Path;Filter,Filter,..'
61 | var F: TProjectEditorCommitForm;
62 | P: PAnsiChar;
63 | v: string;
64 | begin
65 | F := TProjectEditorCommitForm.Create(Application);
66 | try
67 | F.FDefPath := IncludeTrailingPathDelimiter(SysUtils.UpperCase(trim(DefPath)));
68 | F.Caption := ' '+Title;
69 | P := pointer(Value);
70 | F.DisplayName.Text := GetNextItem(P,';');
71 | F.Path.Text := GetNextItem(P,';');
72 | F.FilterDefault.Caption := sCommitFilterDefault;
73 | F.FilterDefault.Hint := FilterDefault;
74 | v := P;
75 | F.FilterDefault.Checked := CSVDelete(v,'FilterDefault');
76 | F.Filters.Text := v;
77 | result := F.ShowModal=mrOk;
78 | if not result then
79 | exit;
80 | Value := trim(F.DisplayName.Text)+';'+trim(F.Path.Text)+';';
81 | v := trim(F.Filters.Text);
82 | if F.FilterDefault.Checked then
83 | if v='' then
84 | v := 'FilterDefault' else
85 | v := 'FilterDefault,'+v;
86 | Value := Value+v;
87 | finally
88 | F.Free;
89 | end;
90 | end;
91 |
92 | procedure TProjectEditorCommitForm.BtnPathClick(Sender: TObject);
93 | var Dir: string;
94 | begin
95 | Dir := Path.Text;
96 | if not DirectoryExists(Dir) and DirectoryExists(FDefPath+Dir) then
97 | Dir := FDefPath+Dir;
98 | if SelectDirectory(Handle,Path.EditLabel.Caption,Dir) then begin
99 | if IdemPChar(pointer(Dir),pointer(FDefPath)) then
100 | Delete(Dir,1,length(FDefPath));
101 | Path.Text := Dir;
102 | end;
103 | end;
104 |
105 | end.
106 |
--------------------------------------------------------------------------------
/PasDocLight/pasdoc_defines.inc:
--------------------------------------------------------------------------------
1 | {$define DONTUSEASPELL}
2 | {$define USEZIPCACHE}
3 | {$define DONTUSETAGS}
4 | // above directives are PasDocLight default
5 |
6 | {$IFDEF WIN32}
7 |
8 | {$IFDEF VER180}
9 | {$DEFINE DELPHI_10}
10 | {$DEFINE DELPHI_10_UP}
11 | {$DEFINE DELPHI_9_UP}
12 | {$DEFINE DELPHI_7_UP}
13 | {$DEFINE DELPHI_6_UP}
14 | {$DEFINE DELPHI_5_UP}
15 | {$DEFINE DELPHI_4_UP}
16 | {$DEFINE DELPHI_3_UP}
17 | {$DEFINE DELPHI_2_UP}
18 | {$DEFINE DELPHI_1_UP}
19 |
20 | {$DEFINE COMPILER_10}
21 | {$DEFINE COMPILER_10_UP}
22 | {$DEFINE COMPILER_9_UP}
23 | {$DEFINE COMPILER_7_UP}
24 | {$DEFINE COMPILER_6_UP}
25 | {$DEFINE COMPILER_5_UP}
26 | {$DEFINE COMPILER_4_UP}
27 | {$DEFINE COMPILER_3_UP}
28 | {$DEFINE COMPILER_2_UP}
29 | {$DEFINE COMPILER_1_UP}
30 | {$ENDIF}
31 |
32 | {$IFDEF VER170}
33 | {$DEFINE DELPHI_9}
34 | {$DEFINE DELPHI_9_UP}
35 | {$DEFINE DELPHI_7_UP}
36 | {$DEFINE DELPHI_6_UP}
37 | {$DEFINE DELPHI_5_UP}
38 | {$DEFINE DELPHI_4_UP}
39 | {$DEFINE DELPHI_3_UP}
40 | {$DEFINE DELPHI_2_UP}
41 | {$DEFINE DELPHI_1_UP}
42 |
43 | {$DEFINE COMPILER_9}
44 | {$DEFINE COMPILER_9_UP}
45 | {$DEFINE COMPILER_7_UP}
46 | {$DEFINE COMPILER_6_UP}
47 | {$DEFINE COMPILER_5_UP}
48 | {$DEFINE COMPILER_4_UP}
49 | {$DEFINE COMPILER_3_UP}
50 | {$DEFINE COMPILER_2_UP}
51 | {$DEFINE COMPILER_1_UP}
52 | {$ENDIF}
53 |
54 | {$IFDEF VER150}
55 | {$DEFINE DELPHI_7}
56 | {$DEFINE DELPHI_7_UP}
57 | {$DEFINE DELPHI_6_UP}
58 | {$DEFINE DELPHI_5_UP}
59 | {$DEFINE DELPHI_4_UP}
60 | {$DEFINE DELPHI_3_UP}
61 | {$DEFINE DELPHI_2_UP}
62 | {$DEFINE DELPHI_1_UP}
63 |
64 | {$DEFINE COMPILER_7}
65 | {$DEFINE COMPILER_7_UP}
66 | {$DEFINE COMPILER_6_UP}
67 | {$DEFINE COMPILER_5_UP}
68 | {$DEFINE COMPILER_4_UP}
69 | {$DEFINE COMPILER_3_UP}
70 | {$DEFINE COMPILER_2_UP}
71 | {$DEFINE COMPILER_1_UP}
72 | {$ENDIF}
73 |
74 | {$IFDEF VER140}
75 | {$DEFINE DELPHI_6}
76 | {$DEFINE DELPHI_6_UP}
77 | {$DEFINE DELPHI_5_UP}
78 | {$DEFINE DELPHI_4_UP}
79 | {$DEFINE DELPHI_3_UP}
80 | {$DEFINE DELPHI_2_UP}
81 | {$DEFINE DELPHI_1_UP}
82 |
83 | {$DEFINE COMPILER_6}
84 | {$DEFINE COMPILER_6_UP}
85 | {$DEFINE COMPILER_5_UP}
86 | {$DEFINE COMPILER_4_UP}
87 | {$DEFINE COMPILER_3_UP}
88 | {$DEFINE COMPILER_2_UP}
89 | {$DEFINE COMPILER_1_UP}
90 | {$ENDIF}
91 |
92 | {$IFDEF VER130}
93 | {$DEFINE DELPHI_5}
94 | {$DEFINE DELPHI_5_UP}
95 | {$DEFINE DELPHI_4_UP}
96 | {$DEFINE DELPHI_3_UP}
97 | {$DEFINE DELPHI_2_UP}
98 | {$DEFINE DELPHI_1_UP}
99 |
100 | {$DEFINE COMPILER_5}
101 | {$DEFINE COMPILER_5_UP}
102 | {$DEFINE COMPILER_4_UP}
103 | {$DEFINE COMPILER_3_UP}
104 | {$DEFINE COMPILER_2_UP}
105 | {$DEFINE COMPILER_1_UP}
106 | {$ENDIF}
107 |
108 | {$IFDEF VER120}
109 | {$DEFINE DELPHI_4}
110 | {$DEFINE DELPHI_4_UP}
111 | {$DEFINE DELPHI_3_UP}
112 | {$DEFINE DELPHI_2_UP}
113 | {$DEFINE DELPHI_1_UP}
114 |
115 | {$DEFINE COMPILER_4}
116 | {$DEFINE COMPILER_4_UP}
117 | {$DEFINE COMPILER_3_UP}
118 | {$DEFINE COMPILER_2_UP}
119 | {$DEFINE COMPILER_1_UP}
120 | {$ENDIF}
121 |
122 | {$IFDEF VER100}
123 | {$DEFINE DELPHI_3}
124 | {$DEFINE DELPHI_3_UP}
125 | {$DEFINE DELPHI_2_UP}
126 | {$DEFINE DELPHI_1_UP}
127 |
128 | {$DEFINE COMPILER_3}
129 | {$DEFINE COMPILER_3_UP}
130 | {$DEFINE COMPILER_2_UP}
131 | {$DEFINE COMPILER_1_UP}
132 | {$ENDIF}
133 |
134 | {$IFDEF VER90}
135 | {$DEFINE DELPHI_2}
136 | {$DEFINE DELPHI_2_UP}
137 | {$DEFINE DELPHI_1_UP}
138 |
139 | {$DEFINE COMPILER_2}
140 | {$DEFINE COMPILER_2_UP}
141 | {$DEFINE COMPILER_1_UP}
142 | {$ENDIF}
143 |
144 | {$IFDEF VER80}
145 | {$DEFINE DELPHI_1}
146 | {$DEFINE DELPHI_1_UP}
147 |
148 | {$DEFINE COMPILER_1}
149 | {$DEFINE COMPILER_1_UP}
150 | {$ENDIF}
151 |
152 | {$IFNDEF MSWINDOWS}
153 | {$DEFINE MSWINDOWS}
154 | {$ENDIF}
155 |
156 | {$ENDIF} // WIN32
157 |
158 | {$IFNDEF FPC}
159 | {$IFDEF LINUX}
160 | {$I pasdoc_kylixversions.inc}
161 | {$ENDIF}
162 | {$ELSE}
163 | {$ENDIF}
164 |
165 | {$IFDEF DELPHI_7_UP}
166 | {$WARN UNSAFE_CAST OFF}
167 | {$WARN UNSAFE_CODE OFF}
168 | {$WARN UNSAFE_TYPE OFF}
169 | {$ENDIF}
170 | (* Disables .NET warnings for Delphi 7 and later. *)
171 |
172 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SynProject
2 | ==========
3 |
4 | *Synopse SynProject* is an open source application for code source versioning and automated documentation of Delphi projects.
5 |
6 | Licensed under a GPL license.
7 |
8 | [Take a look at the SynProject official web site](http://synopse.info/fossil/wiki?name=SynProject)
9 |
10 |
11 |
12 | Features
13 | ========
14 |
15 | Its main features are:
16 |
17 | 1. Local source code versioning;
18 | 2. Automated documentation.
19 |
20 |
21 | Source code versioning
22 | ----------------------
23 |
24 | * handle multiple projects or libraries with the same program;
25 | * allow source code versioning with detailed commits;
26 | * can access to a PVCS tracker (more trackers are coming) and link the commits to the tickets;
27 | * allow automated source code backup (without any commit to document: it's like a daily snapshot of your files);
28 | * backups can be local (on your hard drive) or remote (on a distant drive);
29 | * you can make a visual "diff" and compare source code versions side by side in the graphical user interface;
30 | * you can see pictures (png jpeg bitmap icon) within the main user interface;
31 | * diff storage between version is very optimized, and use little disk space;
32 | * storage is based on .zip files and plain text files, so it's easy to work with.
33 |
34 | Automated Documentation
35 | -----------------------
36 |
37 | * follow a typical Design Inputs -> Risk Assessment -> Software Architecture -> Detailed Design -> Tests protocols -> Traceability matrix -> Release Notes workflow;
38 | * initial (marketing-level) Design Input can be refined into more precise Software Requirement Specifications;
39 | * Design Inputs can evolve during the project life: all documentation stay synchronized and you will have to maintain the DI and their description only at one place;
40 | * therefore, the process is meant to be compliant with the most precise documentation protocols (like IEC 62304);
41 | only one text file, formated like a wiki, contains the whole documentation;
42 | * it's very easy to add pictures, or formated source code (pascal, C, C++, C#, plain text) into the documentation;
43 | * word files (and then pdf) are created from this content, with full table of contents, picture or source code reference tables, unified page layout, customizable templates;
44 | * it's easy to add tables to your document, or link to other part or external resources * you can even put pure RTF content into your documentation;
45 | * pictures are centralized and captioned, people involved in the documentation are maintained once for the whole documentation;
46 | * document version numbering and cross-referencing is handled easily;
47 | * for pascal projects, the source code is parsed and all interface architecture is generated from the source;
48 | it's easy to browse classes, variables and functions from the documentation, and add reference to them to your document;
49 | the source code description can also be located in an external .sae file, therefore your original source code tree won't necessary be changed by the adding of comments;
50 | * all references are cross-linked: Software Architecture Document is created from the source code, and also is able to highlight the classes or methods - involved in implementing every Design Input, from the Software Design Document;
51 | * integrated GraphViz component, in order to create easily diagrams from plain text embedded into your documentation; * integrated fully featured text editor, with word wrapping, wiki-syntax buttons and keyboard shortcuts, and spell checking;
52 | * a step by step Wizard is available to create a new project, from supplied template files;
53 | another Wizard is already available, to browse your documentation workflow, and check its consistency or set up its parameters;
54 | * the documentation is integrated to the Versioning system above.
55 |
56 | Of course, it's a full Open Source - GPL licensed - project. Source code (for Delphi 6/7) is available and maintained, since it is used by our internal projects (including our little [mORMot](http://mormot.net)).
--------------------------------------------------------------------------------
/ProjectEditorCommit.dfm:
--------------------------------------------------------------------------------
1 | object ProjectEditorCommitForm: TProjectEditorCommitForm
2 | Left = 434
3 | Top = 388
4 | BorderStyle = bsDialog
5 | ClientHeight = 300
6 | ClientWidth = 459
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | PixelsPerInch = 96
15 | TextHeight = 13
16 | object DisplayName: TLabeledEdit
17 | Left = 56
18 | Top = 40
19 | Width = 353
20 | Height = 21
21 | EditLabel.Width = 68
22 | EditLabel.Height = 13
23 | EditLabel.Caption = 'Display Name:'
24 | TabOrder = 0
25 | end
26 | object Path: TLabeledEdit
27 | Left = 56
28 | Top = 88
29 | Width = 321
30 | Height = 21
31 | EditLabel.Width = 85
32 | EditLabel.Height = 13
33 | EditLabel.Caption = 'Path to search in:'
34 | TabOrder = 1
35 | end
36 | object BtnOK: TBitBtn
37 | Left = 152
38 | Top = 232
39 | Width = 105
40 | Height = 33
41 | Caption = 'OK'
42 | Default = True
43 | ModalResult = 1
44 | TabOrder = 5
45 | Glyph.Data = {
46 | 96010000424D9601000000000000760000002800000018000000180000000100
47 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
48 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
49 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
50 | 9999999999999999999999999999999999999999999999999999999999999999
51 | 9999999999999999999999999999099999999999999999999990F09999999999
52 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
53 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
54 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
55 | 9999999909999999999017099999999999999999999990A09999999999999999
56 | 9999990109999999999999999999999900999999999999999999999999099999
57 | 9999999999999999999999999999999999999999999999999999999999999999
58 | 9999999999999999999999999999999999999999999999999999}
59 | end
60 | object BtnCancel: TBitBtn
61 | Left = 304
62 | Top = 232
63 | Width = 105
64 | Height = 33
65 | Cancel = True
66 | Caption = 'Cancel'
67 | ModalResult = 2
68 | TabOrder = 6
69 | Glyph.Data = {
70 | 96010000424D9601000000000000760000002800000018000000180000000100
71 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
72 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
73 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
74 | 1111111111111111111111111111111111111111111111111111111111111111
75 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
76 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
77 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
78 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
79 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
80 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
81 | 09D0111111110C40111111111001111111111001111111111111111111111111
82 | 1111111111111111111111111111111111111111111111111111}
83 | end
84 | object FilterDefault: TCheckBox
85 | Left = 56
86 | Top = 120
87 | Width = 353
88 | Height = 17
89 | ParentShowHint = False
90 | ShowHint = True
91 | TabOrder = 3
92 | WordWrap = True
93 | end
94 | object Filters: TLabeledEdit
95 | Left = 56
96 | Top = 168
97 | Width = 353
98 | Height = 21
99 | EditLabel.Width = 275
100 | EditLabel.Height = 13
101 | EditLabel.Caption = 'Additionnal Filters separated by "," ("*.doc,*.rtf,*.emf"):'
102 | TabOrder = 4
103 | end
104 | object BtnPath: TButton
105 | Left = 384
106 | Top = 88
107 | Width = 25
108 | Height = 21
109 | Caption = '...'
110 | TabOrder = 2
111 | OnClick = BtnPathClick
112 | end
113 | end
114 |
--------------------------------------------------------------------------------
/ProjectEditorProgram.dfm:
--------------------------------------------------------------------------------
1 | object ProjectEditorProgramForm: TProjectEditorProgramForm
2 | Left = 47
3 | Top = 204
4 | Width = 903
5 | Height = 450
6 | Caption = ' SynProject - Integrated Reference Class Browser'
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | Position = poScreenCenter
15 | PixelsPerInch = 96
16 | TextHeight = 13
17 | object Panel1: TPanel
18 | Left = 0
19 | Top = 0
20 | Width = 895
21 | Height = 41
22 | Align = alTop
23 | TabOrder = 0
24 | DesignSize = (
25 | 895
26 | 41)
27 | object lUnitName: TLabel
28 | Left = 230
29 | Top = 13
30 | Width = 53
31 | Height = 13
32 | Alignment = taRightJustify
33 | Caption = 'Unit Name:'
34 | end
35 | object lSADSection: TLabel
36 | Left = 29
37 | Top = 13
38 | Width = 62
39 | Height = 13
40 | Alignment = taRightJustify
41 | Caption = 'SAD Section:'
42 | end
43 | object cbUnitName: TComboBox
44 | Left = 287
45 | Top = 10
46 | Width = 170
47 | Height = 21
48 | Style = csDropDownList
49 | DropDownCount = 32
50 | ItemHeight = 13
51 | TabOrder = 0
52 | OnChange = cbUnitNameChange
53 | end
54 | object btnOk: TButton
55 | Left = 713
56 | Top = 8
57 | Width = 74
58 | Height = 25
59 | Anchors = [akTop, akRight]
60 | Caption = 'Save'
61 | ModalResult = 1
62 | TabOrder = 1
63 | end
64 | object btnCancel: TButton
65 | Left = 809
66 | Top = 8
67 | Width = 74
68 | Height = 25
69 | Anchors = [akTop, akRight]
70 | Cancel = True
71 | Caption = 'Cancel'
72 | ModalResult = 2
73 | TabOrder = 2
74 | end
75 | object cbSADSection: TComboBox
76 | Left = 96
77 | Top = 10
78 | Width = 113
79 | Height = 21
80 | Style = csDropDownList
81 | ItemHeight = 13
82 | TabOrder = 3
83 | OnChange = cbSADSectionChange
84 | end
85 | object leUnitDescription: TLabeledEdit
86 | Left = 552
87 | Top = 10
88 | Width = 148
89 | Height = 21
90 | Anchors = [akLeft, akTop, akRight]
91 | EditLabel.Width = 79
92 | EditLabel.Height = 13
93 | EditLabel.Caption = 'Unit Description:'
94 | LabelPosition = lpLeft
95 | LabelSpacing = 3
96 | TabOrder = 4
97 | OnExit = leUnitDescriptionExit
98 | end
99 | end
100 | object pagTypes: TPageControl
101 | Left = 0
102 | Top = 41
103 | Width = 710
104 | Height = 375
105 | Align = alClient
106 | TabOrder = 1
107 | end
108 | object PanelRight: TPanel
109 | Left = 710
110 | Top = 41
111 | Width = 185
112 | Height = 375
113 | Align = alRight
114 | TabOrder = 2
115 | DesignSize = (
116 | 185
117 | 375)
118 | object l1: TLabel
119 | Left = 8
120 | Top = 328
121 | Width = 166
122 | Height = 13
123 | Anchors = [akLeft, akBottom]
124 | Caption = 'Double-click any left item to add it.'
125 | end
126 | object lstValues: TListBox
127 | Left = 1
128 | Top = 1
129 | Width = 183
130 | Height = 320
131 | Align = alTop
132 | Anchors = [akLeft, akTop, akRight, akBottom]
133 | ItemHeight = 13
134 | TabOrder = 0
135 | OnClick = lstValuesClick
136 | end
137 | object btnDeleteItem: TButton
138 | Left = 8
139 | Top = 344
140 | Width = 75
141 | Height = 25
142 | Anchors = [akLeft, akBottom]
143 | Caption = 'Delete item'
144 | TabOrder = 1
145 | OnClick = btnDeleteItemClick
146 | end
147 | object btnClearList: TButton
148 | Left = 88
149 | Top = 344
150 | Width = 75
151 | Height = 25
152 | Anchors = [akLeft, akBottom]
153 | Caption = 'Clear list'
154 | TabOrder = 2
155 | OnClick = btnClearListClick
156 | end
157 | end
158 | end
159 |
--------------------------------------------------------------------------------
/SynProject.dpr:
--------------------------------------------------------------------------------
1 | /// main SynProject program file
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.13
3 | program SynProject;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2016 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 |
25 | Compilation hint:
26 | - tested under Delphi 6/7 ONLY - should work with Delphi 2007, but would
27 | NOT work with Delphi 2009/2010/XE (this source code is not Unicode-Ready)
28 | - you should have entered .\PasDocLight in your Project/Options/Directories
29 | SearchPath field
30 | - you should have added the TMemoEx component (from SynMemoEx.pas) to the IDE
31 | - and of course, the synopse Lib directory must be in your Tools/Environment
32 | Options/Libray/Library Path
33 |
34 | *)
35 |
36 | uses
37 | FastMM4,
38 | Forms,
39 | ProjectVersionMain in 'ProjectVersionMain.pas' {MainForm},
40 | ProjectVersioning in 'ProjectVersioning.pas',
41 | ProjectSections in 'ProjectSections.pas',
42 | ProjectVersionPages in 'ProjectVersionPages.pas' {FramePages: TFrame},
43 | ProjectFrameViewer in 'ProjectFrameViewer.pas' {FrameViewer: TFrame},
44 | ProjectMemoExSyntax in 'ProjectMemoExSyntax.pas',
45 | ProjectFormViewOne in 'ProjectFormViewOne.pas' {FormViewOne},
46 | ProjectFormViewTwo in 'ProjectFormViewTwo.pas' {FormViewTwo},
47 | ProjectEditor in 'ProjectEditor.pas' {FrameEditor: TFrame},
48 | ProjectVersionSCR in 'ProjectVersionSCR.pas' {ProjectVersionSCRForm},
49 | ProjectVersionBackup in 'ProjectVersionBackup.pas' {ProjectVersionBackupForm},
50 | ProjectFrameRisk in 'ProjectFrameRisk.pas' {FrameRisk: TFrame},
51 | ProjectVersionCommit in 'ProjectVersionCommit.pas' {ProjectVersionCommitForm},
52 | ProjectEditMain in 'ProjectEditMain.pas' {ProMainForm},
53 | ProjectVersionCompare in 'ProjectVersionCompare.pas' {ProjectVersionCompareForm},
54 | ProjectFormDocWizard in 'ProjectFormDocWizard.pas' {ProjectDocWizard},
55 | ProjectEditorRelease in 'ProjectEditorRelease.pas' {ProjectEditorReleaseForm},
56 | ProjectTypes in 'ProjectTypes.pas',
57 | ProjectTrackerLogin in 'ProjectTrackerLogin.pas' {ProjectTrackerLoginForm},
58 | ProjectEditorCommit in 'ProjectEditorCommit.pas' {ProjectEditorCommitForm},
59 | ProjectGraphEdit in 'ProjectGraphEdit.pas' {GraphEditForm},
60 | ProjectSpellCheck in 'ProjectSpellCheck.pas' {SpellCheckForm},
61 | ProjectEditorProgram in 'ProjectEditorProgram.pas' {ProjectEditorProgramForm},
62 | ProjectCommons in 'ProjectCommons.pas',
63 | ProjectDiff in 'ProjectDiff.pas',
64 | ProjectDiffUnit in 'ProjectDiffUnit.pas',
65 | ProjectParser in 'ProjectParser.pas',
66 | ProjectRTF in 'ProjectRTF.pas',
67 | ProjectTrkTool in 'ProjectTrkTool.pas',
68 | ProjectFormSelection in 'ProjectFormSelection.pas' {SelectionForm},
69 | ProjectDiagrams in 'ProjectDiagrams.pas';
70 |
71 | {$R *.res}
72 | {$R Vista.res}
73 |
74 | begin
75 | Application.Initialize;
76 | Application.CreateForm(TMainForm, MainForm);
77 | Application.CreateForm(TFormViewOne, FormViewOne);
78 | Application.CreateForm(TFormViewTwo, FormViewTwo);
79 | Application.CreateForm(TProjectVersionSCRForm, ProjectVersionSCRForm);
80 | Application.CreateForm(TProjectVersionBackupForm, ProjectVersionBackupForm);
81 | Application.CreateForm(TProjectVersionCommitForm, ProjectVersionCommitForm);
82 | Application.CreateForm(TProMainForm, ProMainForm);
83 | Application.CreateForm(TProjectVersionCompareForm, ProjectVersionCompareForm);
84 | Application.CreateForm(TProjectDocWizard, ProjectDocWizard);
85 | Application.CreateForm(TProjectTrackerLoginForm, ProjectTrackerLoginForm);
86 | Application.Run;
87 | end.
88 |
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_StringPairVector.pas:
--------------------------------------------------------------------------------
1 | unit PasDoc_StringPairVector;
2 |
3 | interface
4 |
5 | uses
6 | Classes,
7 | PasDoc_ObjectVector;
8 |
9 | type
10 | TStringPair = class
11 | Name: string;
12 | Value: string;
13 | Data: Pointer;
14 |
15 | { Init Name and Value by @link(ExtractFirstWord) from S. }
16 | constructor CreateExtractFirstWord(const S: string);
17 |
18 | constructor Create(const AName, AValue: string; AData: Pointer = nil);
19 | end;
20 |
21 | { This is a list of string pairs.
22 | This class contains only non-nil objects of class TStringPair.
23 |
24 | Using this class instead of TStringList (with it's Name and Value
25 | properties) is often better, because this allows both Name and Value
26 | of each pair to safely contain any special characters (including '='
27 | and newline markers). It's also faster, since it doesn't try to
28 | encode Name and Value into one string. }
29 | TStringPairVector = class(TObjectVector)
30 | private
31 | function GetItems(i: Integer): TStringPair;
32 | procedure SetItems(i: Integer; Item: TStringPair);
33 | public
34 | property Items[i: Integer]: TStringPair read GetItems write SetItems; default;
35 |
36 | { Returns all items Names and Values glued together.
37 | For every item, string Name + NameValueSepapator + Value is
38 | constructed. Then all such strings for every items all
39 | concatenated with ItemSeparator.
40 |
41 | Remember that the very idea of @link(TStringPair) and
42 | @link(TStringPairVector) is that Name and Value strings
43 | may contain any special characters, including things you
44 | give here as NameValueSepapator and ItemSeparator.
45 | So it's practically impossible to later convert such Text
46 | back to items and Names/Value pairs. }
47 | function Text(const NameValueSepapator, ItemSeparator: string): string;
48 |
49 | { Finds a string pair with given Name.
50 | Returns -1 if not found. }
51 | function FindName(const Name: string; IgnoreCase: boolean = true): Integer;
52 |
53 | { Removes first string pair with given Name.
54 | Returns if some pair was removed. }
55 | function DeleteName(const Name: string; IgnoreCase: boolean = true): boolean;
56 | end;
57 |
58 | implementation
59 |
60 | uses
61 | SysUtils,
62 | PasDoc_Utils;
63 |
64 | { TStringPair ---------------------------------------------------------------- }
65 |
66 | constructor TStringPair.CreateExtractFirstWord(const S: string);
67 | var
68 | FirstWord, Rest: string;
69 | begin
70 | ExtractFirstWord(S, FirstWord, Rest);
71 | Create(FirstWord, Rest);
72 | end;
73 |
74 | constructor TStringPair.Create(const AName, AValue: string; AData: Pointer);
75 | begin
76 | inherited Create;
77 | Name := AName;
78 | Value := AValue;
79 | Data := AData;
80 | end;
81 |
82 | { TStringPairVector ---------------------------------------------------------- }
83 |
84 | function TStringPairVector.GetItems(i: Integer): TStringPair;
85 | begin
86 | Result := TStringPair(inherited Items[i]);
87 | end;
88 |
89 | procedure TStringPairVector.SetItems(i: Integer; Item: TStringPair);
90 | begin
91 | inherited Items[i] := Item;
92 | end;
93 |
94 | function TStringPairVector.Text(
95 | const NameValueSepapator, ItemSeparator: string): string;
96 | var
97 | i: Integer;
98 | begin
99 | if Count > 0 then
100 | begin
101 | Result := Items[0].Name + NameValueSepapator + Items[0].Value;
102 | for i := 1 to Count - 1 do
103 | Result := Result + ItemSeparator +
104 | Items[i].Name + NameValueSepapator + Items[i].Value;
105 | end;
106 | end;
107 |
108 | function TStringPairVector.FindName(const Name: string; IgnoreCase: boolean): Integer;
109 | begin
110 | if IgnoreCase then
111 | begin
112 | for Result := 0 to Count - 1 do
113 | if SameText(Items[Result].Name, Name) then
114 | Exit;
115 | Result := -1;
116 | end else
117 | begin
118 | for Result := 0 to Count - 1 do
119 | if Items[Result].Name = Name then
120 | Exit;
121 | Result := -1;
122 | end;
123 | end;
124 |
125 | function TStringPairVector.DeleteName(const Name: string;
126 | IgnoreCase: boolean): boolean;
127 | var
128 | i: Integer;
129 | begin
130 | i := FindName(Name, IgnoreCase);
131 | Result := i <> -1;
132 | if Result then
133 | Delete(i);
134 | end;
135 |
136 | end.
137 |
--------------------------------------------------------------------------------
/ProjectVersionBackup.dfm:
--------------------------------------------------------------------------------
1 | object ProjectVersionBackupForm: TProjectVersionBackupForm
2 | Left = 639
3 | Top = 349
4 | BorderStyle = bsDialog
5 | ClientHeight = 314
6 | ClientWidth = 434
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | KeyPreview = True
14 | OldCreateOrder = False
15 | Position = poScreenCenter
16 | OnKeyDown = FormKeyDown
17 | OnShow = FormShow
18 | PixelsPerInch = 96
19 | TextHeight = 13
20 | object Label1: TLabel
21 | Left = 56
22 | Top = 24
23 | Width = 175
24 | Height = 13
25 | Caption = 'Select the backups to be performed:'
26 | end
27 | object CheckListBox: TCheckListBox
28 | Left = 48
29 | Top = 40
30 | Width = 329
31 | Height = 153
32 | ItemHeight = 13
33 | TabOrder = 0
34 | end
35 | object BtnSelected: TBitBtn
36 | Left = 56
37 | Top = 208
38 | Width = 161
39 | Height = 33
40 | Caption = 'Backup selected (Enter)'
41 | Default = True
42 | ModalResult = 1
43 | TabOrder = 1
44 | OnClick = BtnSelectedClick
45 | Glyph.Data = {
46 | 96010000424D9601000000000000760000002800000018000000180000000100
47 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
48 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
49 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
50 | 9999999999999999999999999999999999999999999999999999999999999999
51 | 9999999999999999999999999999099999999999999999999990F09999999999
52 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
53 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
54 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
55 | 9999999909999999999017099999999999999999999990A09999999999999999
56 | 9999990109999999999999999999999900999999999999999999999999099999
57 | 9999999999999999999999999999999999999999999999999999999999999999
58 | 9999999999999999999999999999999999999999999999999999}
59 | end
60 | object BtnAll: TBitBtn
61 | Left = 56
62 | Top = 248
63 | Width = 161
64 | Height = 33
65 | Caption = 'Backup all (F4)'
66 | ModalResult = 8
67 | TabOrder = 2
68 | OnClick = BtnAllClick
69 | Glyph.Data = {
70 | 96010000424D9601000000000000760000002800000018000000180000000100
71 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
72 | 1000D67F7F0024B43C0048D36F00FC02FC001F9B3100B53F3D00CC676800DD99
73 | 99002FC54F0059E3890037BA5400178F24001CAC2F00C4545400555555555555
74 | 5555555555555555555555555555555555555555555550555555555555555555
75 | 5555060555555555555555555550EE305555555555555555550E3EE305555555
76 | 55555555506A33EE3055555555555555064AAE03E305555555555550D4443050
77 | EE30555555555550BBBC07550DEE055555555550CBC08875550EE05555555557
78 | 040888875550EE055555557820287888755501E0555557F9922757888755550D
79 | 055557999275557F887555501055572927555555788755555005557975555555
80 | 578875555550555755555555557F8755555555555555555555557F7555555555
81 | 5555555555555777555555555555555555555557755555555555555555555555
82 | 5755555555555555555555555555555555555555555555555555}
83 | end
84 | object BtnCancel: TBitBtn
85 | Left = 240
86 | Top = 248
87 | Width = 129
88 | Height = 33
89 | Cancel = True
90 | Caption = 'Cancel'
91 | ModalResult = 2
92 | TabOrder = 3
93 | Glyph.Data = {
94 | 96010000424D9601000000000000760000002800000018000000180000000100
95 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
96 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
97 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
98 | 1111111111111111111111111111111111111111111111111111111111111111
99 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
100 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
101 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
102 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
103 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
104 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
105 | 09D0111111110C40111111111001111111111001111111111111111111111111
106 | 1111111111111111111111111111111111111111111111111111}
107 | end
108 | end
109 |
--------------------------------------------------------------------------------
/ProjectGraphEdit.dfm:
--------------------------------------------------------------------------------
1 | object GraphEditForm: TGraphEditForm
2 | Left = 278
3 | Top = 260
4 | BorderStyle = bsSingle
5 | ClientHeight = 490
6 | ClientWidth = 781
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | KeyPreview = True
14 | OldCreateOrder = False
15 | OnCloseQuery = FormCloseQuery
16 | OnDestroy = FormDestroy
17 | OnKeyUp = FormKeyUp
18 | OnShow = FormShow
19 | PixelsPerInch = 96
20 | TextHeight = 13
21 | object Image: TImage
22 | Left = 323
23 | Top = 0
24 | Width = 458
25 | Height = 490
26 | Align = alClient
27 | Proportional = True
28 | end
29 | object Splitter1: TSplitter
30 | Left = 321
31 | Top = 0
32 | Width = 2
33 | Height = 490
34 | end
35 | object Panel1: TPanel
36 | Left = 0
37 | Top = 0
38 | Width = 321
39 | Height = 490
40 | Align = alLeft
41 | TabOrder = 0
42 | DesignSize = (
43 | 321
44 | 490)
45 | object Label1: TLabel
46 | Left = 24
47 | Top = 42
48 | Width = 20
49 | Height = 13
50 | Alignment = taRightJustify
51 | Caption = 'Title'
52 | end
53 | object Label2: TLabel
54 | Left = 19
55 | Top = 12
56 | Width = 27
57 | Height = 13
58 | Alignment = taRightJustify
59 | Caption = 'Name'
60 | end
61 | object Label3: TLabel
62 | Left = 8
63 | Top = 392
64 | Width = 297
65 | Height = 54
66 | Anchors = [akLeft, akBottom]
67 | AutoSize = False
68 | Font.Charset = DEFAULT_CHARSET
69 | Font.Color = clWindowText
70 | Font.Height = -11
71 | Font.Name = 'Tahoma'
72 | Font.Style = []
73 | ParentFont = False
74 | WordWrap = True
75 | end
76 | object Tree: TTreeView
77 | Left = 8
78 | Top = 72
79 | Width = 305
80 | Height = 313
81 | Anchors = [akLeft, akTop, akRight, akBottom]
82 | Indent = 19
83 | MultiSelect = True
84 | MultiSelectStyle = [msControlSelect, msShiftSelect]
85 | ReadOnly = True
86 | TabOrder = 7
87 | Visible = False
88 | OnClick = TreeClick
89 | end
90 | object EditName: TEdit
91 | Left = 48
92 | Top = 8
93 | Width = 201
94 | Height = 21
95 | Anchors = [akLeft, akTop, akRight]
96 | TabOrder = 0
97 | end
98 | object EditTitle: TEdit
99 | Left = 48
100 | Top = 40
101 | Width = 265
102 | Height = 21
103 | Anchors = [akLeft, akTop, akRight]
104 | TabOrder = 1
105 | end
106 | object Source: TMemo
107 | Left = 8
108 | Top = 72
109 | Width = 305
110 | Height = 313
111 | Anchors = [akLeft, akTop, akRight, akBottom]
112 | ScrollBars = ssBoth
113 | TabOrder = 2
114 | WordWrap = False
115 | end
116 | object btnSave: TButton
117 | Left = 16
118 | Top = 453
119 | Width = 97
120 | Height = 25
121 | Anchors = [akLeft, akBottom]
122 | Caption = 'Save'
123 | Font.Charset = DEFAULT_CHARSET
124 | Font.Color = clWindowText
125 | Font.Height = -12
126 | Font.Name = 'Tahoma'
127 | Font.Style = [fsBold]
128 | ModalResult = 1
129 | ParentFont = False
130 | TabOrder = 3
131 | end
132 | object btnClose: TButton
133 | Left = 128
134 | Top = 453
135 | Width = 89
136 | Height = 25
137 | Anchors = [akLeft, akBottom]
138 | Caption = 'Close'
139 | ModalResult = 2
140 | TabOrder = 4
141 | end
142 | object btnRefresh: TButton
143 | Left = 232
144 | Top = 453
145 | Width = 73
146 | Height = 25
147 | Anchors = [akLeft, akBottom]
148 | Caption = 'Refresh F9'
149 | TabOrder = 5
150 | OnClick = btnRefreshClick
151 | end
152 | object btnFromCode: TButton
153 | Left = 256
154 | Top = 6
155 | Width = 59
156 | Height = 25
157 | Anchors = [akTop, akRight]
158 | Caption = 'From code'
159 | TabOrder = 6
160 | OnClick = btnFromCodeClick
161 | end
162 | end
163 | object PopupMenuFromCode: TPopupMenu
164 | TrackButton = tbLeftButton
165 | Left = 272
166 | Top = 32
167 | object FromCodeObjectHierarchyHide: TMenuItem
168 | Caption = 'Hide'
169 | OnClick = FromCodeClick
170 | end
171 | object N1: TMenuItem
172 | Caption = '-'
173 | end
174 | object FromCodeObjecthierarchy: TMenuItem
175 | Caption = 'Object hierarchy'
176 | end
177 | object FromCodeSQLRecord: TMenuItem
178 | Caption = 'TSQLRecord'
179 | end
180 | end
181 | end
182 |
--------------------------------------------------------------------------------
/ProjectFormSelection.pas:
--------------------------------------------------------------------------------
1 | unit ProjectFormSelection;
2 |
3 | interface
4 |
5 | uses
6 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 | Dialogs, StdCtrls, ExtCtrls;
8 |
9 | type
10 | TSelectionForm = class(TForm)
11 | List: TListBox;
12 | pnlTop: TPanel;
13 | edtFind: TEdit;
14 | btnNext: TButton;
15 | procedure ListDblClick(Sender: TObject);
16 | procedure FormCreate(Sender: TObject);
17 | procedure FormDestroy(Sender: TObject);
18 | procedure FormShow(Sender: TObject);
19 | procedure FormKeyDown(Sender: TObject; var Key: Word;
20 | Shift: TShiftState);
21 | procedure edtFindChange(Sender: TObject);
22 | procedure ListDrawItem(Control: TWinControl; Index: Integer;
23 | Rect: TRect; State: TOwnerDrawState);
24 | public
25 | Lines: TStringList;
26 | OnlyNumberedTitles: boolean;
27 | Selected: integer;
28 | function TitleToNumber(index: integer): integer;
29 | end;
30 |
31 | var
32 | SelectionForm: TSelectionForm;
33 |
34 |
35 | implementation
36 |
37 | {$R *.dfm}
38 |
39 | function TSelectionForm.TitleToNumber(index: integer): integer;
40 | var j: integer;
41 | s: string;
42 | begin
43 | result := 0;
44 | if cardinal(index)>=cardinal(Lines.Count) then
45 | exit;
46 | s := Lines[index];
47 | if (s='') or (s[1]='[') then
48 | exit;
49 | j := 0;
50 | while s[j+1] in ['0'..'9'] do inc(j);
51 | if j>0 then
52 | result := StrToInt(copy(s,1,j));
53 | end;
54 |
55 | procedure TSelectionForm.ListDblClick(Sender: TObject);
56 | begin
57 | Selected := List.ItemIndex;
58 | Close;
59 | end;
60 |
61 | procedure TSelectionForm.FormCreate(Sender: TObject);
62 | begin
63 | Lines := TStringList.Create;
64 | end;
65 |
66 | procedure TSelectionForm.FormDestroy(Sender: TObject);
67 | begin
68 | Lines.Free;
69 | end;
70 |
71 | procedure TSelectionForm.FormShow(Sender: TObject);
72 | var i,n,max: integer;
73 | begin
74 | max := 0;
75 | for i := Lines.Count-1 downto 0 do begin
76 | n := TitleToNumber(i);
77 | if n>0 then begin
78 | if n>max then
79 | max := n;
80 | continue;
81 | end;
82 | if not OnlyNumberedTitles then
83 | continue;
84 | Lines.Delete(i);
85 | if Selected>=i then
86 | if Selected=i then
87 | Selected := -1 else
88 | dec(Selected);
89 | end;
90 | if max>0 then
91 | Caption := format('%s - Maximum title # is %d',[Caption,max]);
92 | List.Count := Lines.Count;
93 | if cardinal(Selected)0 then begin
125 | found := i;
126 | break;
127 | end;
128 | if found<0 then
129 | for i := 0 to List.ItemIndex-1 do
130 | if Pos(Search,UpperCase(Lines[i]))>0 then begin
131 | found := i;
132 | break;
133 | end;
134 | if found>=0 then begin
135 | List.TopIndex := found-10;
136 | List.ItemIndex := found;
137 | end;
138 | end;
139 |
140 | procedure TSelectionForm.ListDrawItem(Control: TWinControl; Index: Integer;
141 | Rect: TRect; State: TOwnerDrawState);
142 | var List: TCustomListBox absolute Control;
143 | Data,Number: string;
144 | i,sp: integer;
145 | begin
146 | with List.Canvas do begin
147 | FillRect(Rect);
148 | if cardinal(Index)'' then begin
151 | if Data[1]<>'[' then begin
152 | sp := 0;
153 | while Data[sp+1] in ['0'..'9'] do inc(sp);
154 | Number := copy(Data,1,sp);
155 | delete(Data,1,sp);
156 | sp := 3;
157 | for i := 1 to length(Data) do
158 | if Data[i]=' ' then
159 | inc(sp) else
160 | break;
161 | end else
162 | sp := 1;
163 | TextOut(Rect.Left+sp*8,Rect.Top,Data);
164 | TextOut(Rect.Right-TextWidth(Number)-12,Rect.Top,Number);
165 | end;
166 | end;
167 | end;
168 | end;
169 |
170 | end.
171 |
172 |
--------------------------------------------------------------------------------
/ProjectVersionSCR.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning SCR Editor form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectVersionSCR;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, SynMemoEx,
30 | Dialogs, StdCtrls, ExtCtrls, Buttons, ProjectFrameRisk;
31 |
32 | type
33 | TProjectVersionSCRForm = class(TForm)
34 | Description: TLabeledEdit;
35 | ShortName: TLabeledEdit;
36 | Request: TLabeledEdit;
37 | BtnOK: TBitBtn;
38 | BtnCancel: TBitBtn;
39 | Ident: TLabeledEdit;
40 | BtnTrackerImport: TBitBtn;
41 | procedure BtnOKClick(Sender: TObject);
42 | procedure FormShow(Sender: TObject);
43 | procedure FormCreate(Sender: TObject);
44 | procedure BtnTrackerImportClick(Sender: TObject);
45 | private
46 | { Private declarations }
47 | public
48 | { Public declarations }
49 | FrameRisk: TFrameRisk;
50 | TrackNumber: integer;
51 | Risk,
52 | Body: string;
53 | procedure Init(const Title: string);
54 | end;
55 |
56 | var
57 | ProjectVersionSCRForm: TProjectVersionSCRForm;
58 |
59 | function NotVoid(Field: TComponent): boolean;
60 |
61 | resourcestring
62 | SErrorFieldEmpty = 'This field must not be empty';
63 |
64 |
65 | implementation
66 |
67 | uses ProjectTrackerLogin;
68 |
69 | {$R *.dfm}
70 |
71 | procedure TProjectVersionSCRForm.Init(const Title: string);
72 | begin
73 | Caption := ' '+Title;
74 | Description.Text := '';
75 | ShortName.Text := '';
76 | Request.Text := '';
77 | Ident.Text := '';
78 | TrackNumber := -1;
79 | Body := '';
80 | FrameRisk.Init('');
81 | end;
82 |
83 | function NotVoid(Field: TComponent): boolean;
84 | begin
85 | if Field<>nil then
86 | if Field.InheritsFrom(TLabeledEdit) then begin
87 | result := TLabeledEdit(Field).Text<>'';
88 | if result then exit;
89 | MessageDlg(TLabeledEdit(Field).EditLabel.Caption+#13#13+
90 | SErrorFieldEmpty,mtError,[mbOk],0);
91 | TLabeledEdit(Field).SetFocus;
92 | exit;
93 | end else
94 | if Field.InheritsFrom(TMemoEx) then begin
95 | result := TMemoEx(Field).Lines.HasText;
96 | if result then exit;
97 | MessageDlg(SErrorFieldEmpty,mtError,[mbOk],0);
98 | TMemoEx(Field).SetFocus;
99 | exit;
100 | end;
101 | result := true;
102 | end;
103 |
104 | procedure TProjectVersionSCRForm.BtnOKClick(Sender: TObject);
105 | begin
106 | if not TryStrToInt(Ident.Text,TrackNumber) then begin
107 | TrackNumber := -1;
108 | MessageDlg(Ident.EditLabel.Caption+' '+Ident.Hint,mtError,[mbOk],0);
109 | Ident.SetFocus;
110 | end else
111 | if (TrackNumber>=0) and notVoid(Description) and notVoid(Request) then begin
112 | Risk := FrameRisk.Risk;
113 | exit;
114 | end;
115 | ModalResult := mrNone;
116 | end;
117 |
118 |
119 | procedure TProjectVersionSCRForm.FormShow(Sender: TObject);
120 | begin
121 | if TrackNumber<0 then
122 | Ident.SetFocus;
123 | end;
124 |
125 | procedure TProjectVersionSCRForm.FormCreate(Sender: TObject);
126 | begin
127 | FrameRisk := TFrameRisk.Create(self);
128 | FrameRisk.Parent := self;
129 | FrameRisk.Left := Ident.Left;
130 | FrameRisk.Top := 216;
131 | end;
132 |
133 | procedure TProjectVersionSCRForm.BtnTrackerImportClick(Sender: TObject);
134 | var F: TProjectTrackerLoginForm;
135 | aDescription, aRequest: string;
136 | begin
137 | F := TrackerLogin(false);
138 | if F<>nil then
139 | try
140 | F.ShowSCRList;
141 | if (F.ShowModal=mrOk) and (F.SelectedID>0) then
142 | try
143 | Screen.Cursor := crHourGlass;
144 | SCRImportOne(F.Tracker,F.SelectedID,aDescription,aRequest,@Body);
145 | Ident.Text := IntToStr(F.SelectedID);
146 | Description.Text := aDescription;
147 | Request.Text := aRequest;
148 | finally
149 | Screen.Cursor := crDefault;
150 | end;
151 | finally
152 | DeleteTempForm(F);
153 | end;
154 | end;
155 |
156 | end.
157 |
--------------------------------------------------------------------------------
/ProjectVersionSCR.dfm:
--------------------------------------------------------------------------------
1 | object ProjectVersionSCRForm: TProjectVersionSCRForm
2 | Left = 287
3 | Top = 319
4 | BorderStyle = bsDialog
5 | ClientHeight = 466
6 | ClientWidth = 450
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | Position = poScreenCenter
15 | OnCreate = FormCreate
16 | OnShow = FormShow
17 | PixelsPerInch = 96
18 | TextHeight = 13
19 | object Description: TLabeledEdit
20 | Left = 56
21 | Top = 88
22 | Width = 353
23 | Height = 21
24 | EditLabel.Width = 57
25 | EditLabel.Height = 13
26 | EditLabel.Caption = 'Description:'
27 | TabOrder = 1
28 | end
29 | object ShortName: TLabeledEdit
30 | Left = 56
31 | Top = 136
32 | Width = 353
33 | Height = 21
34 | EditLabel.Width = 85
35 | EditLabel.Height = 13
36 | EditLabel.Caption = 'Short description:'
37 | TabOrder = 2
38 | end
39 | object Request: TLabeledEdit
40 | Left = 56
41 | Top = 184
42 | Width = 353
43 | Height = 21
44 | EditLabel.Width = 121
45 | EditLabel.Height = 13
46 | EditLabel.Caption = 'Request (SCR #55 e.g.):'
47 | TabOrder = 3
48 | end
49 | object BtnOK: TBitBtn
50 | Left = 152
51 | Top = 416
52 | Width = 105
53 | Height = 33
54 | Caption = 'OK'
55 | Default = True
56 | ModalResult = 1
57 | TabOrder = 4
58 | OnClick = BtnOKClick
59 | Glyph.Data = {
60 | 96010000424D9601000000000000760000002800000018000000180000000100
61 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
62 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
63 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
64 | 9999999999999999999999999999999999999999999999999999999999999999
65 | 9999999999999999999999999999099999999999999999999990F09999999999
66 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
67 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
68 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
69 | 9999999909999999999017099999999999999999999990A09999999999999999
70 | 9999990109999999999999999999999900999999999999999999999999099999
71 | 9999999999999999999999999999999999999999999999999999999999999999
72 | 9999999999999999999999999999999999999999999999999999}
73 | end
74 | object BtnCancel: TBitBtn
75 | Left = 304
76 | Top = 416
77 | Width = 105
78 | Height = 33
79 | Cancel = True
80 | Caption = 'Cancel'
81 | ModalResult = 2
82 | TabOrder = 5
83 | Glyph.Data = {
84 | 96010000424D9601000000000000760000002800000018000000180000000100
85 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
86 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
87 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
88 | 1111111111111111111111111111111111111111111111111111111111111111
89 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
90 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
91 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
92 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
93 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
94 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
95 | 09D0111111110C40111111111001111111111001111111111111111111111111
96 | 1111111111111111111111111111111111111111111111111111}
97 | end
98 | object Ident: TLabeledEdit
99 | Left = 56
100 | Top = 40
101 | Width = 225
102 | Height = 21
103 | Hint = 'This field must have a valid numeric value'
104 | EditLabel.Width = 69
105 | EditLabel.Height = 13
106 | EditLabel.Caption = 'Track number:'
107 | ParentShowHint = False
108 | ShowHint = True
109 | TabOrder = 0
110 | end
111 | object BtnTrackerImport: TBitBtn
112 | Left = 296
113 | Top = 38
114 | Width = 113
115 | Height = 25
116 | Caption = 'Tracker Import'
117 | TabOrder = 6
118 | OnClick = BtnTrackerImportClick
119 | Glyph.Data = {
120 | F6000000424DF600000000000000760000002800000010000000100000000100
121 | 0400000000008000000000000000000000001000000000000000040204000482
122 | 0400848204008402040004FE0400FCFEFC00FC02040004FEFC00000040000000
123 | 00000000000000000000DFFBC100DA67AB00410080007E007C00000555500000
124 | 0000002222500000000000222253633300000022225136363600002222541413
125 | 3330002222514141363603222257143413630622225147414413552222555474
126 | 7143222222225747471422222222577474732222222266774743006666676664
127 | 7460006466777666436000067464666366000000024744660000}
128 | end
129 | end
130 |
--------------------------------------------------------------------------------
/ProjectEditorRelease.dfm:
--------------------------------------------------------------------------------
1 | object ProjectEditorReleaseForm: TProjectEditorReleaseForm
2 | Left = 399
3 | Top = 191
4 | BorderStyle = bsDialog
5 | ClientHeight = 276
6 | ClientWidth = 458
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | Position = poScreenCenter
15 | OnShow = FormShow
16 | PixelsPerInch = 96
17 | TextHeight = 13
18 | object Description: TLabeledEdit
19 | Left = 56
20 | Top = 88
21 | Width = 353
22 | Height = 21
23 | EditLabel.Width = 57
24 | EditLabel.Height = 13
25 | EditLabel.Caption = 'Description:'
26 | TabOrder = 1
27 | end
28 | object BtnCurrent: TBitBtn
29 | Left = 112
30 | Top = 184
31 | Width = 145
32 | Height = 33
33 | Caption = 'Change Current'
34 | Default = True
35 | ModalResult = 1
36 | TabOrder = 4
37 | OnClick = BtnCurrentClick
38 | Glyph.Data = {
39 | 96010000424D9601000000000000760000002800000018000000180000000100
40 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
41 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
42 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
43 | 9999999999999999999999999999999999999999999999999999999999999999
44 | 9999999999999999999999999999099999999999999999999990F09999999999
45 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
46 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
47 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
48 | 9999999909999999999017099999999999999999999990A09999999999999999
49 | 9999990109999999999999999999999900999999999999999999999999099999
50 | 9999999999999999999999999999999999999999999999999999999999999999
51 | 9999999999999999999999999999999999999999999999999999}
52 | end
53 | object BtnCancel: TBitBtn
54 | Left = 304
55 | Top = 184
56 | Width = 105
57 | Height = 33
58 | Cancel = True
59 | Caption = 'Cancel'
60 | ModalResult = 2
61 | TabOrder = 6
62 | Glyph.Data = {
63 | 96010000424D9601000000000000760000002800000018000000180000000100
64 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
65 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
66 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
67 | 1111111111111111111111111111111111111111111111111111111111111111
68 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
69 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
70 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
71 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
72 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
73 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
74 | 09D0111111110C40111111111001111111111001111111111111111111111111
75 | 1111111111111111111111111111111111111111111111111111}
76 | end
77 | object Version: TLabeledEdit
78 | Left = 56
79 | Top = 40
80 | Width = 353
81 | Height = 21
82 | EditLabel.Width = 172
83 | EditLabel.Height = 13
84 | EditLabel.Caption = 'Version release number (1.01 e.g.):'
85 | ParentShowHint = False
86 | ShowHint = True
87 | TabOrder = 0
88 | end
89 | object Date: TLabeledEdit
90 | Left = 56
91 | Top = 136
92 | Width = 297
93 | Height = 21
94 | EditLabel.Width = 65
95 | EditLabel.Height = 13
96 | EditLabel.Caption = 'Version Date:'
97 | TabOrder = 2
98 | end
99 | object BtnToday: TButton
100 | Left = 368
101 | Top = 136
102 | Width = 45
103 | Height = 25
104 | Caption = 'Today'
105 | TabOrder = 3
106 | OnClick = BtnTodayClick
107 | end
108 | object BtnNew: TBitBtn
109 | Left = 112
110 | Top = 224
111 | Width = 145
112 | Height = 33
113 | Caption = 'Create new version'
114 | ModalResult = 1
115 | TabOrder = 5
116 | OnClick = BtnCurrentClick
117 | Glyph.Data = {
118 | 96010000424D9601000000000000760000002800000018000000180000000100
119 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
120 | 1000D67F7F0024B43C0048D36F00FC02FC001F9B3100B53F3D00CC676800DD99
121 | 99002FC54F0059E3890037BA5400178F24001CAC2F00C4545400555555555555
122 | 5555555555555555555555555555555555555555555550555555555555555555
123 | 5555060555555555555555555550EE305555555555555555550E3EE305555555
124 | 55555555506A33EE3055555555555555064AAE03E305555555555550D4443050
125 | EE30555555555550BBBC07550DEE055555555550CBC08875550EE05555555557
126 | 040888875550EE055555557820287888755501E0555557F9922757888755550D
127 | 055557999275557F887555501055572927555555788755555005557975555555
128 | 578875555550555755555555557F8755555555555555555555557F7555555555
129 | 5555555555555777555555555555555555555557755555555555555555555555
130 | 5755555555555555555555555555555555555555555555555555}
131 | end
132 | end
133 |
--------------------------------------------------------------------------------
/ProjectVersionCommit.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning Commit form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectVersionCommit;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, Buttons, CheckLst, ProjectCommons, ExtCtrls, ProjectVersioning;
31 |
32 | type
33 | TProjectVersionCommitForm = class(TForm)
34 | CheckListBox: TCheckListBox;
35 | Label1: TLabel;
36 | BtnSelected: TBitBtn;
37 | BtnAll: TBitBtn;
38 | BtnCancel: TBitBtn;
39 | Description: TLabeledEdit;
40 | Label2: TLabel;
41 | Comments: TMemo;
42 | Label3: TLabel;
43 | SCR: TComboBox;
44 | PVCS: TCheckBox;
45 | procedure FormKeyDown(Sender: TObject; var Key: Word;
46 | Shift: TShiftState);
47 | procedure BtnAllClick(Sender: TObject);
48 | procedure BtnSelectedClick(Sender: TObject);
49 | procedure FormShow(Sender: TObject);
50 | procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
51 | private
52 | { Private declarations }
53 | public
54 | Selected: TIntegerDynArray;
55 | procedure Init(const Title: string; Versions: TVersions);
56 | end;
57 |
58 | var
59 | ProjectVersionCommitForm: TProjectVersionCommitForm;
60 |
61 | implementation
62 |
63 | uses
64 | ProjectVersionSCR, // for notVoid()
65 | ProjectSections;
66 |
67 |
68 | {$R *.dfm}
69 |
70 | procedure TProjectVersionCommitForm.FormKeyDown(Sender: TObject;
71 | var Key: Word; Shift: TShiftState);
72 | begin
73 | if byte(Shift)=0 then
74 | case Key of
75 | vk_F3: BtnSelected.Click;
76 | vk_F4: BtnAll.Click;
77 | end;
78 | end;
79 |
80 | procedure TProjectVersionCommitForm.BtnAllClick(Sender: TObject);
81 | var i: integer;
82 | begin
83 | SetLength(Selected,CheckListBox.Count);
84 | with CheckListBox.Items do
85 | for i := 0 to Count-1 do
86 | Selected[i] := integer(Objects[i]);
87 | end;
88 |
89 | procedure TProjectVersionCommitForm.BtnSelectedClick(Sender: TObject);
90 | var n,i: integer;
91 | begin
92 | SetLength(Selected,CheckListBox.Count);
93 | n := 0;
94 | with CheckListBox.Items do
95 | for i := 0 to Count-1 do
96 | if CheckListBox.Checked[i] then begin
97 | Selected[n] := integer(Objects[i]);
98 | inc(n);
99 | end;
100 | Setlength(Selected,n);
101 | end;
102 |
103 | procedure TProjectVersionCommitForm.FormShow(Sender: TObject);
104 | begin
105 | Description.SetFocus;
106 | end;
107 |
108 | procedure TProjectVersionCommitForm.FormCloseQuery(Sender: TObject;
109 | var CanClose: Boolean);
110 | begin
111 | if not (ModalResult in [mrOK,mrAll]) then exit;
112 | if NotVoid(Description) then exit;
113 | CanClose := false;
114 | end;
115 |
116 | procedure TProjectVersionCommitForm.Init(const Title: string; Versions: TVersions);
117 | var i, s, Value,Code: integer;
118 | sel, u, last: string;
119 | aSCR: TSectionsStorage;
120 | Sec: TSection;
121 | begin
122 | Caption := ' '+Title;
123 | Description.Text := '';
124 | Comments.Clear;
125 | PVCS.Checked := isTrue(Versions.Params['CommitToPVCS']);
126 | sel := Versions.Params['LastUpdate']; // LastUpdate=012
127 | with CheckListBox.Items do begin
128 | Clear; // Update4=IFA Software;Synopse\IFA2;FilterDefault,*.sld,*.ias
129 | for i := 0 to 9 do begin
130 | u := Versions.Params['Update'+IntToStr(i)];
131 | if u='' then continue;
132 | AddObject(format('%s - %s',[ValAt(u,0,';'),ValAt(u,1,';')]),pointer(i));
133 | if pos(chr(i+48),sel)>0 then
134 | CheckListBox.Checked[Count-1] := true;
135 | end;
136 | end;
137 | with SCR.Items do begin
138 | Clear;
139 | aSCR := Versions.SCR;
140 | if aSCR<>nil then begin
141 | s := 0;
142 | last := Versions.Commits[Versions.Params['LastCommit']]['SCR'];
143 | AddObject('-=- None -=-',pointer(-1));
144 | for i := 0 to aSCR.Sections.Count-1 do begin
145 | Sec := aSCR.Sections[i];
146 | Val(Sec.SectionName,Value,Code);
147 | if Code<>0 then continue; // [section] must be numeric
148 | AddObject(format('%s - %s',[Sec.SectionName,Sec.ShortDescription('')]),
149 | pointer(Value));
150 | if Sec.SectionName=last then
151 | s := Count-1;
152 | end;
153 | SCR.ItemIndex := s;
154 | end;
155 | end;
156 | end;
157 |
158 | end.
159 |
--------------------------------------------------------------------------------
/ProjectEditorRelease.pas:
--------------------------------------------------------------------------------
1 | /// Documentation editor Version number wizard form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectEditorRelease;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, ExtCtrls, Buttons,
31 | ProjectSections;
32 |
33 | type
34 | TProjectEditorReleaseForm = class(TForm)
35 | Description: TLabeledEdit;
36 | BtnCurrent: TBitBtn;
37 | BtnCancel: TBitBtn;
38 | Version: TLabeledEdit;
39 | Date: TLabeledEdit;
40 | BtnToday: TButton;
41 | BtnNew: TBitBtn;
42 | procedure BtnCurrentClick(Sender: TObject);
43 | procedure FormShow(Sender: TObject);
44 | procedure BtnTodayClick(Sender: TObject);
45 | private
46 | Doc: TSection;
47 | public
48 | procedure Init(aDoc: TSection);
49 | end;
50 |
51 |
52 | resourcestring
53 | sNewReleaseForDocumentN = 'New Release for the "%s" document';
54 | sDocumentVersionNumberN = '"%s" document version number (1.01 e.g.):';
55 | sErrorRevisionNotInUserN = 'The revision %s is not in use - please enter an existing one';
56 | sErrorRevisionUsedN = 'The revision %s is already used - please enter a new value';
57 |
58 |
59 | implementation
60 |
61 | uses
62 | ProjectCommons,
63 | ProjectFormDocWizard,
64 | ProjectVersionSCR;
65 |
66 | {
67 | Revision=0.1
68 | RevisionDescription=Initial Version
69 | RevisionDate=October 1, 2008
70 | }
71 |
72 | {$R *.dfm}
73 |
74 | procedure TProjectEditorReleaseForm.Init(aDoc: TSection);
75 | var Title: string;
76 | begin
77 | if self=nil then exit;
78 | Doc := aDoc;
79 | Title := Doc.DisplayName(nil);
80 | Caption := ' '+format(sNewReleaseForDocumentN,[Title]);
81 | Version.EditLabel.Caption := format(sDocumentVersionNumberN,[Title]);
82 | Version.Text := aDoc['Revision'];
83 | Description.Text := aDoc['RevisionDescription'];
84 | Date.Text := aDoc['RevisionDate'];
85 | end;
86 |
87 | procedure TProjectEditorReleaseForm.BtnCurrentClick(Sender: TObject);
88 | var i, num, first: integer;
89 | s,up: string;
90 | oldDate: boolean;
91 | begin
92 | ModalResult := mrNone;
93 | if not notVoid(Version) or not notVoid(Description) then exit;
94 | up := uppercase(trim(Version.Text));
95 | if Sender=BtnCurrent then begin
96 | if not SameText(Doc['Revision'],up) then begin // check is current
97 | MessageErrFmt(sErrorRevisionNotInUserN,up);
98 | Version.SetFocus;
99 | exit;
100 | end;
101 | Doc['RevisionDescription'] := Description.Text;
102 | Doc['RevisionDate'] := Date.Text;
103 | end else
104 | if Sender=BtnNew then begin
105 | first := -1;
106 | num := -1;
107 | for i := 0 to Doc.Lines.Count-1 do begin
108 | s := Doc.Lines[i];
109 | if (s='') or (s[1]=':') then break;
110 | if IdemPChar(pointer(s),'REVISION=') then begin
111 | if first<0 then
112 | first := i;
113 | if IdemPChar(@s[length('REVISION=')+1],pointer(up)) then begin
114 | num := i;
115 | break;
116 | end;
117 | end;
118 | end;
119 | if num>=0 then begin // check if unique
120 | MessageErrFmt(sErrorRevisionUsedN,up);
121 | Version.SetFocus;
122 | exit;
123 | end;
124 | if Doc['RevisionDate']='' then begin
125 | Doc['RevisionDate'] := trim(Date.Text); // update old version date
126 | oldDate := true;
127 | end else
128 | oldDate := false;
129 | if first<0 then begin // no Revision= yet -> just add new
130 | Doc['Revision'] := up;
131 | Doc['RevisionDescription'] := trim(Description.Text);
132 | // RevisionDate was '' -> already set
133 | end else begin // add before any existing Revision=
134 | if oldDate then
135 | Doc.Lines.Insert(first,'RevisionDate=') else
136 | Doc.Lines.Insert(first,'RevisionDate='+trim(Date.Text));
137 | Doc.Lines.Insert(first,'RevisionDescription='+trim(Description.Text));
138 | Doc.Lines.Insert(first,'Revision='+up);
139 | end;
140 | end;
141 | ModalResult := mrOk;
142 | end;
143 |
144 |
145 | procedure TProjectEditorReleaseForm.FormShow(Sender: TObject);
146 | begin
147 | if Version.Text='' then
148 | Version.SetFocus;
149 | end;
150 |
151 | procedure TProjectEditorReleaseForm.BtnTodayClick(Sender: TObject);
152 | var s: string;
153 | begin
154 | DateTimeToString(s,'mmmm d, yyyy',now);
155 | Date.Text := s;
156 | end;
157 |
158 | end.
159 |
--------------------------------------------------------------------------------
/PasDocLight/PasDoc_Serialize.pas:
--------------------------------------------------------------------------------
1 | unit PasDoc_Serialize;
2 |
3 | interface
4 | uses
5 | Classes,
6 | SysUtils;
7 |
8 | type
9 | TSerializable = class;
10 | TSerializableClass = class of TSerializable;
11 |
12 | TSerializable = class
13 | private
14 | FWasDeserialized: boolean;
15 | protected
16 | procedure Serialize(const ADestination: TStream); virtual;
17 | procedure Deserialize(const ASource: TStream); virtual;
18 | public
19 | class function LoadStringFromStream(const ASource: TStream): string;
20 | class procedure SaveStringToStream(const AValue: string; const ADestination: TStream);
21 | class function LoadDoubleFromStream(const ASource: TStream): double;
22 | class procedure SaveDoubleToStream(const AValue: double; const ADestination: TStream);
23 | class function LoadIntegerFromStream(const ASource: TStream): Integer;
24 | class procedure SaveIntegerToStream(const AValue: Integer; const ADestination: TStream);
25 |
26 | constructor Create; virtual;
27 | class procedure SerializeObject(const AObject: TSerializable; const ADestination: TStream);
28 | class function DeserializeObject(const ASource: TStream): TSerializable;
29 | class procedure Register(const AClass: TSerializableClass);
30 | procedure SerializeToFile(const AFileName: string);
31 | class function DeserializeFromFile(const AFileName: string): TSerializable;
32 | class function DeserializeFromStream(AStream: TStream): TSerializable;
33 | property WasDeserialized: boolean read FWasDeserialized;
34 | end;
35 |
36 | ESerializedException = class(Exception);
37 |
38 | implementation
39 |
40 | uses
41 | PasDoc_Utils;
42 |
43 | var
44 | GClassNames: TStringList;
45 |
46 | { TSerializable }
47 |
48 | constructor TSerializable.Create;
49 | begin
50 | inherited;
51 | end;
52 |
53 | procedure TSerializable.Serialize(const ADestination: TStream);
54 | begin
55 | end;
56 |
57 | procedure TSerializable.Deserialize(const ASource: TStream);
58 | begin
59 | FWasDeserialized := True;
60 | end;
61 |
62 | class function TSerializable.DeserializeFromFile(
63 | const AFileName: string): TSerializable;
64 | var LF: THeapMemoryStream;
65 | begin
66 | LF := THeapMemoryStream.Create;
67 | LF.LoadFromFile(AFileName);
68 | try
69 | Result := DeserializeObject(LF);
70 | finally
71 | LF.Free;
72 | end;
73 | end;
74 |
75 | class function TSerializable.DeserializeFromStream(AStream: TStream): TSerializable;
76 | begin
77 | Result := DeserializeObject(AStream);
78 | end;
79 |
80 | class function TSerializable.DeserializeObject(
81 | const ASource: TStream): TSerializable;
82 | var S: string;
83 | L: integer;
84 | LClass: TSerializableClass;
85 | Idx: Integer;
86 | begin
87 | L := 0;
88 | ASource.Read(L, 1);
89 | Setlength(S,L);
90 | ASource.Read(S[1], L);
91 | Idx := GClassNames.IndexOf(S);
92 | if Idx<0 then begin
93 | raise ESerializedException.CreateFmt('Tried loading unknown class %s', [S]);
94 | end else begin
95 | LClass := TSerializableClass(GClassNames.Objects[Idx]);
96 | Result := LClass.Create;
97 | Result.Deserialize(ASource);
98 | end;
99 | end;
100 |
101 | class function TSerializable.LoadIntegerFromStream(
102 | const ASource: TStream): Integer;
103 | begin
104 | ASource.Read(Result, SizeOf(Result));
105 | end;
106 |
107 | class function TSerializable.LoadDoubleFromStream(
108 | const ASource: TStream): double;
109 | begin
110 | ASource.Read(Result, SizeOf(Result));
111 | end;
112 |
113 | class function TSerializable.LoadStringFromStream(
114 | const ASource: TStream): string;
115 | var L: Integer;
116 | begin
117 | ASource.Read(L, SizeOf(L));
118 | SetLength(Result, L);
119 | ASource.Read(Pointer(Result)^, L);
120 | end;
121 |
122 | class procedure TSerializable.Register(const AClass: TSerializableClass);
123 | begin
124 | GClassNames.AddObject(AClass.ClassName, TObject(AClass));
125 | end;
126 |
127 | class procedure TSerializable.SaveIntegerToStream(
128 | const AValue: Integer; const ADestination: TStream);
129 | begin
130 | ADestination.Write(AValue, SizeOf(AValue));
131 | end;
132 |
133 | class procedure TSerializable.SaveDoubleToStream(const AValue: double;
134 | const ADestination: TStream);
135 | begin
136 | ADestination.Write(AValue, SizeOf(AValue));
137 | end;
138 |
139 | class procedure TSerializable.SaveStringToStream(const AValue: string;
140 | const ADestination: TStream);
141 | var L: Integer;
142 | begin
143 | L := Length(AValue);
144 | ADestination.Write(L, SizeOf(L));
145 | ADestination.Write(Pointer(AValue)^, L);
146 | end;
147 |
148 | class procedure TSerializable.SerializeObject(const AObject: TSerializable;
149 | const ADestination: TStream);
150 | var
151 | S: shortstring;
152 | begin
153 | S := AObject.ClassName;
154 | if GClassNames.IndexOf(S)<0 then
155 | raise ESerializedException.CreateFmt('Tried saving unregistered class %s', [S]);
156 | ADestination.Write(S[0], Byte(S[0])+1);
157 | AObject.Serialize(ADestination);
158 | end;
159 |
160 | procedure TSerializable.SerializeToFile(const AFileName: string);
161 | var
162 | LF: THeapMemoryStream;
163 | begin
164 | LF := THeapMemoryStream.Create;
165 | try
166 | SerializeObject(Self, LF);
167 | LF.SaveToFile(AFileName);
168 | finally
169 | LF.Free;
170 | end;
171 | end;
172 |
173 |
174 |
175 | initialization
176 | GClassNames := TStringList.Create;
177 | GClassNames.Sorted := true; // faster IndexOf()
178 | finalization
179 | GClassNames.Free;
180 | end.
181 |
--------------------------------------------------------------------------------
/ProjectDiagrams.pas:
--------------------------------------------------------------------------------
1 | /// UML diagrams rendering
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.18
3 | unit ProjectDiagrams;
4 |
5 | interface
6 |
7 | uses
8 | Graphics,
9 | SysUtils,
10 | Classes;
11 |
12 | /// convert a text sequence into an UML-like vectorial diagram
13 | // - returns nil if the supplied content is incorrect
14 | // - text syntax is pretty easy:
15 | // $A=Alice // optional participant naming and ordering
16 | // $B=Bob
17 | // $A->B:synchronous call
18 | // $A->>A:asynchronous arrow
19 | // $B-->A:dotted open arrow
20 | // $A->:Authentication Request
21 | // $alt:successful case // alternative group
22 | // $ B->A:Authentication Accepted // internal lines shall be indented
23 | // $:on failure // same level group will be
24 | // $ B->A:authentication Failure
25 | // $ opt: // nested group
26 | // $ loop:10000 times
27 | // $ A->B:DNS attack
28 | // $:on timeout
29 | // $ B->A:please retry
30 | // $A->+Service:DoQuery() // + - notifies lifeline activation
31 | // $+Service->Domain:PrepareQuery()
32 | // $Domain-->TQuery:Prepare()
33 | // $-Domain-->Service
34 | // $+Service->Domain:CommitQuery()
35 | // $*TQuery // * destroy a participant
36 | function UMLSequenceToMetaFile(const Content: string): TMetafile;
37 |
38 |
39 | {
40 | C=Customer
41 | O=Order
42 | M=Menu Manager
43 | ?>>C:hunger
44 | >>O:<
45 | loop:until complete
46 | >:Add item
47 | >M:Check Available
48 | <:a Callback
49 | =:a self message
50 | >:return
51 | ref:complete Order And Pay
52 | M>?:Stock update
53 |
54 |
55 | W=Website
56 | H=Warehouse
57 | B=Banck
58 | ? "Customer Order" W
59 | alt:deliver to home
60 | W processPayment H <>
61 | H "validate card" B <>
62 | W mailToHome H <>
63 | :collect from store
64 | W mailToStore H <>
65 |
66 | C=Customer
67 | O=Order
68 | M=Menu Manager
69 | ? hunger C
70 | C <> O
71 | loop:until complete
72 | C "Add item" O
73 | O "Check Available" M <>
74 | M "a Callback" O "<>"
75 | O "a self message" O
76 | ref:Complete Order and Pay
77 | M "Stock update" ?
78 |
79 | }
80 | implementation
81 |
82 | type
83 | TUMLSequenceLineStyle = (slsSynchCall, slsAsynchCall, slsSynchReturn);
84 | TUMLSequence = class
85 | protected
86 | function ParticipantIndex(const aName, aIdent: string;
87 | CreateIfNotExisting: boolean=true): integer;
88 | public
89 | Participant: array of record
90 | Name: string;
91 | Ident: string;
92 | end;
93 | Items: array of record
94 | Style: TUMLSequenceLineStyle;
95 | FromParticipant: integer;
96 | ToParticipant: integer;
97 | end;
98 | procedure ParseLine(Line: string);
99 | function RenderContent: TMetaFile;
100 | end;
101 |
102 |
103 | function UMLSequenceToMetaFile(const Content: string): TMetafile;
104 | var Lines: TStringList;
105 | i: integer;
106 | begin
107 | with TUMLSequence.Create do
108 | try
109 | Lines := TStringList.Create;
110 | try
111 | Lines.Text := Content;
112 | for i := 0 to Lines.Count-1 do
113 | ParseLine(Lines[i]);
114 | finally
115 | Lines.Free;
116 | end;
117 | result := RenderContent;
118 | finally
119 | Free;
120 | end;
121 | end;
122 |
123 |
124 | { TUMLSequence }
125 |
126 | procedure TUMLSequence.ParseLine(Line: string);
127 | var i,j: integer;
128 | activation: (aNone, aActivate, aDisactivate, aDestroy);
129 | fromPart, toPart: string;
130 | style: TUMLSequenceLineStyle;
131 | begin
132 | if (Line='') or (Line[1]=';') then
133 | exit;
134 | // A=Alice or Alice=
135 | for i := 1 to length(Line) do
136 | if Line[i]='=' then begin
137 | ParticipantIndex(Copy(Line,1,i-1),copy(Line,i+1,1000));
138 | exit;
139 | end else
140 | if not (Line[i] in ['A'..'Z','a'..'z','0'..'9','_']) then
141 | break;
142 | case Line[1] of
143 | '+': activation := aActivate;
144 | '-': activation := aDisactivate;
145 | '*': activation := aDestroy;
146 | else activation := aNone;
147 | end;
148 | if activation<>aNone then
149 | delete(Line,1,1);
150 | // A->B or Alice-->Bob
151 | for i := 1 to length(Line) do
152 | if Line[i]=':' then break else
153 | if Line[i]='-' then begin
154 | fromPart := copy(line,1,i-1);
155 | j := i+1;
156 | if j>=length(Line) then
157 | break;
158 | if line[j]='>' then
159 | if line[j+1]='>' then begin
160 | style := slsAsynchCall;
161 | inc(j,2);
162 | end else begin
163 | style := slsSynchCall;
164 | inc(j);
165 | end else
166 | if (line[j]='-') and (line[j+1]='>') then begin
167 | style := slsSynchReturn;
168 | inc(j,2);
169 | end else
170 | break;
171 | // TO BE DONE
172 | exit;
173 | end;
174 |
175 | end;
176 |
177 | function TUMLSequence.ParticipantIndex(const aName, aIdent: string;
178 | CreateIfNotExisting: boolean): integer;
179 | begin
180 | for result := 0 to high(Participant) do
181 | if Participant[result].Name=aName then
182 | exit;
183 | if CreateIfNotExisting then begin
184 | result := Length(Participant);
185 | SetLength(Participant,result+1);
186 | Participant[result].Name := aName;
187 | if aIdent='' then
188 | Participant[result].Ident := aName else
189 | Participant[result].Ident := aIdent;
190 | end else
191 | result := -1;
192 | end;
193 |
194 | function TUMLSequence.RenderContent: TMetaFile;
195 | begin
196 |
197 | end;
198 |
199 | end.
200 |
--------------------------------------------------------------------------------
/ProjectVersionCommit.dfm:
--------------------------------------------------------------------------------
1 | object ProjectVersionCommitForm: TProjectVersionCommitForm
2 | Left = 401
3 | Top = 201
4 | BorderStyle = bsDialog
5 | ClientHeight = 513
6 | ClientWidth = 434
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | KeyPreview = True
14 | OldCreateOrder = False
15 | Position = poScreenCenter
16 | OnCloseQuery = FormCloseQuery
17 | OnKeyDown = FormKeyDown
18 | OnShow = FormShow
19 | PixelsPerInch = 96
20 | TextHeight = 13
21 | object Label1: TLabel
22 | Left = 48
23 | Top = 264
24 | Width = 165
25 | Height = 13
26 | Caption = 'Precise the extend of this Commit:'
27 | end
28 | object Label2: TLabel
29 | Left = 48
30 | Top = 112
31 | Width = 54
32 | Height = 13
33 | Caption = 'Comments:'
34 | end
35 | object Label3: TLabel
36 | Left = 48
37 | Top = 64
38 | Width = 129
39 | Height = 13
40 | Caption = 'Associated SCR in Tracker:'
41 | end
42 | object CheckListBox: TCheckListBox
43 | Left = 48
44 | Top = 280
45 | Width = 329
46 | Height = 121
47 | ItemHeight = 13
48 | TabOrder = 3
49 | end
50 | object BtnSelected: TBitBtn
51 | Left = 56
52 | Top = 416
53 | Width = 161
54 | Height = 33
55 | Caption = 'Commit selected (F3)'
56 | Default = True
57 | ModalResult = 1
58 | TabOrder = 4
59 | OnClick = BtnSelectedClick
60 | Glyph.Data = {
61 | 96010000424D9601000000000000760000002800000018000000180000000100
62 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
63 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
64 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
65 | 9999999999999999999999999999999999999999999999999999999999999999
66 | 9999999999999999999999999999099999999999999999999990F09999999999
67 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
68 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
69 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
70 | 9999999909999999999017099999999999999999999990A09999999999999999
71 | 9999990109999999999999999999999900999999999999999999999999099999
72 | 9999999999999999999999999999999999999999999999999999999999999999
73 | 9999999999999999999999999999999999999999999999999999}
74 | end
75 | object BtnAll: TBitBtn
76 | Left = 56
77 | Top = 456
78 | Width = 161
79 | Height = 33
80 | Caption = 'Commit all (F4)'
81 | ModalResult = 8
82 | TabOrder = 5
83 | OnClick = BtnAllClick
84 | Glyph.Data = {
85 | 96010000424D9601000000000000760000002800000018000000180000000100
86 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
87 | 1000D67F7F0024B43C0048D36F00FC02FC001F9B3100B53F3D00CC676800DD99
88 | 99002FC54F0059E3890037BA5400178F24001CAC2F00C4545400555555555555
89 | 5555555555555555555555555555555555555555555550555555555555555555
90 | 5555060555555555555555555550EE305555555555555555550E3EE305555555
91 | 55555555506A33EE3055555555555555064AAE03E305555555555550D4443050
92 | EE30555555555550BBBC07550DEE055555555550CBC08875550EE05555555557
93 | 040888875550EE055555557820287888755501E0555557F9922757888755550D
94 | 055557999275557F887555501055572927555555788755555005557975555555
95 | 578875555550555755555555557F8755555555555555555555557F7555555555
96 | 5555555555555777555555555555555555555557755555555555555555555555
97 | 5755555555555555555555555555555555555555555555555555}
98 | end
99 | object BtnCancel: TBitBtn
100 | Left = 240
101 | Top = 456
102 | Width = 129
103 | Height = 33
104 | Cancel = True
105 | Caption = 'Cancel'
106 | ModalResult = 2
107 | TabOrder = 6
108 | Glyph.Data = {
109 | 96010000424D9601000000000000760000002800000018000000180000000100
110 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
111 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
112 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
113 | 1111111111111111111111111111111111111111111111111111111111111111
114 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
115 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
116 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
117 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
118 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
119 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
120 | 09D0111111110C40111111111001111111111001111111111111111111111111
121 | 1111111111111111111111111111111111111111111111111111}
122 | end
123 | object Description: TLabeledEdit
124 | Left = 48
125 | Top = 32
126 | Width = 329
127 | Height = 21
128 | AutoSize = False
129 | EditLabel.Width = 57
130 | EditLabel.Height = 13
131 | EditLabel.Caption = 'Description:'
132 | TabOrder = 0
133 | end
134 | object Comments: TMemo
135 | Left = 48
136 | Top = 128
137 | Width = 329
138 | Height = 121
139 | ScrollBars = ssVertical
140 | TabOrder = 2
141 | end
142 | object SCR: TComboBox
143 | Left = 48
144 | Top = 80
145 | Width = 329
146 | Height = 21
147 | Style = csDropDownList
148 | DropDownCount = 16
149 | ItemHeight = 13
150 | TabOrder = 1
151 | end
152 | object PVCS: TCheckBox
153 | Left = 240
154 | Top = 62
155 | Width = 145
156 | Height = 17
157 | Caption = 'Add to PVCS as modules'
158 | TabOrder = 7
159 | end
160 | end
161 |
--------------------------------------------------------------------------------
/ProjectVersionMain.dfm:
--------------------------------------------------------------------------------
1 | object MainForm: TMainForm
2 | Left = 244
3 | Top = 158
4 | Width = 694
5 | Height = 376
6 | Color = clBtnFace
7 | Font.Charset = DEFAULT_CHARSET
8 | Font.Color = clWindowText
9 | Font.Height = -11
10 | Font.Name = 'Tahoma'
11 | Font.Style = []
12 | KeyPreview = True
13 | OldCreateOrder = False
14 | OnClose = FormClose
15 | OnCreate = FormCreate
16 | OnDestroy = FormDestroy
17 | OnKeyDown = FormKeyDown
18 | OnResize = FormResize
19 | OnShow = FormShow
20 | PixelsPerInch = 96
21 | TextHeight = 13
22 | object SplitterPanel: TSplitter
23 | Left = 305
24 | Top = 42
25 | Height = 296
26 | end
27 | object ToolBar: TToolBar
28 | Left = 0
29 | Top = 0
30 | Width = 678
31 | Height = 42
32 | AutoSize = True
33 | ButtonHeight = 36
34 | ButtonWidth = 46
35 | EdgeBorders = [ebLeft, ebTop, ebRight, ebBottom]
36 | Images = ImageList
37 | ShowCaptions = True
38 | TabOrder = 0
39 | object BtnReleaseOpen: TToolButton
40 | Left = 0
41 | Top = 2
42 | Hint = 'Open another Release .dvs file'
43 | Caption = 'Open'
44 | DropdownMenu = PopupMenuOpen
45 | ImageIndex = 7
46 | ParentShowHint = False
47 | ShowHint = True
48 | OnClick = BtnReleaseOpenClick
49 | end
50 | object BtnReleaseNew: TToolButton
51 | Left = 46
52 | Top = 2
53 | Hint = 'Create a new Release (.dvs and associated directories and files)'
54 | Caption = 'New'
55 | ImageIndex = 8
56 | ParentShowHint = False
57 | ShowHint = True
58 | OnClick = BtnReleaseNewClick
59 | end
60 | object BtnReleaseSettings: TToolButton
61 | Left = 92
62 | Top = 2
63 | Hint = 'Release Settings (F9)'
64 | Caption = 'Settings'
65 | ImageIndex = 0
66 | ParentShowHint = False
67 | ShowHint = True
68 | OnClick = BtnReleaseSettingsClick
69 | end
70 | object ToolButton1: TToolButton
71 | Left = 138
72 | Top = 2
73 | Width = 8
74 | ImageIndex = 2
75 | Style = tbsSeparator
76 | end
77 | object BtnSCR: TToolButton
78 | Left = 146
79 | Top = 2
80 | Hint = 'SCR Editor (F1)'
81 | Caption = 'SCR'
82 | ImageIndex = 2
83 | ParentShowHint = False
84 | ShowHint = True
85 | OnClick = BtnSCRClick
86 | end
87 | object BtnSCRAdd: TToolButton
88 | Left = 192
89 | Top = 2
90 | Hint = 'Add a new Tracker entry to the SCR file'
91 | Caption = 'Entry'
92 | ImageIndex = 6
93 | ParentShowHint = False
94 | ShowHint = True
95 | OnClick = BtnSCRAddClick
96 | end
97 | object ToolButton5: TToolButton
98 | Left = 238
99 | Top = 2
100 | Width = 8
101 | ImageIndex = 1
102 | Style = tbsSeparator
103 | end
104 | object BtnManual: TToolButton
105 | Left = 246
106 | Top = 2
107 | Hint = 'Software Manual Editor'
108 | Caption = 'Manual'
109 | ImageIndex = 10
110 | ParentShowHint = False
111 | ShowHint = True
112 | OnClick = BtnManualClick
113 | end
114 | object ToolButton3: TToolButton
115 | Left = 292
116 | Top = 2
117 | Width = 8
118 | ImageIndex = 5
119 | Style = tbsSeparator
120 | end
121 | object BtnPRO: TToolButton
122 | Left = 300
123 | Top = 2
124 | Hint = 'Release Documentation Editor (F2)'
125 | Caption = 'Docs'
126 | ImageIndex = 3
127 | ParentShowHint = False
128 | ShowHint = True
129 | OnClick = BtnPROClick
130 | end
131 | object BtnPROWizard: TToolButton
132 | Left = 346
133 | Top = 2
134 | Hint = 'Release Documentation Wizard'
135 | Caption = 'Wizard'
136 | ImageIndex = 5
137 | ParentShowHint = False
138 | ShowHint = True
139 | OnClick = BtnPROWizardClick
140 | end
141 | object ToolButton2: TToolButton
142 | Left = 392
143 | Top = 2
144 | Width = 8
145 | ImageIndex = 2
146 | Style = tbsSeparator
147 | end
148 | object BtnCommit: TToolButton
149 | Left = 400
150 | Top = 2
151 | Hint = 'Commit source modifications (F3)'
152 | Caption = 'Commit'
153 | ImageIndex = 4
154 | ParentShowHint = False
155 | ShowHint = True
156 | OnClick = BtnCommitClick
157 | end
158 | object BtnBackup: TToolButton
159 | Left = 446
160 | Top = 2
161 | Hint = 'Incremental Backup (F4)'
162 | Caption = 'Backup'
163 | ImageIndex = 1
164 | ParentShowHint = False
165 | ShowHint = True
166 | OnClick = BtnBackupClick
167 | end
168 | object BtnBackupOpen: TToolButton
169 | Left = 492
170 | Top = 2
171 | Hint = 'View a backup content'
172 | Caption = 'GetBack'
173 | DropdownMenu = PopupMenuBackup
174 | ImageIndex = 11
175 | ParentShowHint = False
176 | ShowHint = True
177 | OnClick = BtnBackupOpenClick
178 | end
179 | object ToolButton4: TToolButton
180 | Left = 538
181 | Top = 2
182 | Width = 8
183 | Caption = 'ToolButton4'
184 | ImageIndex = 12
185 | Style = tbsSeparator
186 | end
187 | object BtnAbout: TToolButton
188 | Left = 546
189 | Top = 2
190 | Caption = 'About'
191 | ImageIndex = 9
192 | OnClick = BtnAboutClick
193 | end
194 | end
195 | object PanelLeft: TPanel
196 | Left = 0
197 | Top = 42
198 | Width = 305
199 | Height = 296
200 | Align = alLeft
201 | TabOrder = 1
202 | end
203 | object PanelRight: TPanel
204 | Left = 308
205 | Top = 42
206 | Width = 370
207 | Height = 296
208 | Align = alClient
209 | TabOrder = 2
210 | end
211 | object ImageList: TImageList
212 | Left = 32
213 | Top = 181
214 | end
215 | object PopupMenuBackup: TPopupMenu
216 | Left = 500
217 | Top = 50
218 | end
219 | object PopupMenuOpen: TPopupMenu
220 | Left = 8
221 | Top = 50
222 | end
223 | end
224 |
--------------------------------------------------------------------------------
/ProjectVersionPages.dfm:
--------------------------------------------------------------------------------
1 | object FramePages: TFramePages
2 | Left = 0
3 | Top = 0
4 | Width = 567
5 | Height = 315
6 | Font.Charset = DEFAULT_CHARSET
7 | Font.Color = clWindowText
8 | Font.Height = -11
9 | Font.Name = 'Tahoma'
10 | Font.Style = []
11 | ParentFont = False
12 | TabOrder = 0
13 | object Pages: TPageControl
14 | Left = 0
15 | Top = 0
16 | Width = 567
17 | Height = 315
18 | ActivePage = PageFile
19 | Align = alClient
20 | TabOrder = 0
21 | OnChange = PagesChange
22 | object PageCommit: TTabSheet
23 | Caption = 'By Commit'
24 | object Splitter1: TSplitter
25 | Left = 201
26 | Top = 0
27 | Height = 287
28 | end
29 | object ListCommit: TListView
30 | Left = 0
31 | Top = 0
32 | Width = 201
33 | Height = 287
34 | Align = alLeft
35 | Columns = <>
36 | Items.Data = {1D0000000100000000000000FFFFFFFFFFFFFFFF000000000000000000}
37 | TabOrder = 0
38 | end
39 | object CommitRight: TPanel
40 | Left = 204
41 | Top = 0
42 | Width = 355
43 | Height = 287
44 | Align = alClient
45 | TabOrder = 1
46 | object ListCommitFiles: TListView
47 | Left = 1
48 | Top = 25
49 | Width = 353
50 | Height = 261
51 | Align = alClient
52 | Columns = <>
53 | TabOrder = 0
54 | OnMouseDown = ListCommitFilesMouseDown
55 | end
56 | object CommitRightTop: TPanel
57 | Left = 1
58 | Top = 1
59 | Width = 353
60 | Height = 24
61 | Align = alTop
62 | TabOrder = 1
63 | DesignSize = (
64 | 353
65 | 24)
66 | object LabelCommitRightTop: TLabel
67 | Left = 110
68 | Top = 6
69 | Width = 239
70 | Height = 13
71 | Anchors = [akLeft, akTop, akRight]
72 | AutoSize = False
73 | Font.Charset = DEFAULT_CHARSET
74 | Font.Color = clWindowText
75 | Font.Height = -11
76 | Font.Name = 'Tahoma'
77 | Font.Style = [fsItalic]
78 | ParentFont = False
79 | end
80 | object BtnComitRightTop: TSpeedButton
81 | Left = 5
82 | Top = 4
83 | Width = 16
84 | Height = 16
85 | Hint = 'Show / Hide Commit column'
86 | Glyph.Data = {
87 | 36030000424D3603000000000000360000002800000010000000100000000100
88 | 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF
89 | FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
90 | FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
91 | 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
92 | FF00FFFF00FFFF00FF006600006600FF00FFFF00FFFF00FFFF00FFFF00FFFF00
93 | FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0066001EB2311FB13300
94 | 6600FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
95 | FF00FF00660031C24F22B7381AB02D21B437006600FF00FFFF00FFFF00FFFF00
96 | FFFF00FFFF00FFFF00FFFF00FFFF00FF00660047D36D3BCB5E25A83B0066001B
97 | A92E1DB132006600FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF006600
98 | 4FD67953DE7F31B54D006600FF00FF006600179D271EAE31006600FF00FFFF00
99 | FFFF00FFFF00FFFF00FFFF00FFFF00FF00660041C563006600FF00FFFF00FFFF
100 | 00FFFF00FF00660019AA2B006600FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
101 | FF00FF006600FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF006600149D210066
102 | 00FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
103 | 00FFFF00FFFF00FFFF00FFFF00FF006600006600FF00FFFF00FFFF00FFFF00FF
104 | FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
105 | FF006600006600FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
106 | 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
107 | FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
108 | FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
109 | 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF
110 | FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00
111 | FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF
112 | 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF}
113 | Layout = blGlyphBottom
114 | ParentShowHint = False
115 | ShowHint = True
116 | Spacing = 0
117 | OnClick = BtnComitRightTopClick
118 | end
119 | object CheckBoxOnlyModified: TCheckBox
120 | Left = 24
121 | Top = 5
122 | Width = 89
123 | Height = 17
124 | Caption = 'only modified'
125 | Checked = True
126 | State = cbChecked
127 | TabOrder = 0
128 | OnClick = CheckBoxOnlyModifiedClick
129 | end
130 | end
131 | end
132 | end
133 | object PageFile: TTabSheet
134 | Caption = 'By File'
135 | ImageIndex = 1
136 | object Splitter2: TSplitter
137 | Left = 329
138 | Top = 0
139 | Height = 287
140 | end
141 | object ListFiles: TListView
142 | Left = 0
143 | Top = 0
144 | Width = 329
145 | Height = 287
146 | Align = alLeft
147 | Columns = <>
148 | TabOrder = 0
149 | end
150 | object ListFilesCommit: TListView
151 | Left = 332
152 | Top = 0
153 | Width = 227
154 | Height = 287
155 | Align = alClient
156 | Columns = <>
157 | MultiSelect = True
158 | TabOrder = 1
159 | OnSelectItem = ListFilesCommitSelectItem
160 | end
161 | end
162 | end
163 | end
164 |
--------------------------------------------------------------------------------
/ProjectVersionCompare.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning comparison form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectVersionCompare;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
30 | Menus, ComCtrls, ExtCtrls, SynMemoEx, ProjectCommons,
31 | ProjectVersioning,
32 | ProjectEditor, ProjectFrameViewer, ProjectFormViewTwo;
33 |
34 | type
35 | TProjectVersionCompareForm = class(TForm)
36 | PanelLeft: TPanel;
37 | PanelRight: TPanel;
38 | ListFilesCommit: TListView;
39 | procedure FormResize(Sender: TObject);
40 | procedure FormShow(Sender: TObject);
41 | procedure ListFilesCommitSelectItem(Sender: TObject; Item: TListItem;
42 | Selected: Boolean);
43 | private
44 | procedure SynchronizeOnScroll(Sender: TObject);
45 | public
46 | Backup,
47 | Versions: TVersions;
48 | Editor: TFrameEditor;
49 | EditorText: string;
50 | Title,
51 | FileName: string;
52 | FileNameIndex: integer; // in Backup.FileNames[]
53 | View1,
54 | View2: TFrameViewer;
55 | procedure OnEditorBtnHistoryClick(Sender: TObject);
56 | procedure Init(aVersions: TVersions; aEditor: TFrameEditor; const aFileName: string);
57 | procedure CompareUsing(const aTitle: string; Back: TVersions);
58 | end;
59 |
60 | var
61 | ProjectVersionCompareForm: TProjectVersionCompareForm;
62 |
63 | implementation
64 |
65 | uses
66 | ProjectVersionMain;
67 |
68 | {$R *.dfm}
69 |
70 | { TProjectVersionCompareForm }
71 |
72 | procedure TProjectVersionCompareForm.CompareUsing(const aTitle: string; Back: TVersions);
73 | var i: integer;
74 | begin
75 | Backup := Back;
76 | FileNameIndex := Back.FileNames.FindIndex(FileName);
77 | if FileNameIndex<0 then exit;
78 | Title := StringReplaceAll(aTitle,'&','');
79 | Caption := ' '+Title;
80 | WindowState := wsMaximized;
81 | View1.Free;
82 | View1 := TFrameViewer.Create(self,Back,nil,false);
83 | View1.FileName := FileName;
84 | View1.Parent := PanelLeft;
85 | View1.Align := alClient;
86 | View1.Name := 'View1';
87 | View1.Diff := true;
88 | View1.MemoEx.OnScroll := SynchronizeOnScroll;
89 | // right = current Editor content
90 | View2.Free;
91 | View2 := TFrameViewer.Create(self,Back,nil,false);
92 | View2.FileName := FileName;
93 | View2.Parent := PanelRight;
94 | View2.Align := alClient;
95 | View2.Name := 'View2';
96 | View2.Diff := true;
97 | View2.MemoEx.OnScroll := SynchronizeOnScroll;
98 | MainForm.PagesLeft.CommitInit(ListFilesCommit);
99 | for i := Back.Count-1 downto 0 do
100 | with Back.Values[i] do
101 | if FileName=FileNameIndex then
102 | MainForm.PagesLeft.CommitAdd(Back,Commit,true,ListFilesCommit);
103 | MainForm.PagesLeft.CommitEnd(ListFilesCommit);
104 | ListFilesCommit.OnResize := nil; // FormResize;
105 | ShowModal;
106 | end;
107 |
108 | procedure TProjectVersionCompareForm.OnEditorBtnHistoryClick(Sender: TObject);
109 | // just a TMenuItem with Tag = BakcupDir #
110 | var Menu: TMenuItem absolute Sender;
111 | b, path, FN: string;
112 | Back: TVersions;
113 | begin
114 | if not Sender.InheritsFrom(TMenuItem) then exit;
115 | if Menu.Tag=-1 then // Tag=-1 -> commits = Version
116 | Back := Versions else begin
117 | b := Versions.Params['BackupDir'+IntToStr(Menu.Tag)];
118 | // BackupDir0=Local backup,012345,D:\-=- Backup -=-\Synopse\
119 | FN := Versions.GetBackupFileName(b,path);
120 | if not FileExists(FN) then exit;
121 | Back := TVersions.Create(FN);
122 | end;
123 | try
124 | EditorText := Editor.Memo.Lines.Text;
125 | CompareUsing('Compare with '+Menu.Caption, Back);
126 | finally
127 | if Back<>Versions then
128 | Back.Free;
129 | end;
130 | end;
131 |
132 | procedure TProjectVersionCompareForm.FormResize(Sender: TObject);
133 | var W: integer;
134 | begin
135 | W := (ClientWidth-ListFilesCommit.Width)div 2;
136 | PanelLeft.Width := W;
137 | PanelRight.Width := W;
138 | end;
139 |
140 | procedure TProjectVersionCompareForm.SynchronizeOnScroll(Sender: TObject);
141 | var M: TMemoEx absolute Sender;
142 | begin
143 | if not (Sender.InheritsFrom(TMemoEx)) then exit;
144 | if M=View1.MemoEx then
145 | View2.MemoEx.SetLeftTop(0,M.TopRow) else
146 | if M=View2.MemoEx then
147 | View1.MemoEx.SetLeftTop(0,M.TopRow);
148 | end;
149 |
150 | procedure TProjectVersionCompareForm.Init(aVersions: TVersions;
151 | aEditor: TFrameEditor; const aFileName: string);
152 | begin
153 | Versions := aVersions;
154 | Editor := aEditor;
155 | FileName := aFileName;
156 | end;
157 |
158 | procedure TProjectVersionCompareForm.FormShow(Sender: TObject);
159 | begin
160 | if ListFilesCommit.Items.Count>0 then
161 | ListFilesCommit.ItemIndex := 0;
162 | View2.MemoEx.SetFocus; // must be after having been shown
163 | end;
164 |
165 | procedure TProjectVersionCompareForm.ListFilesCommitSelectItem(
166 | Sender: TObject; Item: TListItem; Selected: Boolean);
167 | var List: TListView absolute Sender;
168 | Diff: TDiffCalc;
169 | begin
170 | if csDestroying in ComponentState then exit;
171 | if not Sender.InheritsFrom(TListView) or not Assigned(Backup) then exit;
172 | if List.SelCount>1 then begin // maximum 1 selected item
173 | Item.Selected := false;
174 | exit;
175 | end;
176 | Diff.Execute(Backup.GetVersionData(FileNameIndex,integer(Item.Data)), EditorText,
177 | View1.MemoEx, View2.MemoEx, false);
178 | Caption := format(' %s - %s : %d add, %d mod, %d del',[
179 | Title,FileName,Diff.linesAdd,Diff.linesMod,Diff.linesDel]);
180 | View2.GotoNextModif;
181 | end;
182 |
183 | end.
184 |
--------------------------------------------------------------------------------
/ProjectTrackerLogin.dfm:
--------------------------------------------------------------------------------
1 | object ProjectTrackerLoginForm: TProjectTrackerLoginForm
2 | Left = 470
3 | Top = 204
4 | BorderStyle = bsDialog
5 | Caption = ' PVCS Tracker'
6 | ClientHeight = 345
7 | ClientWidth = 429
8 | Color = clBtnFace
9 | Font.Charset = DEFAULT_CHARSET
10 | Font.Color = clWindowText
11 | Font.Height = -11
12 | Font.Name = 'Tahoma'
13 | Font.Style = []
14 | OldCreateOrder = False
15 | Position = poScreenCenter
16 | OnDestroy = FormDestroy
17 | OnShow = FormShow
18 | PixelsPerInch = 96
19 | TextHeight = 13
20 | object BtnOk: TBitBtn
21 | Left = 136
22 | Top = 296
23 | Width = 105
24 | Height = 33
25 | Hint = 'OK,Connect'
26 | Caption = 'Connect'
27 | Default = True
28 | ModalResult = 1
29 | TabOrder = 0
30 | OnClick = BtnOkClick
31 | Glyph.Data = {
32 | F6000000424DF600000000000000760000002800000010000000100000000100
33 | 0400000000008000000000000000000000001000000000000000040204000482
34 | 0400848204008402040004FE0400FCFEFC00FC02040004FEFC00000040000000
35 | 00000000000000000000DFFBC100DA67AB00410080007E007C00000555500000
36 | 0000002222500000000000222253633300000022225136363600002222541413
37 | 3330002222514141363603222257143413630622225147414413552222555474
38 | 7143222222225747471422222222577474732222222266774743006666676664
39 | 7460006466777666436000067464666366000000024744660000}
40 | end
41 | object BtnCancel: TBitBtn
42 | Left = 288
43 | Top = 296
44 | Width = 105
45 | Height = 33
46 | Cancel = True
47 | Caption = 'Cancel'
48 | ModalResult = 2
49 | TabOrder = 1
50 | Glyph.Data = {
51 | 96010000424D9601000000000000760000002800000018000000180000000100
52 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
53 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
54 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
55 | 1111111111111111111111111111111111111111111111111111111111111111
56 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
57 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
58 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
59 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
60 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
61 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
62 | 09D0111111110C40111111111001111111111001111111111111111111111111
63 | 1111111111111111111111111111111111111111111111111111}
64 | end
65 | object Pages: TPageControl
66 | Left = 0
67 | Top = 0
68 | Width = 431
69 | Height = 281
70 | ActivePage = TabSCRMulti
71 | TabOrder = 2
72 | object TabUser: TTabSheet
73 | TabVisible = False
74 | object Label3: TLabel
75 | Left = 40
76 | Top = 32
77 | Width = 4
78 | Height = 14
79 | Font.Charset = DEFAULT_CHARSET
80 | Font.Color = clNavy
81 | Font.Height = -12
82 | Font.Name = 'Tahoma'
83 | Font.Style = [fsBold]
84 | ParentFont = False
85 | end
86 | object UserName: TLabeledEdit
87 | Left = 40
88 | Top = 80
89 | Width = 353
90 | Height = 21
91 | EditLabel.Width = 175
92 | EditLabel.Height = 13
93 | EditLabel.Caption = 'User Name (leave blank for default):'
94 | TabOrder = 0
95 | end
96 | object PassWord: TLabeledEdit
97 | Left = 40
98 | Top = 128
99 | Width = 353
100 | Height = 21
101 | EditLabel.Width = 169
102 | EditLabel.Height = 13
103 | EditLabel.Caption = 'Password (leave blank for default):'
104 | TabOrder = 1
105 | end
106 | end
107 | object TabProject: TTabSheet
108 | ImageIndex = 1
109 | TabVisible = False
110 | object Label1: TLabel
111 | Left = 40
112 | Top = 32
113 | Width = 70
114 | Height = 13
115 | Caption = 'Select Project:'
116 | end
117 | object Project: TListBox
118 | Left = 40
119 | Top = 48
120 | Width = 345
121 | Height = 185
122 | ItemHeight = 13
123 | TabOrder = 0
124 | end
125 | end
126 | object TabSCR: TTabSheet
127 | ImageIndex = 2
128 | TabVisible = False
129 | object Label2: TLabel
130 | Left = 40
131 | Top = 16
132 | Width = 113
133 | Height = 13
134 | Caption = 'Choose one SCR entry:'
135 | end
136 | object SCRList: TListBox
137 | Left = 40
138 | Top = 32
139 | Width = 345
140 | Height = 225
141 | Style = lbOwnerDrawFixed
142 | ItemHeight = 13
143 | TabOrder = 0
144 | OnClick = SCRListClick
145 | OnDrawItem = SCRListDrawItem
146 | end
147 | end
148 | object TabSCRMulti: TTabSheet
149 | ImageIndex = 3
150 | TabVisible = False
151 | object Label4: TLabel
152 | Left = 40
153 | Top = 16
154 | Width = 3
155 | Height = 13
156 | end
157 | object SCRListMulti: TCheckListBox
158 | Left = 40
159 | Top = 32
160 | Width = 345
161 | Height = 225
162 | OnClickCheck = SCRListMultiClickCheck
163 | ItemHeight = 16
164 | Style = lbOwnerDrawFixed
165 | TabOrder = 0
166 | OnDrawItem = SCRListDrawItem
167 | end
168 | object BtnSelAll: TButton
169 | Left = 4
170 | Top = 168
171 | Width = 33
172 | Height = 25
173 | Hint = 'Select all entries'
174 | Caption = 'All'
175 | ParentShowHint = False
176 | ShowHint = True
177 | TabOrder = 1
178 | OnClick = BtnSelAllClick
179 | end
180 | object BtnSelNone: TButton
181 | Left = 4
182 | Top = 200
183 | Width = 33
184 | Height = 25
185 | Hint = 'Select no entry'
186 | Caption = 'None'
187 | ParentShowHint = False
188 | ShowHint = True
189 | TabOrder = 2
190 | OnClick = BtnSelAllClick
191 | end
192 | object BtnSelOpen: TButton
193 | Left = 4
194 | Top = 232
195 | Width = 33
196 | Height = 25
197 | Hint = 'Select all opened entries'
198 | Caption = 'Open'
199 | ParentShowHint = False
200 | ShowHint = True
201 | TabOrder = 3
202 | OnClick = BtnSelAllClick
203 | end
204 | end
205 | end
206 | end
207 |
--------------------------------------------------------------------------------
/ProjectFormViewOne.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning one file content view form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectFormViewOne;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | ProjectVersioning, ProjectFrameViewer, Menus, ExtCtrls;
31 |
32 | type
33 | TFormViewOne = class(TForm)
34 | PopupMenu: TPopupMenu;
35 | Image: TImage;
36 | private
37 | { Private declarations }
38 | Current: PVersion;
39 | Versions: TVersions;
40 | Commit1, Commit2: integer;
41 | function NewMenu(const Name: string; Value: integer; Menu: TMenuItem): TMenuItem;
42 | procedure ViewCreate(aVersions: TVersions; aVersion: PVersion; fillMemo: boolean);
43 | public
44 | { Public declarations }
45 | View: TFrameViewer;
46 | procedure Load(aVersions: TVersions; aVersion: PVersion; aCommit2: integer=-1);
47 | procedure CompareMenu(Sender: TObject);
48 | end;
49 |
50 | var
51 | FormViewOne: TFormViewOne;
52 |
53 | implementation
54 |
55 | {$R *.dfm}
56 |
57 | uses
58 | ProjectCommons,
59 | ProjectRTF,
60 | ProjectDiff,
61 | ProjectFormViewTwo;
62 |
63 | { TFormViewOne }
64 |
65 | procedure TFormViewOne.CompareMenu(Sender: TObject);
66 | var Menu: TMenuItem absolute Sender;
67 | isDiff: boolean;
68 | FileName, Commit: integer;
69 | Diff: TDiffCalc;
70 | begin
71 | if not Sender.InheritsFrom(TMenuItem) or (View=nil) then exit;
72 | isDiff := (Menu.Tag and (1 shl 16))<>0;
73 | Commit := Menu.Tag;
74 | if isDiff then
75 | Commit := Commit and pred(1 shl 16);
76 | dec(Commit);
77 | FileName := Current^.FileName;
78 | if Commit=-1 then
79 | Commit := Versions.PreviousCommit(FileName,Current^.Commit);
80 | if isDiff then begin
81 | if View=nil then begin
82 | ViewCreate(Versions, Current, false); // fillMemo=false
83 | Show;
84 | end;
85 | View.Diff := true;
86 | Diff.Execute(Versions.GetVersionData(FileName,Commit),
87 | Versions.GetVersionData(FileName,Current^.Commit),
88 | nil, View.MemoEx, true);
89 | Caption := format('%s diff vs #%d: %d add, %d mod, %d del',[
90 | Caption,Commit,Diff.linesAdd,Diff.linesMod,Diff.linesDel]);
91 | end else begin
92 | Hide;
93 | FormViewTwo.Load(Versions,Versions.GetVersion(FileName,Commit),Current,false);
94 | end;
95 | end;
96 |
97 | procedure TFormViewOne.ViewCreate(aVersions: TVersions; aVersion: PVersion; fillMemo: boolean);
98 | var firstVisible: boolean;
99 | Ext, FN, tmp: string;
100 | M, W, H: integer;
101 | begin
102 | firstVisible := View=nil;
103 | FreeAndNil(View);
104 | FN := aVersions.FileNames.Value[aVersion^.FileName];
105 | Ext := ExtractFileExt(FN);
106 | if (GetStringIndex(VALID_PICTURES_EXT, Ext)>=0)
107 | or SameText(Ext,'.BMP') or SameText(Ext,'.ICO') then begin
108 | // 1. display picture file
109 | SetLength(tmp,255);
110 | SetLength(tmp,GetTempPath(255,pointer(tmp)));
111 | tmp := tmp+ExtractFileName(FN); // use a temporary file to load pic contents
112 | if FileExists(tmp) and not DeleteFile(tmp) then exit;
113 | try
114 | StringToFile(tmp,aVersions.GetVersionData(aVersion^.FileName,aVersion^.Commit));
115 | Image.Picture.LoadFromFile(tmp);
116 | finally // on any load error -> exception -> delete tmp and display nothing
117 | DeleteFile(tmp);
118 | end;
119 | W := Image.Picture.Width;
120 | H := Image.Picture.Height;
121 | M := Monitor.Width div 2;
122 | if W>M then begin
123 | Image.Stretch := true;
124 | ClientWidth := M;
125 | ClientHeight := (M*H)div W;
126 | end else begin
127 | Image.Stretch := false;
128 | ClientWidth := W;
129 | ClientHeight := H;
130 | end;
131 | Image.Visible := true;
132 | Left := Monitor.Width-Width;
133 | Top := Monitor.WorkareaRect.Bottom-Height;
134 | end else begin
135 | // 2. display text content (using a TFrameViewer.MemoEx)
136 | Image.Visible := false;
137 | View := TFrameViewer.Create(self,aVersions,aVersion,true);
138 | View.Parent := self;
139 | View.Align := alClient;
140 | if firstVisible then
141 | ClientWidth := View.MemoEx.CellRect.Width*84+View.MemoEx.GutterWidth;
142 | if firstVisible then begin
143 | Top := 200;
144 | Left := Monitor.Width-Width;
145 | Height := Monitor.WorkareaRect.Bottom-Top;
146 | end;
147 | end;
148 | end;
149 |
150 | procedure TFormViewOne.Load(aVersions: TVersions; aVersion: PVersion; aCommit2: integer);
151 | procedure CompareWith(Commit: integer);
152 | begin
153 | NewMenu(format('Compare with %s',[aVersions.CommitToString(Commit)]),
154 | Commit+1,PopupMenu.Items).OnClick := CompareMenu;
155 | end;
156 | procedure DiffFrom(Commit: integer);
157 | begin
158 | NewMenu(format('Diff from %s',[aVersions.CommitToString(Commit)]),
159 | (Commit+1)or(1 shl 16),PopupMenu.Items).OnClick := CompareMenu;
160 | end;
161 | var Menu: TMenuItem;
162 | i: integer;
163 | FN, C: integer;
164 | begin
165 | if visible then begin // update only if visible
166 | ViewCreate(aVersions, aVersion, true); // fillMemo=true
167 | if View<>nil then
168 | View.MemoEx.PopupMenu := PopupMenu;
169 | end;
170 | FN := aVersion^.FileName;
171 | C := aVersion^.Commit;
172 | Caption := format('%s - #%d',[aVersions.FileNames.Value[FN],C]);
173 | Current := aVersion; // update PopupMenu (used also for caller)
174 | Versions := aVersions;
175 | Commit1 := aVersion^.Commit;
176 | Commit2 := Commit1;
177 | PopupMenu.Items.Clear;
178 | if View=nil then exit;
179 | if (aCommit2>=0) and (aCommit2<=aVersions.LastCommit) and (Commit1<>aCommit2) then begin
180 | Commit2 := aCommit2;
181 | CompareWith(-1);
182 | CompareWith(Commit2);
183 | DiffFrom(-1);
184 | DiffFrom(Commit2);
185 | end else begin
186 | CompareWith(-1);
187 | DiffFrom(-1);
188 | end;
189 | Menu := NewMenu(format('Compare #%d with',[C]),0,PopupMenu.Items);
190 | with Versions do
191 | for i := Count-1 downto 0 do
192 | with Values[i] do
193 | if FileName=FN then
194 | if Commit=C then
195 | NewMenu('-',0,Menu) else
196 | NewMenu(CommitToString(Commit),Commit+1,Menu).OnClick := CompareMenu;
197 | if Menu.Count=1 then
198 | PopupMenu.Items.Clear; // no other version -> no popupmenu
199 | end;
200 |
201 | function TFormViewOne.NewMenu(const Name: string; Value: integer; Menu: TMenuItem): TMenuItem;
202 | begin
203 | result := TMenuItem.Create(Owner);
204 | result.Caption := Name;
205 | result.Tag := Value;
206 | Menu.Add(result);
207 | end;
208 |
209 |
210 | end.
211 |
--------------------------------------------------------------------------------
/ProjectFormDocWizard.dfm:
--------------------------------------------------------------------------------
1 | object ProjectDocWizard: TProjectDocWizard
2 | Left = 188
3 | Top = 142
4 | BorderStyle = bsDialog
5 | ClientHeight = 597
6 | ClientWidth = 778
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -11
11 | Font.Name = 'Tahoma'
12 | Font.Style = []
13 | OldCreateOrder = False
14 | Position = poScreenCenter
15 | OnDestroy = FormDestroy
16 | OnShow = FormShow
17 | PixelsPerInch = 96
18 | TextHeight = 13
19 | object BtnPrev: TBitBtn
20 | Left = 208
21 | Top = 552
22 | Width = 113
23 | Height = 38
24 | Caption = 'Previous'
25 | ParentShowHint = False
26 | ShowHint = True
27 | TabOrder = 1
28 | OnClick = BtnPrevClick
29 | Glyph.Data = {
30 | B6020000424DB602000000000000760000002800000030000000180000000100
31 | 04000000000040020000130B0000130B00001000000000000000055806000C84
32 | 1B00999B990010B525005CCF84008EDEAB0032BB5500CDCDCD0037C56600FC02
33 | FC007C7A7C00B0B0B000CAF0D60013A62800F8FAF800B3E9C400999999990000
34 | 00009999999999999999AAAAAAAA9999999999999900D333333D009999999999
35 | 99AA22222222AA999999999900D3333333333D0099999999AA222222222222AA
36 | 99999991133333333333333109999992222222222222222AA999991133333333
37 | 3333333310999922B222222222222222AA999913333333FEE83333333099992B
38 | B22222CEEB2222222A9991D633333FEEE53333333109922BBB222EEEE7222222
39 | 22A991866633FEEEC8333333330992BBBB22EEEEEB22222222A93D86663FEEEC
40 | 83333333331022BBBB2EEEEEBBB22222222A3688885EEE586633333333D02BBB
41 | BB7EEE7BBBBB2222222A388885EEEEECCCCCCCCF33302BBBB7EEEEEEEEEEEEEC
42 | 222A38488EEEEEEEEEEEEEEE33302BBBBEEEEEEEEEEEEEEE222A34488CEEEEEE
43 | EEEEEEEE3330277BBEEEEEEEEEEEEEEE222A345444CEEEF44444444833D0277B
44 | B7EEEEC77777777B222A3454444FEEEF8888666333D027C7BBBEEEEEBBBBBBBB
45 | 222A38554444FEEEE486333333102BCCBBBBEEEEE7BBBB2222AA935F58444FEE
46 | EF8663333309927E7BBBBEEEECBBBBB222A9934FC544445EE4866633310992BE
47 | E7BBBB7EE7BBBBBBB2A99934CC54444444466666D0999927EE7BBBBBBBBBBBBB
48 | 2A9999365CCF5488888886631099992B7EEE77BBBBBBBBB22A99999364FCCF55
49 | 4444486119999992B7EEEE7777777B22299999993385FCCFF5548D1199999999
50 | 22B7EEEEEC77B2229999999999336444446D1199999999999922B77777B22299
51 | 9999999999993333333399999999999999992222222299999999}
52 | NumGlyphs = 2
53 | end
54 | object BtnNext: TBitBtn
55 | Left = 336
56 | Top = 552
57 | Width = 113
58 | Height = 38
59 | Caption = 'Next'
60 | ParentShowHint = False
61 | ShowHint = True
62 | TabOrder = 2
63 | OnClick = BtnNextClick
64 | Glyph.Data = {
65 | B6020000424DB602000000000000760000002800000030000000180000000100
66 | 04000000000040020000130B0000130B00001000000000000000055806000C84
67 | 1B00999A990011B526005DD086008CDEAA0030BC5300CECECE0037C56500FC02
68 | FC007C7A7C00B1B1B100CCF0D80013A62800F8FAF800AFE7C000999999990000
69 | 00009999999999999999AAAAAAAA9999999999999900D333333D009999999999
70 | 99AA22222222AA999999999900D3333333333D0099999999AA222222222222AA
71 | 99999991133333333333333109999992222222222222222AA999991133333333
72 | 33333333109999222222222222222222AA99991633333338EEF3333330999922
73 | 2222222BEEC222222A9991D633333665EEEF33333109922B22222B27EEEC2222
74 | 22A9918666666668CEEEF333330992BBBBBBBBBBEEEEC22222A93D8666686666
75 | 8FEEEF33331022BBBBBBBBBBBEEEEC22222A368888888666685EEE4333D02BBB
76 | BBBBBBBBBB7EEE72222A38888FCCCCCCCCEEEEE433302BBBBEEEEEEEEEEEEEE7
77 | 222A38488EEEEEEEEEEEEEEE33302BBBBEEEEEEEEEEEEEEE222A34488EEEEEEE
78 | EEEEEEEC3330277BBEEEEEEEEEEEEEEE222A34544455444444FEEEC633D0277B
79 | B777777777CEEEEB222A3454444444888FEEEF6333D027C7BBBBBBBBBEEEEEB2
80 | 222A38F544444444EEEEF33333102BCCBBBBBBB7EEEEC222222A935C5844444F
81 | EEEF63333309927E7BBBBBBCEEEEB22222A9934FC5444445EE566633310992BE
82 | E7BBBBB7EE7BBB2222A99934CC54444444466666D0999927EE7BBBBBBBBBBB2B
83 | 2A9999365CCF5488888886631099992B7EEE77BBBBBBBBB22A99999364FCCF55
84 | 4444486119999992B7EEEE7777777B22299999993385FCCCF5548D1199999999
85 | 22B7EEEEEC77B2229999999999338444446D1199999999999922B77777B22299
86 | 9999999999993333333399999999999999992222222299999999}
87 | NumGlyphs = 2
88 | end
89 | object BtnCancel: TBitBtn
90 | Left = 640
91 | Top = 552
92 | Width = 113
93 | Height = 38
94 | Cancel = True
95 | Caption = 'Cancel'
96 | ModalResult = 2
97 | TabOrder = 3
98 | Glyph.Data = {
99 | 96010000424D9601000000000000760000002800000018000000180000000100
100 | 04000000000020010000130B0000130B0000100000000000000004029C00FC02
101 | FC001343FA003461F900204FFB000424EA001C42ED000733F7002C4FE4004172
102 | FC00143AEC00052CF7001E48F7002D59F7003967FA002457FC00111111111111
103 | 1111111111111111111111111111111111111111111111111111111111111111
104 | 1001111111111001111111110270111111110BB011111110C22B01111110577B
105 | 011111102C227011110B7B7501111111064C270110B77750111111111064CCA0
106 | 0BBB75011111111111064CCA77B750111111111111106422A77B011111111111
107 | 11110C2222701111111111111111044C22A01111111111111110DF44444A0111
108 | 11111111110D3DDCCF44601111111111103E3E400CF44601111111110E9EE801
109 | 106F446011111110999980111106D44C011111109998011111106DFC01111111
110 | 09D0111111110C40111111111001111111111001111111111111111111111111
111 | 1111111111111111111111111111111111111111111111111111}
112 | end
113 | object PanelTop: TPanel
114 | Left = 0
115 | Top = 0
116 | Width = 778
117 | Height = 33
118 | Align = alTop
119 | Alignment = taLeftJustify
120 | Font.Charset = DEFAULT_CHARSET
121 | Font.Color = clNavy
122 | Font.Height = -16
123 | Font.Name = 'Tahoma'
124 | Font.Style = [fsItalic]
125 | ParentFont = False
126 | TabOrder = 0
127 | end
128 | object Pages: TPanel
129 | Left = 0
130 | Top = 33
131 | Width = 778
132 | Height = 504
133 | Align = alTop
134 | TabOrder = 4
135 | end
136 | object BtnWelcome: TBitBtn
137 | Left = 32
138 | Top = 552
139 | Width = 113
140 | Height = 38
141 | Caption = 'Pages'
142 | ParentShowHint = False
143 | ShowHint = True
144 | TabOrder = 5
145 | OnClick = BtnWelcomeClick
146 | Glyph.Data = {
147 | 96010000424D9601000000000000760000002800000018000000180000000100
148 | 04000000000020010000130B0000130B000010000000000000001B1209009D8E
149 | 6F00D5CDB200744D21008482FC00B7A8890094612500FBFBE70059381500BCB5
150 | 9F0078705D0031261B00BF8F4600D7AF5F00AA7A3700E9D59D0043EDFFFDFCDD
151 | C38BA9777FA4483CFFDDDC6366577777777A4433F7DCC688577777777F774443
152 | 65EEE3327777777144876B408366E577777777A44441D8444863D77777777A44
153 | 444BF64443357777777794444444FE4448E777777777B4444444DC8443777777
154 | 777144444444EEEBB2777777777B444444448CDE9777777777944444444403EC
155 | 7777777777A44444444400857777777777B4444444440A85777277777FB44444
156 | 44443772771319777FE304444444417777F5A8F772DDC8444444442777DFF977
157 | 243DFC6B4444448F7FF2F772B448DDFE344444812C77777754443DDE044444B2
158 | FAE97772544446F94444446C1821B44444444417FA44445ED6104444444444A7
159 | 71444088B0044444444444B52B4444444BA444444444444BB944}
160 | end
161 | object BtnSave: TBitBtn
162 | Left = 512
163 | Top = 552
164 | Width = 113
165 | Height = 38
166 | Caption = 'Save changes'
167 | ModalResult = 1
168 | TabOrder = 6
169 | OnClick = BtnSaveClick
170 | Glyph.Data = {
171 | 96010000424D9601000000000000760000002800000018000000180000000100
172 | 04000000000020010000130B0000130B00001000000000000000046604000C7C
173 | 10001EB6340041CE67001C9830002FC54F0059E3890017AC270034B24C00FC02
174 | FC00178F24004FD977002CB2470024AA3A0038BE580024A23400999999999999
175 | 9999999999999999999999999999999999999999999999999999999999999999
176 | 9999999999999999999999999999099999999999999999999990F09999999999
177 | 99999999990D7C09999999999999999990D277D099999999999999990452277D
178 | 09999999999999904355D0C7D09999999999990ABB3C09027D09999999999906
179 | 6BE09990A7D09999999999086E099999907D0999999999903099999999077099
180 | 9999999909999999999017099999999999999999999990A09999999999999999
181 | 9999990109999999999999999999999900999999999999999999999999099999
182 | 9999999999999999999999999999999999999999999999999999999999999999
183 | 9999999999999999999999999999999999999999999999999999}
184 | end
185 | object PopupMenu: TPopupMenu
186 | Left = 2
187 | Top = 544
188 | end
189 | end
190 |
--------------------------------------------------------------------------------
/synproject.css:
--------------------------------------------------------------------------------
1 | /*
2 | * synproject.css
3 | * ==============
4 | *
5 | * CSS typical for Synopse SynProject web export
6 | * http://synopse.info
7 | * Licensed under a GPL license
8 | *
9 | */
10 |
11 | body {
12 | font-family: Arial, Verdana, sans-serif;
13 | font-size: 1em;
14 | color: black;
15 | letter-spacing: -0.01em;
16 | line-height: 150%;
17 | text-align: left;
18 | background-color: #BFD1D4;
19 | padding: 0;
20 | border: 1px solid #aaa;
21 | margin: 0px 80px 0px 80px;
22 | min-width: 740px;
23 | max-width: 1240px;
24 | }
25 |
26 | svg {
27 | max-width: 100%;
28 | }
29 |
30 | div.document {
31 | font-family: Arial, Verdana, sans-serif;
32 | color: black;
33 | background-color: white;
34 | text-align: left;
35 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAoCAYAAAA/tpB3AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gBDRUWN0N7tMwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAN0lEQVQI16WNOQ4AIADCWv7/XhMnXdR4jC4kQAOUWlsAghIaBCECozhFHMieLatv9sOdbxfsXOngpgVLkKkPEQAAAABJRU5ErkJggg==);
36 | background-repeat: repeat-x;
37 | }
38 |
39 | div.bodywrapper {
40 | margin: 0 240px 0 0;
41 | border-right: 1px solid #ccc;
42 | }
43 |
44 | div.body {
45 | margin: 0;
46 | padding: 0.5em 20px 20px 20px;
47 | }
48 |
49 | div.related {
50 | background-color: white;
51 | font-size: 1em;
52 | }
53 |
54 | div.related a {
55 | color: #444444;
56 | }
57 |
58 | div.related ul {
59 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA8CAYAAACn8dD6AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gBDRUOAHndiZoAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAR0lEQVQY072NwRHAMAzCBPtP6wFCH6mddIF+OBlxZ6oqBrBtLKkJMBLWERJ7LJpChsAEzHSX2DZvnC6ZcfpcWR+bfnSNf48HN9YiTAPwk98AAAAASUVORK5CYII=);
60 | height: 2em;
61 | border-top: 1px solid #ddd;
62 | border-bottom: 1px solid #ddd;
63 | }
64 |
65 | div.related ul li {
66 | margin: 0;
67 | padding: 0;
68 | height: 2em;
69 | float: left;
70 | }
71 |
72 | div.related ul li.right {
73 | float: right;
74 | margin-right: 5px;
75 | }
76 |
77 | div.related ul li a {
78 | margin: 0;
79 | padding: 0 5px 0 5px;
80 | line-height: 1.75em;
81 | color: #EE9816;
82 | }
83 |
84 | div.related ul li a:hover {
85 | color: #3CA8E7;
86 | }
87 |
88 | div.sidebarwrapper {
89 | padding: 0;
90 | }
91 |
92 | div.sidebar {
93 | font-family: Arial, Verdana, sans-serif;
94 | margin: 0;
95 | padding: 0.5em 15px 15px 0;
96 | width: 210px;
97 | float: right;
98 | font-size: 1em;
99 | text-align: left;
100 | }
101 |
102 | @media (max-width: 1200px) {
103 | body {
104 | margin: 0;
105 | }
106 | }
107 | @media (max-width: 767px) {
108 | div.sidebar {
109 | float: none;
110 | padding: 0 0 0 80px
111 | }
112 | }
113 |
114 | div.sidebar h3, div.sidebar h4 {
115 | margin: 1em 0 0.5em 0;
116 | font-size: 1em;
117 | padding: 0.1em 0 0.1em 0.5em;
118 | color: white;
119 | border: 1px solid #86989B;
120 | background-color: #AFC1C4;
121 | }
122 |
123 | div.sidebar h3 a {
124 | color: white;
125 | }
126 |
127 | div.sidebar ul {
128 | padding-left: 1.5em;
129 | margin-top: 7px;
130 | padding: 0;
131 | line-height: 130%;
132 | }
133 |
134 | div.sidebar ul ul {
135 | margin-left: 20px;
136 | }
137 |
138 | div.footer {
139 | background-color: #E3EFF1;
140 | color: #86989B;
141 | padding: 3px 8px 3px 0;
142 | clear: both;
143 | font-size: 0.8em;
144 | text-align: right;
145 | }
146 |
147 | div.footer a {
148 | color: #86989B;
149 | text-decoration: underline;
150 | }
151 |
152 | p {
153 | margin: 0.8em 0 0.5em 0;
154 | }
155 |
156 | a {
157 | color: #00799A;
158 | text-decoration: none;
159 | }
160 |
161 | a:hover {
162 | color: #2491CF;
163 | }
164 |
165 | div.body a {
166 | text-decoration: underline;
167 | }
168 |
169 | h1 {
170 | margin: 2em 0 0 0;
171 | padding: 2em 0 0 0;
172 | font-size: 2em;
173 | color: black;
174 | }
175 |
176 | h2 {
177 | margin: 1.3em 0 0.2em 0;
178 | padding: 1.3em 0 0.3em 0;
179 | font-size: 1.5em;
180 | color: black;
181 | }
182 |
183 | h3, h4, h5, h6 {
184 | margin: 1em 0 -0.3em 0;
185 | padding: 1em 0 0.3em 0;
186 | font-size: 1.35em;
187 | color: black;
188 | }
189 |
190 | div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
191 | color: black!important;
192 | }
193 |
194 | h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
195 | display: none;
196 | margin: 0 0 0 0.3em;
197 | padding: 0 0.2em 0 0.2em;
198 | color: #aaa!important;
199 | }
200 |
201 | h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
202 | h5:hover a.anchor, h6:hover a.anchor {
203 | display: inline;
204 | }
205 |
206 | h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
207 | h5 a.anchor:hover, h6 a.anchor:hover {
208 | color: #777;
209 | background-color: #eee;
210 | }
211 |
212 | a.headerlink {
213 | color: #c60f0f!important;
214 | font-size: 1em;
215 | margin-left: 6px;
216 | padding: 0 4px 0 4px;
217 | text-decoration: none!important;
218 | }
219 |
220 | a.headerlink:hover {
221 | background-color: #ccc;
222 | color: white!important;
223 | }
224 |
225 | cite, code {
226 | font-family: Consolas, 'Deja Vu Sans Mono', monospace;
227 | font-size: 0.95em;
228 | letter-spacing: 0.01em;
229 | }
230 |
231 | code {
232 | background-color: #f2f2f2;
233 | border-bottom: 1px solid #ddd;
234 | color: black;
235 | }
236 |
237 | code.descname, code.descclassname, code.xref {
238 | border: 0;
239 | }
240 |
241 | hr {
242 | border: 1px solid #abc;
243 | margin: 2em;
244 | }
245 |
246 | a code {
247 | border: 0;
248 | color: #CA7900;
249 | }
250 |
251 | a code:hover {
252 | color: #2491CF;
253 | }
254 |
255 | pre {
256 | font-family: Consolas, 'Deja Vu Sans Mono', monospace;
257 | font-size: 0.95em;
258 | white-space: pre-wrap;
259 | letter-spacing: 0.015em;
260 | line-height: 120%;
261 | padding: 0.5em;
262 | border: 1px solid #ccc;
263 | background-color: #f8f8f8;
264 | }
265 |
266 | pre a {
267 | color: inherit;
268 | text-decoration: underline;
269 | }
270 |
271 | td.linenos pre {
272 | padding: 0.5em 0;
273 | }
274 |
275 | div.quotebar {
276 | background-color: #f8f8f8;
277 | max-width: 250px;
278 | float: right;
279 | padding: 2px 7px;
280 | border: 1px solid #ccc;
281 | }
282 |
283 | div.topic {
284 | background-color: #f8f8f8;
285 | }
286 |
287 | table {
288 | border-collapse: collapse;
289 | margin: 0 -0.5em 0 -0.5em;
290 | color: #00498A;
291 | }
292 |
293 | table td, table th {
294 | padding: 0.2em 0.5em 0.2em 0.5em;
295 | border-top: 0;
296 | border-left: 0;
297 | border-right: 0;
298 | border-bottom: 1px solid #aaa;
299 | }
300 |
301 | table pre, table code {
302 | color: #00498A;
303 | }
304 |
305 | div.admonition, div.warning {
306 | font-size: 0.9em;
307 | margin: 1em 0 1em 0;
308 | border: 1px solid #86989B;
309 | background-color: #f7f7f7;
310 | padding: 0;
311 | }
312 |
313 | div.admonition p, div.warning p {
314 | margin: 0.5em 1em 0.5em 1em;
315 | padding: 0;
316 | }
317 |
318 | div.admonition pre, div.warning pre {
319 | margin: 0.4em 1em 0.4em 1em;
320 | }
321 |
322 | div.admonition p.admonition-title,
323 | div.warning p.admonition-title {
324 | margin: 0;
325 | padding: 0.1em 0 0.1em 0.5em;
326 | color: white;
327 | border-bottom: 1px solid #86989B;
328 | font-weight: bold;
329 | background-color: #AFC1C4;
330 | }
331 |
332 | div.warning {
333 | border: 1px solid #940000;
334 | }
335 |
336 | div.warning p.admonition-title {
337 | background-color: #CF0000;
338 | border-bottom-color: #940000;
339 | }
340 |
341 | div.admonition ul, div.admonition ol,
342 | div.warning ul, div.warning ol {
343 | margin: 0.1em 0.5em 0.5em 3em;
344 | padding: 0;
345 | }
346 |
347 | div.versioninfo {
348 | margin: 1em 0 0 0;
349 | border: 1px solid #ccc;
350 | background-color: #DDEAF0;
351 | padding: 8px;
352 | line-height: 1.3em;
353 | font-size: 0.9em;
354 | }
355 |
356 | .label {
357 | display: inline-block;
358 | max-width: 100%;
359 | padding: 1px 5px 1px 5px;
360 | margin-bottom: 5px;
361 | color: white;
362 | background-color: #428bca;
363 | font-family: 'Comic Sans MS', cursive, sans-serif;
364 | font-size: 0.95em;
365 | border: 1px solid #ccc;
366 | }
367 |
368 | .label-primary {
369 | background-color: #5ac7ff;
370 | border: 1px solid #ddd;
371 | }
372 |
373 | @media print {
374 | div.document,
375 | div.documentwrapper,
376 | div.bodywrapper {
377 | margin: 0 !important;
378 | width: 100%;
379 | }
380 | div.sidebar,
381 | div.related,
382 | div.footer,
383 | #top-link {
384 | display: none;
385 | }
386 | }
--------------------------------------------------------------------------------
/ProjectFormViewTwo.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning two files diff view form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectFormViewTwo;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | ProjectVersioning, ProjectFrameViewer, ExtCtrls, SynMemoEx;
31 |
32 | type
33 | TDiffCalc = object
34 | FirstDiffLineIndex,
35 | linesAdd, linesMod, linesDel: integer;
36 | procedure Execute(Text1, Text2: string; Memo1, Memo2: TMemoEx;
37 | ShowDiffsOnly: boolean);
38 | end;
39 |
40 | TFormViewTwo = class(TForm)
41 | PanelLeft: TPanel;
42 | Splitter1: TSplitter;
43 | PanelRight: TPanel;
44 | procedure FormResize(Sender: TObject);
45 | procedure SynchronizeOnScroll(Sender: TObject);
46 | public
47 | View1,
48 | View2: TFrameViewer;
49 | Diff: TDiffCalc; // filled by Load()
50 | procedure Load(aVersions: TVersions; aVersion1, aVersion2: PVersion; ShowDiffsOnly: boolean);
51 | end;
52 |
53 | var
54 | FormViewTwo: TFormViewTwo;
55 |
56 |
57 | implementation
58 |
59 | {$R *.dfm}
60 |
61 | uses
62 | ProjectCommons,
63 | ProjectSections,
64 | ProjectDiffUnit; // diff calculation, less efficient than SynDiff, but human-readable
65 |
66 |
67 |
68 | { TDiffCalc }
69 |
70 | procedure TDiffCalc.Execute(Text1, Text2: string; // not const (BinToText...)
71 | Memo1, Memo2: TMemoEx; ShowDiffsOnly: boolean);
72 | var Diff: TDiff;
73 | P1, P2: PChar;
74 | i,j,k, v: integer;
75 | M1, M2: TStrings;
76 | s: string;
77 | procedure WriteIdem;
78 | begin
79 | if M1=nil then
80 | P1 := IgnoreLine(P1) else
81 | M1.AddObject(GetNextLine(P1,P1),pointer(integer(dkIdem)+j shl 3));
82 | if M2=nil then
83 | P2 := IgnoreLine(P2) else
84 | M2.AddObject(GetNextLine(P2,P2),pointer(integer(dkIdem)+k shl 3));
85 | inc(j);
86 | inc(k);
87 | end;
88 | begin
89 | // 1. init;
90 | linesAdd := 0;
91 | linesMod := 0;
92 | linesDel := 0;
93 | FirstDiffLineIndex := 0;
94 | if (Memo1=nil) and (Memo2=nil) then exit;
95 | Memo1.BeginUpdate;
96 | Memo2.BeginUpdate;
97 | if Memo1=nil then
98 | M1 := nil else
99 | M1 := Memo1.Lines;
100 | if Memo2=nil then
101 | M2 := nil else
102 | M2 := Memo2.Lines;
103 | try
104 | // 2. if binary file -> format as 80 bytes per line viewable text
105 | BinToTextIfNecessary(Text1);
106 | BinToTextIfNecessary(Text2);
107 | // 3. calculate changes
108 | Diff := CalculateDiff(Text1,Text2);
109 | if Diff=nil then begin
110 | if M1<>nil then
111 | M1.Text := Text1;
112 | if M2<>nil then
113 | M2.Text := Text2;
114 | exit;
115 | end;
116 | // 4. write changes
117 | if M1<>nil then
118 | M1.Clear;
119 | if M2<>nil then
120 | M2.Clear;
121 | j := 0;
122 | k := 0;
123 | P1 := pointer(Text1);
124 | P2 := pointer(Text2);
125 | for i := 0 to Diff.ChangeCount-1 do
126 | with Diff.Changes[i] do begin
127 | //first add preceeding unmodified lines
128 | if ShowDiffsOnly then begin // add from j to x
129 | v := x-j;
130 | if (i>0) and (v>3) then begin // show up to 3 lines after(i>0) modif
131 | WriteIdem;
132 | WriteIdem;
133 | WriteIdem;
134 | dec(v,3);
135 | end;
136 | if v>3 then begin // show 3 lines before modif
137 | if M2<>nil then M2.Add(' ...');
138 | v := 3;
139 | end;
140 | inc(k, x-j-v);
141 | while j < x-v do begin
142 | P1 := IgnoreLine(P1);
143 | P2 := IgnoreLine(P2);
144 | inc(j);
145 | end;
146 | end;
147 | while j < x do
148 | WriteIdem;
149 | if FirstDiffLineIndex=0 then
150 | FirstDiffLineIndex := k+1;
151 | case Kind of
152 | ckAdd: begin
153 | for j := k to k+Range-1 do begin
154 | if M1<>nil then
155 | M1.AddObject('',pointer(integer(dkAdd)));
156 | if M2=nil then
157 | P2 := IgnoreLine(P2) else
158 | M2.AddObject(GetNextLine(P2,P2),pointer(integer(dkAdd)+j shl 3));
159 | end;
160 | inc(linesAdd,Range);
161 | j := x;
162 | k := y+Range;
163 | end;
164 | ckModify: begin
165 | for j := 0 to Range-1 do begin
166 | s := GetNextLine(P1,P1);
167 | if M1<>nil then
168 | M1.AddObject(s,pointer(integer(dkModify)+(x+j)shl 3));
169 | if M2=nil then
170 | P2 := IgnoreLine(P2) else begin
171 | if ShowDiffsOnly then // diff: show original line before
172 | M2.AddObject(s,pointer(integer(dkModify)));
173 | M2.AddObject(GetNextLine(P2,P2),pointer(integer(dkModify)+(k+j)shl 3));
174 | end;
175 | end;
176 | inc(linesMod,Range);
177 | j := x+Range;
178 | k := y+Range;
179 | end;
180 | ckDelete: begin
181 | for j := x to x+Range-1 do begin
182 | s := GetNextLine(P1,P1);
183 | if M1<>nil then
184 | M1.AddObject(s,pointer(integer(dkDelete)+j shl 3));
185 | if M2<>nil then
186 | if (M1=nil) and ShowDiffsOnly then // diff: show deleted lines in red
187 | M2.AddObject(s,pointer(integer(dkDelete))) else
188 | M2.AddObject('',pointer(integer(dkDelete)));
189 | end;
190 | inc(linesDel,Range);
191 | j := x+Range;
192 | end;
193 | end;
194 | end;
195 | //add remaining unmodified lines...
196 | if ShowDiffsOnly then begin
197 | if P1^<>#0 then begin WriteIdem; // diff: show up to 3 lines after
198 | if P1^<>#0 then begin WriteIdem;
199 | if P1^<>#0 then begin WriteIdem;
200 | if P1^<>#0 then M2.Add(' ...'); end; end; end;
201 | end else
202 | while P1^<>#0 do
203 | WriteIdem;
204 | Diff.Free;
205 | finally
206 | Memo2.EndUpdate;
207 | Memo1.EndUpdate;
208 | end;
209 | end;
210 |
211 | { TFormViewTwo }
212 |
213 | procedure TFormViewTwo.Load(aVersions: TVersions; aVersion1, aVersion2: PVersion; ShowDiffsOnly: boolean);
214 | var s: string;
215 | M: TMonitor;
216 | v1, v2: string;
217 | begin
218 | if not Visible then begin
219 | Show;
220 | if Screen.MonitorCount>1 then begin // put on other monitor
221 | if Screen.Monitors[0]=Monitor then
222 | M := Screen.Monitors[1] else
223 | M := Screen.Monitors[0];
224 | with M.WorkareaRect do // manual maximize
225 | SetBounds(Left,Top,Right-Left,Bottom-Top);
226 | end;
227 | end;
228 | View1.Free;
229 | View1 := TFrameViewer.Create(self,aVersions,aVersion1,false);
230 | View1.Parent := PanelLeft;
231 | View1.Align := alClient;
232 | View1.Name := 'View1';
233 | View1.Diff := true;
234 | View1.MemoEx.OnScroll := SynchronizeOnScroll;
235 | View2.Free;
236 | View2 := TFrameViewer.Create(self,aVersions,aVersion2,false);
237 | View2.Parent := PanelRight;
238 | View2.Align := alClient;
239 | View2.MemoEx.SetFocus;
240 | View2.Name := 'View2';
241 | View2.Diff := true;
242 | View2.MemoEx.OnScroll := SynchronizeOnScroll;
243 | if (aVersion1=nil) or (aVersion2=nil) then
244 | exit; // Diff.Execute() and Caption will be done manually
245 | v1 := aVersions.GetVersionData(aVersion1^.FileName,aVersion1^.Commit);
246 | v2 := aVersions.GetVersionData(aVersion2^.FileName,aVersion2^.Commit);
247 | Diff.Execute(v1, v2, View1.MemoEx, View2.MemoEx, ShowDiffsOnly);
248 | View1.GotoNextModif;
249 | if aVersion1^.FileName=aVersion2^.FileName then
250 | s := format('%s #%d vs #%d',[
251 | aVersions.FileNames.Value[aVersion1^.FileName],aVersion1^.Commit,aVersion2^.Commit]) else
252 | s := format('%s #%d vs %s #%d',[
253 | aVersions.FileNames.Value[aVersion1^.FileName],aVersion1^.Commit,
254 | aVersions.FileNames.Value[aVersion2^.FileName],aVersion2^.Commit]);
255 | Caption := format('%s: %d add, %d mod, %d del',[
256 | s,Diff.linesAdd,Diff.linesMod,Diff.linesDel]);
257 | end;
258 |
259 | procedure TFormViewTwo.FormResize(Sender: TObject);
260 | begin
261 | PanelLeft.Width := ClientWidth div 2-Splitter1.Width;
262 | end;
263 |
264 | procedure TFormViewTwo.SynchronizeOnScroll(Sender: TObject);
265 | var M: TMemoEx absolute Sender;
266 | begin
267 | if not (Sender.InheritsFrom(TMemoEx)) then exit;
268 | if M=View1.MemoEx then
269 | View2.MemoEx.SetLeftTop(0,M.TopRow) else
270 | if M=View2.MemoEx then
271 | View1.MemoEx.SetLeftTop(0,M.TopRow);
272 | end;
273 |
274 |
275 | end.
276 |
--------------------------------------------------------------------------------
/ProjectFrameViewer.pas:
--------------------------------------------------------------------------------
1 | /// File Versioning file view frame
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectFrameViewer;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
30 | Dialogs, ProjectCommons,
31 | ProjectSections, ProjectVersioning, SynMemoEx;
32 |
33 | type
34 | TDiffKind = (dkIdem, dkAdd, dkDelete, dkModify);
35 |
36 | TFrameViewer = class(TFrame)
37 | MemoEx: TMemoEx;
38 | FindDialog: TFindDialog;
39 | procedure MemoExPaintGutter(Sender: TObject; Canvas: TCanvas; const Rect: TRect);
40 | procedure MemoExKeyDown(Sender: TObject; var Key: Word;
41 | Shift: TShiftState);
42 | procedure FindDialogFind(Sender: TObject);
43 | private
44 | fExt,
45 | fFileName: string;
46 | fDiff: boolean;
47 | fInternalOnGetLineAttr: TOnGetLineAttr;
48 | procedure MemoExGetLineAttr(Sender: TObject; const Line: String;
49 | index: Integer; const SelAttrs: TSelAttrs; var Attrs: TLineAttrs);
50 | procedure SetDiff(const Value: boolean);
51 | procedure SetFileName(const Value: string);
52 | public
53 | Versions: TVersions;
54 | constructor Create(AOwner: TComponent; aVersions: TVersions;
55 | aVersion: PVersion; fillMemo: boolean); reintroduce;
56 | procedure GotoNextModif;
57 | property FileName: string read fFileName write SetFileName;
58 | property Diff: boolean read fDiff write SetDiff;
59 | end;
60 |
61 | const
62 | DIFF_KIND_COLOR: array[TDiffKind] of TColor =
63 | (clWhite, $F0CCA8, $BB77FF, $6FFB8A);
64 |
65 | /// if binary file -> format as 80 bytes per line viewable text
66 | procedure BinToTextIfNecessary(var Text: string);
67 |
68 | /// if binary file -> format as 40 bytes per line viewable hex text
69 | procedure BinToHexIfNecessary(var Text: string);
70 |
71 | procedure TabToSpace(P: PChar);
72 |
73 | const
74 | BIN_MAX_SIZE = 256*1024; // truncate binary files under this size
75 |
76 | implementation
77 |
78 | {$R *.dfm}
79 |
80 | uses
81 | ProjectMemoExSyntax, ProjectRTF, ProjectVersionMain;
82 |
83 |
84 | { TFrameViewer }
85 |
86 | procedure TabToSpace(P: PChar);
87 | begin
88 | if P<>nil then
89 | while P^<>#0 do begin
90 | if P^=#9 then
91 | P^ := ' ';
92 | inc(P);
93 | end;
94 | end;
95 |
96 | procedure BinToHexIfNecessary(var Text: string);
97 | // if binary file -> format as 40 bytes per line viewable hex text
98 | var L, i, j, n: integer;
99 | old: string;
100 | S,D: PChar;
101 | begin
102 | L := length(Text);
103 | if L=0 then exit;
104 | for i := 0 to L-1 do
105 | if not (Text[i+1] in [#9,#13,#10,#26,' '..#255]) then begin // may be binary file
106 | if L>BIN_MAX_SIZE then begin
107 | L := BIN_MAX_SIZE; // trunc too big file
108 | old := Copy(Text,1,L);
109 | end else
110 | old := Text;
111 | n := (L+39) div 40; // line count
112 | SetLength(Text,L*2+n*2);
113 | S := pointer(old);
114 | D := pointer(Text);
115 | for j := 0 to n-2 do begin
116 | BinToHex(S,D,40);
117 | inc(S,40);
118 | inc(D,80);
119 | pWord(D)^ := $0a0d;
120 | inc(D,2);
121 | end;
122 | n := L mod 40;
123 | if n>0 then begin
124 | BinToHex(S,D,n);
125 | inc(D,n);
126 | pWord(D)^ := $0a0d;
127 | inc(D,2);
128 | end;
129 | D^ := #0;
130 | exit;
131 | end;
132 | TabToSpace(pointer(Text));
133 | end;
134 |
135 | procedure GoodWrite(S,D: PChar; n: integer);
136 | var i: integer;
137 | begin
138 | for i := 1 to n do begin
139 | if S^<' ' then
140 | D^ := ' ' else
141 | D^ := S^;
142 | inc(S);
143 | inc(D);
144 | end;
145 | end;
146 |
147 | procedure BinToTextIfNecessary(var Text: string);
148 | // if binary file -> format as 80 bytes per line viewable text
149 | var L, i, j, n: integer;
150 | old: string;
151 | S,D: PChar;
152 | begin
153 | L := length(Text);
154 | if L=0 then exit;
155 | for i := 0 to L-1 do
156 | if not (Text[i+1] in [#9,#13,#10,#26,' '..#255]) then begin // may be binary file
157 | if L>BIN_MAX_SIZE then begin
158 | L := BIN_MAX_SIZE; // trunc too big file
159 | old := Copy(Text,1,L);
160 | end else
161 | old := Text;
162 | n := (L+79) div 80; // line count
163 | SetLength(Text,L+n*2);
164 | S := pointer(old);
165 | D := pointer(Text);
166 | for j := 0 to n-2 do begin
167 | GoodWrite(S,D,80);
168 | inc(S,80);
169 | inc(D,80);
170 | pWord(D)^ := $0a0d;
171 | inc(D,2);
172 | end;
173 | n := L mod 80;
174 | if n>0 then begin
175 | GoodWrite(S,D,n);
176 | inc(D,n);
177 | pWord(D)^ := $0a0d;
178 | inc(D,2);
179 | end;
180 | D^ := #0;
181 | exit;
182 | end;
183 | TabToSpace(pointer(Text));
184 | end;
185 |
186 | constructor TFrameViewer.Create(AOwner: TComponent; aVersions: TVersions;
187 | aVersion: PVersion; fillMemo: boolean);
188 | var Text: string;
189 | begin
190 | inherited Create(AOwner);
191 | if Screen.Fonts.IndexOf('Consolas')>=0 then
192 | MemoEx.Font.Name := 'Consolas';
193 | MemoEx.Font.Size := 9;
194 | Versions := aVersions;
195 | if (aVersion=nil) or (Versions=nil) then exit;
196 | FileName := Versions.FileNames.Value[aVersion^.FileName];
197 | MemoEx.GutterWidth := 40;
198 | MemoEx.OnPaintGutter := MemoExPaintGutter;
199 | if fillMemo then begin
200 | Text := Versions.GetVersionData(aVersion^.FileName,aVersion^.Commit);
201 | if not Assigned(fInternalOnGetLineAttr) then
202 | BinToTextIfNecessary(Text) else
203 | TabToSpace(pointer(Text));
204 | MemoEx.Lines.Text := Text;
205 | MemoEx.OnGetLineAttr := fInternalOnGetLineAttr;
206 | end else
207 | MemoEx.OnGetLineAttr := MemoExGetLineAttr;
208 | end;
209 |
210 | procedure LineBackColor(Color: TColor; var Attrs: TLineAttrs; L: integer);
211 | var i: integer;
212 | begin
213 | for i := 0 to L-1 do
214 | Attrs[i].BC := Color;
215 | end;
216 |
217 | procedure TFrameViewer.MemoExGetLineAttr(Sender: TObject;
218 | const Line: String; index: Integer; const SelAttrs: TSelAttrs;
219 | var Attrs: TLineAttrs);
220 | var Kind: TDiffKind;
221 | begin
222 | if Assigned(fInternalOnGetLineAttr) then // syntax highlighting of the text
223 | fInternalOnGetLineAttr(Sender,Line,Index,SelAttrs,Attrs);
224 | if Diff and (index>=0) and (indexdkIdem then // modified? -> special background color
227 | LineBackColor(DIFF_KIND_COLOR[Kind],Attrs,length(Line));
228 | end;
229 | end;
230 |
231 | procedure TFrameViewer.MemoExPaintGutter(Sender: TObject; Canvas: TCanvas; const Rect: TRect);
232 | var L: integer;
233 | M: TMemoEx absolute Sender;
234 | s: string;
235 | i, v: integer;
236 | begin
237 | if M.GutterWidth=0 then exit;
238 | Canvas.Font.Color := clWhite;
239 | for L := 0 to M.VisibleRowCount-1 do begin
240 | v := M.TopRow+L;
241 | if v>=M.Lines.Count then exit;
242 | with M.Lines.Paragraphs[v]^ do
243 | if Diff and (FStrings[0]='') then // diff: don't show line number for void line
244 | continue else begin
245 | i := integer(FObject) shr 3;
246 | if i=0 then
247 | if Diff then
248 | continue else
249 | i := v+1;
250 | s := IntToStr(i);
251 | Canvas.TextOut(Rect.Right-Canvas.TextWidth(s)-8,Rect.Top+1+L*M.CellRect.Height,s);
252 | end;
253 | end;
254 | end;
255 |
256 | procedure TFrameViewer.GotoNextModif;
257 | var i: integer;
258 | L: TEditorStrings;
259 | K1,K2: TDiffKind;
260 | begin
261 | if not Diff then exit;
262 | L := MemoEx.Lines;
263 | if MemoEx.CaretY>=L.Count then exit;
264 | K1 := TDiffKind(integer(L.Paragraphs[MemoEx.CaretY]^.FObject) and 7);
265 | for i := MemoEx.CaretY+1 to L.Count-1 do begin // search current
266 | K2 := TDiffKind(integer(L.Paragraphs[i]^.FObject) and 7);
267 | if (K2<>dkIdem) and (K2<>K1) then begin
268 | MemoEx.TopRow := i-8;
269 | MemoEx.SetCaret(0,i);
270 | exit;
271 | end;
272 | K1 := K2;
273 | end;
274 | MemoEx.SetCaret(0,0); // not found -> will search from bottom down
275 | end;
276 |
277 | procedure TFrameViewer.MemoExKeyDown(Sender: TObject; var Key: Word;
278 | Shift: TShiftState);
279 | var P: TWinControl;
280 | W: string;
281 | begin
282 | case Key of
283 | VK_F3:
284 | if FindDialog.FindText<>'' then // F3 = Find Next
285 | FindDialog.OnFind(nil);
286 | VK_ESCAPE: begin // escape key -> hide code form
287 | P := Parent;
288 | while (P<>nil) and not P.InheritsFrom(TCustomForm) do
289 | P := P.Parent;
290 | if (P<>nil) and (P<>Application.MainForm) and P.InheritsFrom(TCustomForm) then
291 | if fsModal in TCustomForm(P).FormState then
292 | TCustomForm(P).Close else
293 | TCustomForm(P).Hide;
294 | end;
295 | VK_F7: begin
296 | GotoNextModif; // F7 for next modif
297 | Key := 0;
298 | end;
299 | ord('F'):
300 | if ssCtrl in Shift then begin
301 | W := MemoEx.GetWordOnCaret;
302 | if W<>'' then
303 | FindDialog.FindText := W;
304 | FindDialog.Execute; // Ctrl + F = find
305 | end;
306 | { ord('S'):
307 | if ssAlt in Shift then begin
308 | GotoNextModif; // Alt-S for next modif
309 | Key := 0;
310 | end; }
311 | end; // case Key of
312 | end;
313 |
314 | procedure TFrameViewer.SetDiff(const Value: boolean);
315 | begin
316 | fDiff := Value;
317 | if fDiff then
318 | MemoEx.OnGetLineAttr := MemoExGetLineAttr else
319 | MemoEx.OnGetLineAttr := fInternalOnGetLineAttr;
320 | end;
321 |
322 |
323 | procedure TFrameViewer.FindDialogFind(Sender: TObject);
324 | begin
325 | if not MemoEx.FindNext(FindDialog.FindText,not(frMatchCase in FindDialog.Options)) then
326 | FindDialog.CloseDialog;
327 | end;
328 |
329 | procedure TFrameViewer.SetFileName(const Value: string);
330 | begin
331 | fFileName := Value;
332 | fExt := ExtractFileExt(fFileName);
333 | fInternalOnGetLineAttr := TProjectSyntax.GetHighliter(fExt);
334 | end;
335 |
336 | initialization
337 | assert(integer(high(TDiffKind))<8);
338 | end.
339 |
340 |
--------------------------------------------------------------------------------
/ProjectTrackerLogin.pas:
--------------------------------------------------------------------------------
1 | /// PVCS Tracker connection login form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectTrackerLogin;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | uses
29 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
30 | Dialogs, StdCtrls, Buttons, ExtCtrls, ProjectTrkTool, ProjectCommons, ComCtrls,
31 | ProjectSections, CheckLst;
32 |
33 | type
34 | TProjectTrackerLoginForm = class(TForm)
35 | BtnOk: TBitBtn;
36 | BtnCancel: TBitBtn;
37 | Pages: TPageControl;
38 | TabUser: TTabSheet;
39 | TabProject: TTabSheet;
40 | TabSCR: TTabSheet;
41 | UserName: TLabeledEdit;
42 | PassWord: TLabeledEdit;
43 | Label1: TLabel;
44 | Project: TListBox;
45 | Label2: TLabel;
46 | SCRList: TListBox;
47 | Label3: TLabel;
48 | TabSCRMulti: TTabSheet;
49 | Label4: TLabel;
50 | SCRListMulti: TCheckListBox;
51 | BtnSelAll: TButton;
52 | BtnSelNone: TButton;
53 | BtnSelOpen: TButton;
54 | procedure FormShow(Sender: TObject);
55 | procedure FormDestroy(Sender: TObject);
56 | procedure BtnOkClick(Sender: TObject);
57 | procedure SCRListDrawItem(Control: TWinControl; Index: Integer;
58 | Rect: TRect; State: TOwnerDrawState);
59 | procedure SCRListClick(Sender: TObject);
60 | procedure BtnSelAllClick(Sender: TObject);
61 | procedure SCRListMultiClickCheck(Sender: TObject);
62 | private
63 | OriginalProjectIndex: integer;
64 | public
65 | Tracker: TPVCSTracker;
66 | SelectedID: integer;
67 | procedure ShowLogin;
68 | procedure ShowSCRList;
69 | procedure ShowSCRListMulti(const Title: string);
70 | end;
71 |
72 | var
73 | ProjectTrackerLoginForm: TProjectTrackerLoginForm = nil;
74 |
75 | function TrackerLogin(forceLog: boolean): TProjectTrackerLoginForm;
76 | procedure DeleteTempForm(F: TForm); // call after TrackerLogin()
77 |
78 | procedure SCRImportOne(Tracker: TPVCSTracker; n: integer;
79 | out Description, Request: string; Body: PString=nil);
80 |
81 | // show TProjectTrackerLoginForm to select entries to import
82 | function SCRImport(SCR: TSectionsStorage; forceLog: boolean=false): boolean;
83 |
84 |
85 | resourcestring
86 | sSelectEntriesToImport = 'Select entries to import';
87 | sLocalSCRN = 'BRS SCR #%d';
88 |
89 | implementation
90 |
91 | uses
92 | ProjectRTF;
93 |
94 | {$R *.dfm}
95 |
96 | procedure DeleteTempForm(F: TForm);
97 | begin
98 | if F<>ProjectTrackerLoginForm then
99 | F.Free; // delete temp form created if ProjectTrackerLoginForm not available
100 | end;
101 |
102 | function TrackerLogin(forceLog: boolean): TProjectTrackerLoginForm;
103 | begin
104 | if ProjectTrackerLoginForm=nil then // create temp form if not available
105 | result := TProjectTrackerLoginForm.Create(Application) else begin
106 | result := ProjectTrackerLoginForm;
107 | if not forceLog and (result.Tracker<>nil) and result.Tracker.Logged then
108 | exit;
109 | end;
110 | try
111 | result.ShowLogin;
112 | if result.ShowModal=mrOk then
113 | assert((result.Tracker<>nil)and(result.Tracker.Logged)) else begin
114 | DeleteTempForm(result);
115 | result := nil; // return nil of error login
116 | end;
117 | except
118 | on TPVCSTrackerException do begin
119 | // if result.Visible then result.Hide;
120 | DeleteTempForm(result);
121 | result := nil;
122 | end;
123 | end;
124 | end;
125 |
126 | function StringImport(const s: string): string;
127 | var j: integer;
128 | begin
129 | result := s;
130 | j := 1;
131 | while jnil then
179 | try
180 | F.ShowSCRListMulti(sSelectEntriesToImport);
181 | if F.ShowModal=mrOk then
182 | try
183 | Screen.Cursor := crHourGlass;
184 | for i := 0 to F.SCRListMulti.Count-1 do
185 | if F.SCRListMulti.Checked[i] then begin
186 | // 1. get checked item
187 | n := integer(F.SCRListMulti.Items.Objects[i]);
188 | num := IntToStr(n);
189 | if SCR[num]<>nil then
190 | exit; // don't add if already there
191 | // 2. update SCR with PVCS values
192 | SCRImportOne(F.Tracker,n,aDescription,aRequest,@aBody);
193 | with SCR.GetOrCreateSection(num,true) do begin
194 | Value['Request'] := aRequest;
195 | Value['ShortName'] := '';
196 | Value['Description'] := aDescription;
197 | end;
198 | SCR.WriteBody(num,aBody);
199 | end;
200 | result := true;
201 | finally
202 | Screen.Cursor := crDefault;
203 | end;
204 | finally
205 | DeleteTempForm(F);
206 | end;
207 | end;
208 |
209 | procedure TProjectTrackerLoginForm.FormShow(Sender: TObject);
210 | begin
211 | SelectedID := 0;
212 | if Tracker=nil then
213 | try
214 | Tracker := TPVCSTracker.Create;
215 | except
216 | on TPVCSTrackerException do
217 | FreeAndNil(Tracker);
218 | end;
219 | end;
220 |
221 | procedure TProjectTrackerLoginForm.FormDestroy(Sender: TObject);
222 | begin
223 | FreeAndNil(Tracker);
224 | end;
225 |
226 | procedure TProjectTrackerLoginForm.BtnOkClick(Sender: TObject);
227 | var i: integer;
228 | begin
229 | try
230 | try
231 | Screen.Cursor := crHourGlass;
232 | if Tracker<>nil then
233 | case Pages.ActivePageIndex of
234 | 0: begin
235 | Tracker.Login(UserName.Text,PassWord.Text);
236 | if Tracker.Logged then begin
237 | Pages.ActivePageIndex := 1;
238 | OriginalProjectIndex := Tracker.GetProjects(Project.Items);
239 | Project.ItemIndex := OriginalProjectIndex;
240 | end;
241 | end;
242 | 1: begin
243 | i := Project.ItemIndex;
244 | if i>=0 then begin
245 | if i<>OriginalProjectIndex then // relog only if necessary
246 | Tracker.Login(UserName.Text,PassWord.Text,Project.Items[i]);
247 | if Tracker.Logged then
248 | exit; // leave ModalResult=mrOk
249 | end;
250 | end;
251 | 2: begin
252 | SelectedID := SCRList.ItemIndex;
253 | if SelectedID>=0 then begin
254 | SelectedID := integer(SCRList.Items.Objects[SelectedID]);
255 | exit; // leave ModalResult=mrOk
256 | end;
257 | end;
258 | 3: exit; // BtnOk.enabled=true only if something was checked -> direct exit
259 | end;
260 | finally
261 | Screen.Cursor := crDefault;
262 | end;
263 | except
264 | on E: TPVCSTrackerException do
265 | ShowMessage(E.Message); // just show error message from Tracker
266 | end;
267 | ModalResult := mrNone; // don't close form
268 | end;
269 |
270 | procedure TProjectTrackerLoginForm.ShowSCRList;
271 | begin
272 | BtnOK.Enabled := false;
273 | Pages.ActivePageIndex := 2;
274 | if (Tracker=nil) or not Tracker.Logged then
275 | exit;
276 | BtnOK.Caption := ValAt(BtnOK.Hint,0); // Hint='OK,Connect'
277 | Tracker.FillQuery(SCRList.Items);
278 | end;
279 |
280 | procedure TProjectTrackerLoginForm.ShowLogin;
281 | begin
282 | Pages.ActivePageIndex := 0;
283 | BtnOK.Enabled := true;
284 | BtnOK.Caption := ValAt(BtnOK.Hint,1); // Hint='OK,Connect'
285 | Label3.Caption := Caption+' '+BtnOK.Caption;
286 | end;
287 |
288 | procedure TProjectTrackerLoginForm.SCRListDrawItem(Control: TWinControl;
289 | Index: Integer; Rect: TRect; State: TOwnerDrawState);
290 | var List: TCustomListBox absolute Control;
291 | begin
292 | with List.Canvas do begin
293 | FillRect(Rect);
294 | Font.Style := [fsBold];
295 | TextOut(Rect.Left+4,Rect.Top,'#'+IntToStr(integer(List.Items.Objects[Index])));
296 | Font.Style := [];
297 | TextOut(Rect.Left+40,Rect.Top,List.Items[Index]);
298 | end;
299 | end;
300 |
301 | procedure TProjectTrackerLoginForm.SCRListClick(Sender: TObject);
302 | begin
303 | BtnOk.Enabled := SCRList.ItemIndex>=0;
304 | end;
305 |
306 | procedure TProjectTrackerLoginForm.ShowSCRListMulti(const Title: string);
307 | begin
308 | Label4.Caption := Title;
309 | BtnOK.Enabled := false;
310 | Pages.ActivePageIndex := 3;
311 | if (Tracker=nil) or not Tracker.Logged then
312 | exit;
313 | BtnOK.Caption := ValAt(BtnOK.Hint,0); // Hint='OK,Connect'
314 | Tracker.FillQuery(SCRListMulti.Items);
315 | end;
316 |
317 | procedure TProjectTrackerLoginForm.BtnSelAllClick(Sender: TObject);
318 | var i: integer;
319 | begin
320 | for i := 0 to SCRListMulti.Count-1 do
321 | if Sender=BtnSelAll then
322 | SCRListMulti.Checked[i] := true else
323 | if Sender=BtnSelNone then
324 | SCRListMulti.Checked[i] := false else
325 | SCRListMulti.Checked[i] := pos('(Open)',SCRListMulti.Items[i])>0;
326 | SCRListMultiClickCheck(nil);
327 | end;
328 |
329 | procedure TProjectTrackerLoginForm.SCRListMultiClickCheck(Sender: TObject);
330 | var i: integer;
331 | begin
332 | for i := 0 to SCRListMulti.Count-1 do
333 | if SCRListMulti.Checked[i] then begin
334 | BtnOk.Enabled := true;
335 | exit;
336 | end;
337 | BtnOk.Enabled := false;
338 | end;
339 |
340 | end.
341 |
--------------------------------------------------------------------------------
/ProjectEditMain.pas:
--------------------------------------------------------------------------------
1 | /// Documentation Editor main form
2 | // - this unit is part of SynProject, under GPL 3.0 license; version 1.7
3 | unit ProjectEditMain;
4 |
5 | (*
6 | This file is part of SynProject.
7 |
8 | Synopse SynProject. Copyright (C) 2008-2023 Arnaud Bouchez
9 | Synopse Informatique - https://synopse.info
10 |
11 | SynProject is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU General Public License as published by
13 | the Free Software Foundation; either version 3 of the License, or (at
14 | your option) any later version.
15 |
16 | SynProject is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | GNU Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU General Public License
22 | along with SynProject. If not, see .
23 |
24 | *)
25 |
26 | interface
27 |
28 | {.$define AUTOBACKUPASZIP}
29 | { if defined, an automatic backup copy will be made in a .ZIP file for each day
30 | not to be used in global ProjectVersion (uses project differential backup) }
31 |
32 | uses
33 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
34 | Dialogs, SynMemoEx,
35 | ProjectCommons, ProjectEditor, ProjectTypes, ProjectSections,
36 | StdCtrls, ExtCtrls, ComCtrls;
37 |
38 | type
39 | TProMainForm = class(TForm)
40 | Sections: TListBox;
41 | Splitter2: TSplitter;
42 | Splitter1: TSplitter;
43 | StatusBar: TStatusBar;
44 | procedure FormCreate(Sender: TObject);
45 | procedure SectionsClick(Sender: TObject);
46 | procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
47 | procedure WholeFileClick(Sender: TObject);
48 | procedure FormShow(Sender: TObject);
49 | procedure FormDestroy(Sender: TObject);
50 | procedure SectionsMouseDown(Sender: TObject; Button: TMouseButton;
51 | Shift: TShiftState; X, Y: Integer);
52 | private
53 | fData: TSectionsStorage;
54 | OldSectionIndex: integer;
55 | procedure DataToSections;
56 | procedure EditorsToData(const FocusSectionName: string);
57 | procedure SaveToFile(Sender: TObject);
58 | public
59 | Editor, Params: TFrameEditor;
60 | procedure InitEditor(const Title, ProFileName: string);
61 | procedure DataChangedInEditorSection(Sender: TObject; const newData: string);
62 | property Data: TSectionsStorage read FData;
63 | end;
64 |
65 | var
66 | ProMainForm: TProMainForm;
67 |
68 | resourcestring
69 | sWholeFile = 'Whole File';
70 |
71 |
72 |
73 | implementation
74 |
75 | {$R *.dfm}
76 |
77 | uses
78 | ProjectDiff, // for Adler32Asm
79 | {$ifdef AUTOBACKUPASZIP}
80 | ZipOnly,
81 | {$endif}
82 | ProjectRTF, ProjectVersionMain;
83 |
84 | procedure TProMainForm.DataToSections;
85 | var i: integer;
86 | begin
87 | if fData=nil then exit;
88 | with Sections.Items do begin
89 | BeginUpdate;
90 | Clear;
91 | Add('* '+sWholeFile);
92 | for i := 0 to fData.Sections.Count-1 do
93 | AddObject(fData.Sections[i].SectionName,fData.Sections[i]);
94 | EndUpdate;
95 | end;
96 | end;
97 |
98 | procedure TProMainForm.EditorsToData(const FocusSectionName: string);
99 | var OldSec: TSection;
100 | paramsText, bodyText: string;
101 | begin
102 | if fData=nil then exit;
103 | if OldSectionIndex>=0 then begin
104 | OldSec := TSection(Sections.Items.Objects[OldSectionIndex]);
105 | if OldSec=nil then begin // all Text
106 | if Editor.UpdateDataFromTextAllIfNecessary then
107 | DataToSections;
108 | if FocusSectionName<>'' then
109 | Sections.ItemIndex := Sections.Items.IndexOf(FocusSectionName);
110 | end else begin
111 | if Editor.Memo.Modified or Params.Memo.Modified then begin
112 | paramsText := trim(Params.Memo.Lines.Text);
113 | bodyText := trim(Editor.Memo.Lines.Text);
114 | if paramsText<>'' then begin // Params exists -> enforce separate from body
115 | if (bodyText<>'') and (bodyText[1]<>':') then
116 | paramsText := paramsText+#13#10;
117 | end else // paramsText='' -> put body after a CRLF if not title first
118 | if (bodyText<>'') and (bodyText[1]<>':') then
119 | paramsText := #13#10;
120 | OldSec.ReadSection(PChar(paramsText+bodyText));
121 | fData.Modified := true;
122 | end;
123 | end;
124 | end;
125 | end;
126 |
127 | procedure TProMainForm.FormCreate(Sender: TObject);
128 | begin
129 | OldSectionIndex := -1;
130 | Editor := TFrameEditor.Create(Self);
131 | Editor.BtnSave.OnClick := SaveToFile;
132 | Editor.Name := 'Editor';
133 | Editor.Parent := Self;
134 | Editor.Align := alClient;
135 | Editor.Params := false;
136 | Editor.BtnTextAll.OnClick := WholeFileClick;
137 | Params := TFrameEditor.Create(Self);
138 | Params.Parent := Self;
139 | Params.Align := alRight;
140 | Params.Params := true;
141 | Params.Panel.Width := Max((ClientWidth -Sections.Width) div 3,300);
142 | Params.BtnTextAll.OnClick := WholeFileClick;
143 | Splitter1.Left := Params.Left;
144 | OnKeyDown := Editor.OnEscKeyDown; // Escape key will close form
145 | end;
146 |
147 | procedure TProMainForm.SectionsMouseDown(Sender: TObject;
148 | Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
149 | var index: integer;
150 | E: TFrameEditor;
151 | aText: string;
152 | begin
153 | if Button=mbRight then begin
154 | index := Sections.ItemAtPos(Point(X,Y),true);
155 | if index<0 then exit;
156 | aText := fData[Sections.Items[index]].Lines.Text;
157 | if aText='' then exit;
158 | with CreateFormEditor(nil,E,false,
159 | ' ['+Sections.Items[index]+'] Section Read-Only View') do begin
160 | E.BtnWordWrap.Down := true;
161 | E.Memo.WordWrap := true;
162 | E.Memo.Lines.Text := aText;
163 | Width := Width-E.Sections.Width;
164 | E.Sections.Hide;
165 | E.ReadOnly := true;
166 | E.BtnReadOnly.Enabled := false;
167 | E.BtnSave.Enabled := false;
168 | E.BtnWizard.Enabled := false;
169 | OnClose := MainForm.FormClose; // Action := caFree
170 | Show; // show as Read-Only text
171 | end;
172 | end;
173 | end;
174 |
175 | procedure TProMainForm.SectionsClick(Sender: TObject);
176 | var Sec: TSection;
177 | i, index: integer;
178 | SecName, s: string;
179 | M: TStrings;
180 | begin
181 | if fData=nil then exit;
182 | index := Sections.ItemIndex;
183 | if index<0 then exit;
184 | if index=OldSectionIndex then exit;
185 | SecName := Sections.Items[index];
186 | EditorsToData(SecName); // if Modified in the Editors -> save to Data
187 | Sec := TSection(Sections.Items.Objects[index]);
188 | if Sec=nil then begin // first line: all Text
189 | Params.Memo.Lines.Clear;
190 | Params.Hide;
191 | Editor.OnDataChange := nil;
192 | Editor.Memo.Lines.Text := fData.Text;
193 | Editor.TextAll := true;
194 | if OldSectionIndex>=0 then begin
195 | Sec := TSection(Sections.Items.Objects[OldSectionIndex]);
196 | if Sec<>nil then begin
197 | i := Editor.Sections.Items.IndexOf(Sec.SectionName);
198 | if i>=0 then begin
199 | Editor.Sections.ItemIndex := i;
200 | Editor.SectionsClick(self); // Sender<>nil -> no search of MemoWordClickText
201 | end;
202 | end;
203 | end;
204 | end else begin // update Params+Editor with Sec content:
205 | Params.Memo.BeginUpdate; // M.BeginUpdate is not sufficient
206 | M := Params.Memo.Lines;
207 | M.Clear;
208 | with Sec.Lines do begin
209 | i := 0;
210 | while i'' then
227 | M.Add(s);
228 | inc(i);
229 | end;
230 | Editor.Memo.EndUpdate;
231 | Editor.Memo.Modified := false;
232 | Params.Show;
233 | if Params.Memo.Lines.Count=0 then
234 | Params.Width := 140 else
235 | if M.Count=0 then
236 | Params.Width := (ClientWidth-Sections.Width)-140 else
237 | Params.Width := (ClientWidth-Sections.Width)div 2;
238 | Editor.TextAll := false;
239 | end;
240 | OldSectionIndex := index;
241 | end;
242 |
243 | procedure TProMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
244 | begin
245 | if fData=nil then exit;
246 | EditorsToData(''); // if Modified in the Editors -> save to Data
247 | if fData.Modified then // if Data modified -> save to file
248 | case MessageDlg(SErrorDocModifiedAskSave,mtConfirmation,mbYesNoCancel,0) of
249 | mrYes: SaveToFile(nil);
250 | mrCancel: CanClose := false;
251 | end;
252 | end;
253 |
254 | procedure TProMainForm.WholeFileClick(Sender: TObject);
255 | begin
256 | Sections.ItemIndex := 0;
257 | SectionsClick(nil);
258 | end;
259 |
260 | procedure TProMainForm.FormShow(Sender: TObject);
261 | begin
262 | Sections.ItemIndex := 0;
263 | SectionsClick(nil);
264 | Application.ProcessMessages;
265 | Editor.Memo.SetFocus;
266 | end;
267 |
268 | procedure TProMainForm.SaveToFile(Sender: TObject);
269 | var Bak: string;
270 | W: TStringWriter;
271 | Adler32: cardinal;
272 | {$ifdef AUTOBACKUPASZIP}
273 | SystemTime: TSystemTime;
274 | Zip: TZip;
275 | FileName: string;
276 | {$endif}
277 | begin
278 | if fData=nil then exit;
279 | EditorsToData(''); // if Modified in the Editors -> save to Data
280 | if not fData.Modified then exit;
281 | bak := ChangeFileExt(fData.FileName,'.~pro');
282 | fData.SaveText(W);
283 | Adler32 := Adler32Asm(0,W.DataPointer,W.len);
284 | if Adler32<>fData.Adler32AsCreated then begin // if something really changed :)
285 | fData.Adler32AsCreated := Adler32;
286 | DeleteFile(bak);
287 | RenameFile(fData.FileName,bak);
288 | W.SaveToFile(fData.FileName);
289 | {$ifdef AUTOBACKUPASZIP}
290 | GetLocalTime(SystemTime);
291 | bak := ExtractFilePath(fData.FileName)+'Backup';
292 | if not DirectoryExists(bak) then
293 | mkDir(bak);
294 | FileName := ValAt(ExtractFileName(fData.FileName),0,'.');
295 | bak := format('%s\%s %d%.2d%.2d.zip',[bak,FileName,
296 | SystemTime.wYear,SystemTime.wMonth,SystemTime.wDay]);
297 | Zip := TZip.Create(bak);
298 | Zip.AddBuf(format('%s %.2dh%.2d%s',[ValAt(ExtractFileName(bak),0,'.'),
299 | SystemTime.wHour,SystemTime.wMinute,ExtractFileExt(fData.FileName)]),
300 | 6,W.DataPointer,W.len);
301 | Zip.Free;
302 | {$endif}
303 | end;
304 | fData.Modified := false;
305 | Editor.Memo.Modified := false;
306 | Params.Memo.Modified := false;
307 | end;
308 |
309 | procedure TProMainForm.DataChangedInEditorSection(Sender: TObject; const newData: string);
310 | begin
311 | if fData=nil then exit;
312 | fData.LoadFromMemory(pointer(newData),length(newData));
313 | fData.Modified := true;
314 | DataToSections;
315 | Sections.ItemIndex := 0; // whole file edit
316 | SectionsClick(nil);
317 | if Sender<>nil then
318 | Editor.Memo.Command(ecEndDoc);
319 | end;
320 |
321 | procedure TProMainForm.InitEditor(const Title, ProFileName: string);
322 | begin
323 | FreeAndNil(fData);
324 | fData := TSectionsStorage.Create(ProFileName);
325 | Editor.Data := fData;
326 | Editor.Memo.RightMargin := StrToIntDef(
327 | fData.Section['Project'].Value['EditorRightMargin'],100);
328 | OldSectionIndex := -1; // force reload editor text
329 | Params.Data := fData;
330 | DataToSections;
331 | Caption := ' SynProject - '+Title;
332 | end;
333 |
334 | procedure TProMainForm.FormDestroy(Sender: TObject);
335 | begin
336 | FreeAndNil(fData);
337 | end;
338 |
339 | end.
340 |
--------------------------------------------------------------------------------
/ProjectEditor.dfm:
--------------------------------------------------------------------------------
1 | object FrameEditor: TFrameEditor
2 | Left = 0
3 | Top = 0
4 | Width = 904
5 | Height = 238
6 | TabOrder = 0
7 | object Panel: TPanel
8 | Left = 0
9 | Top = 0
10 | Width = 904
11 | Height = 238
12 | Align = alClient
13 | AutoSize = True
14 | TabOrder = 0
15 | object Memo: TMemoEx
16 | Left = 121
17 | Top = 35
18 | Width = 782
19 | Height = 202
20 | Cursor = crIBeam
21 | TabOrder = 0
22 | GutterWidth = 0
23 | RightMarginColor = clSilver
24 | Completion.Separator = '='
25 | Completion.ItemHeight = 13
26 | Completion.Interval = 800
27 | Completion.ListBoxStyle = lbStandard
28 | Completion.CaretChar = '|'
29 | Completion.CRLF = '/n'
30 | TabStops = '8'
31 | CursorBeyondEOL = True
32 | SelForeColor = clHighlightText
33 | SelBackColor = clHighlight
34 | OnKeyDown = MemoKeyDown
35 | OnChange = MemoChange
36 | OnMouseOver = MemoMouseOver
37 | OnSetCaretPos = MemoSetCaretPos
38 | Align = alClient
39 | Ctl3D = True
40 | Font.Charset = DEFAULT_CHARSET
41 | Font.Color = clWindowText
42 | Font.Height = -13
43 | Font.Name = 'Courier New'
44 | Font.Pitch = fpFixed
45 | Font.Style = []
46 | ParentColor = False
47 | PopupMenu = EditorPopup
48 | TabStop = True
49 | UseDockManager = False
50 | WordWrap = False
51 | end
52 | object ToolBar: TToolBar
53 | Left = 1
54 | Top = 1
55 | Width = 902
56 | Height = 34
57 | ButtonHeight = 30
58 | ButtonWidth = 31
59 | DisabledImages = ImageListDisabled
60 | Images = ImageListEnabled
61 | TabOrder = 1
62 | object BtnHistoryBack: TToolButton
63 | Left = 0
64 | Top = 2
65 | Enabled = False
66 | ImageIndex = 5
67 | OnClick = BtnHistoryBackClick
68 | end
69 | object BtnHistoryNext: TToolButton
70 | Left = 31
71 | Top = 2
72 | Enabled = False
73 | ImageIndex = 6
74 | OnClick = BtnHistoryNextClick
75 | end
76 | object BtnTextAll: TToolButton
77 | Left = 62
78 | Top = 2
79 | Hint = 'Whole File edition'
80 | ImageIndex = 12
81 | ParentShowHint = False
82 | ShowHint = True
83 | end
84 | object ToolButton1: TToolButton
85 | Left = 93
86 | Top = 2
87 | Width = 8
88 | ImageIndex = 3
89 | Style = tbsSeparator
90 | end
91 | object BtnReadOnly: TToolButton
92 | Left = 101
93 | Top = 2
94 | Hint = 'Read Only'
95 | ImageIndex = 0
96 | ParentShowHint = False
97 | ShowHint = True
98 | OnClick = BtnReadOnlyClick
99 | end
100 | object BtnSave: TToolButton
101 | Left = 132
102 | Top = 2
103 | Hint = 'Save (Ctrl+S)'
104 | ImageIndex = 3
105 | ParentShowHint = False
106 | ShowHint = True
107 | end
108 | object BtnHistory: TToolButton
109 | Left = 163
110 | Top = 2
111 | Hint = 'File History'
112 | DropdownMenu = PopupMenuBtnHistory
113 | ImageIndex = 21
114 | ParentShowHint = False
115 | ShowHint = True
116 | Visible = False
117 | end
118 | object BtnWizard: TToolButton
119 | Left = 194
120 | Top = 2
121 | Hint = 'Documentation Wizard'
122 | ImageIndex = 23
123 | ParentShowHint = False
124 | ShowHint = True
125 | OnClick = BtnWizardClick
126 | end
127 | object BtnDocument: TToolButton
128 | Left = 225
129 | Top = 2
130 | Hint = 'Create Word Document'
131 | ImageIndex = 15
132 | ParentShowHint = False
133 | ShowHint = True
134 | OnClick = BtnLinkSectionClick
135 | end
136 | object ToolButton2: TToolButton
137 | Left = 256
138 | Top = 2
139 | Width = 8
140 | ImageIndex = 4
141 | Style = tbsSeparator
142 | end
143 | object BtnUndo: TToolButton
144 | Left = 264
145 | Top = 2
146 | Hint = 'Undo'
147 | ImageIndex = 10
148 | ParentShowHint = False
149 | ShowHint = True
150 | OnClick = BtnUndoClick
151 | end
152 | object BtnWordWrap: TToolButton
153 | Left = 295
154 | Top = 2
155 | Hint = 'Word Wrap'
156 | ImageIndex = 2
157 | ParentShowHint = False
158 | ShowHint = True
159 | OnClick = BtnWordWrapClick
160 | end
161 | object BtnSpellCheck: TToolButton
162 | Left = 326
163 | Top = 2
164 | Hint = 'Spell Check selection (F7)'
165 | ImageIndex = 26
166 | ParentShowHint = False
167 | ShowHint = True
168 | OnClick = BtnSpellCheckClick
169 | end
170 | object ToolButton3: TToolButton
171 | Left = 357
172 | Top = 2
173 | Width = 8
174 | ImageIndex = 3
175 | Style = tbsSeparator
176 | end
177 | object BtnBold: TToolButton
178 | Left = 365
179 | Top = 2
180 | Hint = 'Selected text to Bold (Ctrl+B)'
181 | ImageIndex = 7
182 | ParentShowHint = False
183 | ShowHint = True
184 | OnClick = BtnBoldItalicUnderlineClick
185 | end
186 | object BtnItalic: TToolButton
187 | Tag = 1
188 | Left = 396
189 | Top = 2
190 | Hint = 'Selected text to Italic (Ctrl+I)'
191 | ImageIndex = 8
192 | ParentShowHint = False
193 | ShowHint = True
194 | OnClick = BtnBoldItalicUnderlineClick
195 | end
196 | object BtnUnderline: TToolButton
197 | Tag = 2
198 | Left = 427
199 | Top = 2
200 | Hint = 'Selected text to Underline (Ctrl+U)'
201 | ImageIndex = 9
202 | ParentShowHint = False
203 | ShowHint = True
204 | OnClick = BtnBoldItalicUnderlineClick
205 | end
206 | object BtnFixedFont: TToolButton
207 | Tag = 3
208 | Left = 458
209 | Top = 2
210 | Hint = 'Selected text to FixedFont (Ctrl+0)'
211 | ImageIndex = 16
212 | ParentShowHint = False
213 | ShowHint = True
214 | OnClick = BtnBoldItalicUnderlineClick
215 | end
216 | object BtnMarkProgram: TToolButton
217 | Left = 489
218 | Top = 2
219 | Hint = 'Mark Selected lines as program code'
220 | DropdownMenu = PopupMenuProgram
221 | ImageIndex = 17
222 | ParentShowHint = False
223 | ShowHint = True
224 | OnClick = BtnMarkProgramClick
225 | end
226 | object BtnLinkSection: TToolButton
227 | Left = 520
228 | Top = 2
229 | Hint = 'Link to Section'
230 | ImageIndex = 11
231 | ParentShowHint = False
232 | ShowHint = True
233 | OnClick = BtnLinkSectionClick
234 | end
235 | object BtnLinkPeople: TToolButton
236 | Left = 551
237 | Top = 2
238 | Hint = 'Link to People'
239 | ImageIndex = 13
240 | ParentShowHint = False
241 | ShowHint = True
242 | OnClick = BtnLinkSectionClick
243 | end
244 | object BtnLinkPicture: TToolButton
245 | Left = 582
246 | Top = 2
247 | Hint = 'Link to Picture'
248 | ImageIndex = 14
249 | ParentShowHint = False
250 | ShowHint = True
251 | OnClick = BtnLinkSectionClick
252 | end
253 | object BtnLinkProgram: TToolButton
254 | Left = 613
255 | Top = 2
256 | Hint = 'Link to an Object (.pas only)'
257 | ImageIndex = 28
258 | ParentShowHint = False
259 | ShowHint = True
260 | OnClick = BtnLinkProgramClick
261 | end
262 | object ToolButton4: TToolButton
263 | Left = 644
264 | Top = 2
265 | Width = 8
266 | ImageIndex = 19
267 | Style = tbsSeparator
268 | end
269 | object BtnAddPicture: TToolButton
270 | Left = 652
271 | Top = 2
272 | Hint = 'Add Picture'
273 | ImageIndex = 19
274 | ParentShowHint = False
275 | ShowHint = True
276 | OnClick = BtnLinkSectionClick
277 | end
278 | object BtnAddGraph: TToolButton
279 | Left = 683
280 | Top = 2
281 | Hint = 'Add/Edit a Graph'
282 | ImageIndex = 25
283 | ParentShowHint = False
284 | ShowHint = True
285 | Visible = False
286 | OnClick = BtnAddGraphClick
287 | end
288 | object BtnAutoSections: TToolButton
289 | Left = 714
290 | Top = 2
291 | Hint = 'Create missing sections for current Document'
292 | ImageIndex = 18
293 | ParentShowHint = False
294 | ShowHint = True
295 | OnClick = BtnAutoSectionsClick
296 | end
297 | object BtnReleaseDocument: TToolButton
298 | Left = 745
299 | Top = 2
300 | Hint = 'Increment the the document history'
301 | ImageIndex = 22
302 | ParentShowHint = False
303 | ShowHint = True
304 | OnClick = BtnReleaseDocumentClick
305 | end
306 | object BtnAddTracker: TToolButton
307 | Left = 776
308 | Top = 2
309 | Hint = 'Add a new Tracker entry (F1)'
310 | ImageIndex = 20
311 | ParentShowHint = False
312 | ShowHint = True
313 | Visible = False
314 | end
315 | object BtnImportTracker: TToolButton
316 | Left = 807
317 | Top = 2
318 | Hint = 'Import entries from PVCS'
319 | Caption = 'BtnImportTracker'
320 | ImageIndex = 24
321 | ParentShowHint = False
322 | ShowHint = True
323 | Visible = False
324 | end
325 | object ToolButton5: TToolButton
326 | Left = 838
327 | Top = 2
328 | Width = 8
329 | Caption = 'ToolButton5'
330 | ImageIndex = 28
331 | Style = tbsSeparator
332 | end
333 | object BtnAbout: TToolButton
334 | Left = 846
335 | Top = 2
336 | Hint = 'About'
337 | ImageIndex = 27
338 | ParentShowHint = False
339 | ShowHint = True
340 | OnClick = BtnAboutClick
341 | end
342 | end
343 | object Sections: TListBox
344 | Left = 1
345 | Top = 35
346 | Width = 120
347 | Height = 202
348 | Align = alLeft
349 | ItemHeight = 13
350 | TabOrder = 2
351 | Visible = False
352 | OnClick = SectionsClick
353 | OnMouseDown = SectionsMouseDown
354 | end
355 | end
356 | object ImageListEnabled: TImageList
357 | Height = 24
358 | Width = 24
359 | Left = 168
360 | Top = 168
361 | end
362 | object ImageListDisabled: TImageList
363 | Height = 24
364 | Width = 24
365 | Left = 256
366 | Top = 168
367 | end
368 | object PopupMenuLink: TPopupMenu
369 | Images = ImageList16
370 | Left = 536
371 | Top = 40
372 | end
373 | object FindDialog: TFindDialog
374 | Options = [frDown, frHideWholeWord, frHideUpDown]
375 | OnFind = FindDialogFind
376 | Left = 128
377 | Top = 40
378 | end
379 | object PopupMenuProgram: TPopupMenu
380 | Images = ImageList16
381 | Left = 496
382 | Top = 40
383 | object PopupMenuProgramDelphi: TMenuItem
384 | Caption = 'Delphi/Pascal'
385 | Hint = '!'
386 | ImageIndex = 17
387 | ShortCut = 113
388 | OnClick = BtnMarkProgramClick
389 | end
390 | object PopupMenuProgramModula2: TMenuItem
391 | Caption = 'Modula2'
392 | Hint = #181
393 | ImageIndex = 17
394 | OnClick = BtnMarkProgramClick
395 | end
396 | object PopupMenuProgramC: TMenuItem
397 | Caption = 'C/C++'
398 | Hint = '&'
399 | ImageIndex = 17
400 | OnClick = BtnMarkProgramClick
401 | end
402 | object PopupMenuProgramCSharp: TMenuItem
403 | Caption = 'C#'
404 | Hint = '#'
405 | ImageIndex = 17
406 | OnClick = BtnMarkProgramClick
407 | end
408 | object PopupMenuProgramINI: TMenuItem
409 | Caption = 'INI/TXT'
410 | Hint = '$'
411 | ImageIndex = 17
412 | OnClick = BtnMarkProgramClick
413 | end
414 | object PopupMenuProgramXML: TMenuItem
415 | Caption = 'XML/HTML'
416 | Hint = '$$'
417 | ImageIndex = 17
418 | OnClick = BtnMarkProgramClick
419 | end
420 | object PopupMenuProgramDFM: TMenuItem
421 | Caption = 'DFM'
422 | Hint = '!$'
423 | ImageIndex = 17
424 | OnClick = BtnMarkProgramClick
425 | end
426 | object PopupMenuProgramComment: TMenuItem
427 | Caption = '; comment'
428 | Hint = ';'
429 | ImageIndex = 17
430 | OnClick = BtnMarkProgramClick
431 | end
432 | end
433 | object PopupMenuBtnHistory: TPopupMenu
434 | Left = 168
435 | Top = 40
436 | end
437 | object EditorPopup: TPopupMenu
438 | Images = ImageList16
439 | OnPopup = EditorPopupPopup
440 | Left = 464
441 | Top = 168
442 | object EditorPopupCopy: TMenuItem
443 | Caption = 'Copy'
444 | ShortCut = 16451
445 | OnClick = EditorPopupCopyClick
446 | end
447 | object EditorPopupCopyAs: TMenuItem
448 | Caption = 'Copy as'
449 | object EditorPopupCopyAsHtml: TMenuItem
450 | Caption = 'HTML'
451 | OnClick = EditorPopupCopyAsHtmlClick
452 | end
453 | object EditorPopupCopyAsBBCode: TMenuItem
454 | Caption = 'BBCODE'
455 | OnClick = EditorPopupCopyAsBBCodeClick
456 | end
457 | end
458 | object EditorPopupPaste: TMenuItem
459 | Caption = 'Paste'
460 | ShortCut = 16470
461 | OnClick = EditorPopupPasteClick
462 | end
463 | object EditorPopupCut: TMenuItem
464 | Caption = 'Cut'
465 | ShortCut = 16472
466 | OnClick = EditorPopupCutClick
467 | end
468 | object N1: TMenuItem
469 | Caption = '-'
470 | end
471 | object EditorPopupUndo: TMenuItem
472 | Caption = 'Undo'
473 | ImageIndex = 10
474 | ShortCut = 16474
475 | OnClick = BtnUndoClick
476 | end
477 | object EditorPopupWordWrap: TMenuItem
478 | Caption = 'Word Wrap'
479 | ImageIndex = 2
480 | OnClick = BtnWordWrapClick
481 | end
482 | object EditorPopupSpellCheck: TMenuItem
483 | Caption = 'Spell check'
484 | ImageIndex = 26
485 | ShortCut = 118
486 | OnClick = BtnSpellCheckClick
487 | end
488 | end
489 | object ImageList16: TImageList
490 | Left = 344
491 | Top = 168
492 | end
493 | end
494 |
--------------------------------------------------------------------------------