├── .gitignore
├── LICENSE
├── Packages
├── Delphi10Berlin
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── Delphi10Rio
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── Delphi10Seattle
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── Delphi10Sydney
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── Delphi10Tokyo
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── Delphi11Alexandria
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
└── Delphi12Athens
│ ├── dclDelphi4PythonExperts.dpk
│ └── dclDelphi4PythonExperts.dproj
├── README.md
├── Samples
├── Simple_Demo
│ ├── D4P_export_demo.dpr
│ ├── D4P_export_demo.dproj
│ ├── Python_Export
│ │ ├── Export_forms_separately
│ │ │ ├── child_window.py
│ │ │ ├── child_window.pyfmx
│ │ │ ├── parent_window.py
│ │ │ └── parent_window.pyfmx
│ │ └── Export_whole_project
│ │ │ ├── D4P_export_demo.py
│ │ │ ├── child_window.py
│ │ │ ├── child_window.pyfmx
│ │ │ ├── parent_window.py
│ │ │ └── parent_window.pyfmx
│ ├── child_window.fmx
│ ├── child_window.pas
│ ├── parent_window.fmx
│ └── parent_window.pas
└── TipCalculator
│ ├── AndroidManifest.template.xml
│ ├── Python_Export
│ ├── Modified_TipMain
│ │ ├── TipCalculator.py
│ │ ├── TipMain.py
│ │ └── TipMain.pyfmx
│ ├── TipCalculator.py
│ ├── TipMain.py
│ └── TipMain.pyfmx
│ ├── TipCalculator.deployproj
│ ├── TipCalculator.dpr
│ ├── TipCalculator.dproj
│ ├── TipCalculator.res
│ ├── TipMain.fmx
│ └── TipMain.pas
├── Source
├── Design
│ ├── PythonTools.Design.Forms.dfm
│ ├── PythonTools.Design.Forms.pas
│ ├── PythonTools.Design.Project.dfm
│ ├── PythonTools.Design.Project.pas
│ ├── PythonTools.Design.dfm
│ └── PythonTools.Design.pas
├── Exporter
│ ├── PythonTools.Exporter.Application.pas
│ ├── PythonTools.Exporter.Form.pas
│ ├── PythonTools.Exporter.Forms.pas
│ └── PythonTools.Exporter.Project.pas
├── Menu
│ ├── PythonTools.Menu.ExportForms.pas
│ ├── PythonTools.Menu.ExportProject.pas
│ └── PythonTools.Menu.pas
├── Model
│ ├── Design
│ │ ├── PythonTools.Model.Design.Forms.pas
│ │ └── PythonTools.Model.Design.Project.pas
│ └── Producer
│ │ ├── PythonTools.Model.Producer.Application.pas
│ │ ├── PythonTools.Model.Producer.Form.pas
│ │ ├── PythonTools.Model.Producer.FormFile.pas
│ │ └── PythonTools.Model.Producer.pas
├── Producer
│ ├── PythonTools.Producer.AbstractForm.pas
│ ├── PythonTools.Producer.FMXForm.pas
│ ├── PythonTools.Producer.SimpleFactory.pas
│ ├── PythonTools.Producer.VCLForm.pas
│ └── PythonTools.Producer.pas
├── PythonTools.Common.pas
├── PythonTools.Exceptions.pas
├── PythonTools.IOTAUtils.pas
├── PythonTools.Registration.pas
├── PythonTools.Registry.pas
├── PythonTools.SplashScreen.pas
└── PythonTools.inc
├── Tests
├── FMX.Producer.Test.pas
├── PythonExporterTest.dpr
├── PythonExporterTest.dproj
├── VCL.Producer.Test.pas
└── data
│ ├── Data.FMXForm.fmx
│ ├── Data.FMXForm.pas
│ ├── Data.VCLForm.dfm
│ └── Data.VCLForm.pas
└── images
├── EmbarcaderoPython(154px).png
├── EmbarcaderoPython(16px).bmp
├── EmbarcaderoPython(16px).png
├── EmbarcaderoPython(24px).bmp
├── EmbarcaderoPython(24px).png
├── Export2Python.png
├── ExportCurrentProject.png
├── ExportForms.png
└── readme.md
/.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 | #
16 | # Visual LiveBindings file. Added in Delphi XE2.
17 | # Uncomment this if you are not using LiveBindings Designer.
18 | #*.vlb
19 | #
20 | # Deployment Manager configuration file for your project. Added in Delphi XE2.
21 | # Uncomment this if it is not mobile development and you do not use remote debug feature.
22 | #*.deployproj
23 | #
24 | # C++ object files produced when C/C++ Output file generation is configured.
25 | # Uncomment this if you are not using external objects (zlib library for example).
26 | #*.obj
27 | #
28 |
29 | # Delphi compiler-generated binaries (safe to delete)
30 | *.exe
31 | *.dll
32 | *.bpl
33 | *.bpi
34 | *.dcp
35 | *.so
36 | *.apk
37 | *.drc
38 | *.map
39 | *.dres
40 | *.rsm
41 | *.tds
42 | *.dcu
43 | *.lib
44 | *.a
45 | *.o
46 | *.ocx
47 | *.vlb
48 |
49 | # Delphi autogenerated files (duplicated info)
50 | *.cfg
51 | *.hpp
52 | *Resource.rc
53 |
54 | # Delphi local files (user-specific info)
55 | *.local
56 | *.identcache
57 | *.projdata
58 | *.tvsconfig
59 | *.dsk
60 |
61 | # Delphi history and backups
62 | __history/
63 | __recovery/
64 | *.~*
65 |
66 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
67 | *.stat
68 |
69 | # Boss dependency manager vendor folder https://github.com/HashLoad/boss
70 | modules/
71 |
72 | # Library folder
73 | /Library
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Embarcadero Technologies
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Packages/Delphi10Berlin/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS ON}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION OFF}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO ON}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES ON}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE DEBUG}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
30 | {$LIBSUFFIX '240'}
31 | {$DESIGNONLY}
32 | {$IMPLICITBUILD ON}
33 |
34 | requires
35 | rtl,
36 | designide,
37 | fmx,
38 | vcl,
39 | dbrtl,
40 | vcldb,
41 | dsnap,
42 | vclwinx;
43 |
44 | contains
45 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
46 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
47 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
48 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
49 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
50 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
51 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
52 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
53 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
54 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
55 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
56 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
57 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
58 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
59 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
60 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
61 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
62 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
63 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
64 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
65 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
66 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
67 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
68 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
69 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
70 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm};
71 |
72 | end.
73 |
--------------------------------------------------------------------------------
/Packages/Delphi10Rio/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS ON}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION OFF}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO ON}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES ON}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE DEBUG}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
30 | {$LIBSUFFIX '260'}
31 | {$DESIGNONLY}
32 | {$IMPLICITBUILD ON}
33 |
34 | requires
35 | rtl,
36 | designide,
37 | fmx,
38 | vcl,
39 | dbrtl,
40 | vcldb,
41 | dsnap,
42 | vclwinx;
43 |
44 | contains
45 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
46 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
47 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
48 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
49 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
50 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
51 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
52 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
53 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
54 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
55 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
56 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
57 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
58 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
59 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
60 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
61 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
62 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
63 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
64 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
65 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
66 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
67 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
68 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
69 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
70 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm};
71 |
72 | end.
73 |
--------------------------------------------------------------------------------
/Packages/Delphi10Seattle/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS ON}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION OFF}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO ON}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES ON}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE DEBUG}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
30 | {$LIBSUFFIX '230'}
31 | {$DESIGNONLY}
32 | {$IMPLICITBUILD ON}
33 |
34 | requires
35 | rtl,
36 | designide,
37 | fmx,
38 | vcl,
39 | dbrtl,
40 | vcldb,
41 | dsnap,
42 | vclwinx;
43 |
44 | contains
45 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
46 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
47 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
48 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
49 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
50 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
51 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
52 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
53 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
54 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
55 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
56 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
57 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
58 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
59 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
60 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
61 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
62 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
63 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
64 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
65 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
66 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
67 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
68 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
69 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
70 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm};
71 |
72 | end.
73 |
--------------------------------------------------------------------------------
/Packages/Delphi10Sydney/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS ON}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION OFF}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO ON}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES ON}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE DEBUG}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
30 | {$LIBSUFFIX '270'}
31 | {$DESIGNONLY}
32 | {$IMPLICITBUILD ON}
33 |
34 | requires
35 | rtl,
36 | designide,
37 | fmx,
38 | vcl,
39 | dbrtl,
40 | vcldb,
41 | dsnap;
42 |
43 | contains
44 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
45 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
46 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
47 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
48 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
49 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
50 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
51 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
52 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
53 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
54 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
55 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
56 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
57 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
58 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
59 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
60 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
61 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
62 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
63 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
64 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
65 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
66 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
67 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
68 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
69 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm};
70 |
71 | end.
72 |
--------------------------------------------------------------------------------
/Packages/Delphi10Tokyo/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 |
3 | {$R *.res}
4 | {$R *.dres}
5 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
6 | {$ALIGN 8}
7 | {$ASSERTIONS ON}
8 | {$BOOLEVAL OFF}
9 | {$DEBUGINFO OFF}
10 | {$EXTENDEDSYNTAX ON}
11 | {$IMPORTEDDATA ON}
12 | {$IOCHECKS ON}
13 | {$LOCALSYMBOLS ON}
14 | {$LONGSTRINGS ON}
15 | {$OPENSTRINGS ON}
16 | {$OPTIMIZATION OFF}
17 | {$OVERFLOWCHECKS OFF}
18 | {$RANGECHECKS OFF}
19 | {$REFERENCEINFO ON}
20 | {$SAFEDIVIDE OFF}
21 | {$STACKFRAMES ON}
22 | {$TYPEDADDRESS OFF}
23 | {$VARSTRINGCHECKS ON}
24 | {$WRITEABLECONST OFF}
25 | {$MINENUMSIZE 1}
26 | {$IMAGEBASE $400000}
27 | {$DEFINE DEBUG}
28 | {$ENDIF IMPLICITBUILDING}
29 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
30 | {$LIBSUFFIX '250'}
31 | {$DESIGNONLY}
32 | {$IMPLICITBUILD ON}
33 |
34 | requires
35 | rtl,
36 | designide,
37 | fmx,
38 | vcl,
39 | dbrtl,
40 | vcldb,
41 | dsnap,
42 | vclwinx;
43 |
44 | contains
45 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
46 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
47 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
48 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
49 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
50 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
51 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
52 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
53 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
54 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
55 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
56 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
57 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
58 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
59 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
60 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
61 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
62 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
63 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
64 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
65 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
66 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
67 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
68 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
69 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
70 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm};
71 |
72 | end.
73 |
--------------------------------------------------------------------------------
/Packages/Delphi11Alexandria/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 | {$R *.res}
3 | {$R *.dres}
4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
5 | {$ALIGN 8}
6 | {$ASSERTIONS ON}
7 | {$BOOLEVAL OFF}
8 | {$DEBUGINFO OFF}
9 | {$EXTENDEDSYNTAX ON}
10 | {$IMPORTEDDATA ON}
11 | {$IOCHECKS ON}
12 | {$LOCALSYMBOLS OFF}
13 | {$LONGSTRINGS ON}
14 | {$OPENSTRINGS ON}
15 | {$OPTIMIZATION ON}
16 | {$OVERFLOWCHECKS OFF}
17 | {$RANGECHECKS OFF}
18 | {$REFERENCEINFO OFF}
19 | {$SAFEDIVIDE OFF}
20 | {$STACKFRAMES OFF}
21 | {$TYPEDADDRESS OFF}
22 | {$VARSTRINGCHECKS ON}
23 | {$WRITEABLECONST OFF}
24 | {$MINENUMSIZE 1}
25 | {$IMAGEBASE $400000}
26 | {$DEFINE RELEASE}
27 | {$ENDIF IMPLICITBUILDING}
28 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
29 | {$LIBSUFFIX AUTO}
30 | {$DESIGNONLY}
31 | {$IMPLICITBUILD ON}
32 |
33 | requires
34 | rtl,
35 | designide,
36 | fmx,
37 | vcl,
38 | dbrtl,
39 | vcldb,
40 | dsnap;
41 |
42 | contains
43 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
44 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
45 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
46 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
47 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
48 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
49 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
50 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
51 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
52 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
53 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
54 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
55 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
56 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
57 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
58 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
59 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
60 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
61 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
62 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
63 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
64 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
65 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
66 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
67 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
68 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm},
69 | PythonTools.Model.Producer in '..\..\Source\Model\Producer\PythonTools.Model.Producer.pas';
70 |
71 | end.
72 |
--------------------------------------------------------------------------------
/Packages/Delphi12Athens/dclDelphi4PythonExperts.dpk:
--------------------------------------------------------------------------------
1 | package dclDelphi4PythonExperts;
2 | {$R *.res}
3 | {$R *.dres}
4 | {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
5 | {$ALIGN 8}
6 | {$ASSERTIONS ON}
7 | {$BOOLEVAL OFF}
8 | {$DEBUGINFO OFF}
9 | {$EXTENDEDSYNTAX ON}
10 | {$IMPORTEDDATA ON}
11 | {$IOCHECKS ON}
12 | {$LOCALSYMBOLS OFF}
13 | {$LONGSTRINGS ON}
14 | {$OPENSTRINGS ON}
15 | {$OPTIMIZATION ON}
16 | {$OVERFLOWCHECKS OFF}
17 | {$RANGECHECKS OFF}
18 | {$REFERENCEINFO OFF}
19 | {$SAFEDIVIDE OFF}
20 | {$STACKFRAMES OFF}
21 | {$TYPEDADDRESS OFF}
22 | {$VARSTRINGCHECKS ON}
23 | {$WRITEABLECONST OFF}
24 | {$MINENUMSIZE 1}
25 | {$IMAGEBASE $400000}
26 | {$DEFINE RELEASE}
27 | {$ENDIF IMPLICITBUILDING}
28 | {$DESCRIPTION 'Delphi4Python - Export forms for Python'}
29 | {$LIBSUFFIX AUTO}
30 | {$DESIGNONLY}
31 | {$IMPLICITBUILD ON}
32 |
33 | requires
34 | rtl,
35 | designide,
36 | fmx,
37 | vcl,
38 | dbrtl,
39 | vcldb,
40 | dsnap;
41 |
42 | contains
43 | PythonTools.Registration in '..\..\Source\PythonTools.Registration.pas',
44 | PythonTools.SplashScreen in '..\..\Source\PythonTools.SplashScreen.pas',
45 | PythonTools.IOTAUtils in '..\..\Source\PythonTools.IOTAUtils.pas',
46 | PythonTools.Exceptions in '..\..\Source\PythonTools.Exceptions.pas',
47 | PythonTools.Common in '..\..\Source\PythonTools.Common.pas',
48 | PythonTools.Menu in '..\..\Source\Menu\PythonTools.Menu.pas',
49 | PythonTools.Menu.ExportProject in '..\..\Source\Menu\PythonTools.Menu.ExportProject.pas',
50 | PythonTools.Menu.ExportForms in '..\..\Source\Menu\PythonTools.Menu.ExportForms.pas',
51 | PythonTools.Design.Project in '..\..\Source\Design\PythonTools.Design.Project.pas' {ProjectExportDialog},
52 | PythonTools.Exporter.Application in '..\..\Source\Exporter\PythonTools.Exporter.Application.pas',
53 | PythonTools.Exporter.Form in '..\..\Source\Exporter\PythonTools.Exporter.Form.pas',
54 | PythonTools.Exporter.Project in '..\..\Source\Exporter\PythonTools.Exporter.Project.pas',
55 | PythonTools.Producer.FMXForm in '..\..\Source\Producer\PythonTools.Producer.FMXForm.pas',
56 | PythonTools.Producer in '..\..\Source\Producer\PythonTools.Producer.pas',
57 | PythonTools.Producer.SimpleFactory in '..\..\Source\Producer\PythonTools.Producer.SimpleFactory.pas',
58 | PythonTools.Producer.VCLForm in '..\..\Source\Producer\PythonTools.Producer.VCLForm.pas',
59 | PythonTools.Producer.AbstractForm in '..\..\Source\Producer\PythonTools.Producer.AbstractForm.pas',
60 | PythonTools.Design.Forms in '..\..\Source\Design\PythonTools.Design.Forms.pas' {FormsExportDialog},
61 | PythonTools.Exporter.Forms in '..\..\Source\Exporter\PythonTools.Exporter.Forms.pas',
62 | PythonTools.Model.Producer.Application in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Application.pas',
63 | PythonTools.Model.Producer.FormFile in '..\..\Source\Model\Producer\PythonTools.Model.Producer.FormFile.pas',
64 | PythonTools.Model.Producer.Form in '..\..\Source\Model\Producer\PythonTools.Model.Producer.Form.pas',
65 | PythonTools.Model.Design.Forms in '..\..\Source\Model\Design\PythonTools.Model.Design.Forms.pas',
66 | PythonTools.Model.Design.Project in '..\..\Source\Model\Design\PythonTools.Model.Design.Project.pas',
67 | PythonTools.Registry in '..\..\Source\PythonTools.Registry.pas',
68 | PythonTools.Design in '..\..\Source\Design\PythonTools.Design.pas' {DesignForm},
69 | PythonTools.Model.Producer in '..\..\Source\Model\Producer\PythonTools.Model.Producer.pas';
70 |
71 | end.
72 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Delphi4PythonExporter
2 | For use with [DelphiFMX4Python](https://github.com/Embarcadero/DelphiFMX4Python) or [DelphiVCL4Python](https://github.com/Embarcadero/DelphiVCL4Python).
3 |
4 | Design your Python GUI using Delphi's VCL and FMX designers and then export them for Python use.
5 |
6 | ## eBook, Webinar, and Styles Bundle
7 |
8 | There is an free [eBook and styles bundle](https://embt.co/PythonGUIBundle) with 29 custom styles and 50 pages of content.
9 |
10 |
11 | ## Usage
12 |
13 | Install this Export in Delphi, C++Builder, or RAD Studio 11 Alexandria. Design your GUI forms with VCL or FireMonkey (FMX) and then select **Tools** -> **Export to Python**.
14 |
15 | The easiest way to install is via the [GetIt Package Manager](https://getitnow.embarcadero.com/?q=Delphi4PythonExporter). Instructions for [installing via GetIt](https://docwiki.embarcadero.com/RADStudio/en/Installing_a_Package_Using_GetIt_Package_Manager).
16 |
17 | 
18 |
19 | 
20 |
21 | * Text format is easier to edit
22 | * Binary format is more space efficient
23 |
24 | 
25 |
26 | Powered by [Python4Delphi](https://github.com/Embarcadero/python4delphi) and [Embarcadero Delphi](https://embarcadero.com/products/delphi).
27 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/D4P_export_demo.dpr:
--------------------------------------------------------------------------------
1 | program D4P_export_demo;
2 |
3 | uses
4 | System.StartUpCopy,
5 | FMX.Forms,
6 | parent_window in 'parent_window.pas' {Parent_Form},
7 | child_window in 'child_window.pas' {Child_Form};
8 |
9 | {$R *.res}
10 |
11 | begin
12 | Application.Initialize;
13 | Application.CreateForm(TParent_Form, Parent_Form);
14 | Application.CreateForm(TChild_Form, Child_Form);
15 | Application.Run;
16 | end.
17 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_forms_separately/child_window.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Child_Form(Form):
5 |
6 | def __init__(self, owner):
7 | self.child_heading = None
8 | self.result_text_heading = None
9 | self.result_text_label = None
10 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "child_window.pyfmx"))
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_forms_separately/child_window.pyfmx:
--------------------------------------------------------------------------------
1 | object Child_Form: TChild_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Child Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object child_heading: TLabel
12 | StyledSettings = [Family, FontColor]
13 | Position.X = 192.000000000000000000
14 | Position.Y = 40.000000000000000000
15 | Size.Width = 161.000000000000000000
16 | Size.Height = 41.000000000000000000
17 | Size.PlatformDefault = False
18 | TextSettings.Font.Size = 20.000000000000000000
19 | TextSettings.Font.StyleExt = {00070000000000000004000000}
20 | Text = 'I'#39'm a child form'
21 | TabOrder = 0
22 | end
23 | object result_text_heading: TLabel
24 | Position.X = 16.000000000000000000
25 | Position.Y = 128.000000000000000000
26 | Size.Width = 201.000000000000000000
27 | Size.Height = 17.000000000000000000
28 | Size.PlatformDefault = False
29 | Text = 'Text you entered in the Mainform is:'
30 | TabOrder = 1
31 | end
32 | object result_text_label: TLabel
33 | Position.X = 225.000000000000000000
34 | Position.Y = 128.000000000000000000
35 | Size.Width = 384.000000000000000000
36 | Size.Height = 17.000000000000000000
37 | Size.PlatformDefault = False
38 | TabOrder = 2
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_forms_separately/parent_window.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Parent_Form(Form):
5 |
6 | def __init__(self, owner):
7 | self.my_button = None
8 | self.enter_text_edit = None
9 | self.enter_text_label = None
10 | self.main_heading = None
11 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "parent_window.pyfmx"))
12 |
13 | def my_buttonClick(self, Sender):
14 | pass
15 |
16 | def main():
17 | Application.Initialize()
18 | Application.Title = 'Parent Window'
19 | Application.MainForm = Parent_Form(Application)
20 | Application.MainForm.Show()
21 | Application.Run()
22 | Application.MainForm.Destroy()
23 |
24 | if __name__ == '__main__':
25 | main()
26 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_forms_separately/parent_window.pyfmx:
--------------------------------------------------------------------------------
1 | object Parent_Form: TParent_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Parent Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object my_button: TButton
12 | Position.X = 241.000000000000000000
13 | Position.Y = 192.000000000000000000
14 | TabOrder = 0
15 | Text = 'Press Me'
16 | OnClick = my_buttonClick
17 | end
18 | object enter_text_edit: TEdit
19 | Touch.InteractiveGestures = [LongTap, DoubleTap]
20 | TabOrder = 1
21 | Position.X = 176.000000000000000000
22 | Position.Y = 144.000000000000000000
23 | Size.Width = 209.000000000000000000
24 | Size.Height = 30.000000000000000000
25 | Size.PlatformDefault = False
26 | end
27 | object enter_text_label: TLabel
28 | Position.X = 176.000000000000000000
29 | Position.Y = 119.000000000000000000
30 | Size.Width = 217.000000000000000000
31 | Size.Height = 17.000000000000000000
32 | Size.PlatformDefault = False
33 | Text = 'Please enter something in the Edit box'
34 | TabOrder = 2
35 | end
36 | object main_heading: TLabel
37 | StyledSettings = [Family, FontColor]
38 | Position.X = 136.000000000000000000
39 | Position.Y = 32.000000000000000000
40 | Size.Width = 281.000000000000000000
41 | Size.Height = 41.000000000000000000
42 | Size.PlatformDefault = False
43 | TextSettings.Font.Size = 30.000000000000000000
44 | TextSettings.Font.StyleExt = {00070000000000000004000000}
45 | Text = 'I'#39'm the MainForm'
46 | TabOrder = 3
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_whole_project/D4P_export_demo.py:
--------------------------------------------------------------------------------
1 | from delphifmx import *
2 | from parent_window import Parent_Form
3 |
4 | def main():
5 | Application.Initialize()
6 | Application.Title = 'Exporter Demo'
7 | Application.MainForm = Parent_Form(Application)
8 | Application.MainForm.Show()
9 | Application.Run()
10 | Application.MainForm.Destroy()
11 |
12 | if __name__ == '__main__':
13 | main()
14 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_whole_project/child_window.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Child_Form(Form):
5 |
6 | def __init__(self, owner):
7 | self.child_heading = None
8 | self.result_text_heading = None
9 | self.result_text_label = None
10 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "child_window.pyfmx"))
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_whole_project/child_window.pyfmx:
--------------------------------------------------------------------------------
1 | object Child_Form: TChild_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Child Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object child_heading: TLabel
12 | StyledSettings = [Family, FontColor]
13 | Position.X = 192.000000000000000000
14 | Position.Y = 40.000000000000000000
15 | Size.Width = 161.000000000000000000
16 | Size.Height = 41.000000000000000000
17 | Size.PlatformDefault = False
18 | TextSettings.Font.Size = 20.000000000000000000
19 | TextSettings.Font.StyleExt = {00070000000000000004000000}
20 | Text = 'I'#39'm a child form'
21 | TabOrder = 0
22 | end
23 | object result_text_heading: TLabel
24 | Position.X = 16.000000000000000000
25 | Position.Y = 128.000000000000000000
26 | Size.Width = 201.000000000000000000
27 | Size.Height = 17.000000000000000000
28 | Size.PlatformDefault = False
29 | Text = 'Text you entered in the Mainform is:'
30 | TabOrder = 1
31 | end
32 | object result_text_label: TLabel
33 | Position.X = 225.000000000000000000
34 | Position.Y = 128.000000000000000000
35 | Size.Width = 384.000000000000000000
36 | Size.Height = 17.000000000000000000
37 | Size.PlatformDefault = False
38 | TabOrder = 3
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_whole_project/parent_window.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Parent_Form(Form):
5 |
6 | def __init__(self, owner):
7 | self.my_button = None
8 | self.enter_text_edit = None
9 | self.enter_text_label = None
10 | self.main_heading = None
11 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "parent_window.pyfmx"))
12 |
13 | def my_buttonClick(self, Sender):
14 | pass
15 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/Python_Export/Export_whole_project/parent_window.pyfmx:
--------------------------------------------------------------------------------
1 | object Parent_Form: TParent_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Parent Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object my_button: TButton
12 | Position.X = 241.000000000000000000
13 | Position.Y = 192.000000000000000000
14 | TabOrder = 0
15 | Text = 'Press Me'
16 | OnClick = my_buttonClick
17 | end
18 | object enter_text_edit: TEdit
19 | Touch.InteractiveGestures = [LongTap, DoubleTap]
20 | TabOrder = 1
21 | Position.X = 176.000000000000000000
22 | Position.Y = 144.000000000000000000
23 | Size.Width = 209.000000000000000000
24 | Size.Height = 22.000000000000000000
25 | Size.PlatformDefault = False
26 | end
27 | object enter_text_label: TLabel
28 | Position.X = 176.000000000000000000
29 | Position.Y = 119.000000000000000000
30 | Size.Width = 217.000000000000000000
31 | Size.Height = 17.000000000000000000
32 | Size.PlatformDefault = False
33 | Text = 'Please enter something in the Edit box'
34 | TabOrder = 2
35 | end
36 | object main_heading: TLabel
37 | StyledSettings = [Family, FontColor]
38 | Position.X = 136.000000000000000000
39 | Position.Y = 32.000000000000000000
40 | Size.Width = 281.000000000000000000
41 | Size.Height = 41.000000000000000000
42 | Size.PlatformDefault = False
43 | TextSettings.Font.Size = 30.000000000000000000
44 | TextSettings.Font.StyleExt = {00070000000000000004000000}
45 | Text = 'I'#39'm the MainForm'
46 | TabOrder = 3
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/child_window.fmx:
--------------------------------------------------------------------------------
1 | object Child_Form: TChild_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Child Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object child_heading: TLabel
12 | StyledSettings = [Family, FontColor]
13 | Position.X = 192.000000000000000000
14 | Position.Y = 40.000000000000000000
15 | Size.Width = 161.000000000000000000
16 | Size.Height = 41.000000000000000000
17 | Size.PlatformDefault = False
18 | TextSettings.Font.Size = 20.000000000000000000
19 | TextSettings.Font.StyleExt = {00070000000000000004000000}
20 | Text = 'I'#39'm a child form'
21 | TabOrder = 0
22 | end
23 | object result_text_heading: TLabel
24 | Position.X = 16.000000000000000000
25 | Position.Y = 128.000000000000000000
26 | Size.Width = 201.000000000000000000
27 | Size.Height = 17.000000000000000000
28 | Size.PlatformDefault = False
29 | Text = 'Text you entered in the Mainform is:'
30 | TabOrder = 1
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/child_window.pas:
--------------------------------------------------------------------------------
1 | unit child_window;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
8 | FMX.Controls.Presentation, FMX.StdCtrls;
9 |
10 | type
11 | TChild_Form = class(TForm)
12 | child_heading: TLabel;
13 | result_text_heading: TLabel;
14 | private
15 | { Private declarations }
16 | public
17 | { Public declarations }
18 | end;
19 |
20 | var
21 | Child_Form: TChild_Form;
22 |
23 | implementation
24 |
25 | {$R *.fmx}
26 |
27 | end.
28 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/parent_window.fmx:
--------------------------------------------------------------------------------
1 | object Parent_Form: TParent_Form
2 | Left = 0
3 | Top = 0
4 | Caption = 'Parent Window'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object my_button: TButton
12 | Position.X = 241.000000000000000000
13 | Position.Y = 192.000000000000000000
14 | TabOrder = 0
15 | Text = 'Press Me'
16 | OnClick = my_buttonClick
17 | end
18 | object enter_text_edit: TEdit
19 | Touch.InteractiveGestures = [LongTap, DoubleTap]
20 | TabOrder = 1
21 | Position.X = 176.000000000000000000
22 | Position.Y = 144.000000000000000000
23 | Size.Width = 209.000000000000000000
24 | Size.Height = 22.000000000000000000
25 | Size.PlatformDefault = False
26 | end
27 | object enter_text_label: TLabel
28 | Position.X = 176.000000000000000000
29 | Position.Y = 119.000000000000000000
30 | Size.Width = 217.000000000000000000
31 | Size.Height = 17.000000000000000000
32 | Size.PlatformDefault = False
33 | Text = 'Please enter something in the Edit box'
34 | TabOrder = 2
35 | end
36 | object main_heading: TLabel
37 | StyledSettings = [Family, FontColor]
38 | Position.X = 136.000000000000000000
39 | Position.Y = 32.000000000000000000
40 | Size.Width = 281.000000000000000000
41 | Size.Height = 41.000000000000000000
42 | Size.PlatformDefault = False
43 | TextSettings.Font.Size = 30.000000000000000000
44 | TextSettings.Font.StyleExt = {00070000000000000004000000}
45 | Text = 'I'#39'm the MainForm'
46 | TabOrder = 3
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/Samples/Simple_Demo/parent_window.pas:
--------------------------------------------------------------------------------
1 | unit parent_window;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
8 | FMX.Edit, FMX.Controls.Presentation;
9 |
10 | type
11 | TParent_Form = class(TForm)
12 | my_button: TButton;
13 | enter_text_edit: TEdit;
14 | enter_text_label: TLabel;
15 | main_heading: TLabel;
16 | procedure my_buttonClick(Sender: TObject);
17 | private
18 | { Private declarations }
19 | public
20 | { Public declarations }
21 | end;
22 |
23 | var
24 | Parent_Form: TParent_Form;
25 |
26 | implementation
27 |
28 | {$R *.fmx}
29 |
30 | procedure TParent_Form.my_buttonClick(Sender: TObject);
31 | begin
32 | //
33 | end;
34 |
35 | end.
36 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/AndroidManifest.template.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 | <%uses-permission%>
10 |
11 |
12 | <%queries-child-elements%>
13 |
14 |
25 | <%provider%>
26 | <%application-meta-data%>
27 | <%uses-libraries%>
28 | <%services%>
29 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | <%activity%>
46 | <%receivers%>
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/Python_Export/Modified_TipMain/TipCalculator.py:
--------------------------------------------------------------------------------
1 | from delphifmx import *
2 | from TipMain import Main_Window
3 |
4 | def main():
5 | Application.Initialize()
6 | Application.Title = 'Tip Calculator'
7 | Application.MainForm = Main_Window(Application)
8 | Application.MainForm.Show()
9 | Application.Run()
10 | Application.MainForm.Destroy()
11 |
12 | if __name__ == '__main__':
13 | main()
14 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/Python_Export/Modified_TipMain/TipMain.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Main_Window(Form):
5 |
6 | def __init__(self, owner):
7 | self.styleRuby = None
8 | self.styleLight = None
9 | self.ListBox1 = None
10 | self.ListBoxItem1 = None
11 | self.editTotal = None
12 | self.Label6 = None
13 | self.ListBoxItem2 = None
14 | self.Label7 = None
15 | self.editTip = None
16 | self.ListBoxItem3 = None
17 | self.trackTip = None
18 | self.ListBoxItem4 = None
19 | self.editPeople = None
20 | self.Label3 = None
21 | self.ListBoxItem5 = None
22 | self.trackPeople = None
23 | self.ListBoxItem6 = None
24 | self.Layout2 = None
25 | self.ListBoxItem7 = None
26 | self.per_person_share = None
27 | self.Label1 = None
28 | self.ListBoxItem8 = None
29 | self.bill_plus_tip = None
30 | self.Label5 = None
31 | self.ListBoxItem9 = None
32 | self.gold_style_btn = None
33 | self.ruby_style_btn = None
34 | self.light_style_btn = None
35 | self.default_style = None
36 | self.styleGold = None
37 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "TipMain.pyfmx"))
38 | self.editTotal.OnChange = self.editTotalChange
39 | self.editTotal.Value = 100
40 | self.editTip.Value = 20
41 | self.editPeople.Value = 4
42 |
43 | def calc_bill_plus_tip(self):
44 | total = self.editTotal.Value
45 | tip_percent = self.editTip.Value
46 |
47 | if total != 0:
48 | self.bill_plus_tip.Text = str(round(total + (tip_percent*total)/100, 2))
49 | print(round(total + (tip_percent/total)*100, 2))
50 | else:
51 | self.bill_plus_tip.Text = str(0)
52 |
53 | def calc_per_person_share(self):
54 | persons = self.editPeople.Value
55 |
56 | self.per_person_share.Text = str(round(float(self.bill_plus_tip.Text) / persons, 2))
57 |
58 | def editTotalChange(self, Sender):
59 | self.calc_bill_plus_tip()
60 | self.calc_per_person_share()
61 |
62 | def editTipChange(self, Sender):
63 | self.trackTip.Value = self.editTip.Value
64 | self.calc_bill_plus_tip()
65 | self.calc_per_person_share()
66 |
67 | def trackTipChange(self, Sender):
68 | self.editTip.Value = self.trackTip.Value
69 | self.calc_bill_plus_tip()
70 | self.calc_per_person_share()
71 |
72 | def editPeopleChange(self, Sender):
73 | self.trackPeople.Value = self.editPeople.Value
74 | self.calc_bill_plus_tip()
75 | self.calc_per_person_share()
76 |
77 | def trackPeopleChange(self, Sender):
78 | self.editPeople.Value = self.trackPeople.Value
79 | self.calc_bill_plus_tip()
80 | self.calc_per_person_share()
81 |
82 | def gold_style_btnClick(self, Sender):
83 | self.styleBook = self.styleGold
84 |
85 | def ruby_style_btnClick(self, Sender):
86 | self.styleBook = self.styleRuby
87 |
88 | def light_style_btnClick(self, Sender):
89 | self.styleBook = self.styleLight
90 |
91 | def default_styleClick(self, Sender):
92 | self.styleBook = None
--------------------------------------------------------------------------------
/Samples/TipCalculator/Python_Export/TipCalculator.py:
--------------------------------------------------------------------------------
1 | from delphifmx import *
2 | from TipMain import Main_Window
3 |
4 | def main():
5 | Application.Initialize()
6 | Application.Title = 'Tip Calculator'
7 | Application.MainForm = Main_Window(Application)
8 | Application.MainForm.Show()
9 | Application.Run()
10 | Application.MainForm.Destroy()
11 |
12 | if __name__ == '__main__':
13 | main()
14 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/Python_Export/TipMain.py:
--------------------------------------------------------------------------------
1 | import os
2 | from delphifmx import *
3 |
4 | class Main_Window(Form):
5 |
6 | def __init__(self, owner):
7 | self.styleRuby = None
8 | self.styleLight = None
9 | self.ListBox1 = None
10 | self.ListBoxItem1 = None
11 | self.editTotal = None
12 | self.Label6 = None
13 | self.ListBoxItem2 = None
14 | self.Label7 = None
15 | self.editTip = None
16 | self.ListBoxItem3 = None
17 | self.trackTip = None
18 | self.ListBoxItem4 = None
19 | self.editPeople = None
20 | self.Label3 = None
21 | self.ListBoxItem5 = None
22 | self.trackPeople = None
23 | self.ListBoxItem6 = None
24 | self.Layout2 = None
25 | self.ListBoxItem7 = None
26 | self.per_person_share = None
27 | self.Label1 = None
28 | self.ListBoxItem8 = None
29 | self.bill_plus_tip = None
30 | self.Label5 = None
31 | self.ListBoxItem9 = None
32 | self.gold_style_btn = None
33 | self.ruby_style_btn = None
34 | self.light_style_btn = None
35 | self.default_style = None
36 | self.styleGold = None
37 | self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "TipMain.pyfmx"))
38 |
39 | def editTipChange(self, Sender):
40 | pass
41 |
42 | def trackTipChange(self, Sender):
43 | pass
44 |
45 | def editPeopleChange(self, Sender):
46 | pass
47 |
48 | def trackPeopleChange(self, Sender):
49 | pass
50 |
51 | def gold_style_btnClick(self, Sender):
52 | pass
53 |
54 | def ruby_style_btnClick(self, Sender):
55 | pass
56 |
57 | def light_style_btnClick(self, Sender):
58 | pass
59 |
60 | def default_styleClick(self, Sender):
61 | pass
--------------------------------------------------------------------------------
/Samples/TipCalculator/TipCalculator.deployproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 12
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | TipCalculator\library\lib\armeabi-v7a\
16 | libTipCalculator.so
17 | AndroidLibnativeArmeabiv7aFile
18 | 1
19 |
20 |
21 | True
22 |
23 |
24 | TipCalculator\res\drawable-mdpi\
25 | ic_notification.png
26 | Android_NotificationIcon24
27 | 1
28 |
29 |
30 | True
31 |
32 |
33 | TipCalculator\res\drawable-ldpi\
34 | ic_launcher.png
35 | Android_LauncherIcon36
36 | 1
37 |
38 |
39 | True
40 |
41 |
42 | TipCalculator\res\drawable-hdpi\
43 | ic_launcher.png
44 | Android_LauncherIcon72
45 | 1
46 |
47 |
48 | True
49 |
50 |
51 | TipCalculator\res\drawable-xlarge\
52 | splash_image.png
53 | Android_SplashImage960
54 | 1
55 |
56 |
57 | True
58 |
59 |
60 | TipCalculator\
61 | AndroidManifest.xml
62 | ProjectAndroidManifest
63 | 1
64 |
65 |
66 | True
67 |
68 |
69 | TipCalculator\res\drawable-mdpi\
70 | ic_launcher.png
71 | Android_LauncherIcon48
72 | 1
73 |
74 |
75 | True
76 |
77 |
78 | TipCalculator\library\lib\arm64-v8a\
79 | libTipCalculator.so
80 | ProjectOutput
81 | 1
82 |
83 |
84 | True
85 | True
86 |
87 |
88 | TipCalculator\res\drawable-xxhdpi\
89 | ic_launcher.png
90 | Android_LauncherIcon144
91 | 1
92 |
93 |
94 | True
95 |
96 |
97 | TipCalculator\res\drawable-xxxhdpi\
98 | ic_launcher.png
99 | Android_LauncherIcon192
100 | 1
101 |
102 |
103 | True
104 |
105 |
106 | TipCalculator\res\values\
107 | styles.xml
108 | AndroidSplashStyles
109 | 1
110 |
111 |
112 | True
113 |
114 |
115 | TipCalculator\res\drawable-xhdpi\
116 | ic_notification.png
117 | Android_NotificationIcon48
118 | 1
119 |
120 |
121 | True
122 |
123 |
124 | TipCalculator\res\drawable-small\
125 | splash_image.png
126 | Android_SplashImage426
127 | 1
128 |
129 |
130 | True
131 |
132 |
133 | TipCalculator\res\drawable-large\
134 | splash_image.png
135 | Android_SplashImage640
136 | 1
137 |
138 |
139 | True
140 |
141 |
142 | TipCalculator\library\lib\armeabi\
143 | libTipCalculator.so
144 | AndroidLibnativeArmeabiFile
145 | 1
146 |
147 |
148 | True
149 |
150 |
151 | TipCalculator\classes\
152 | TipCalculator.classes
153 | AndroidClasses
154 | 64
155 |
156 |
157 | True
158 |
159 |
160 | TipCalculator\res\values\
161 | strings.xml
162 | Android_Strings
163 | 1
164 |
165 |
166 | True
167 |
168 |
169 | TipCalculator\res\values-v21\
170 | styles.xml
171 | AndroidSplashStylesV21
172 | 1
173 |
174 |
175 | True
176 |
177 |
178 | TipCalculator\res\values\
179 | colors.xml
180 | Android_Colors
181 | 1
182 |
183 |
184 | True
185 |
186 |
187 | TipCalculator\res\drawable\
188 | splash_image_def.xml
189 | AndroidSplashImageDef
190 | 1
191 |
192 |
193 | True
194 |
195 |
196 | TipCalculator\res\drawable-hdpi\
197 | ic_notification.png
198 | Android_NotificationIcon36
199 | 1
200 |
201 |
202 | True
203 |
204 |
205 | TipCalculator\res\drawable-xxhdpi\
206 | ic_notification.png
207 | Android_NotificationIcon72
208 | 1
209 |
210 |
211 | True
212 |
213 |
214 | TipCalculator\res\drawable-xxxhdpi\
215 | ic_notification.png
216 | Android_NotificationIcon96
217 | 1
218 |
219 |
220 | True
221 |
222 |
223 | TipCalculator\library\lib\mips\
224 | libTipCalculator.so
225 | AndroidLibnativeMipsFile
226 | 1
227 |
228 |
229 | True
230 |
231 |
232 | TipCalculator\res\drawable-xhdpi\
233 | ic_launcher.png
234 | Android_LauncherIcon96
235 | 1
236 |
237 |
238 | True
239 |
240 |
241 | TipCalculator\res\drawable-normal\
242 | splash_image.png
243 | Android_SplashImage470
244 | 1
245 |
246 |
247 | True
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/TipCalculator.dpr:
--------------------------------------------------------------------------------
1 | program TipCalculator;
2 |
3 | uses
4 | System.StartUpCopy,
5 | FMX.Forms,
6 | TipMain in 'TipMain.pas' {Main_Window};
7 |
8 | {$R *.res}
9 |
10 | begin
11 | Application.Initialize;
12 | Application.CreateForm(TMain_Window, Main_Window);
13 | Application.Run;
14 | end.
15 |
--------------------------------------------------------------------------------
/Samples/TipCalculator/TipCalculator.res:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/Samples/TipCalculator/TipCalculator.res
--------------------------------------------------------------------------------
/Samples/TipCalculator/TipMain.pas:
--------------------------------------------------------------------------------
1 | unit TipMain;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit,
8 | FMX.EditBox, FMX.SpinBox, FMX.Controls.Presentation, FMX.StdCtrls,
9 | Data.Bind.EngExt, Fmx.Bind.DBEngExt, System.Rtti,
10 | System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Components,
11 | FMX.Objects, FMX.ListBox, FMX.Layouts;
12 |
13 | type
14 | TMain_Window = class(TForm)
15 | styleGold: TStyleBook;
16 | styleRuby: TStyleBook;
17 | styleLight: TStyleBook;
18 | ListBox1: TListBox;
19 | ListBoxItem1: TListBoxItem;
20 | editTotal: TSpinBox;
21 | ListBoxItem2: TListBoxItem;
22 | ListBoxItem3: TListBoxItem;
23 | ListBoxItem4: TListBoxItem;
24 | ListBoxItem5: TListBoxItem;
25 | Label7: TLabel;
26 | Label6: TLabel;
27 | editTip: TSpinBox;
28 | trackTip: TTrackBar;
29 | ListBoxItem6: TListBoxItem;
30 | ListBoxItem7: TListBoxItem;
31 | trackPeople: TTrackBar;
32 | editPeople: TSpinBox;
33 | Label3: TLabel;
34 | Layout2: TLayout;
35 | ListBoxItem8: TListBoxItem;
36 | bill_plus_tip: TEdit;
37 | per_person_share: TEdit;
38 | Label1: TLabel;
39 | Label5: TLabel;
40 | ListBoxItem9: TListBoxItem;
41 | gold_style_btn: TButton;
42 | ruby_style_btn: TButton;
43 | light_style_btn: TButton;
44 | default_style: TButton;
45 | procedure gold_style_btnClick(Sender: TObject);
46 | procedure ruby_style_btnClick(Sender: TObject);
47 | procedure light_style_btnClick(Sender: TObject);
48 | procedure default_styleClick(Sender: TObject);
49 | procedure editTipChange(Sender: TObject);
50 | procedure trackTipChange(Sender: TObject);
51 | procedure editPeopleChange(Sender: TObject);
52 | procedure trackPeopleChange(Sender: TObject);
53 | procedure btnUpClick(Sender: TObject);
54 | procedure btnDownClick(Sender: TObject);
55 | private
56 | { Private declarations }
57 | public
58 | { Public declarations }
59 | end;
60 |
61 | var
62 | Main_Window: TMain_Window;
63 |
64 | implementation
65 |
66 | {$R *.fmx}
67 |
68 | procedure TMain_Window.gold_style_btnClick(Sender: TObject);
69 | begin
70 | StyleBook := styleGold;
71 | end;
72 |
73 | procedure TMain_Window.ruby_style_btnClick(Sender: TObject);
74 | begin
75 | StyleBook := styleRuby;
76 | end;
77 |
78 | procedure TMain_Window.light_style_btnClick(Sender: TObject);
79 | begin
80 | StyleBook := styleLight;
81 | end;
82 |
83 | procedure TMain_Window.btnDownClick(Sender: TObject);
84 | begin
85 | //
86 | end;
87 |
88 | procedure TMain_Window.btnUpClick(Sender: TObject);
89 | begin
90 | //
91 | end;
92 |
93 | procedure TMain_Window.default_styleClick(Sender: TObject);
94 | begin
95 | StyleBook := nil;
96 | end;
97 |
98 | procedure TMain_Window.editPeopleChange(Sender: TObject);
99 | begin
100 | //
101 | end;
102 |
103 | procedure TMain_Window.editTipChange(Sender: TObject);
104 | begin
105 | //
106 | end;
107 |
108 | procedure TMain_Window.trackPeopleChange(Sender: TObject);
109 | begin
110 | //
111 | end;
112 |
113 | procedure TMain_Window.trackTipChange(Sender: TObject);
114 | begin
115 | //
116 | end;
117 |
118 | end.
119 |
--------------------------------------------------------------------------------
/Source/Design/PythonTools.Design.Forms.pas:
--------------------------------------------------------------------------------
1 | {$I PythonTools.inc}
2 | unit PythonTools.Design.Forms;
3 |
4 | interface
5 |
6 | uses
7 | System.SysUtils, System.Variants, System.Classes,
8 | Data.DB, Datasnap.DBClient, Vcl.Dialogs,
9 | Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids, Vcl.Buttons, Vcl.Imaging.pngimage,
10 | Vcl.ExtCtrls, Vcl.Controls, Vcl.Forms, System.Types,
11 | PythonTools.Design, PythonTools.Model.Design.Forms;
12 |
13 | {$WARN SYMBOL_PLATFORM OFF}
14 |
15 | type
16 | TDBGrid = class(Vcl.DBGrids.TDBGrid)
17 | protected
18 | procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
19 | public
20 | function ScaleValue(const Value: Integer): Integer; overload;
21 | function ScaleValue(const Value: TSize): TSize; overload;
22 | end;
23 |
24 | TFormsExportDialog = class(TDesignForm)
25 | FileOpenDialog1: TFileOpenDialog;
26 | pnlHeader: TPanel;
27 | imgExport: TImage;
28 | lblDescription: TLabel;
29 | lblExport: TLabel;
30 | spHeader: TShape;
31 | pnlContents: TPanel;
32 | pnlAppDir: TPanel;
33 | lblApplicationDirectory: TLabel;
34 | edtDirectory: TEdit;
35 | plnFooter: TPanel;
36 | btnCancel: TButton;
37 | btnExport: TButton;
38 | pnlGrid: TPanel;
39 | grForms: TDBGrid;
40 | cdsForms: TClientDataSet;
41 | dsForms: TDataSource;
42 | cdsFormsFL_EXPORT: TBooleanField;
43 | cdsFormsDESC_FORM: TStringField;
44 | cdsFormsTITLE: TStringField;
45 | cdsFormsFL_INITIALIZE: TBooleanField;
46 | cdsFormsFL_FORM_FILE_KIND: TStringField;
47 | btnSelectDir: TButton;
48 | llblNotification: TLinkLabel;
49 | cbShowExportedFiles: TCheckBox;
50 | pnlFormFileOptions: TPanel;
51 | cbFormFileCompatibleMode: TCheckBox;
52 | procedure btnExportClick(Sender: TObject);
53 | procedure btnSelectDirClick(Sender: TObject);
54 | procedure FormCreate(Sender: TObject);
55 | procedure grFormsKeyPress(Sender: TObject; var Key: Char);
56 | procedure grFormsCellClick(Column: TColumn);
57 | procedure cdsFormsFL_EXPORTGetText(Sender: TField; var Text: string;
58 | DisplayText: Boolean);
59 | procedure grFormsColEnter(Sender: TObject);
60 | procedure cdsFormsFL_INITIALIZEGetText(Sender: TField; var Text: string;
61 | DisplayText: Boolean);
62 | procedure grFormsTitleClick(Column: TColumn);
63 | procedure grFormsDrawColumnCell(Sender: TObject; const Rect: TRect;
64 | DataCol: Integer; Column: TColumn; State: TGridDrawState);
65 | procedure llblNotificationLinkClick(Sender: TObject; const Link: string;
66 | LinkType: TSysLinkType);
67 | public
68 | function Execute(const AModel: TExportFormsDesignModel): boolean;
69 | end;
70 |
71 | var
72 | FormsExportDialog: TFormsExportDialog;
73 |
74 | implementation
75 |
76 | uses
77 | System.Generics.Collections, System.Math,
78 | CommCtrl, Vcl.Themes,
79 | ShellApi,
80 | Winapi.Windows,
81 | Vcl.Graphics,
82 | PythonTools.Common;
83 |
84 | var
85 | gCheckBoxElement: TCheckBox;
86 |
87 | {$R *.dfm}
88 |
89 | function RectVCenter(var R: TRect; Bounds: TRect): TRect;
90 | begin
91 | OffsetRect(R, -R.Left, -R.Top);
92 | OffsetRect(R, Bounds.Right - (R.Width div 2), (Bounds.Height - R.Height) div 2);
93 | OffsetRect(R, Bounds.Left, Bounds.Top);
94 |
95 | Result := R;
96 | end;
97 |
98 | procedure DrawCheckBox(const ADBGrid: TDBGrid; const AColumn: TColumn;
99 | ARect: TRect; const AChecked: boolean; AState: TGridDrawState);
100 | const
101 | IS_CHECKED: array[boolean] of integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
102 | var
103 | LStyle: TCustomStyleServices;
104 | LBoxSize: TSize;
105 | LDetail: TThemedButton;
106 | LDetails: TThemedElementDetails;
107 | LRect: TRect;
108 | begin
109 | ADBGrid.Canvas.FillRect(ARect);
110 |
111 | LStyle := StyleServices;
112 | if LStyle.Available then begin
113 | LDetail := tbCheckBoxUncheckedNormal;
114 |
115 | if (gdPressed in AState) then
116 | LDetail := tbCheckBoxUncheckedPressed
117 | else if (gdFocused in AState) then
118 | LDetail := tbCheckBoxUncheckedHot;
119 |
120 | if AChecked then
121 | LDetail := TThemedButton(Integer(LDetail) + 4);
122 |
123 | LDetails := LStyle.GetElementDetails(tbCheckBoxUncheckedNormal);
124 | if not LStyle.GetElementSize(gCheckBoxElement.Handle, LDetails, esActual, LBoxSize {$IFDEF DELPHI10_3_UP}, ADBGrid.CurrentPPI {$ENDIF}) then
125 | begin
126 | LBoxSize.cx := GetSystemMetrics(SM_CXMENUCHECK);
127 | LBoxSize.cy := GetSystemMetrics(SM_CYMENUCHECK);
128 | end;
129 |
130 | if LStyle.IsSystemStyle then
131 | LBoxSize := ADBGrid.ScaleValue(LBoxSize);
132 |
133 | LRect := Rect(0, 0, LBoxSize.cx, LBoxSize.cy);
134 | RectVCenter(LRect, Rect(0, ARect.Top, ARect.Right, ARect.Bottom));
135 |
136 | LDetails := LStyle.GetElementDetails(LDetail);
137 | LStyle.DrawElement(ADBGrid.Canvas.Handle, LDetails, LRect, nil {$IFDEF DELPHI10_3_UP}, ADBGrid.CurrentPPI {$ENDIF});
138 |
139 | if not (gdFocused in AState) then
140 | ADBGrid.Canvas.Brush.Color := LStyle.GetSystemColor(clHighlight);
141 | end else
142 | DrawFrameControl(ADBGrid.Canvas.Handle, ARect, DFC_BUTTON, IS_CHECKED[AChecked]);
143 | end;
144 |
145 | procedure TFormsExportDialog.btnExportClick(Sender: TObject);
146 | var
147 | LMark: TArray;
148 | LHasSelection: boolean;
149 | begin
150 | //Make some validations
151 | if Trim(edtDirectory.Text) = String.Empty then
152 | raise Exception.Create('Select the Directory.');
153 |
154 | cdsForms.DisableControls();
155 | try
156 | LMark := cdsForms.Bookmark;
157 | try
158 | cdsForms.Filter := 'FL_EXPORT = True';
159 | cdsForms.Filtered := true;
160 | LHasSelection := not cdsForms.IsEmpty();
161 | cdsForms.Filtered := false;
162 | finally
163 | if cdsForms.BookmarkValid(LMark) then
164 | cdsForms.Bookmark := LMark;
165 | end;
166 | finally
167 | cdsForms.EnableControls();
168 | end;
169 |
170 | if not LHasSelection then
171 | raise Exception.Create('Select one form at least.');
172 |
173 | ModalResult := mrOk;
174 | end;
175 |
176 | procedure TFormsExportDialog.btnSelectDirClick(Sender: TObject);
177 | begin
178 | with FileOpenDialog1 do begin
179 | DefaultFolder := edtDirectory.Text;
180 | FileName := edtDirectory.Text;
181 | if Execute then
182 | edtDirectory.Text := FileName
183 | else
184 | edtDirectory.Text := String.Empty;
185 | end;
186 | end;
187 |
188 | procedure TFormsExportDialog.cdsFormsFL_EXPORTGetText(Sender: TField;
189 | var Text: string; DisplayText: Boolean);
190 | begin
191 | Text := ' ';
192 | end;
193 |
194 | procedure TFormsExportDialog.cdsFormsFL_INITIALIZEGetText(Sender: TField;
195 | var Text: string; DisplayText: Boolean);
196 | begin
197 | Text := ' ';
198 | end;
199 |
200 | procedure TFormsExportDialog.grFormsCellClick(Column: TColumn);
201 | begin
202 | if Column.Field.DataType = ftBoolean then begin
203 | cdsForms.Edit();
204 | Column.Field.AsBoolean := not Column.Field.AsBoolean;
205 | cdsForms.Post();
206 | end;
207 | end;
208 |
209 | procedure TFormsExportDialog.grFormsColEnter(Sender: TObject);
210 | begin
211 | with Sender as TDBGrid do
212 | if (SelectedField.DataType = ftBoolean) then
213 | Options := Options - [dgEditing]
214 | else
215 | Options := Options + [dgEditing];
216 | end;
217 |
218 | procedure TFormsExportDialog.grFormsDrawColumnCell(Sender: TObject;
219 | const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
220 | var
221 | LRect: TRect;
222 | begin
223 | inherited;
224 | if Column.Field.DataType = ftBoolean then begin
225 | LRect := System.Classes.Rect(
226 | Rect.Left,
227 | Rect.Top,
228 | Rect.Right - (Column.Width div 2),
229 | Rect.Bottom
230 | );
231 | DrawCheckBox(TDBGrid(Sender), Column, LRect, Column.Field.AsBoolean, State);
232 | end;
233 | end;
234 |
235 | procedure TFormsExportDialog.grFormsKeyPress(Sender: TObject; var Key: Char);
236 | begin
237 | if (key = Chr(9)) then
238 | Exit;
239 |
240 | with Sender as TDBGrid do
241 | if Assigned(SelectedField) and (Ord(Key) in [VK_RETURN, VK_SPACE]) then begin
242 | cdsForms.Edit();
243 | SelectedField.AsBoolean := not SelectedField.AsBoolean;
244 | cdsForms.Post();
245 | end;
246 | end;
247 |
248 | procedure TFormsExportDialog.grFormsTitleClick(Column: TColumn);
249 | var
250 | LMark: TArray;
251 | begin
252 | if Column.Field.DataType = ftBoolean then begin
253 | Column.Field.Tag := Integer(not Boolean(Column.Field.Tag));
254 |
255 | cdsForms.DisableControls();
256 | try
257 | LMark := cdsForms.Bookmark;
258 | try
259 | cdsForms.First();
260 | while not cdsForms.Eof do begin
261 | cdsForms.Edit();
262 | Column.Field.AsBoolean := Boolean(Column.Field.Tag);
263 | cdsForms.Post();
264 | cdsForms.Next();
265 | end;
266 | finally
267 | if cdsForms.BookmarkValid(LMark) then
268 | cdsForms.Bookmark := LMark;
269 | end;
270 | finally
271 | cdsForms.EnableControls();
272 | end;
273 | end;
274 | end;
275 |
276 | procedure TFormsExportDialog.llblNotificationLinkClick(Sender: TObject;
277 | const Link: string; LinkType: TSysLinkType);
278 | begin
279 | ShellExecute(0, 'open', pchar(Link), nil, nil, SW_NORMAL);
280 | end;
281 |
282 | function TFormsExportDialog.Execute(const AModel: TExportFormsDesignModel): boolean;
283 | var
284 | LInput: TInputForm;
285 | LOutput: TList;
286 | LFormFileMode: TFormFileMode;
287 | begin
288 | edtDirectory.Text := AModel.Directory;
289 | cbShowExportedFiles.Checked := AModel.ShowInExplorer;
290 |
291 | cdsForms.EmptyDataSet();
292 | for LInput in AModel.InputForms do begin
293 | cdsForms.AppendRecord([
294 | true,
295 | LInput.Form.CombineFileAndFormName(),
296 | LInput.Title,
297 | True,
298 | TFormFileKind.ffkText.ToString()
299 | ]);
300 | end;
301 | cdsForms.First();
302 |
303 | with grForms do
304 | if SelectedField.DataType = ftBoolean then
305 | Options := Options - [dgEditing];
306 |
307 | Result := ShowModal() = mrOk;
308 |
309 | if not Result then
310 | Exit();
311 |
312 | AModel.Directory := edtDirectory.Text;
313 | AModel.ShowInExplorer := cbShowExportedFiles.Checked;
314 |
315 | LFormFileMode := TFormFileMode.ffmPython;
316 | if cbFormFileCompatibleMode.Checked then
317 | LFormFileMode := TFormFileMode.ffmCompatible;
318 |
319 | LOutput := TList.Create();
320 | try
321 | cdsForms.DisableControls();
322 | try
323 | cdsForms.First();
324 | for LInput in AModel.InputForms do begin
325 | if cdsForms.Locate('DESC_FORM', LInput.Form.CombineFileAndFormName(), []) then begin
326 | if not cdsFormsFL_EXPORT.AsBoolean then
327 | Continue;
328 | LOutput.Add(TOutputForm.Create(
329 | LInput.Form,
330 | cdsFormsFL_INITIALIZE.AsBoolean,
331 | cdsFormsTITLE.AsString,
332 | TFormFileKind.FromString(cdsFormsFL_FORM_FILE_KIND.AsString),
333 | LFormFileMode
334 | ));
335 | end;
336 | end;
337 | finally
338 | cdsForms.EnableControls();
339 | end;
340 | AModel.OutputForms := LOutput.ToArray();
341 | finally
342 | LOutput.Free();
343 | end;
344 | end;
345 |
346 | procedure TFormsExportDialog.FormCreate(Sender: TObject);
347 | begin
348 | inherited;
349 | gCheckBoxElement := cbShowExportedFiles;
350 | cdsForms.CreateDataSet();
351 | end;
352 |
353 | { TDBGrid }
354 |
355 | procedure TDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
356 | AState: TGridDrawState);
357 | const
358 | TEXT_LEFT_OFFSET = 15;
359 | var
360 | LRect: TRect;
361 | LChecked: Boolean;
362 | begin
363 | inherited;
364 | Dec(ARow);
365 | if ARow < 0 then
366 | if Columns[ACol].Field.DataType = ftBoolean then begin
367 | LRect := ARect;
368 | LRect.Right := LRect.Right - (
369 | (ColWidths[ACol] div 2)
370 | + (Canvas.TextWidth(Columns[ACol].Title.Caption) div 2)
371 | + ScaleValue(TEXT_LEFT_OFFSET)
372 | );
373 | LChecked := Boolean(Columns[ACol].Field.Tag);
374 | DrawCheckBox(Self, Columns[ACol], LRect, LChecked, AState);
375 | end;
376 | end;
377 |
378 | function TDBGrid.ScaleValue(const Value: TSize): TSize;
379 | begin
380 | {$IFDEF DELPHI10_4_UP}
381 | Result := inherited;
382 | {$ELSE}
383 | Result := Value;
384 | {$ENDIF}
385 | end;
386 |
387 | function TDBGrid.ScaleValue(const Value: Integer): Integer;
388 | begin
389 | {$IFDEF DELPHI10_4_UP}
390 | Result := inherited;
391 | {$ELSE}
392 | Result := Value;
393 | {$ENDIF}
394 | end;
395 |
396 | end.
397 |
--------------------------------------------------------------------------------
/Source/Design/PythonTools.Design.Project.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Design.Project;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Imaging.pngimage,
8 | Vcl.StdCtrls, Vcl.Buttons,
9 | PythonTools.Design,
10 | PythonTools.Common,
11 | PythonTools.Model.Design.Project, Vcl.WinXCtrls;
12 |
13 | {$WARN SYMBOL_PLATFORM OFF}
14 |
15 | type
16 | TProjectExportDialog = class(TDesignForm)
17 | pnlHeader: TPanel;
18 | plnFooter: TPanel;
19 | pnlAppDir: TPanel;
20 | pnlAppSettings: TPanel;
21 | imgExport: TImage;
22 | lblExport: TLabel;
23 | lblProjectName: TLabel;
24 | spHeader: TShape;
25 | lblAppTitle: TLabel;
26 | edtApplicationTitle: TEdit;
27 | lblAppMainForm: TLabel;
28 | cbApplicationMainForm: TComboBox;
29 | FileOpenDialog1: TFileOpenDialog;
30 | lblApplicationDirectory: TLabel;
31 | edtApplicationDirectory: TEdit;
32 | btnCancel: TButton;
33 | btnExport: TButton;
34 | pnlFormFileOptions: TPanel;
35 | lblFormFileKind: TLabel;
36 | swFormFileKind: TToggleSwitch;
37 | Label1: TLabel;
38 | Label2: TLabel;
39 | llblNotification: TLinkLabel;
40 | pnlContents: TPanel;
41 | lbForms: TListBox;
42 | pnlClient: TPanel;
43 | cbShowExportedFiles: TCheckBox;
44 | btnSelectDir: TButton;
45 | cbFormFileCompatibleMode: TCheckBox;
46 | procedure btnExportClick(Sender: TObject);
47 | procedure btnSelectDirClick(Sender: TObject);
48 | procedure Label1Click(Sender: TObject);
49 | procedure Label2Click(Sender: TObject);
50 | procedure llblNotificationLinkClick(Sender: TObject; const Link: string;
51 | LinkType: TSysLinkType);
52 | procedure FormShow(Sender: TObject);
53 | private
54 | procedure EnableHorizontalScrollBar(const AListBox: TListBox);
55 | public
56 | function Execute(const AModel: TExportProjectDesignModel): boolean;
57 | end;
58 |
59 | var
60 | ProjectExportDialog: TProjectExportDialog;
61 |
62 | implementation
63 |
64 | {$R *.dfm}
65 |
66 | uses ShellApi;
67 |
68 | procedure TProjectExportDialog.btnExportClick(Sender: TObject);
69 | begin
70 | //Make some validations
71 | if Trim(edtApplicationTitle.Text) = String.Empty then
72 | raise Exception.Create('Type the Application Title.');
73 |
74 | if cbApplicationMainForm.ItemIndex = -1 then
75 | raise Exception.Create('Select the Application Main Form');
76 |
77 | if Trim(edtApplicationDirectory.Text) = String.Empty then
78 | raise Exception.Create('Select the Application Directory.');
79 |
80 | ModalResult := mrOk;
81 | end;
82 |
83 | procedure TProjectExportDialog.EnableHorizontalScrollBar(
84 | const AListBox: TListBox);
85 | var
86 | I: integer;
87 | LMaxWidth: integer;
88 | LWidth: integer;
89 | begin
90 | inherited;
91 | LMaxWidth := AListBox.Width;
92 | for I := 0 to Pred(AListBox.Items.Count) do begin
93 | LWidth := Canvas.TextWidth(AListBox.Items[I]);
94 | if LWidth > LMaxWidth then
95 | LMaxWidth := LWidth;
96 | end;
97 |
98 | if (LMaxWidth > AListBox.Width) then
99 | SendMessage(AListBox.Handle, LB_SETHORIZONTALEXTENT,
100 | LMaxWidth + GetSystemMetrics(SM_CXFRAME), 0);
101 | end;
102 |
103 | function TProjectExportDialog.Execute(const AModel: TExportProjectDesignModel): boolean;
104 | var
105 | LFormNameAndFile: TFormNameAndFile;
106 | begin
107 | lblProjectName.Caption := AModel.ApplicationName;
108 | edtApplicationTitle.Text := AModel.ApplicationTitle;
109 | edtApplicationDirectory.Text := AModel.ApplicationDirectory;
110 | cbShowExportedFiles.Checked := AModel.ShowInExplorer;
111 |
112 | for LFormNameAndFile in AModel.ApplicationForms do begin
113 | cbApplicationMainForm.Items.Add(LFormNameAndFile.CombineFileAndFormName());
114 | lbForms.Items.Add(LFormNameAndFile.CombineFileAndFormName());
115 | end;
116 |
117 | if (AModel.ApplicationMainForm.CombineFileAndFormName() <> String.Empty) then
118 | cbApplicationMainForm.ItemIndex := cbApplicationMainForm.Items.IndexOf(
119 | AModel.ApplicationMainForm.CombineFileAndFormName())
120 | else if (cbApplicationMainForm.Items.Count > 0) then
121 | cbApplicationMainForm.ItemIndex := 0;
122 |
123 | case AModel.FormFileKind of
124 | ffkText: swFormFileKind.State := tssOff;
125 | ffkBinary: swFormFileKind.State := tssOn;
126 | end;
127 |
128 | Result := ShowModal() = mrOk;
129 |
130 | if not Result then
131 | Exit();
132 |
133 | AModel.ApplicationTitle := edtApplicationTitle.Text;
134 | AModel.ApplicationMainForm := AModel.ApplicationForms[cbApplicationMainForm.ItemIndex];
135 | AModel.ApplicationDirectory := edtApplicationDirectory.Text;
136 | if cbFormFileCompatibleMode.Checked then
137 | AModel.FormFileMode := TFormFileMode.ffmCompatible
138 | else
139 | AModel.FormFileMode := TFormFileMode.ffmPython;
140 | Amodel.ShowInExplorer := cbShowExportedFiles.Checked;
141 |
142 | case swFormFileKind.State of
143 | tssOff: AModel.FormFileKind := ffkText;
144 | tssOn: AModel.FormFileKind := ffkBinary;
145 | end;
146 | end;
147 |
148 | procedure TProjectExportDialog.FormShow(Sender: TObject);
149 | begin
150 | inherited;
151 | EnableHorizontalScrollBar(lbForms);
152 | end;
153 |
154 | procedure TProjectExportDialog.Label1Click(Sender: TObject);
155 | begin
156 | swFormFileKind.State := tssOn;
157 | end;
158 |
159 | procedure TProjectExportDialog.Label2Click(Sender: TObject);
160 | begin
161 | swFormFileKind.State := tssOff;
162 | end;
163 |
164 | procedure TProjectExportDialog.llblNotificationLinkClick(Sender: TObject;
165 | const Link: string; LinkType: TSysLinkType);
166 | Begin
167 | ShellExecute(0, 'open', pchar(Link), nil, nil, SW_NORMAL);
168 | end;
169 |
170 | procedure TProjectExportDialog.btnSelectDirClick(Sender: TObject);
171 | begin
172 | with FileOpenDialog1 do begin
173 | DefaultFolder := edtApplicationDirectory.Text;
174 | FileName := edtApplicationDirectory.Text;
175 | if Execute then
176 | edtApplicationDirectory.Text := FileName
177 | else
178 | edtApplicationDirectory.Text := String.Empty;
179 | end;
180 | end;
181 |
182 | end.
183 |
--------------------------------------------------------------------------------
/Source/Design/PythonTools.Design.dfm:
--------------------------------------------------------------------------------
1 | object DesignForm: TDesignForm
2 | Left = 0
3 | Top = 0
4 | Caption = 'DesignForm'
5 | ClientHeight = 464
6 | ClientWidth = 644
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -12
11 | Font.Name = 'Segoe UI'
12 | Font.Style = []
13 | TextHeight = 15
14 | end
15 |
--------------------------------------------------------------------------------
/Source/Design/PythonTools.Design.pas:
--------------------------------------------------------------------------------
1 | {$I PythonTools.inc}
2 | unit PythonTools.Design;
3 |
4 | interface
5 |
6 | uses
7 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
8 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ToolsAPI;
9 |
10 | type
11 | TDesignForm = class(TForm {$IFDEF DELPHI10_2_UP}, INTAIDEThemingServicesNotifier{$ENDIF DELPHI10_2_UP})
12 | private
13 | {$IFDEF DELPHI10_2_UP}
14 | FIDEThemingNotifierId: integer;
15 | {$ENDIF DELPHI10_2_UP}
16 | private
17 | {$IFDEF DELPHI10_2_UP}
18 | //IOTANotifier
19 | procedure AfterSave;
20 | procedure BeforeSave;
21 | procedure Destroyed;
22 | procedure Modified;
23 | //INTAIDEThemingServicesNotifier
24 | procedure ChangingTheme();
25 | procedure ChangedTheme();
26 | {$ENDIF DELPHI10_2_UP}
27 | protected
28 | procedure RegisterIDEThemingNotifier();
29 | procedure UnRegisterIDEThemingNotifier();
30 | procedure ApplyIDETheming();
31 | public
32 | constructor Create(AOwner: TComponent); override;
33 | destructor Destroy(); override;
34 | end;
35 |
36 | var
37 | DesignForm: TDesignForm;
38 |
39 | implementation
40 |
41 | {$R *.dfm}
42 |
43 | { TDesignForm }
44 |
45 | constructor TDesignForm.Create(AOwner: TComponent);
46 | begin
47 | inherited;
48 | {$IFDEF DELPHI10_2_UP}
49 | {$IFDEF DELPHI10_4_UP}
50 | with (BorlandIDEServices as IOTAIDEThemingServices) do begin
51 | {$ELSE}
52 | with (BorlandIDEServices as IOTAIDEThemingServices250) do begin
53 | {$ENDIF DELPHI10_4_UP}
54 | RegisterFormClass(TCustomFormClass(Self.ClassType));
55 | ApplyIDETheming();
56 | RegisterIDEThemingNotifier();
57 | end;
58 | {$ENDIF DELPHI10_2_UP}
59 | end;
60 |
61 | destructor TDesignForm.Destroy;
62 | begin
63 | UnRegisterIDEThemingNotifier();
64 | inherited;
65 | end;
66 |
67 | {$IFDEF DELPHI10_2_UP}
68 |
69 | procedure TDesignForm.AfterSave;
70 | begin
71 | end;
72 |
73 | procedure TDesignForm.BeforeSave;
74 | begin
75 | end;
76 |
77 | procedure TDesignForm.Destroyed;
78 | begin
79 | end;
80 |
81 | procedure TDesignForm.Modified;
82 | begin
83 | end;
84 |
85 | procedure TDesignForm.ChangingTheme;
86 | begin
87 | end;
88 |
89 | procedure TDesignForm.ChangedTheme;
90 | begin
91 | ApplyIDETheming();
92 | end;
93 |
94 | {$ENDIF DELPHI10_2_UP}
95 |
96 | procedure TDesignForm.ApplyIDETheming;
97 | begin
98 | {$IFDEF DELPHI10_2_UP}
99 | with (BorlandIDEServices as IOTAIDEThemingServices) do begin
100 | ApplyTheme(Self);
101 | end;
102 | {$ENDIF DELPHI10_2_UP}
103 | end;
104 |
105 | procedure TDesignForm.RegisterIDEThemingNotifier;
106 | begin
107 | {$IFDEF DELPHI10_2_UP}
108 | with (BorlandIDEServices as IOTAIDEThemingServices) do begin
109 | FIDEThemingNotifierId := AddNotifier(Self);
110 | end;
111 | {$ENDIF DELPHI10_2_UP}
112 | end;
113 |
114 | procedure TDesignForm.UnRegisterIDEThemingNotifier;
115 | begin
116 | {$IFDEF DELPHI10_2_UP}
117 | with (BorlandIDEServices as IOTAIDEThemingServices) do begin
118 | RemoveNotifier(FIDEThemingNotifierId);
119 | end;
120 | {$ENDIF DELPHI10_2_UP}
121 | end;
122 |
123 | end.
124 |
--------------------------------------------------------------------------------
/Source/Exporter/PythonTools.Exporter.Application.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Exporter.Application;
2 |
3 | interface
4 |
5 | uses
6 | ToolsAPI,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Producer.SimpleFactory,
10 | PythonTools.Model.Design.Project,
11 | PythonTools.Model.Producer.Application;
12 |
13 | type
14 | TApplicationExporter = class
15 | private
16 | FModel: TExportProjectDesignModel;
17 | FProject: IOTAProject;
18 | protected
19 | //Producers models
20 | function BuildApplicationProducerModel: TApplicationProducerModel;
21 | //Exporters
22 | procedure DoExportApplication;
23 | public
24 | constructor Create(const AExportProjectModel: TExportProjectDesignModel;
25 | const AProject: IOTAProject);
26 |
27 | procedure ExportApplication;
28 | end;
29 |
30 | implementation
31 |
32 | uses
33 | System.IOUtils,
34 | System.Classes,
35 | System.SysUtils;
36 |
37 | { TApplicationExporter }
38 |
39 | function TApplicationExporter.BuildApplicationProducerModel: TApplicationProducerModel;
40 | begin
41 | Result := TApplicationProducerModel.Create();
42 | try
43 | Result.Directory := FModel.ApplicationDirectory;
44 | Result.FileName := ChangeFileExt(ExtractFileName(FProject.FileName), '');
45 | Result.MainForm := FModel.ApplicationMainForm.FormName;
46 | Result.Title := FModel.ApplicationTitle;
47 | Result.ImportedForms := [FModel.ApplicationMainForm];
48 | except
49 | on E: Exception do begin
50 | FreeAndNil(Result);
51 | raise;
52 | end;
53 | end;
54 | end;
55 |
56 | constructor TApplicationExporter.Create(
57 | const AExportProjectModel: TExportProjectDesignModel; const AProject: IOTAProject);
58 | begin
59 | FModel := AExportProjectModel;
60 | FProject := AProject;
61 | end;
62 |
63 | procedure TApplicationExporter.DoExportApplication;
64 | var
65 | LProducer: IPythonCodeProducer;
66 | LProducerModel: TApplicationProducerModel;
67 | begin
68 | LProducer := TProducerSimpleFactory.CreateProducer(FProject.FrameworkType);
69 |
70 | LProducerModel := BuildApplicationProducerModel();
71 | try
72 | LProducer.SavePyApplicationFile(LProducerModel, LProducerModel.Stream);
73 | finally
74 | LProducerModel.Free();
75 | end;
76 | end;
77 |
78 | procedure TApplicationExporter.ExportApplication;
79 | begin
80 | DoExportApplication();
81 | end;
82 |
83 | end.
84 |
--------------------------------------------------------------------------------
/Source/Exporter/PythonTools.Exporter.Form.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Exporter.Form;
2 |
3 | interface
4 |
5 | uses
6 | DesignIntf,
7 | System.Classes, System.Generics.Collections, System.Rtti,
8 | PythonTools.Common,
9 | PythonTools.IOTAUtils,
10 | PythonTools.Model.Producer.Form,
11 | PythonTools.Model.Producer.FormFile,
12 | PythonTools.Model.Design.Forms,
13 | PythonTools.Model.Design.Project;
14 |
15 | type
16 | TFormExporter = class abstract
17 | private
18 | //Utils
19 | function FindComponents(): TExportedComponents;
20 | function FindEvents(): TExportedEvents;
21 | protected
22 | FormInfo: TIOTAFormInfo;
23 | //Producer models
24 | function BuildFormModel: TFormProducerModel; virtual;
25 | function BuildFormFileModel: TFormFileProducerModel; virtual;
26 | //Exporters
27 | procedure DoExportForm(const AFormModel: TFormProducerModel;
28 | const AFormFileModel: TFormFileProducerModel);
29 | procedure DoExportFormFileBin(const AModel: TFormFileProducerModel);
30 | procedure DoExportFormFileTxt(const AModel: TFormFileProducerModel);
31 | public
32 | constructor Create(const AFormInfo: TIOTAFormInfo);
33 |
34 | procedure ExportForm;
35 | procedure ExportFormFile(const AFormFileKind: TFormFileKind);
36 | end;
37 |
38 | TFormExporterFromProject = class sealed(TFormExporter)
39 | private
40 | FModel: TExportProjectDesignModel;
41 | protected
42 | //Producer models
43 | function BuildFormModel: TFormProducerModel; override;
44 | function BuildFormFileModel: TFormFileProducerModel; override;
45 | public
46 | constructor Create(const AModel: TExportProjectDesignModel;
47 | const AFormInfo: TIOTAFormInfo);
48 | end;
49 |
50 | TFormExporterFromForms = class sealed(TFormExporter)
51 | private
52 | FModel: TExportFormsDesignModel;
53 | FCurrentForm: integer;
54 | protected
55 | //Producer models
56 | function BuildFormModel: TFormProducerModel; override;
57 | function BuildFormFileModel: TFormFileProducerModel; override;
58 | public
59 | constructor Create(const AModel: TExportFormsDesignModel;
60 | const ACurrentForm: integer; const AFormInfo: TIOTAFormInfo);
61 | end;
62 |
63 | implementation
64 |
65 | uses
66 | System.SysUtils,
67 | PythonTools.Exceptions,
68 | PythonTools.Producer,
69 | PythonTools.Producer.SimpleFactory;
70 |
71 | { TFormExporter }
72 |
73 | constructor TFormExporter.Create(const AFormInfo: TIOTAFormInfo);
74 | begin
75 | FormInfo := AFormInfo;
76 | end;
77 |
78 | function TFormExporter.FindComponents(): TExportedComponents;
79 | begin
80 | Result := TIOTAUtils.FindComponents(FormInfo.Editor);
81 | end;
82 |
83 | function TFormExporter.FindEvents(): TExportedEvents;
84 | begin
85 | Result := TIOTAUtils.FindEvents(FormInfo.Editor, FormInfo.Designer);
86 | end;
87 |
88 | procedure TFormExporter.ExportForm;
89 | var
90 | LFormProducerModel: TFormProducerModel;
91 | LFormFileProducerModel: TFormFileProducerModel;
92 | begin
93 | LFormProducerModel := BuildFormModel();
94 | try
95 | LFormFileProducerModel := BuildFormFileModel();
96 | try
97 | DoExportForm(LFormProducerModel, LFormFileProducerModel);
98 | finally
99 | LFormFileProducerModel.Free();
100 | end;
101 | finally
102 | LFormProducerModel.Free();
103 | end;
104 | end;
105 |
106 | procedure TFormExporter.ExportFormFile(const AFormFileKind: TFormFileKind);
107 | var
108 | LProducerModel: TFormFileProducerModel;
109 | begin
110 | LProducerModel := BuildFormFileModel();
111 | try
112 | if (AFormFileKind = ffkText) then
113 | DoExportFormFileTxt(LProducerModel)
114 | else if (AFormFileKind = ffkBinary) then
115 | DoExportFormFileBin(LProducerModel)
116 | else
117 | raise EInvalidFormFileKind.Create('Invalid form file kind.');
118 | finally
119 | LProducerModel.Free();
120 | end;
121 | end;
122 |
123 | function TFormExporter.BuildFormModel: TFormProducerModel;
124 | begin
125 | Result := TFormProducerModel.Create();
126 | try
127 | with Result do begin
128 | FormName := FormInfo.FormName;
129 | FormParentName := System.Copy(
130 | FormInfo.Designer.Root.ClassParent.ClassName,
131 | 2,
132 | FormInfo.Designer.Root.ClassParent.ClassName.Length);
133 | FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
134 | ExportedComponents := FindComponents();
135 | ExportedEvents := FindEvents();
136 | with ModuleInitialization do begin
137 | GenerateInitialization := false;
138 | end;
139 | end;
140 | except
141 | on E: Exception do begin
142 | FreeAndNil(Result);
143 | raise;
144 | end;
145 | end;
146 | end;
147 |
148 | function TFormExporter.BuildFormFileModel: TFormFileProducerModel;
149 | begin
150 | Result := TFormFileProducerModel.Create();
151 | try
152 | with Result do begin
153 | FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
154 | Form := FormInfo.Designer.Root;
155 | FormInfo.Editor.GetFormResource(TStreamAdapter.Create(FormResource));
156 | FormResource.Position := 0;
157 | end;
158 | except
159 | on E: Exception do begin
160 | FreeAndNil(Result);
161 | raise;
162 | end;
163 | end;
164 | end;
165 |
166 | procedure TFormExporter.DoExportForm(const AFormModel: TFormProducerModel;
167 | const AFormFileModel: TFormFileProducerModel);
168 | var
169 | LProducer: IPythonCodeProducer;
170 | begin
171 | LProducer := TProducerSimpleFactory.CreateProducer(FormInfo.FrameworkType);
172 |
173 | if not LProducer.IsValidFormInheritance(FormInfo.Designer.Root.ClassParent) then
174 | raise EFormInheritanceNotSupported.CreateFmt(
175 | '%s TForm direct inheritance only', [FormInfo.FrameworkType]);
176 |
177 | LProducer.SavePyForm(AFormModel, AFormFileModel, AFormModel.Stream);
178 | end;
179 |
180 | procedure TFormExporter.DoExportFormFileTxt(const AModel: TFormFileProducerModel);
181 | var
182 | LProducer: IPythonCodeProducer;
183 | begin
184 | LProducer := TProducerSimpleFactory.CreateProducer(FormInfo.FrameworkType);
185 | LProducer.SavePyFormFileTxt(AModel, AModel.Stream);
186 | end;
187 |
188 | procedure TFormExporter.DoExportFormFileBin(const AModel: TFormFileProducerModel);
189 | var
190 | LProducer: IPythonCodeProducer;
191 | begin
192 | LProducer := TProducerSimpleFactory.CreateProducer(FormInfo.FrameworkType);
193 | LProducer.SavePyFormFileBin(AModel, AModel.Stream);
194 | end;
195 |
196 | { TFormExporterFromProject }
197 |
198 | constructor TFormExporterFromProject.Create(
199 | const AModel: TExportProjectDesignModel; const AFormInfo: TIOTAFormInfo);
200 | begin
201 | inherited Create(AFormInfo);
202 | FModel := AModel;
203 | end;
204 |
205 | function TFormExporterFromProject.BuildFormModel: TFormProducerModel;
206 | begin
207 | Result := inherited;
208 | Result.Directory := FModel.ApplicationDirectory;
209 | Result.FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
210 | end;
211 |
212 | function TFormExporterFromProject.BuildFormFileModel: TFormFileProducerModel;
213 | begin
214 | Result := inherited;
215 | Result.Directory := FModel.ApplicationDirectory;
216 | Result.FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
217 | Result.Mode := FModel.FormFileMode;
218 | Result.FrameworkType := FormInfo.FrameworkType;
219 | end;
220 |
221 | { TFormExporterFromForms }
222 |
223 | constructor TFormExporterFromForms.Create(const AModel: TExportFormsDesignModel;
224 | const ACurrentForm: integer; const AFormInfo: TIOTAFormInfo);
225 | begin
226 | inherited Create(AFormInfo);
227 | FModel := AModel;
228 | FCurrentForm := ACurrentForm;
229 | end;
230 |
231 | function TFormExporterFromForms.BuildFormModel: TFormProducerModel;
232 | var
233 | LForm: TOutputForm;
234 | begin
235 | Result := inherited;
236 | Result.Directory := FModel.Directory;
237 | Result.FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
238 | with Result.ModuleInitialization do begin
239 | LForm := FModel.OutputForms[FCurrentForm];
240 | //Generate the initialization section for the MainForm only
241 | if LForm.GenerateInitialization
242 | and (Result.FormName = LForm.Form.FormName) then
243 | begin
244 | GenerateInitialization := true;
245 | Title := LForm.Title;
246 | MainForm := LForm.Form.FormName;
247 | end else
248 | GenerateInitialization := false;
249 | end;
250 | end;
251 |
252 | function TFormExporterFromForms.BuildFormFileModel: TFormFileProducerModel;
253 | begin
254 | Result := inherited;
255 | Result.Directory := FModel.Directory;
256 | Result.FileName := ChangeFileExt(ExtractFileName(FormInfo.FileName), '');
257 | Result.Mode := FModel.OutputForms[FCurrentForm].FormFileMode;
258 | Result.FrameworkType := FormInfo.FrameworkType;
259 | end;
260 |
261 | end.
262 |
--------------------------------------------------------------------------------
/Source/Exporter/PythonTools.Exporter.Forms.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Exporter.Forms;
2 |
3 | interface
4 |
5 | uses
6 | ToolsAPI,
7 | PythonTools.IOTAUtils,
8 | PythonTools.Model.Design.Forms;
9 |
10 | type
11 | TFormsExporter = class
12 | protected
13 | //Producer models
14 | function BuildExportFormsModel: TExportFormsDesignModel;
15 | public
16 | //constructor Create(const AProject: IOTAProject);
17 | //Request export project info
18 | function RequestExportInfo(const AModel: TExportFormsDesignModel): boolean;
19 | //Export the given project
20 | function ExportForms(): boolean;
21 | end;
22 |
23 | implementation
24 |
25 | uses
26 | System.SysUtils, System.Generics.Collections,
27 | ShellApi, Winapi.Windows,
28 | PythonTools.Exceptions, PythonTools.Common, PythonTools.Registry,
29 | PythonTools.Exporter.Form,
30 | PythonTools.Design.Forms;
31 |
32 | { TFormsExporter }
33 |
34 | function TFormsExporter.BuildExportFormsModel: TExportFormsDesignModel;
35 | var
36 | LInputs: TList;
37 | LInput: TInputForm;
38 | begin
39 | Result := TExportFormsDesignModel.Create();
40 | try
41 | // Result.Title := String.Empty;
42 | Result.Directory := String.Empty;
43 | LInputs := TList.Create();
44 | try
45 | TIOTAUtils.EnumForms(procedure(AFormInfo: TIOTAFormInfo) begin
46 | LInput.Form := TFormNameAndFile.Create(
47 | AFormInfo.FormName,
48 | ChangeFileExt(ExtractFileName(AFormInfo.FileName), ''));
49 | LInput.Title := AFormInfo.Caption;
50 | LInputs.Add(LInput);
51 | end);
52 |
53 | Result.InputForms := LInputs.ToArray();
54 | finally
55 | LInputs.Free();
56 | end;
57 | except
58 | on E: Exception do begin
59 | FreeAndNil(Result);
60 | raise;
61 | end;
62 | end;
63 | end;
64 |
65 | function TFormsExporter.ExportForms: boolean;
66 | var
67 | I: integer;
68 | LExportModel: TExportFormsDesignModel;
69 | LFormInfo: TIOTAFormInfo;
70 | LFormExporter: TFormExporterFromForms;
71 | begin
72 | LExportModel := BuildExportFormsModel();
73 | try
74 | TExporterRegistry.LoadFormsModel(LExportModel);
75 | //Request user info
76 | if not RequestExportInfo(LExportModel) then
77 | Exit(false);
78 | TExporterRegistry.SaveFormsModel(LExportModel);
79 |
80 | //Export each selected form
81 | for I := Low(LExportModel.OutputForms) to High(LExportModel.OutputForms) do
82 | if TIOTAUtils.FindForm(LExportModel.OutputForms[I].Form.FormName, LFormInfo) then begin
83 | //Export the current form
84 | LFormExporter := TFormExporterFromForms.Create(LExportModel, I, LFormInfo);
85 | try
86 | //Export current form
87 | LFormExporter.ExportForm();
88 | //Export current form dfm/fmx
89 | LFormExporter.ExportFormFile(LExportModel.OutputForms[I].FormFileKind);
90 | finally
91 | LFormExporter.Free();
92 | end;
93 | end;
94 |
95 | if LExportModel.ShowInExplorer then
96 | ShellExecute(0, 'open', PChar(LExportModel.Directory), nil, nil, SW_NORMAL);
97 | finally
98 | LExportModel.Free();
99 | end;
100 | Result := true;
101 | end;
102 |
103 | function TFormsExporter.RequestExportInfo(
104 | const AModel: TExportFormsDesignModel): boolean;
105 | var
106 | LForm: TFormsExportDialog;
107 | begin
108 | LForm := TFormsExportDialog.Create(nil);
109 | try
110 | Result := LForm.Execute(AModel);
111 | finally
112 | LForm.Free();
113 | end;
114 | end;
115 |
116 | end.
117 |
--------------------------------------------------------------------------------
/Source/Exporter/PythonTools.Exporter.Project.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Exporter.Project;
2 |
3 | interface
4 |
5 | uses
6 | ToolsAPI,
7 | PythonTools.IOTAUtils,
8 | PythonTools.Model.Design.Project;
9 |
10 | type
11 | TProjectExporter = class
12 | private
13 | FProject: IOTAProject;
14 | protected
15 | //Checks
16 | procedure CheckDesigner(const AFormInfo: TIOTAFormInfo);
17 | //Producer models
18 | function BuildExportProjectModel: TExportProjectDesignModel;
19 | public
20 | constructor Create(const AProject: IOTAProject);
21 | //Request export project info
22 | function RequestExportInfo(const AModel: TExportProjectDesignModel): boolean;
23 | //Export the given project
24 | function ExportProject(): boolean;
25 | end;
26 |
27 | implementation
28 |
29 | uses
30 | System.SysUtils,
31 | ShellApi, Winapi.Windows,
32 | PythonTools.Exceptions, PythonTools.Common, PythonTools.Registry,
33 | PythonTools.Exporter.Application,
34 | PythonTools.Exporter.Form,
35 | PythonTools.Design.Project;
36 |
37 | { TProjectExporter }
38 |
39 | constructor TProjectExporter.Create(const AProject: IOTAProject);
40 | begin
41 | FProject := AProject;
42 | end;
43 |
44 | function TProjectExporter.ExportProject: boolean;
45 | var
46 | LExportProjectModel: TExportProjectDesignModel;
47 | LAppExporter: TApplicationExporter;
48 | begin
49 | LExportProjectModel := BuildExportProjectModel();
50 | try
51 | TExporterRegistry.LoadProjectModel(LExportProjectModel);
52 | //Request user info
53 | if not RequestExportInfo(LExportProjectModel) then
54 | Exit(false);
55 | TExporterRegistry.SaveProjectModel(LExportProjectModel);
56 | //Export the application file as the app initializer
57 | LAppExporter := TApplicationExporter.Create(LExportProjectModel, FProject);
58 | try
59 | LAppExporter.ExportApplication();
60 | finally
61 | LAppExporter.Free();
62 | end;
63 |
64 | //Navigate through all forms
65 | TIOTAUtils.EnumForms(FProject, procedure(AFormInfo: TIOTAFormInfo)
66 | var
67 | LFormExporter: TFormExporter;
68 | begin
69 | //Check for valid instances
70 | CheckDesigner(AFormInfo);
71 | //Export the current form
72 | LFormExporter := TFormExporterFromProject.Create(LExportProjectModel, AFormInfo);
73 | try
74 | //Export current form
75 | LFormExporter.ExportForm();
76 | //Export current form dfm/fmx
77 | LFormExporter.ExportFormFile(LExportProjectModel.FormFileKind);
78 | finally
79 | LFormExporter.Free();
80 | end;
81 | end);
82 |
83 | if LExportProjectModel.ShowInExplorer then
84 | ShellExecute(0, 'open', PChar(LExportProjectModel.ApplicationDirectory), nil, nil, SW_NORMAL);
85 |
86 | Result := true;
87 | finally
88 | LExportProjectModel.Free();
89 | end;
90 | end;
91 |
92 | procedure TProjectExporter.CheckDesigner(const AFormInfo: TIOTAFormInfo);
93 | begin
94 | if not Assigned(AFormInfo.Designer) then
95 | raise EUnableToObtainFormDesigner.CreateFmt(
96 | 'Unable to obtain the form designer for type %s.', [AFormInfo.FormName]);
97 | end;
98 |
99 | function TProjectExporter.BuildExportProjectModel: TExportProjectDesignModel;
100 | var
101 | LFormInfo: TFormNameAndFileList;
102 | begin
103 | Result := TExportProjectDesignModel.Create();
104 | try
105 | Result.ApplicationId := FProject.GetProjectGUID();
106 | Result.ApplicationName := ChangeFileExt(
107 | ExtractFileName(FProject.FileName), String.Empty);
108 | LFormInfo := TFormNameAndFileList.Create();
109 | try
110 | TIOTAUtils.EnumForms(FProject, procedure(AFormInfo: TIOTAFormInfo) begin
111 | LFormInfo.Add(TFormNameAndFile.Create(
112 | AFormInfo.FormName,
113 | ChangeFileExt(ExtractFileName(AFormInfo.FileName), '')));
114 | end);
115 | Result.ApplicationForms := LFormInfo.ToArray();
116 | finally
117 | LFormInfo.Free();
118 | end;
119 | except
120 | on E: Exception do begin
121 | FreeAndNil(Result);
122 | raise;
123 | end;
124 | end;
125 | end;
126 |
127 | function TProjectExporter.RequestExportInfo(
128 | const AModel: TExportProjectDesignModel): boolean;
129 | var
130 | LForm: TProjectExportDialog;
131 | begin
132 | LForm := TProjectExportDialog.Create(nil);
133 | try
134 | Result := LForm.Execute(AModel);
135 | finally
136 | LForm.Free();
137 | end;
138 | end;
139 |
140 | end.
141 |
--------------------------------------------------------------------------------
/Source/Menu/PythonTools.Menu.ExportForms.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Menu.ExportForms;
2 |
3 | interface
4 |
5 | uses
6 | Vcl.ActnList, Vcl.Menus;
7 |
8 | type
9 | TPythonToolsExportFormsMenuAction = class(TCustomAction)
10 | private
11 | procedure DoExportForms(Sender: TObject);
12 | public
13 | procedure AfterConstruction(); override;
14 |
15 | function Update: boolean; override;
16 | end;
17 |
18 | TPythonToolsExportFormsMenuItem = class(TMenuItem)
19 | public
20 | procedure AfterConstruction(); override;
21 | end;
22 |
23 | implementation
24 |
25 | uses
26 | Vcl.Dialogs,
27 | PythonTools.IOTAUtils,
28 | PythonTools.Exporter.Forms;
29 |
30 | { TPythonToolsExportFormsMenuAction }
31 |
32 | procedure TPythonToolsExportFormsMenuAction.AfterConstruction;
33 | begin
34 | inherited;
35 | Name := 'PythonToolsExportFormsAction';
36 | Caption := 'Export Select Forms';
37 | OnExecute := DoExportForms;
38 | end;
39 |
40 | procedure TPythonToolsExportFormsMenuAction.DoExportForms(Sender: TObject);
41 | var
42 | LExporter: TFormsExporter;
43 | begin
44 | //Exports the current project
45 | LExporter := TFormsExporter.Create();
46 | try
47 | if LExporter.ExportForms() then
48 | ShowMessage('Forms successfully exported.');
49 | finally
50 | LExporter.Free();
51 | end;
52 | end;
53 |
54 | function TPythonToolsExportFormsMenuAction.Update: boolean;
55 | begin
56 | Enabled := TIOTAUtils.HasForms();
57 | Result := inherited;
58 | end;
59 |
60 | { TPythonToolsExportFormsMenuItem }
61 |
62 | procedure TPythonToolsExportFormsMenuItem.AfterConstruction;
63 | begin
64 | inherited;
65 | Name := 'PythonToolsExportFormsMenu';
66 | end;
67 |
68 | end.
69 |
--------------------------------------------------------------------------------
/Source/Menu/PythonTools.Menu.ExportProject.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Menu.ExportProject;
2 |
3 | interface
4 |
5 | uses
6 | ToolsAPI,
7 | System.Classes, System.SysUtils,
8 | Vcl.ActnList, Vcl.Menus, Vcl.Dialogs;
9 |
10 | type
11 | TPythonToolsExportProjectMenuAction = class(TCustomAction)
12 | private
13 | procedure DoExportProject(Sender: TObject);
14 | public
15 | constructor Create(AOwner: TComponent); override;
16 |
17 | function Update: boolean; override;
18 | end;
19 |
20 | TPythonToolsExportProjectMenuItem = class(TMenuItem)
21 | public
22 | procedure AfterConstruction(); override;
23 | end;
24 |
25 | implementation
26 |
27 | uses
28 | System.StrUtils,
29 | PythonTools.Exporter.Project;
30 |
31 | { TPythonToolsExportProjectMenuAction }
32 |
33 | constructor TPythonToolsExportProjectMenuAction.Create(AOwner: TComponent);
34 | begin
35 | inherited;
36 | Name := 'PythonToolsExportProjectAction';
37 | Caption := 'Export Entire Current Project';
38 | OnExecute := DoExportProject;
39 | end;
40 |
41 | function TPythonToolsExportProjectMenuAction.Update: boolean;
42 | begin
43 | Enabled := Assigned(GetActiveProject());
44 | Result := inherited;
45 | end;
46 |
47 | procedure TPythonToolsExportProjectMenuAction.DoExportProject(Sender: TObject);
48 | var
49 | LExporter: TProjectExporter;
50 | begin
51 | //Exports the current project
52 | LExporter := TProjectExporter.Create(GetActiveProject());
53 | try
54 | if LExporter.ExportProject() then
55 | ShowMessage('Project successfully exported.');
56 | finally
57 | LExporter.Free();
58 | end;
59 | end;
60 |
61 | { TPythonToolsExportProjectMenuItem }
62 |
63 | procedure TPythonToolsExportProjectMenuItem.AfterConstruction;
64 | begin
65 | inherited;
66 | Name := 'PythonToolsExportProjectMenu';
67 | end;
68 |
69 | end.
70 |
--------------------------------------------------------------------------------
/Source/Menu/PythonTools.Menu.pas:
--------------------------------------------------------------------------------
1 | {$I PythonTools.inc}
2 |
3 | unit PythonTools.Menu;
4 |
5 | interface
6 |
7 | uses
8 | ToolsAPI, System.SysUtils, System.Classes, System.Generics.Collections,
9 | Winapi.Messages,
10 | Vcl.Menus, Vcl.ImgList, Vcl.Graphics, Vcl.ActnList, Vcl.Controls;
11 |
12 | type
13 | TToolsMenuEventHook = class;
14 |
15 | TPythonToolsMenu = class
16 | private
17 | class var FInstance: TPythonToolsMenu;
18 | private
19 | FToolsMenuItems: TObjectList;
20 | FToolsMenuHook: TToolsMenuEventHook;
21 | function GetINTAServices(): INTAServices;
22 | function GetToolsMenu(): TMenuItem;
23 | function LoadPythonToolMenuImage(): integer;
24 |
25 | procedure DoCreateMenuHooked(Sender: TObject);
26 | procedure DoDestroyMenu();
27 | public
28 | class procedure Initialize();
29 | class procedure Finalize();
30 |
31 | constructor Create();
32 | destructor Destroy(); override;
33 |
34 | //Include the PythonTools menu under Tools
35 | procedure BuildMenu();
36 |
37 | //Hook the menu creation to a event
38 | procedure HookMenu();
39 | procedure UnHookMenu();
40 |
41 | function BuildPythonToolsSeparatorMenuItem(): TMenuItem;
42 | function BuildPythonToolsMenuItem(const ACallback: TProc): TMenuItem;
43 | function BuildPythonToolsExportProjectMenuItem(AOwner: TMenuItem): TMenuItem;
44 | function BuildPythonToolsExportFormsMenuItem(AOwner: TMenuItem): TMenuItem;
45 |
46 | class property Instance: TPythonToolsMenu read FInstance;
47 | end;
48 |
49 | {**** We're creating the menu after the first user's click on the "Tools" menu. ****}
50 | {**** The coreide lib rebuilds the "Tools" menu, removing unknown items at the ending of the list ****}
51 | TToolsMenuEventHook = class
52 | private
53 | FMenuItem: TMenuItem;
54 | FHook: TNotifyEvent;
55 | FDefaultAction: TNotifyEvent;
56 | procedure DoEvent(Sender: TObject);
57 | public
58 | constructor Create(AMenuItem: TMenuItem); reintroduce;
59 | destructor Destroy(); override;
60 |
61 | procedure Hook(AEvt: TNotifyEvent);
62 | procedure UnHook(AEvt: TNotifyEvent);
63 | end;
64 |
65 | implementation
66 |
67 | uses
68 | Vcl.Imaging.pngimage,
69 | PythonTools.Menu.ExportProject, PythonTools.Menu.ExportForms;
70 |
71 | const
72 | sToolsMenu = 'ToolsMenu';
73 | sPythonToolsMenuItem = 'PythonToolsMenuItem';
74 |
75 | type
76 | TPythonToolsMenuAction = class(TCustomAction)
77 | end;
78 |
79 | TPythonToolsMenuItem = class(TMenuItem)
80 | end;
81 |
82 | { TPythonToolsMenu }
83 |
84 | class procedure TPythonToolsMenu.Initialize;
85 | begin
86 | FInstance := TPythonToolsMenu.Create();
87 | end;
88 |
89 | class procedure TPythonToolsMenu.Finalize;
90 | begin
91 | FInstance.Free();
92 | end;
93 |
94 | constructor TPythonToolsMenu.Create;
95 | begin
96 | FToolsMenuItems := TObjectList.Create();
97 | FToolsMenuHook := TToolsMenuEventHook.Create(GetToolsMenu());
98 | end;
99 |
100 | destructor TPythonToolsMenu.Destroy;
101 | begin
102 | DoDestroyMenu();
103 | FToolsMenuItems.Free();
104 | FToolsMenuHook.Free();
105 | inherited;
106 | end;
107 |
108 | function TPythonToolsMenu.GetToolsMenu: TMenuItem;
109 | var
110 | LMenuItem: TMenuItem;
111 | begin
112 | for LMenuItem in GetINTAServices().MainMenu.Items do begin
113 | if (LMenuItem.Name = sToolsMenu) then
114 | Exit(LMenuItem);
115 | end;
116 | raise Exception.Create('Tools menu not found.');
117 | end;
118 |
119 | function TPythonToolsMenu.GetINTAServices: INTAServices;
120 | begin
121 | if not Supports(BorlandIDEServices, INTAServices, Result) then
122 | raise Exception.Create('An error ocurred while accessing the IDE services.');
123 | end;
124 |
125 | procedure TPythonToolsMenu.HookMenu;
126 | begin
127 | if Assigned(FToolsMenuHook) then
128 | FToolsMenuHook.Hook(DoCreateMenuHooked);
129 | end;
130 |
131 | procedure TPythonToolsMenu.UnHookMenu;
132 | begin
133 | if Assigned(FToolsMenuHook) then
134 | FToolsMenuHook.UnHook(DoCreateMenuHooked);
135 | end;
136 |
137 | procedure TPythonToolsMenu.BuildMenu;
138 | var
139 | LServices: INTAServices;
140 | begin
141 | LServices := GetINTAServices();
142 | LServices.MenuBeginUpdate();
143 | try
144 | //Tools->---------
145 | LServices.AddActionMenu(sToolsMenu, nil, BuildPythonToolsSeparatorMenuItem(), true, true);
146 | //Tools->Export to Python
147 | BuildPythonToolsMenuItem(procedure(AMenuItem: TMenuItem; AAction: TCustomAction) begin
148 | LServices.AddActionMenu(sToolsMenu, AAction, AMenuItem, true, true);
149 | AMenuItem.Add([
150 | //Tools->Export to Python->Export Current Project
151 | BuildPythonToolsExportProjectMenuItem(AMenuItem),
152 | //Tools->Export to Python->Export Forms
153 | BuildPythonToolsExportFormsMenuItem(AMenuItem)
154 | ]);
155 | end);
156 | finally
157 | LServices.MenuEndUpdate();
158 | end;
159 | end;
160 |
161 | function TPythonToolsMenu.LoadPythonToolMenuImage(): integer;
162 | const
163 | EMB_PY_IMG = 'embarcaderopython_16px';
164 | var
165 | LImg: {$IFDEF DELPHI11_UP}TPngImage{$ELSE}TBitmap{$ENDIF DELPHI11_UP};
166 | begin
167 | LImg := {$IFDEF DELPHI11_UP}TPngImage{$ELSE}TBitmap{$ENDIF DELPHI11_UP}.Create();
168 | try
169 | LImg.LoadFromResourceName(HInstance, EMB_PY_IMG);
170 | {$IFDEF DELPHI11_UP}
171 | Result := GetINTAServices().AddImage(EMB_PY_IMG, [LImg]);
172 | {$ELSE}
173 | Result := GetINTAServices().AddMasked(LImg, LImg.Handle, EMB_PY_IMG);
174 | {$ENDIF DELPHI11_UP}
175 | finally
176 | LImg.Free();
177 | end;
178 | end;
179 |
180 | function TPythonToolsMenu.BuildPythonToolsExportFormsMenuItem(AOwner: TMenuItem): TMenuItem;
181 | begin
182 | Result := TPythonToolsExportFormsMenuItem.Create(AOwner);
183 | Result.Action := TPythonToolsExportFormsMenuAction.Create(Result);
184 | end;
185 |
186 | function TPythonToolsMenu.BuildPythonToolsExportProjectMenuItem(AOwner: TMenuItem): TMenuItem;
187 | begin
188 | Result := TPythonToolsExportProjectMenuItem.Create(AOwner);
189 | Result.Action := TPythonToolsExportProjectMenuAction.Create(Result);
190 | end;
191 |
192 | function TPythonToolsMenu.BuildPythonToolsMenuItem(
193 | const ACallback: TProc): TMenuItem;
194 | var
195 | LAction: TPythonToolsMenuAction;
196 | begin
197 | Result := TPythonToolsMenuItem.Create(nil);
198 | try
199 | LAction := TPythonToolsMenuAction.Create(Result);
200 | LAction.Caption := 'Export to Python';
201 | LAction.ImageIndex := LoadPythonToolMenuImage();
202 | ACallback(Result, TCustomAction(Result.Action));
203 | Result.Action := LAction;
204 | Result.Name := sPythonToolsMenuItem;
205 | Result.ImageIndex := LAction.ImageIndex;
206 | Result.AutoHotkeys := maAutomatic;
207 | finally
208 | FToolsMenuItems.Add(Result)
209 | end;
210 | end;
211 |
212 | function TPythonToolsMenu.BuildPythonToolsSeparatorMenuItem: TMenuItem;
213 | begin
214 | Result := TMenuItem.Create(nil);
215 | try
216 | Result.Caption := '-';
217 | finally
218 | FToolsMenuItems.Add(Result);
219 | end;
220 | end;
221 |
222 | procedure TPythonToolsMenu.DoCreateMenuHooked(Sender: TObject);
223 | begin
224 | try
225 | BuildMenu();
226 | finally
227 | UnHookMenu();
228 | end;
229 | end;
230 |
231 | procedure TPythonToolsMenu.DoDestroyMenu;
232 | var
233 | LRoot: TMenuItem;
234 | LMenuItem: TMenuItem;
235 | begin
236 | LRoot := GetToolsMenu();
237 | if Assigned(LRoot) then begin
238 | with GetINTAServices() do begin
239 | MenuBeginUpdate();
240 | try
241 | for LMenuItem in FToolsMenuItems do begin
242 | LRoot.Remove(LMenuItem);
243 | end;
244 | FToolsMenuItems.Clear();
245 | finally
246 | MenuEndUpdate();
247 | end;
248 | end;
249 | end;
250 | end;
251 |
252 | { TToolsMenuEventHook }
253 |
254 | constructor TToolsMenuEventHook.Create(AMenuItem: TMenuItem);
255 | begin
256 | inherited Create();
257 | FMenuItem := AMenuItem;
258 | if Assigned(FMenuItem.Action) and Assigned(FMenuItem.Action.OnExecute) then begin
259 | FDefaultAction := FMenuItem.Action.OnExecute;
260 | FMenuItem.Action.OnExecute := DoEvent;
261 | end else begin
262 | if Assigned(FMenuItem.OnClick) then
263 | FDefaultAction := FMenuItem.OnClick
264 | else
265 | FDefaultAction := nil;
266 | FMenuItem.OnClick := DoEvent;
267 | end;
268 | end;
269 |
270 | destructor TToolsMenuEventHook.Destroy;
271 | begin
272 | if Assigned(FMenuItem.Action) and Assigned(FMenuItem.Action.OnExecute) then begin
273 | FMenuItem.Action.OnExecute := FDefaultAction;
274 | end else begin
275 | FMenuItem.OnClick := FDefaultAction;
276 | end;
277 | inherited;
278 | end;
279 |
280 | procedure TToolsMenuEventHook.DoEvent(Sender: TObject);
281 | begin
282 | if Assigned(FDefaultAction) then
283 | FDefaultAction(Sender);
284 |
285 | if Assigned(FHook) then
286 | FHook(Sender);
287 | end;
288 |
289 | procedure TToolsMenuEventHook.Hook(AEvt: TNotifyEvent);
290 | begin
291 | FHook := AEvt;
292 | end;
293 |
294 | procedure TToolsMenuEventHook.UnHook(AEvt: TNotifyEvent);
295 | begin
296 | if (TMethod(FHook).Code = TMethod(AEvt).Code)
297 | and (TMethod(FHook).Data = TMethod(AEvt).Data) then
298 | FHook := nil;
299 | end;
300 |
301 | initialization
302 | TPythonToolsMenu.Initialize();
303 |
304 | finalization
305 | TPythonToolsMenu.Finalize();
306 |
307 | end.
308 |
--------------------------------------------------------------------------------
/Source/Model/Design/PythonTools.Model.Design.Forms.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Design.Forms;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes,
7 | PythonTools.Common;
8 |
9 | type
10 | TOutputForm = record
11 | private
12 | FForm: TFormNameAndFile;
13 | FGenerateInitialization: boolean;
14 | FTitle: string;
15 | FFormFileKind: TFormFileKind;
16 | FFormFileMode: TFormFileMode;
17 | public
18 | constructor Create(const AForm: TFormNameAndFile;
19 | const AGenerateInitialization: boolean;
20 | const ATitle: string;
21 | const AFormFileKind: TFormFileKind;
22 | const AFormFileMode: TFormFileMode);
23 |
24 | property Form: TFormNameAndFile read FForm write FForm;
25 | property GenerateInitialization: boolean read FGenerateInitialization write FGenerateInitialization;
26 | property Title: string read FTitle write FTitle;
27 | property FormFileKind: TFormFileKind read FFormFileKind write FFormFileKind;
28 | property FormFileMode: TFormFileMode read FFormFileMode write FFormFileMode;
29 | end;
30 |
31 | TInputForm = record
32 | private
33 | FForm: TFormNameAndFile;
34 | FTitle: string;
35 | public
36 | property Form: TFormNameAndFile read FForm write FForm;
37 | property Title: string read FTitle write FTitle;
38 | end;
39 |
40 | TExportFormsDesignModel = class
41 | private
42 | FInputForms: TArray;
43 | FDirectory: string;
44 | FOutputForms: TArray;
45 | FShowInExplorer: boolean;
46 | public
47 | property InputForms: TArray read FInputForms write FInputForms;
48 | property OutputForms: TArray read FOutputForms write FOutputForms;
49 | property Directory: string read FDirectory write FDirectory;
50 | property ShowInExplorer: boolean read FShowInExplorer write FShowInExplorer;
51 | end;
52 |
53 | implementation
54 |
55 | { TOutputForm }
56 |
57 | constructor TOutputForm.Create(const AForm: TFormNameAndFile;
58 | const AGenerateInitialization: boolean; const ATitle: string;
59 | const AFormFileKind: TFormFileKind; const AFormFileMode: TFormFileMode);
60 | begin
61 | Form := AForm;
62 | GenerateInitialization := AGenerateInitialization;
63 | Title := ATitle;
64 | FormFileKind := AFormFileKind;
65 | FormFileMode := AFormFileMode;
66 | end;
67 |
68 | end.
69 |
--------------------------------------------------------------------------------
/Source/Model/Design/PythonTools.Model.Design.Project.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Design.Project;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes,
7 | PythonTools.Common;
8 |
9 | type
10 | TExportProjectDesignModel = class
11 | private
12 | FApplicationId: TGUID;
13 | FApplicationName: string;
14 | FApplicationDirectory: string;
15 | FApplicationTitle: string;
16 | FApplicationForms: TFormNamesAndFiles;
17 | FApplicationMainForm: TFormNameAndFile;
18 | FFormFileKind: TFormFileKind;
19 | FFormFileMode: TFormFileMode;
20 | FShowInExplorer: boolean;
21 | public
22 | property ApplicationId: TGUID read FApplicationId write FApplicationId;
23 | property ApplicationName: string read FApplicationName write FApplicationName;
24 | property ApplicationTitle: string read FApplicationTitle write FApplicationTitle;
25 | property ApplicationForms: TFormNamesAndFiles read FApplicationForms write FApplicationForms;
26 | property ApplicationMainForm: TFormNameAndFile read FApplicationMainForm write FApplicationMainForm;
27 | property ApplicationDirectory: string read FApplicationDirectory write FApplicationDirectory;
28 | property FormFileKind: TFormFileKind read FFormFileKind write FFormFileKind;
29 | property FormFileMode: TFormFileMode read FFormFileMode write FFormFileMode;
30 | property ShowInExplorer: boolean read FShowInExplorer write FShowInExplorer;
31 | end;
32 |
33 | implementation
34 |
35 | { TExportProjectModel }
36 |
37 | end.
38 |
--------------------------------------------------------------------------------
/Source/Model/Producer/PythonTools.Model.Producer.Application.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Producer.Application;
2 |
3 | interface
4 |
5 | uses
6 | PythonTools.Common,
7 | PythonTools.Model.Producer;
8 |
9 | type
10 | TApplicationProducerModel = class(TAbastractProducerModel)
11 | private
12 | FTitle: string;
13 | FMainForm: string;
14 | FImportedForms: TFormNamesAndFiles;
15 | function GetApplicationFile: TApplicationFile;
16 | protected
17 | function GetPythonFileName: string; override;
18 | public
19 | ///
20 | /// The application file name.
21 | ///
22 | property ApplicationFile: TApplicationFile read GetApplicationFile;
23 | ///
24 | /// The GUI application main form
25 | ///
26 | property MainForm: string read FMainForm write FMainForm;
27 | ///
28 | /// The application title
29 | ///
30 | property Title: string read FTitle write FTitle;
31 | ///
32 | /// Forms included in the import section
33 | ///
34 | property ImportedForms: TFormNamesAndFiles read FImportedForms write FImportedForms;
35 | end;
36 |
37 | implementation
38 |
39 | uses
40 | System.IOUtils;
41 |
42 | { TApplicationProducerModel }
43 |
44 | function TApplicationProducerModel.GetApplicationFile: TApplicationFile;
45 | begin
46 | Result := TApplicationFile(FileName);
47 | end;
48 |
49 | function TApplicationProducerModel.GetPythonFileName: string;
50 | begin
51 | Result := TPath.Combine(Directory, ApplicationFile.AsPython())
52 | end;
53 |
54 | end.
55 |
--------------------------------------------------------------------------------
/Source/Model/Producer/PythonTools.Model.Producer.Form.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Producer.Form;
2 |
3 | interface
4 |
5 | uses
6 | System.Rtti,
7 | System.Classes,
8 | PythonTools.Common,
9 | PythonTools.Model.Producer;
10 |
11 | type
12 | TBaseFormProducerModel = class(TAbastractProducerModel)
13 | private type
14 | TModuleInitialization = class
15 | private
16 | FGenerateInitialization: boolean;
17 | FTitle: string;
18 | FMainForm: string;
19 | public
20 | ///
21 | /// Generate the Python module app GUI initialization section
22 | ///
23 | property GenerateInitialization: boolean read FGenerateInitialization write FGenerateInitialization;
24 | ///
25 | /// The GUI application title
26 | ///
27 | property Title: string read FTitle write FTitle;
28 | ///
29 | /// The GUI application Main Form
30 | ///
31 | property MainForm: string read FMainForm write FMainForm;
32 | end;
33 | private
34 | FFormName: string;
35 | FFormParentName: string;
36 | FExportedComponents: TExportedComponents;
37 | FModuleInitialization: TModuleInitialization;
38 | FExportedEvents: TExportedEvents;
39 | public
40 | constructor Create(); override;
41 | destructor Destroy(); override;
42 | ///
43 | /// The Form name: used to generate the Python class name
44 | ///
45 | property FormName: string read FFormName write FFormName;
46 | ///
47 | /// The Form parent class name: used to the Form inheritance chain
48 | ///
49 | property FormParentName: string read FFormParentName write FFormParentName;
50 | ///
51 | /// List of exported components
52 | ///
53 | property ExportedComponents: TExportedComponents read FExportedComponents write FExportedComponents;
54 | ///
55 | /// List of exported events
56 | ///
57 | property ExportedEvents: TExportedEvents read FExportedEvents write FExportedEvents;
58 | ///
59 | /// Generates the model initialization section
60 | ///
61 | property ModuleInitialization: TModuleInitialization read FModuleInitialization;
62 | end;
63 |
64 | TFormProducerModel = class(TBaseFormProducerModel);
65 |
66 | implementation
67 |
68 | { TBaseFormProducerModel }
69 |
70 | constructor TBaseFormProducerModel.Create;
71 | begin
72 | inherited;
73 | FModuleInitialization := TModuleInitialization.Create();
74 | end;
75 |
76 | destructor TBaseFormProducerModel.Destroy;
77 | begin
78 | FModuleInitialization.Free();
79 | inherited;
80 | end;
81 |
82 | end.
83 |
--------------------------------------------------------------------------------
/Source/Model/Producer/PythonTools.Model.Producer.FormFile.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Producer.FormFile;
2 | interface
3 | uses
4 | System.Classes,
5 | PythonTools.Common,
6 | PythonTools.Model.Producer;
7 | type
8 | TFormFileProducerModel = class(TAbastractProducerModel)
9 | private
10 | FForm: TComponent;
11 | FFormResource: TStream;
12 | FMode: TFormFileMode;
13 | FFrameworkType: string;
14 | function GetFormFile: TFormFile;
15 | procedure SetFormResource(const Value: TStream);
16 | protected
17 | function GetPythonFileName: string; override;
18 | public
19 | constructor Create(); overload; override;
20 | constructor Create(const AFrameworkType, ADirectory: string; const AFileName: TFileName); overload;
21 | destructor Destroy(); override;
22 | ///
23 | /// The .dfm/.fmx file name.
24 | ///
25 | property FormFile: TFormFile read GetFormFile;
26 | ///
27 | /// The exported form
28 | ///
29 | property Form: TComponent read FForm write FForm;
30 | ///
31 | /// The .dfm/.fmx text stream.
32 | ///
33 | property FormResource: TStream read FFormResource write SetFormResource;
34 | ///
35 | /// Delphi and Python can share the same .dfm/.fmx in compatible mode.
36 | ///
37 | property Mode: TFormFileMode read FMode write FMode;
38 | ///
39 | /// Define if we're going to use .dfm or .fmx.
40 | ///
41 | property FrameworkType: string read FFrameworkType write FFrameworkType;
42 | end;
43 | implementation
44 | uses
45 | System.IOUtils;
46 | { TFormFileProducerModel }
47 | constructor TFormFileProducerModel.Create;
48 | begin
49 | inherited;
50 | FFormResource := TMemoryStream.Create();
51 | FMode := TFormFileMode.ffmCompatible;
52 | end;
53 | constructor TFormFileProducerModel.Create(const AFrameworkType,
54 | ADirectory: string; const AFileName: TFileName);
55 | begin
56 | inherited Create(ADirectory, AFileName);
57 | FFrameworkType := AFrameworkType;
58 | end;
59 |
60 | destructor TFormFileProducerModel.Destroy;
61 | begin
62 | FFormResource.Free();
63 | inherited;
64 | end;
65 | function TFormFileProducerModel.GetPythonFileName: string;
66 | begin
67 | if FFrameworkType = 'VCL' then
68 | Result := TPath.Combine(Directory, FormFile.AsDfm(FMode))
69 | else if FFrameworkType = 'FMX' then
70 | Result := TPath.Combine(Directory, FormFile.AsFmx(FMode))
71 | else
72 | Result := inherited;
73 | end;
74 | function TFormFileProducerModel.GetFormFile: TFormFile;
75 | begin
76 | Result := TFormFile(FileName);
77 | end;
78 |
79 | procedure TFormFileProducerModel.SetFormResource(const Value: TStream);
80 | begin
81 | FFormResource.Size := 0;
82 | FFormResource.Position := 0;
83 | FFormResource.CopyFrom(Value, Value.Size);
84 | end;
85 | end.
86 |
--------------------------------------------------------------------------------
/Source/Model/Producer/PythonTools.Model.Producer.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Model.Producer;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes,
7 | System.SysUtils,
8 | PythonTools.Common;
9 |
10 | type
11 | TAbastractProducerModel = class
12 | private
13 | FDirectory: string;
14 | FFileName: TFileName;
15 | FOwned: boolean;
16 | FStream: TStream;
17 | function GetStream: TStream;
18 | procedure SetFileName(const Value: TFileName);
19 | protected
20 | function GetPythonFileName: string; virtual;
21 | public
22 | constructor Create(); overload; virtual;
23 | constructor Create(const AStream: TStream; const AOwned: boolean = true); overload;
24 | constructor Create(const ADirectory: string; const AFileName: TFileName); overload;
25 | destructor Destroy(); override;
26 |
27 | ///
28 | /// The directory where the generated files will be saved
29 | ///
30 | property Directory: string read FDirectory write FDirectory;
31 | ///
32 | /// The Delphi file name: used to generate the Python (.py) file name.
33 | ///
34 | property FileName: TFileName read FFileName write SetFileName;
35 | ///
36 | /// The final Python file name.
37 | ///
38 | property PythonFileName: string read GetPythonFileName;
39 | ///
40 | /// Producers will use this stream to save Python code.
41 | ///
42 | property Stream: TStream read GetStream;
43 | end;
44 |
45 | implementation
46 |
47 | uses
48 | System.IOUtils;
49 |
50 | { TAbastractProducerModel }
51 |
52 | constructor TAbastractProducerModel.Create;
53 | begin
54 | inherited;
55 | end;
56 |
57 | constructor TAbastractProducerModel.Create(const AStream: TStream;
58 | const AOwned: boolean);
59 | begin
60 | Create();
61 | FStream := AStream;
62 | FOwned := AOwned;
63 | end;
64 |
65 | constructor TAbastractProducerModel.Create(const ADirectory: string;
66 | const AFileName: TFileName);
67 | begin
68 | Create();
69 | FDirectory := ADirectory;
70 | SetFileName(AFileName);
71 | end;
72 |
73 | destructor TAbastractProducerModel.Destroy;
74 | begin
75 | if FOwned then
76 | FStream.Free();
77 | inherited;
78 | end;
79 |
80 | function TAbastractProducerModel.GetPythonFileName: string;
81 | begin
82 | Result := TPath.Combine(FDirectory, FFileName.AsPython());
83 | end;
84 |
85 | function TAbastractProducerModel.GetStream: TStream;
86 | begin
87 | if not Assigned(FStream) then begin
88 | FStream := TFileStream.Create(GetPythonFileName(), fmCreate or fmOpenWrite or fmShareDenyWrite);
89 | FOwned := true;
90 | end;
91 |
92 | Result := FStream;
93 | end;
94 |
95 | procedure TAbastractProducerModel.SetFileName(const Value: TFileName);
96 | begin
97 | FFileName := TFileName(
98 | ExtractFileName(Value)
99 | .Replace('.pas', '', [])
100 | .Replace('.dfm', '', [])
101 | .Replace('.fmx', '', [])
102 | .Replace('.dpr', '', [])
103 | .Replace('.dproj', '', [])
104 | );
105 | end;
106 |
107 | end.
108 |
--------------------------------------------------------------------------------
/Source/Producer/PythonTools.Producer.AbstractForm.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Producer.AbstractForm;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes, System.SysUtils, System.Generics.Collections,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Model.Producer.Application,
10 | PythonTools.Model.Producer.Form,
11 | PythonTools.Model.Producer.FormFile;
12 |
13 | type
14 | TAbstractFormProducer = class abstract(TInterfacedObject)
15 | protected
16 | function GetPythonModuleName(): string; virtual; abstract;
17 | function GetPythonFormFileExtension(
18 | const AMode: TFormFileMode): string; virtual; abstract;
19 | function GetAppInitializationSection(): string; virtual; abstract;
20 | //File generators
21 | procedure GeneratePyApplicationFile(const AStream: TStream;
22 | const AModel: TApplicationProducerModel);
23 | procedure GeneratePyFormFile(const AStream: TStream;
24 | const AFormModel: TFormProducerModel;
25 | const AFormFileModel: TFormFileProducerModel);
26 | procedure GeneratePyFormFileBin(const AStream: TStream;
27 | const AModel: TFormFileProducerModel);
28 | procedure GeneratePyFormFileTxt(const AStream: TStream;
29 | const AModel: TFormFileProducerModel);
30 | public
31 |
32 | end;
33 |
34 | implementation
35 |
36 | uses
37 | TypInfo, System.StrUtils;
38 |
39 | const
40 | PY_APP_IMPORTED_FORMS =
41 | 'from @MODULE_NAME import *'
42 | + sLineBreak
43 | + '@IMPORTED_FORMS';
44 |
45 | PY_APP_IMPORT =
46 | 'from @FILE import @FORM';
47 |
48 | PY_MODULE_IMPORT =
49 | 'import os'
50 | + sLineBreak
51 | + 'from @MODULE_NAME import *';
52 |
53 | PY_MODULE_CLASS =
54 | 'class @CLASSNAME(@CLASSPARENT):'
55 | + sLineBreak
56 | + sLineBreak
57 | + sIdentation1
58 | + 'def __init__(self, owner):';
59 |
60 | PY_MODULE_PROPS =
61 | sIdentation2
62 | + '@PROPERTIES';
63 |
64 | PY_MODULE_LOAD_PROPS =
65 | sIdentation2
66 | + 'self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "@FILE@FORMFILEEXT"))';
67 |
68 | PY_MODULE_EVTS =
69 | sIdentation1
70 | + '@EVENTS';
71 |
72 | { TAbstractFormProducer }
73 |
74 | procedure TAbstractFormProducer.GeneratePyApplicationFile(
75 | const AStream: TStream; const AModel: TApplicationProducerModel);
76 | var
77 | LImportedForms: string;
78 | LFormInfo: TFormNameAndFile;
79 | LStrFile: string;
80 | LBytes: TBytes;
81 | begin
82 | LImportedForms := String.Empty;
83 | for LFormInfo in AModel.ImportedForms do begin
84 | if not LImportedForms.IsEmpty() then
85 | LImportedForms := LImportedForms + sLineBreak;
86 |
87 | LImportedForms := LImportedForms
88 | + PY_APP_IMPORT
89 | .Replace('@FILE', LFormInfo.FileName)
90 | .Replace('@FORM', LFormInfo.FormName);
91 | end;
92 |
93 | LStrFile := String.Empty;
94 | if not LImportedForms.IsEmpty() then
95 | LStrFile :=
96 | PY_APP_IMPORTED_FORMS
97 | .Replace('@MODULE_NAME', GetPythonModuleName())
98 | .Replace('@IMPORTED_FORMS', LImportedForms)
99 | + sLineBreak
100 | + sLineBreak;
101 |
102 | LStrFile := LStrFile
103 | + GetAppInitializationSection()
104 | .Replace('@APP_TITLE', AModel.Title.QuotedString())
105 | .Replace('@CLASSNAME', AModel.MainForm);
106 |
107 | LBytes := TEncoding.UTF8.GetBytes(LStrFile);
108 | AStream.WriteData(LBytes, Length(LBytes));
109 | end;
110 |
111 | procedure TAbstractFormProducer.GeneratePyFormFile(const AStream: TStream;
112 | const AFormModel: TFormProducerModel;
113 | const AFormFileModel: TFormFileProducerModel);
114 | var
115 | LProps: string;
116 | LComp: TExportedComponent;
117 | LEvts: string;
118 | LEvt: TExportedEvent;
119 | LParam: string;
120 | LStrFile: string;
121 | LBytes: TBytes;
122 | begin
123 | LProps := String.Empty;
124 | for LComp in AFormModel.ExportedComponents do begin
125 | if not LProps.IsEmpty() then
126 | LProps := LProps
127 | + sLineBreak
128 | + sIdentation2;
129 | LProps := LProps + 'self.' + LComp.ComponentName + ' = None';
130 | end;
131 |
132 | LEvts := String.Empty;
133 | for LEvt in AFormModel.ExportedEvents do begin
134 | if not LEvts.IsEmpty then
135 | LEvts := LEvts
136 | + sLineBreak
137 | + sLineBreak
138 | + sIdentation1;
139 | LEvts := LEvts + 'def ' + LEvt.MethodName + '(self';
140 | for LParam in LEvt.MethodParams do begin
141 | LEvts := LEvts + ', ' + LParam
142 | end;
143 | LEvts := LEvts + '):'
144 | + sLineBreak
145 | + sIdentation2
146 | + 'pass';
147 | end;
148 |
149 | LStrFile :=
150 | PY_MODULE_IMPORT
151 | .Replace('@MODULE_NAME', GetPythonModuleName())
152 | + sLineBreak
153 | + sLineBreak
154 | + PY_MODULE_CLASS
155 | .Replace('@CLASSNAME', AFormModel.FormName)
156 | .Replace('@CLASSPARENT', AFormModel.FormParentName);
157 |
158 | if not LProps.IsEmpty() then
159 | LStrFile := LStrFile
160 | + sLineBreak
161 | + PY_MODULE_PROPS
162 | .Replace('@PROPERTIES', LProps);
163 |
164 | LStrFile := LStrFile
165 | + sLineBreak
166 | + PY_MODULE_LOAD_PROPS
167 | .Replace('@FILE', AFormModel.FileName)
168 | .Replace('@FORMFILEEXT', GetPythonFormFileExtension(AFormFileModel.Mode));
169 |
170 | if not LEvts.IsEmpty() then
171 | LStrFile := LStrFile
172 | + sLineBreak
173 | + sLineBreak
174 | + PY_MODULE_EVTS
175 | .Replace('@EVENTS', LEvts);
176 |
177 | if AFormModel.ModuleInitialization.GenerateInitialization then
178 | LStrFile := LStrFile
179 | + sLineBreak
180 | + sLineBreak
181 | + GetAppInitializationSection()
182 | .Replace('@APP_TITLE', AFormModel.ModuleInitialization.Title.QuotedString())
183 | .Replace('@CLASSNAME', AFormModel.ModuleInitialization.MainForm);
184 |
185 | LBytes := TEncoding.UTF8.GetBytes(LStrFile);
186 | AStream.WriteData(LBytes, Length(LBytes));
187 | end;
188 |
189 | procedure TAbstractFormProducer.GeneratePyFormFileBin(const AStream: TStream;
190 | const AModel: TFormFileProducerModel);
191 | begin
192 | AStream.WriteComponent(AModel.Form);
193 | end;
194 |
195 | procedure TAbstractFormProducer.GeneratePyFormFileTxt(const AStream: TStream;
196 | const AModel: TFormFileProducerModel);
197 | begin
198 | AStream.CopyFrom(AModel.FormResource, AModel.FormResource.Size);
199 | end;
200 |
201 | end.
202 |
--------------------------------------------------------------------------------
/Source/Producer/PythonTools.Producer.FMXForm.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Producer.FMXForm;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Producer.AbstractForm,
10 | PythonTools.Model.Producer.Application,
11 | PythonTools.Model.Producer.Form,
12 | PythonTools.Model.Producer.FormFile;
13 |
14 | type
15 | TFMXFormProducer = class(TAbstractFormProducer, IPythonCodeProducer)
16 | protected
17 | function GetPythonModuleName(): string; override;
18 | function GetPythonFormFileExtension(const AMode: TFormFileMode): string; override;
19 | function GetAppInitializationSection(): string; override;
20 | public
21 | function IsValidFormInheritance(const AClass: TClass): boolean;
22 |
23 | procedure SavePyApplicationFile(
24 | const AModel: TApplicationProducerModel;
25 | const AStream: TStream);
26 | procedure SavePyForm(
27 | const AFormModel: TFormProducerModel;
28 | const AFormFileModel: TFormFileProducerModel;
29 | const AStream: TStream);
30 | procedure SavePyFormFileBin(
31 | const AModel: TFormFileProducerModel;
32 | const AStream: TStream);
33 | procedure SavePyFormFileTxt(
34 | const AModel: TFormFileProducerModel;
35 | const AStream: TStream);
36 | end;
37 |
38 | implementation
39 |
40 | uses
41 | System.SysUtils, System.IOUtils, FMX.Forms,
42 | PythonTools.Exceptions;
43 |
44 | const
45 | DELPHI_FMX_MODULE_NAME = 'delphifmx';
46 |
47 | PY_MODULE_APP_INITIALIZATION =
48 | 'def main():'
49 | + sLineBreak
50 | + sIdentation1
51 | + 'Application.Initialize()'
52 | + sLineBreak
53 | + sIdentation1
54 | + 'Application.Title = @APP_TITLE'
55 | + sLineBreak
56 | + sIdentation1
57 | + 'Application.MainForm = @CLASSNAME(Application)'
58 | + sLineBreak
59 | + sIdentation1
60 | + 'Application.MainForm.Show()'
61 | + sLineBreak
62 | + sIdentation1
63 | + 'Application.Run()'
64 | + sLineBreak
65 | + sIdentation1
66 | + 'Application.MainForm.Destroy()'
67 | + sLineBreak
68 | + sLineBreak
69 | + 'if __name__ == ''__main__'':'
70 | + sLineBreak
71 | + sIdentation1
72 | + 'main()'
73 | + sLineBreak;
74 |
75 | { TFMXFormProducer }
76 |
77 | function TFMXFormProducer.GetPythonFormFileExtension(
78 | const AMode: TFormFileMode): string;
79 | begin
80 | Result := TFormFile('').AsFmx(AMode);
81 | end;
82 |
83 | function TFMXFormProducer.GetPythonModuleName: string;
84 | begin
85 | Result := DELPHI_FMX_MODULE_NAME;
86 | end;
87 |
88 | function TFMXFormProducer.GetAppInitializationSection: string;
89 | begin
90 | Result := PY_MODULE_APP_INITIALIZATION;
91 | end;
92 |
93 | function TFMXFormProducer.IsValidFormInheritance(const AClass: TClass): boolean;
94 | begin
95 | Result := AClass = TForm;
96 | end;
97 |
98 | procedure TFMXFormProducer.SavePyApplicationFile(
99 | const AModel: TApplicationProducerModel; const AStream: TStream);
100 | begin
101 | GeneratePyApplicationFile(AStream, AModel);
102 | end;
103 |
104 | procedure TFMXFormProducer.SavePyForm(const AFormModel: TFormProducerModel;
105 | const AFormFileModel: TFormFileProducerModel; const AStream: TStream);
106 | begin
107 | GeneratePyFormFile(AStream, AFormModel, AFormFileModel);
108 | end;
109 |
110 | procedure TFMXFormProducer.SavePyFormFileBin(
111 | const AModel: TFormFileProducerModel; const AStream: TStream);
112 | begin
113 | GeneratePyFormFileBin(AStream, AModel);
114 | end;
115 |
116 | procedure TFMXFormProducer.SavePyFormFileTxt(
117 | const AModel: TFormFileProducerModel; const AStream: TStream);
118 | begin
119 | GeneratePyFormFileTxt(AStream, AModel);
120 | end;
121 |
122 | end.
123 |
--------------------------------------------------------------------------------
/Source/Producer/PythonTools.Producer.SimpleFactory.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Producer.SimpleFactory;
2 |
3 | interface
4 |
5 | uses
6 | PythonTools.Producer;
7 |
8 | type
9 | TProducerSimpleFactory = class
10 | public
11 | class function CreateProducer(const AFrameworkType: string): IPythonCodeProducer;
12 | end;
13 |
14 | implementation
15 |
16 | uses
17 | System.SysUtils,
18 | PythonTools.Exceptions,
19 | PythonTools.Producer.FMXForm,
20 | PythonTools.Producer.VCLForm;
21 |
22 | { TProducerSimpleFactory }
23 |
24 | class function TProducerSimpleFactory.CreateProducer(
25 | const AFrameworkType: string): IPythonCodeProducer;
26 | begin
27 | if CompareText(AFrameworkType, 'FMX') = 0 then
28 | Result := TFMXFormProducer.Create()
29 | else if CompareText(AFrameworkType, 'VCL') = 0 then
30 | Result := TVCLFormProducer.Create()
31 | else
32 | raise EProducerNotFound.CreateFmt('Producer not found for framework type %s', [
33 | AFrameworkType]);
34 | end;
35 |
36 | end.
37 |
--------------------------------------------------------------------------------
/Source/Producer/PythonTools.Producer.VCLForm.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Producer.VCLForm;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Producer.AbstractForm,
10 | PythonTools.Model.Producer.Application,
11 | PythonTools.Model.Producer.Form,
12 | PythonTools.Model.Producer.FormFile;
13 |
14 | type
15 | TVCLFormProducer = class(TAbstractFormProducer, IPythonCodeProducer)
16 | protected
17 | function GetPythonModuleName(): string; override;
18 | function GetPythonFormFileExtension(const AMode: TFormFileMode): string; override;
19 | function GetAppInitializationSection(): string; override;
20 | public
21 | function IsValidFormInheritance(const AClass: TClass): boolean;
22 |
23 | procedure SavePyApplicationFile(
24 | const AModel: TApplicationProducerModel;
25 | const AStream: TStream);
26 | procedure SavePyForm(
27 | const AFormModel: TFormProducerModel;
28 | const AFormFileModel: TFormFileProducerModel;
29 | const AStream: TStream);
30 | procedure SavePyFormFileBin(
31 | const AModel: TFormFileProducerModel;
32 | const AStream: TStream);
33 | procedure SavePyFormFileTxt(
34 | const AModel: TFormFileProducerModel;
35 | const AStream: TStream);
36 | end;
37 |
38 | implementation
39 |
40 | uses
41 | System.SysUtils, System.IOUtils, Vcl.Forms,
42 | PythonTools.Exceptions;
43 |
44 | const
45 | DELPHI_VCL_MODULE_NAME = 'delphivcl';
46 |
47 | PY_MODULE_APP_INITIALIZATION =
48 | 'def main():'
49 | + sLineBreak
50 | + sIdentation1
51 | + 'Application.Initialize()'
52 | + sLineBreak
53 | + sIdentation1
54 | + 'Application.Title = @APP_TITLE'
55 | + sLineBreak
56 | + sIdentation1
57 | + 'MainForm = @CLASSNAME(Application)'
58 | + sLineBreak
59 | + sIdentation1
60 | + 'MainForm.Show()'
61 | + sLineBreak
62 | + sIdentation1
63 | + 'FreeConsole()'
64 | + sLineBreak
65 | + sIdentation1
66 | + 'Application.Run()'
67 | + sLineBreak
68 | + sLineBreak
69 | + 'if __name__ == ''__main__'':'
70 | + sLineBreak
71 | + sIdentation1
72 | + 'main()'
73 | + sLineBreak;
74 |
75 | { TVCLFormProducer }
76 |
77 | function TVCLFormProducer.GetPythonFormFileExtension(
78 | const AMode: TFormFileMode): string;
79 | begin
80 | Result := TFormFile('').AsDfm(AMode);
81 | end;
82 |
83 | function TVCLFormProducer.GetPythonModuleName: string;
84 | begin
85 | Result := DELPHI_VCL_MODULE_NAME;
86 | end;
87 |
88 | function TVCLFormProducer.GetAppInitializationSection: string;
89 | begin
90 | Result := PY_MODULE_APP_INITIALIZATION;
91 | end;
92 |
93 | function TVCLFormProducer.IsValidFormInheritance(const AClass: TClass): boolean;
94 | begin
95 | Result := AClass = TForm;
96 | end;
97 |
98 | procedure TVCLFormProducer.SavePyApplicationFile(
99 | const AModel: TApplicationProducerModel; const AStream: TStream);
100 | begin
101 | GeneratePyApplicationFile(AStream, AModel);
102 | end;
103 |
104 | procedure TVCLFormProducer.SavePyForm(const AFormModel: TFormProducerModel;
105 | const AFormFileModel: TFormFileProducerModel; const AStream: TStream);
106 | begin
107 | GeneratePyFormFile(AStream, AFormModel, AFormFileModel);
108 | end;
109 |
110 | procedure TVCLFormProducer.SavePyFormFileBin(
111 | const AModel: TFormFileProducerModel; const AStream: TStream);
112 | begin
113 | GeneratePyFormFileBin(AStream, AModel);
114 | end;
115 |
116 | procedure TVCLFormProducer.SavePyFormFileTxt(
117 | const AModel: TFormFileProducerModel; const AStream: TStream);
118 | begin
119 | GeneratePyFormFileTxt(AStream, AModel);
120 | end;
121 |
122 | end.
123 |
--------------------------------------------------------------------------------
/Source/Producer/PythonTools.Producer.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Producer;
2 |
3 | interface
4 |
5 | uses
6 | System.Classes, System.Generics.Collections,
7 | PythonTools.Common,
8 | PythonTools.Model.Producer.Application,
9 | PythonTools.Model.Producer.Form,
10 | PythonTools.Model.Producer.FormFile;
11 |
12 | type
13 | IPythonCodeProducer = interface
14 | ['{D3A5C0FE-EAF4-4301-9DA9-E867B3081E21}']
15 | function IsValidFormInheritance(const AClass: TClass): boolean;
16 | procedure SavePyApplicationFile(
17 | const AModel: TApplicationProducerModel;
18 | const AStream: TStream);
19 | procedure SavePyForm(
20 | const AFormModel: TFormProducerModel;
21 | const AFormFileModel: TFormFileProducerModel;
22 | const AStream: TStream);
23 | procedure SavePyFormFileBin(
24 | const AModel: TFormFileProducerModel;
25 | const AStream: TStream);
26 | procedure SavePyFormFileTxt(
27 | const AModel: TFormFileProducerModel;
28 | const AStream: TStream);
29 | end;
30 |
31 | const
32 | //Using 4 spaces identation
33 | sIdentation1 = ' ';
34 | sIdentation2 = sIdentation1 + sIdentation1;
35 |
36 | implementation
37 |
38 | end.
39 |
--------------------------------------------------------------------------------
/Source/PythonTools.Common.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Common;
2 |
3 | interface
4 |
5 | uses
6 | System.Generics.Collections, System.SysUtils;
7 |
8 | type
9 | TFormFileKind = (ffkText, ffkBinary);
10 | TFormFileMode = (ffmDelphi, ffmPython, ffmCompatible);
11 |
12 | TFormNameAndFile = record
13 | public
14 | FormName: string;
15 | FileName: string;
16 | public
17 | constructor Create(const AFormName, AFileName: string);
18 | function CombineFileAndFormName(): string;
19 | end;
20 |
21 | TFormNamesAndFiles = TArray;
22 | TFormNameAndFileList = TList;
23 |
24 | TExportedComponent = record
25 | public
26 | ComponentName: string;
27 | public
28 | constructor Create(const AComponentName: string);
29 | end;
30 |
31 | TExportedComponents = TArray;
32 | TExportedComponentList = TList;
33 |
34 | TExportedEvent = record
35 | public
36 | MethodName: string;
37 | MethodParams: TArray;
38 | public
39 | constructor Create(const AMethodName: string; const AMethodParams: TArray);
40 | end;
41 |
42 | TExportedEvents = TArray;
43 | TExportedEventList = TList;
44 | TApplicationFile = System.SysUtils.TFileName;
45 | TFileName = System.SysUtils.TFileName;
46 | TFormFile = type string;
47 | TFormFilePath = TFormFile;
48 |
49 | TApplicationFileHelper = record helper for TApplicationFile
50 | public
51 | function AsDelphi(): string;
52 | function AsPython(): string;
53 | end;
54 |
55 | TFileNameHelper = record helper for TFileName
56 | public
57 | function AsDelphi(): string;
58 | function AsPython(): string;
59 | end;
60 |
61 | TFormFileHelper = record helper for TFormFile
62 | public
63 | function AsDelphiDfm(): string;
64 | function AsDelphiFmx(): string;
65 | function AsPythonDfm(): string;
66 | function AsPythonFmx(): string;
67 | function AsDfm(const AMode: TFormFileMode): string;
68 | function AsFmx(const AMode: TFormFileMode): string;
69 | end;
70 |
71 | TFormFileKindHelper = record helper for TFormFileKind
72 | public
73 | function ToString(): string;
74 | class function FromString(const AValue: string): TFormFileKind; static;
75 | end;
76 |
77 | implementation
78 |
79 | { TFormNameAndFile }
80 |
81 | function TFormNameAndFile.CombineFileAndFormName: string;
82 | begin
83 | if (FileName = String.Empty) and (FormName = String.Empty) then
84 | Result := String.Empty
85 | else
86 | Result := FileName + '.' + FormName;
87 | end;
88 |
89 | constructor TFormNameAndFile.Create(const AFormName, AFileName: string);
90 | begin
91 | FormName := AFormName;
92 | FileName := AFileName;
93 | end;
94 |
95 | { TExportedComponent }
96 |
97 | constructor TExportedComponent.Create(const AComponentName: string);
98 | begin
99 | ComponentName := AComponentName;
100 | end;
101 |
102 | { TExportedEvent }
103 |
104 | constructor TExportedEvent.Create(const AMethodName: string;
105 | const AMethodParams: TArray);
106 | begin
107 | MethodName := AMethodName;
108 | MethodParams := AMethodParams;
109 | end;
110 |
111 | { TApplicationFileHelper }
112 |
113 | function TApplicationFileHelper.AsDelphi: string;
114 | begin
115 | Result := Self + '.dpr'
116 | end;
117 |
118 | function TApplicationFileHelper.AsPython: string;
119 | begin
120 | Result := Self + '.py'
121 | end;
122 |
123 | { TFileNameHelper }
124 |
125 | function TFileNameHelper.AsDelphi: string;
126 | begin
127 | Result := Self + '.pas';
128 | end;
129 |
130 | function TFileNameHelper.AsPython: string;
131 | begin
132 | Result := Self + '.py';
133 | end;
134 |
135 | { TFormFileHelper }
136 |
137 | function TFormFileHelper.AsDelphiDfm: string;
138 | begin
139 | Result := Self + '.dfm';
140 | end;
141 |
142 | function TFormFileHelper.AsDelphiFmx: string;
143 | begin
144 | Result := Self + '.fmx';
145 | end;
146 |
147 | function TFormFileHelper.AsPythonDfm: string;
148 | begin
149 | Result := Self + '.pydfm';
150 | end;
151 |
152 | function TFormFileHelper.AsPythonFmx: string;
153 | begin
154 | Result := Self + '.pyfmx';
155 | end;
156 |
157 | function TFormFileHelper.AsDfm(const AMode: TFormFileMode): string;
158 | begin
159 | case AMode of
160 | ffmCompatible,
161 | ffmDelphi:
162 | Result := AsDelphiDfm();
163 | ffmPython:
164 | Result := AsPythonDfm();
165 | else
166 | Result := String.Empty;
167 | end;
168 | end;
169 |
170 | function TFormFileHelper.AsFmx(const AMode: TFormFileMode): string;
171 | begin
172 | case AMode of
173 | ffmCompatible,
174 | ffmDelphi:
175 | Result := AsDelphiFmx();
176 | ffmPython:
177 | Result := AsPythonFmx();
178 | else
179 | Result := String.Empty;
180 | end;
181 | end;
182 |
183 | { TFormFileKindHelper }
184 |
185 | class function TFormFileKindHelper.FromString(
186 | const AValue: string): TFormFileKind;
187 | begin
188 | if AValue = 'Text' then
189 | Result := ffkText
190 | else if AValue = 'Binary' then
191 | Result := ffkBinary
192 | else
193 | raise ENotImplemented.Create('Form file kind not found.');
194 | end;
195 |
196 | function TFormFileKindHelper.ToString: string;
197 | begin
198 | case Self of
199 | ffkText:
200 | Result := 'Text';
201 | ffkBinary:
202 | Result := 'Binary';
203 | else
204 | raise ENotImplemented.Create('Form file kind not found.');
205 | end;
206 | end;
207 |
208 | end.
209 |
--------------------------------------------------------------------------------
/Source/PythonTools.Exceptions.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Exceptions;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils;
7 |
8 | type
9 | EFormInheritanceNotSupported = class(Exception)
10 | end;
11 |
12 | EUnableToObtainFormDesigner = class(Exception)
13 | end;
14 |
15 | EInvalidFormFileKind = class(Exception)
16 | end;
17 |
18 | EUnknownFrameworkType = class(Exception)
19 | end;
20 |
21 | EProducerNotFound = class(Exception)
22 | end;
23 |
24 | implementation
25 |
26 | end.
27 |
--------------------------------------------------------------------------------
/Source/PythonTools.IOTAUtils.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.IOTAUtils;
2 |
3 | interface
4 |
5 | uses
6 | DesignIntf, ToolsAPI,
7 | System.Classes, System.Generics.Collections, System.SysUtils, System.Rtti,
8 | PythonTools.Common;
9 |
10 | type
11 | TIOTAFormInfo = record
12 | FormName: string;
13 | FileName: string;
14 | Caption: string;
15 | FrameworkType: string;
16 | Module: IOTAModule;
17 | Editor: IOTAFormEditor;
18 | Designer: IDesigner;
19 | end;
20 |
21 | TFormClassName = string;
22 | TFormGlobalVarName = string;
23 | TDprEntry = TPair;
24 | TDprEntries = TArray;
25 |
26 | TIOTAUtils = class
27 | private
28 | class function ModuleIsPas(const AModule: IOTAModule): boolean;
29 | class function ModuleIsCpp(const AModule: IOTAModule): boolean;
30 | class function ModuleIsForm(const AModule: IOTAModule): boolean;
31 | class function ModuleIsExportable(const AModule: IOTAModule): boolean;
32 | class procedure EnumComps(const AFormEditor: IOTAFormEditor; const ACallback: TProc);
33 | class function GetFormCaption(const AComponent: TComponent): string;
34 | class function ScanDprEntries(const AProject: IOTAProject): TDprEntries;
35 | public
36 | class function FindComponents(const AFormEditor: IOTAFormEditor): TExportedComponents;
37 | class function FindEvents(const AFormEditor: IOTAFormEditor; const ADesigner: IDesigner): TExportedEvents;
38 | class function HasForms(): boolean;
39 | class procedure EnumForms(const AProc: TProc); overload;
40 | class procedure EnumForms(const AProject: IOTAProject; const AProc: TProc); overload;
41 | class function FindForm(const AFormName: string; out AFormInfo: TIOTAFormInfo): boolean;
42 | class function FindDelphiProjectEditor(const AProject: IOTAProject): IOTAEditor;
43 | class function GuessMainForm(const AProject: IOTAProject): IOTAModule;
44 | class function GetEditorContentFromEditor(const AEditor: IOTAEditor): IOTAEditorContent;
45 | class function GetFormEditorFromModule(const AModule: IOTAModule): IOTAFormEditor;
46 | class function GetFrameworkTypeFromDesigner(const ADesigner: IDesigner): string;
47 | end;
48 |
49 | implementation
50 |
51 | uses
52 | System.TypInfo,
53 | System.Generics.Defaults,
54 | System.RegularExpressions,
55 | Vcl.AxCtrls,
56 | Vcl.Forms,
57 | Fmx.Forms,
58 | PythonTools.Exceptions;
59 |
60 | { TIOTAUtils }
61 |
62 | class procedure TIOTAUtils.EnumForms(const AProject: IOTAProject;
63 | const AProc: TProc);
64 | var
65 | LFormPredicate: TPredicate;
66 | I: integer;
67 | LModuleInfo: IOTAModuleInfo;
68 | LResult: TIOTAFormInfo;
69 | begin
70 | LFormPredicate := function(AModuleInfo: IOTAModuleInfo): boolean begin
71 | Result := (AModuleInfo.ModuleType = omtForm)
72 | and not AModuleInfo.FormName.Trim().IsEmpty();
73 | end;
74 | for I := 0 to AProject.GetModuleCount() - 1 do begin
75 | LModuleInfo := AProject.GetModule(I);
76 | if not LFormPredicate(LModuleInfo) then
77 | Continue;
78 | LResult.Module := LModuleInfo.OpenModule();
79 | LResult.Editor := TIOTAUtils.GetFormEditorFromModule(LResult.Module);
80 | LResult.Designer := (LResult.Editor as INTAFormEditor).FormDesigner;
81 | LResult.FileName := LModuleInfo.FileName;
82 | LResult.FormName := LModuleInfo.FormName;
83 | LResult.Caption := GetFormCaption(LResult.Designer.Root);
84 | LResult.FrameworkType := GetFrameworkTypeFromDesigner(LResult.Designer);
85 | AProc(LResult);
86 | end;
87 | end;
88 |
89 | class procedure TIOTAUtils.EnumForms(const AProc: TProc);
90 | var
91 | I: integer;
92 | LModuleServices: IOTAModuleServices;
93 | LProject: IOTAProject;
94 | LModule: IOTAModule;
95 | LEditor: IOTAFormEditor;
96 | LDesigner: IDesigner;
97 | LResult: TIOTAFormInfo;
98 | begin
99 | LModuleServices := (BorlandIDEServices as IOTAModuleServices);
100 | //User has created a project and added files on it.
101 | if Assigned(LModuleServices.MainProjectGroup) then begin
102 | for I := 0 to LModuleServices.MainProjectGroup.ProjectCount - 1 do begin
103 | LProject := LModuleServices.MainProjectGroup.Projects[I];
104 | EnumForms(LProject, AProc);
105 | end;
106 | end else
107 | //User has created files out of a project.
108 | for I := 0 to LModuleServices.ModuleCount - 1 do begin
109 | LModule := LModuleServices.Modules[I];
110 | LEditor := GetFormEditorFromModule(LModule);
111 | if not ModuleIsExportable(LModule) then
112 | Continue;
113 | LDesigner := (LEditor as INTAFormEditor).FormDesigner;
114 | if not Assigned(LDesigner) then
115 | Continue;
116 | LResult.FileName := LModule.FileName;
117 | LResult.FormName := LDesigner.Root.Name;
118 | LResult.Caption := GetFormCaption(LDesigner.Root);
119 | LResult.FrameworkType := GetFrameworkTypeFromDesigner(LDesigner);
120 | LResult.Module := LModule;
121 | LResult.Editor := LEditor;
122 | LResult.Designer := LDesigner;
123 | AProc(LResult);
124 | end;
125 | end;
126 |
127 | class function TIOTAUtils.FindComponents(const AFormEditor: IOTAFormEditor): TExportedComponents;
128 | var
129 | LCompList: TExportedComponentList;
130 | begin
131 | LCompList := TExportedComponentList.Create();
132 | try
133 | EnumComps(AFormEditor, procedure(AComponent: TComponent) begin
134 | LCompList.Add(TExportedComponent.Create(AComponent.Name));
135 | end);
136 | Result := LCompList.ToArray();
137 | finally
138 | LCompList.Free();
139 | end;
140 | end;
141 |
142 | class function TIOTAUtils.FindDelphiProjectEditor(
143 | const AProject: IOTAProject): IOTAEditor;
144 | var
145 | I: Integer;
146 | begin
147 | for I := 0 to AProject.ModuleFileCount -1 do
148 | if AProject.ModuleFileEditors[I].FileName.EndsWith('.dpr') then
149 | Exit(AProject.ModuleFileEditors[I]);
150 |
151 | Result := nil;
152 | end;
153 |
154 | class function TIOTAUtils.FindEvents(const AFormEditor: IOTAFormEditor; const ADesigner: IDesigner): TExportedEvents;
155 | procedure ExtractPropertyEvents(const ARttiContext: TRttiContext;
156 | const AComponent: TComponent; const AEvents: TExportedEventList);
157 | var
158 | LRttiType: TRttiType;
159 | LRttiProp: TRttiProperty;
160 | LMethod: TValue;
161 | LMethodName: string;
162 | LRttiMethod: TRttiMethodType;
163 | LParamList: TList;
164 | LParam: TRttiParameter;
165 | LEvt: TExportedEvent;
166 | begin
167 | LRttiType := ARttiContext.GetType(AComponent.ClassInfo);
168 | for LRttiProp in LRttiType.GetProperties() do begin
169 | if not (LRttiProp.Visibility = TMemberVisibility.mvPublished) then
170 | Continue;
171 | if not (LRttiProp.PropertyType is TRttiMethodType) then
172 | Continue;
173 | LMethod := LRttiProp.GetValue(AComponent);
174 | if LMethod.IsEmpty then
175 | Continue;
176 |
177 | LMethodName := ADesigner.GetMethodName(PMethod(LMethod.GetReferenceToRawData)^);
178 | if not ADesigner.MethodExists(LMethodName) then
179 | Continue;
180 |
181 | LRttiMethod := LRttiProp.PropertyType as TRttiMethodType;
182 | LParamList := TList.Create();
183 | try
184 | for LParam in LRttiMethod.GetParameters() do begin
185 | LParamList.Add(LParam.Name);
186 | end;
187 | LEvt := TExportedEvent.Create(LMethodName, LParamList.ToArray());
188 | if not AEvents.Contains(LEvt) then
189 | AEvents.Add(LEvt);
190 | finally
191 | LParamList.Free();
192 | end;
193 | end;
194 | end;
195 | function FindComponentRefs(): TArray;
196 | var
197 | LCompList: TList;
198 | begin
199 | LCompList := TList.Create();
200 | try
201 | EnumComps(AFormEditor, procedure(AComponent: TComponent) begin
202 | LCompList.Add(AComponent);
203 | end);
204 |
205 | Result := LCompList.ToArray();
206 | finally
207 | LCompList.Free();
208 | end;
209 | end;
210 | var
211 | LEvts: TExportedEventList;
212 | LRttiCtx: TRttiContext;
213 | LComponent: TComponent;
214 | begin
215 | LEvts := TExportedEventList.Create(
216 | TDelegatedComparer.Create(
217 | function(const Left, Right: TExportedEvent): Integer begin
218 | Result := CompareStr(Left.MethodName, Right.MethodName);
219 | end));
220 |
221 | try
222 | LRttiCtx := TRttiContext.Create();
223 | try
224 | //Extract the form events
225 | ExtractPropertyEvents(LRttiCtx, ADesigner.Root, LEvts);
226 | //Extract the component events
227 | for LComponent in FindComponentRefs() do
228 | ExtractPropertyEvents(LRttiCtx, LComponent, LEvts);
229 | finally
230 | LRttiCtx.Free();
231 | end;
232 | Result := LEvts.ToArray();
233 | finally
234 | LEvts.Free();
235 | end;
236 | end;
237 |
238 | class function TIOTAUtils.FindForm(const AFormName: string; out AFormInfo: TIOTAFormInfo): boolean;
239 | var
240 | LModuleServices: IOTAModuleServices;
241 | LModule: IOTAModule;
242 | LEditor: IOTAFormEditor;
243 | LDesigner: IDesigner;
244 | begin
245 | LModuleServices := (BorlandIDEServices as IOTAModuleServices);
246 | LModule := LModuleServices.FindFormModule(AFormName);
247 | if not Assigned(LModule) then
248 | Exit(false);
249 |
250 | LEditor := GetFormEditorFromModule(LModule);
251 | if not Assigned(LEditor) then
252 | Exit(false);
253 |
254 | LDesigner := (LEditor as INTAFormEditor).FormDesigner;
255 | if not Assigned(LDesigner) then
256 | Exit(false);
257 |
258 | AFormInfo.FileName := LModule.FileName;
259 | AFormInfo.FormName := LDesigner.Root.Name;
260 | AFormInfo.FrameworkType := GetFrameworkTypeFromDesigner(LDesigner);
261 | AFormInfo.Module := LModule;
262 | AFormInfo.Editor := LEditor;
263 | AFormInfo.Designer := LDesigner;
264 | Result := true;
265 | end;
266 |
267 | class function TIOTAUtils.GetEditorContentFromEditor(
268 | const AEditor: IOTAEditor): IOTAEditorContent;
269 | begin
270 | if not Supports(AEditor, IOTAEditorContent, Result) then
271 | Result := nil;
272 | end;
273 |
274 | class function TIOTAUtils.GetFormCaption(const AComponent: TComponent): string;
275 | begin
276 | if AComponent is Vcl.Forms.TForm then
277 | Result := Vcl.Forms.TForm(AComponent).Caption
278 | else if AComponent is Fmx.Forms.TForm then
279 | Result := Fmx.Forms.TForm(AComponent).Caption
280 | else
281 | Result := String.Empty;
282 | end;
283 |
284 | class function TIOTAUtils.GetFormEditorFromModule(const AModule: IOTAModule): IOTAFormEditor;
285 | var
286 | I: integer;
287 | LEditor: IOTAEditor;
288 | begin
289 | if AModule = nil then
290 | Exit(nil);
291 |
292 | for I := 0 to AModule.GetModuleFileCount - 1 do begin
293 | LEditor := AModule.GetModuleFileEditor(i);
294 | if Supports(LEditor, IOTAFormEditor, Result) then
295 | Break;
296 | end;
297 | end;
298 |
299 | class function TIOTAUtils.GetFrameworkTypeFromDesigner(
300 | const ADesigner: IDesigner): string;
301 | begin
302 | if CompareText(ADesigner.DesignerExtention, 'dfm') = 0 then
303 | Result := 'VCL'
304 | else if CompareText(ADesigner.DesignerExtention, 'fmx') = 0 then
305 | Result := 'FMX'
306 | else
307 | raise EUnknownFrameworkType.Create('Unknown framework type.');
308 | end;
309 |
310 | class function TIOTAUtils.GuessMainForm(
311 | const AProject: IOTAProject): IOTAModule;
312 | var
313 | LEntries: TDprEntries;
314 | LModuleServices: IOTAModuleServices;
315 | begin
316 | LEntries := ScanDprEntries(AProject);
317 | if not Assigned(LEntries) then
318 | Exit(nil);
319 |
320 | LModuleServices := (BorlandIDEServices as IOTAModuleServices);
321 | Result := LModuleServices.FindFormModule(LEntries[Low(LEntries)].Value);
322 | end;
323 |
324 | class function TIOTAUtils.HasForms: boolean;
325 | var
326 | LModuleServices: IOTAModuleServices;
327 | I: Integer;
328 | LModule: IOTAModule;
329 | begin
330 | LModuleServices := (BorlandIDEServices as IOTAModuleServices);
331 | for I := 0 to LModuleServices.ModuleCount - 1 do begin
332 | LModule := LModuleServices.Modules[I];
333 | if ModuleIsExportable(LModule) then
334 | Exit(true);
335 | end;
336 | Result := false;
337 | end;
338 |
339 | class function TIOTAUtils.ModuleIsForm(const AModule: IOTAModule): boolean;
340 | var
341 | LEditor: IOTAFormEditor;
342 | LDesigner: IDesigner;
343 | LRoot: TComponent;
344 | begin
345 | LEditor := GetFormEditorFromModule(AModule);
346 | if not Assigned(LEditor) then
347 | Exit(false);
348 | LDesigner := (LEditor as INTAFormEditor).FormDesigner;
349 | if not Assigned(LDesigner) then
350 | Exit(false);
351 | LRoot := LDesigner.Root;
352 | if not Assigned(LRoot) then
353 | Exit(false);
354 | if not (LRoot.InheritsFrom(Vcl.Forms.TForm)
355 | or LRoot.InheritsFrom(Fmx.Forms.TForm)) then
356 | Exit(false);
357 | Result := true;
358 | end;
359 |
360 | class function TIOTAUtils.ModuleIsPas(const AModule: IOTAModule): boolean;
361 | begin
362 | Result := SameText(ExtractFileExt(AModule.FileName), '.pas');
363 | end;
364 |
365 | class function TIOTAUtils.ScanDprEntries(
366 | const AProject: IOTAProject): TDprEntries;
367 | var
368 | I: integer;
369 | LEditor: IOTAEditor;
370 | LEditorContent: IOTAEditorContent;
371 | LOleStream: TStream;
372 | LStream: TStringStream;
373 | LMatches: TMatchCollection;
374 | LValues: string;
375 | LPair: TArray;
376 | begin
377 | LEditor := FindDelphiProjectEditor(AProject);
378 | if not Assigned(LEditor) then
379 | Exit(nil);
380 |
381 | LEditorContent := GetEditorContentFromEditor(LEditor);
382 | if not Assigned(LEditorContent) then
383 | Exit(nil);
384 |
385 | LOleStream := TOleStream.Create(LEditorContent.Content);
386 | try
387 | LStream := TStringStream.Create('');
388 | try
389 | LStream.CopyFrom(LOleStream);
390 |
391 | LMatches := TRegEx.Matches(
392 | LStream.DataString,
393 | 'Application.CreateForm\((.*?)\);',
394 | [roIgnoreCase, roMultiLine]);
395 |
396 | finally
397 | LStream.Free();
398 | end;
399 | finally
400 | LOleStream.Free();
401 | end;
402 |
403 | if (LMatches.Count = 0) then
404 | Exit(nil);
405 |
406 | LValues := String.Empty;
407 | for I := 0 to LMatches.Count - 1 do
408 | LValues := LValues + LMatches.Item[I].Value + sLineBreak;
409 |
410 | LMatches := TRegEx.Matches(
411 | LValues,
412 | '\((.*?)\)',
413 | [roIgnoreCase, roMultiLine]);
414 |
415 | for I := 0 to LMatches.Count - 1 do begin
416 | LPair := LMatches.Item[I].Value
417 | .Replace('(', '', [])
418 | .Replace(')', '', [])
419 | .Replace(' ', '', [rfReplaceAll])
420 | .Split([',']);
421 |
422 | if Length(LPair) <> 2 then
423 | Continue;
424 |
425 | Result := Result + [
426 | TDprEntry.Create(
427 | LPair[Low(LPair)],
428 | LPair[Low(LPair) + 1])
429 | ];
430 | end;
431 | end;
432 |
433 | class function TIOTAUtils.ModuleIsCpp(const AModule: IOTAModule): boolean;
434 | begin
435 | Result := SameText(ExtractFileExt(AModule.FileName), '.cpp');
436 | end;
437 |
438 | class function TIOTAUtils.ModuleIsExportable(
439 | const AModule: IOTAModule): boolean;
440 | begin
441 | Result := (ModuleIsPas(AModule) or ModuleIsCpp(AModule))
442 | and ModuleIsForm(AModule);
443 | end;
444 |
445 | class procedure TIOTAUtils.EnumComps(const AFormEditor: IOTAFormEditor;
446 | const ACallback: TProc);
447 | var
448 | LRoot: IOTAComponent;
449 | I: integer;
450 | LComp: TComponent;
451 | begin
452 | if not Assigned(ACallback) then
453 | Exit;
454 | LRoot := AFormEditor.GetRootComponent();
455 | if not Assigned(LRoot) then
456 | Exit;
457 |
458 | for I := 0 to LRoot.GetComponentCount() - 1 do begin
459 | LComp := TComponent(LRoot.GetComponent(I).GetComponentHandle());
460 | if not Assigned(LComp) then
461 | Continue;
462 |
463 | ACallback(LComp);
464 | end;
465 | end;
466 |
467 | end.
468 |
--------------------------------------------------------------------------------
/Source/PythonTools.Registration.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Registration;
2 |
3 | interface
4 |
5 | uses
6 | PythonTools.SplashScreen, PythonTools.Menu;
7 |
8 | procedure Register();
9 |
10 | implementation
11 |
12 | procedure RegisterPythonToolsMenuServices();
13 | begin
14 | with TPythonToolsMenu.Instance do
15 | HookMenu();
16 | end;
17 |
18 | procedure Register();
19 | begin
20 | RegisterPythonToolsMenuServices;
21 | end;
22 |
23 | initialization
24 | AddSplashScreen();
25 |
26 | finalization
27 |
28 | end.
29 |
--------------------------------------------------------------------------------
/Source/PythonTools.Registry.pas:
--------------------------------------------------------------------------------
1 | unit PythonTools.Registry;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Win.Registry,
7 | Winapi.Windows,
8 | PythonTools.Model.Design.Project,
9 | PythonTools.Model.Design.Forms;
10 |
11 | type
12 | TExporterRegistry = class
13 | private
14 | class function GetBaseRegistryKey(): string;
15 | class procedure UseActionKey(const AKey: string; const AProc: TProc);
16 | public
17 | class procedure SaveProjectModel(const AModel: TExportProjectDesignModel);
18 | class procedure LoadProjectModel(const AModel: TExportProjectDesignModel);
19 |
20 | class procedure SaveFormsModel(const AModel: TExportFormsDesignModel);
21 | class procedure LoadFormsModel(const AModel: TExportFormsDesignModel);
22 | end;
23 |
24 | implementation
25 |
26 | uses
27 | ToolsAPI,
28 | PythonTools.Common;
29 |
30 | const
31 | PROGRAM_KEY = 'Delphi4PythonExporter';
32 | //Actions
33 | PROJECT_ACTION_KEY = 'ProjectAction';
34 | FORMS_ACTION_KEY = 'FormsAction';
35 | //Values
36 | DEFAULT_DIRECTORY_KEY = 'DefaultDirectory';
37 | DEFAULT_SHOW_IN_EXPLORER = 'DefaultShowInExplorer';
38 | DEFAULT_FORM_FILE_KIND = 'DefaultFormFileKind';
39 | //Project values
40 | PROJECT_TITLE_KEY = 'ProjectTile';
41 | PROJECT_MAIN_FORM = 'ProjectMainForm';
42 |
43 |
44 | { TExporterRegistry }
45 |
46 | class function TExporterRegistry.GetBaseRegistryKey: string;
47 | begin
48 | with (BorlandIDEServices as IOTAServices) do
49 | Result := GetBaseRegistryKey();
50 | end;
51 |
52 | class procedure TExporterRegistry.UseActionKey(const AKey: string;
53 | const AProc: TProc);
54 | var
55 | LRegistry: TRegistry;
56 | begin
57 | LRegistry := TRegistry.Create();
58 | try
59 | LRegistry.RootKey := HKEY_CURRENT_USER;
60 | try
61 | if LRegistry.OpenKey(GetBaseRegistryKey(), false) then
62 | try
63 | if LRegistry.OpenKey(PROGRAM_KEY, true) then
64 | try
65 | if LRegistry.OpenKey(AKey, true) then
66 | try
67 | AProc(LRegistry);
68 | finally
69 | LRegistry.CloseKey();
70 | end;
71 | finally
72 | LRegistry.CloseKey();
73 | end;
74 | finally
75 | LRegistry.CloseKey();
76 | end;
77 | finally
78 | LRegistry.CloseKey();
79 | end;
80 | finally
81 | LRegistry.Free();
82 | end;
83 | end;
84 |
85 | class procedure TExporterRegistry.LoadProjectModel(
86 | const AModel: TExportProjectDesignModel);
87 | begin
88 | UseActionKey(PROJECT_ACTION_KEY, procedure(ARegistry: TRegistry) begin
89 | AModel.ApplicationDirectory := ARegistry.ReadString(DEFAULT_DIRECTORY_KEY);
90 | if ARegistry.ValueExists(DEFAULT_SHOW_IN_EXPLORER) then
91 | AModel.ShowInExplorer := ARegistry.ReadBool(DEFAULT_SHOW_IN_EXPLORER);
92 | if ARegistry.ValueExists(DEFAULT_FORM_FILE_KIND) then
93 | AModel.FormFileKind := TFormFileKind(ARegistry.ReadInteger(DEFAULT_FORM_FILE_KIND));
94 | if ARegistry.OpenKey(GuidToString(AModel.ApplicationId), false) then
95 | try
96 | AModel.ApplicationTitle := ARegistry.ReadString(PROJECT_TITLE_KEY);
97 | AModel.ApplicationMainForm := TFormNameAndFile.Create(
98 | Copy(ARegistry.ReadString(PROJECT_MAIN_FORM),
99 | Pos('.', ARegistry.ReadString(PROJECT_MAIN_FORM)) + 1,
100 | Length(ARegistry.ReadString(PROJECT_MAIN_FORM))
101 | - Pos('.', ARegistry.ReadString(PROJECT_MAIN_FORM))),
102 | Copy(ARegistry.ReadString(PROJECT_MAIN_FORM),
103 | 1,
104 | Pos('.', ARegistry.ReadString(PROJECT_MAIN_FORM)) - 1));
105 | finally
106 | ARegistry.CloseKey();
107 | end;
108 | end);
109 | end;
110 |
111 | class procedure TExporterRegistry.SaveProjectModel(
112 | const AModel: TExportProjectDesignModel);
113 | begin
114 | UseActionKey(PROJECT_ACTION_KEY, procedure(ARegistry: TRegistry) begin
115 | ARegistry.WriteString(DEFAULT_DIRECTORY_KEY, AModel.ApplicationDirectory);
116 | ARegistry.WriteBool(DEFAULT_SHOW_IN_EXPLORER, AModel.ShowInExplorer);
117 | ARegistry.WriteInteger(DEFAULT_FORM_FILE_KIND, Integer(AModel.FormFileKind));
118 | if ARegistry.OpenKey(GuidToString(AModel.ApplicationId), true) then begin
119 | try
120 | ARegistry.WriteString(PROJECT_TITLE_KEY, AModel.ApplicationTitle);
121 | ARegistry.WriteString(PROJECT_MAIN_FORM,
122 | AModel.ApplicationMainForm.CombineFileAndFormName());
123 | finally
124 | ARegistry.CloseKey();
125 | end;
126 | end;
127 |
128 | end);
129 | end;
130 |
131 | class procedure TExporterRegistry.LoadFormsModel(
132 | const AModel: TExportFormsDesignModel);
133 | begin
134 | UseActionKey(FORMS_ACTION_KEY, procedure(ARegistry: TRegistry) begin
135 | AModel.Directory := ARegistry.ReadString(DEFAULT_DIRECTORY_KEY);
136 | if ARegistry.ValueExists(DEFAULT_SHOW_IN_EXPLORER) then
137 | AModel.ShowInExplorer := ARegistry.ReadBool(DEFAULT_SHOW_IN_EXPLORER);
138 | end);
139 | end;
140 |
141 | class procedure TExporterRegistry.SaveFormsModel(
142 | const AModel: TExportFormsDesignModel);
143 | begin
144 | UseActionKey(FORMS_ACTION_KEY, procedure(ARegistry: TRegistry) begin
145 | ARegistry.WriteString(DEFAULT_DIRECTORY_KEY, AModel.Directory);
146 | ARegistry.WriteBool(DEFAULT_SHOW_IN_EXPLORER, AModel.ShowInExplorer);
147 | end);
148 | end;
149 |
150 | end.
151 |
--------------------------------------------------------------------------------
/Source/PythonTools.SplashScreen.pas:
--------------------------------------------------------------------------------
1 | {$I PythonTools.inc}
2 |
3 | unit PythonTools.SplashScreen;
4 |
5 | interface
6 |
7 | procedure AddSplashScreen();
8 |
9 | implementation
10 |
11 | uses
12 | ToolsAPI, Vcl.Graphics, Vcl.Imaging.pngimage;
13 |
14 | procedure AddSplashScreen();
15 | const
16 | EMB_PY_IMG = 'embarcaderopython_24px';
17 | var
18 | LImg: {$IFDEF DELPHI11_UP}TPngImage{$ELSE}TBitmap{$ENDIF DELPHI11_UP};
19 | begin
20 | LImg := {$IFDEF DELPHI11_UP}TPngImage{$ELSE}TBitmap{$ENDIF DELPHI11_UP}.Create();
21 | try
22 | LImg.LoadFromResourceName(HInstance, EMB_PY_IMG);
23 | {$IFDEF DELPHI11_UP}
24 | SplashScreenServices.AddPluginBitmap('Delphi4Python - Export forms for Python', [LImg], false, 'Registered', '');
25 | {$ELSE}
26 | SplashScreenServices.AddPluginBitmap('Delphi4Python - Export forms for Python', LImg.Handle, false, 'Registered', '');
27 | {$ENDIF DELPHI11_UP}
28 | finally
29 | LImg.Free();
30 | end;
31 | end;
32 |
33 | end.
34 |
--------------------------------------------------------------------------------
/Source/PythonTools.inc:
--------------------------------------------------------------------------------
1 | {$IFDEF VER300}
2 | {$DEFINE DELPHI10_UP}
3 | {$ENDIF VER300}
4 |
5 | {$IFDEF VER310}
6 | {$DEFINE DELPHI10_UP}
7 | {$DEFINE DELPHI10_1_UP}
8 | {$ENDIF VER310}
9 |
10 | {$IFDEF VER320}
11 | {$DEFINE DELPHI10_UP}
12 | {$DEFINE DELPHI10_1_UP}
13 | {$DEFINE DELPHI10_2_UP}
14 | {$ENDIF VER320}
15 |
16 | {$IFDEF VER330}
17 | {$DEFINE DELPHI10_UP}
18 | {$DEFINE DELPHI10_1_UP}
19 | {$DEFINE DELPHI10_2_UP}
20 | {$DEFINE DELPHI10_3_UP}
21 | {$ENDIF VER330}
22 |
23 | {$IFDEF VER340}
24 | {$DEFINE DELPHI10_UP}
25 | {$DEFINE DELPHI10_1_UP}
26 | {$DEFINE DELPHI10_2_UP}
27 | {$DEFINE DELPHI10_3_UP}
28 | {$DEFINE DELPHI10_4_UP}
29 | {$ENDIF VER340}
30 |
31 | {$IFDEF VER350}
32 | {$DEFINE DELPHI10_UP}
33 | {$DEFINE DELPHI10_1_UP}
34 | {$DEFINE DELPHI10_2_UP}
35 | {$DEFINE DELPHI10_3_UP}
36 | {$DEFINE DELPHI10_4_UP}
37 | {$DEFINE DELPHI11_UP}
38 | {$ENDIF VER350}
39 |
40 | {$IFDEF VER360}
41 | {$DEFINE DELPHI10_UP}
42 | {$DEFINE DELPHI10_1_UP}
43 | {$DEFINE DELPHI10_2_UP}
44 | {$DEFINE DELPHI10_3_UP}
45 | {$DEFINE DELPHI10_4_UP}
46 | {$DEFINE DELPHI11_UP}
47 | {$DEFINE DELPHI12_UP}
48 | {$ENDIF VER360}
49 |
50 | {$IFNDEF DELPHI10_UP}
51 | {$MESSAGE ERROR 'This framework requires Delphi 10 or higher.'}
52 | {$ENDIF DELPHI10_UP}
53 |
--------------------------------------------------------------------------------
/Tests/FMX.Producer.Test.pas:
--------------------------------------------------------------------------------
1 | unit FMX.Producer.Test;
2 |
3 | interface
4 |
5 | uses
6 | DUnitX.TestFramework,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Producer.SimpleFactory,
10 | PythonTools.Model.Producer.Application,
11 | PythonTools.Model.Producer.Form,
12 | PythonTools.Model.Producer.FormFile;
13 |
14 | type
15 | [TestFixture]
16 | TFMXProducerTest = class
17 | private
18 | FProducer: IPythonCodeProducer;
19 | FApplicationModel: TApplicationProducerModel;
20 | FFormModel: TFormProducerModel;
21 | FFormFileModel: TFormFileProducerModel;
22 |
23 | function GetFilesDir(): string;
24 | function GetDataDir(): string;
25 |
26 | function BuildApplicationModel(): TApplicationProducerModel;
27 | function BuildFormModel(): TFormProducerModel;
28 | function BuildFormFileModel(): TFormFileProducerModel;
29 | public
30 | [Setup]
31 | procedure Setup;
32 | [TearDown]
33 | procedure TearDown;
34 |
35 | [Test]
36 | procedure CheckFormInheritance();
37 | [Test]
38 | procedure GenerateApplication();
39 | [Test]
40 | procedure GenerateForm();
41 | [Test]
42 | procedure GenerateFormFileBin();
43 | [Test]
44 | procedure GenerateFormFileTxt();
45 | end;
46 |
47 | implementation
48 |
49 | uses
50 | System.SysUtils, System.IOUtils, System.Classes, FMX.Forms, Data.FMXForm;
51 |
52 | procedure TFMXProducerTest.Setup;
53 | begin
54 | FProducer := TProducerSimpleFactory.CreateProducer('FMX');
55 | FApplicationModel := BuildApplicationModel();
56 | FFormModel := BuildFormModel();
57 | FFormFileModel := BuildFormFileModel();
58 | end;
59 |
60 | procedure TFMXProducerTest.TearDown;
61 | begin
62 | FFormFileModel.Free();
63 | FFormModel.Free();
64 | FApplicationModel.Free();
65 | FProducer := nil;
66 | TDirectory.Delete(GetFilesDir(), true);
67 | end;
68 |
69 | function TFMXProducerTest.GetDataDir: string;
70 | begin
71 | Result := TDirectory.GetParent(TDirectory.GetParent(ExtractFileDir(ParamStr(0))));
72 | Result := TPath.Combine(Result, 'data');
73 | end;
74 |
75 | function TFMXProducerTest.GetFilesDir: string;
76 | begin
77 | Result := TPath.Combine(ExtractFileDir(ParamStr(0)), 'testfiles');
78 | if not TDirectory.Exists(Result) then
79 | TDirectory.CreateDirectory(Result);
80 | end;
81 |
82 | function TFMXProducerTest.BuildApplicationModel: TApplicationProducerModel;
83 | const
84 | UNIT_NAME = 'UnitProjectTest';
85 | FORM_NAME = 'FormTest';
86 | begin
87 | Result := TApplicationProducerModel.Create();
88 | try
89 | Result.Directory := GetFilesDir();
90 | Result.FileName := UNIT_NAME;
91 |
92 | Result.Title := 'Test';
93 | Result.MainForm := FORM_NAME;
94 |
95 | var LForms := TFormNameAndFileList.Create();
96 | try
97 | LForms.Add(TFormNameAndFile.Create(FORM_NAME, UNIT_NAME));
98 | Result.ImportedForms := LForms.ToArray();
99 | finally
100 | LForms.Free();
101 | end;
102 | except
103 | on E: Exception do begin
104 | FreeAndNil(Result);
105 | raise;
106 | end;
107 | end;
108 | end;
109 |
110 | function TFMXProducerTest.BuildFormFileModel: TFormFileProducerModel;
111 | begin
112 | Result := TFormFileProducerModel.Create();
113 | try
114 | Result.Directory := GetFilesDir();
115 | Result.FileName := 'Data.FMXForm';
116 | var LStream := TFileStream.Create(TPath.Combine(GetDataDir(), 'Data.FMXForm.fmx'), fmOpenRead);
117 | try
118 | Result.FormResource := LStream;
119 | Result.FormResource.Position := 0;
120 | finally
121 | LStream.Free();
122 | end;
123 | Result.Form := FmxForm;
124 | Result.Mode := TFormFileMode.ffmPython;
125 | Result.FrameworkType := 'FMX';
126 | except
127 | on E: Exception do begin
128 | FreeAndNil(Result);
129 | raise;
130 | end;
131 | end;
132 | end;
133 |
134 | function TFMXProducerTest.BuildFormModel: TFormProducerModel;
135 | const
136 | UNIT_NAME = 'UnitFormTest';
137 | FORM_NAME = 'FormTest';
138 | begin
139 | Result := TFormProducerModel.Create();
140 | try
141 | Result.Directory := GetFilesDir();
142 | Result.FileName := UNIT_NAME;
143 |
144 | Result.FormName := FORM_NAME;
145 | Result.FormParentName := TForm.ClassName.Replace('T', '');
146 |
147 | var LExportCompList := TExportedComponentList.Create();
148 | try
149 | LExportCompList.Add(TExportedComponent.Create('Comp1'));
150 | Result.ExportedComponents := LExportCompList.ToArray();
151 | finally
152 | LExportCompList.Free();
153 | end;
154 |
155 | var LExporEvtList := TExportedEventList.Create();
156 | try
157 | LExporEvtList.Add(TExportedEvent.Create('Event1',
158 | TArray.Create('Param1', 'Param2')));
159 | Result.ExportedEvents := LExporEvtList.ToArray();
160 | finally
161 | LExporEvtList.Free();
162 | end;
163 | except
164 | on E: Exception do begin
165 | FreeAndNil(Result);
166 | raise;
167 | end;
168 | end;
169 | end;
170 |
171 | procedure TFMXProducerTest.CheckFormInheritance;
172 | begin
173 | Assert.IsTrue(FProducer.IsValidFormInheritance(TForm));
174 | end;
175 |
176 | procedure TFMXProducerTest.GenerateApplication;
177 | begin
178 | //Save the project file
179 | FProducer.SavePyApplicationFile(FApplicationModel, FApplicationModel.Stream);
180 | FApplicationModel.Stream.Position := 0;
181 |
182 | //Check for the generated file
183 | var LFilePath := TPath.Combine(FApplicationModel.Directory, FApplicationModel.FileName.AsPython());
184 | Assert.IsTrue(TFile.Exists(LFilePath));
185 |
186 | var LStrings := TStringList.Create();
187 | try
188 | LStrings.LoadFromStream(FApplicationModel.Stream);
189 |
190 | {** this is what we excpect **}
191 | // from delphivcl import *
192 | // from UnitFormTest import FormTest
193 | //
194 | // def main():
195 | // Application.Initialize()
196 | // Application.Title = 'Test'
197 | // MainForm = FormTest(Application)
198 | // MainForm.Show()
199 | // FreeConsole()
200 | // Application.Run()
201 | //
202 | // if __name__ == '__main__':
203 | // main()
204 |
205 | Assert.IsTrue(LStrings.Count = 13);
206 | Assert.IsTrue(LStrings[0] = 'from delphifmx import *');
207 | Assert.IsTrue(LStrings[1] = Format('from %s import %s', [
208 | FApplicationModel.ImportedForms[0].FileName,
209 | FApplicationModel.ImportedForms[0].FormName]));
210 | Assert.IsTrue(LStrings[2] = String.Empty);
211 | Assert.IsTrue(LStrings[3] = 'def main():');
212 | Assert.IsTrue(LStrings[4] = sIdentation1 + 'Application.Initialize()');
213 | Assert.IsTrue(LStrings[5] = sIdentation1 + Format('Application.Title = %s', [
214 | FApplicationModel.Title.QuotedString()]));
215 | Assert.IsTrue(LStrings[6] = sIdentation1 + Format('Application.MainForm = %s(Application)', [
216 | FApplicationModel.MainForm]));
217 | Assert.IsTrue(LStrings[7] = sIdentation1 + 'Application.MainForm.Show()');
218 | Assert.IsTrue(LStrings[8] = sIdentation1 + 'Application.Run()');
219 | Assert.IsTrue(LStrings[9] = sIdentation1 + 'Application.MainForm.Destroy()');
220 | Assert.IsTrue(LStrings[10] = String.Empty);
221 | Assert.IsTrue(LStrings[11] = 'if __name__ == ''__main__'':');
222 | Assert.IsTrue(LStrings[12] = sIdentation1 + 'main()');
223 | finally
224 | LStrings.Free();
225 | end;
226 | end;
227 |
228 | procedure TFMXProducerTest.GenerateForm;
229 | begin
230 | //Save the form file
231 | FProducer.SavePyForm(FFormModel, FFormFileModel, FFormModel.Stream);
232 | FFormModel.Stream.Position := 0;
233 |
234 | //Check for the generated file
235 | var LFilePath := TPath.Combine(FFormModel.Directory, FFormModel.FileName.AsPython());
236 | Assert.IsTrue(TFile.Exists(LFilePath));
237 |
238 | var LStrings := TStringList.Create();
239 | try
240 | LStrings.LoadFromStream(FFormModel.Stream);
241 | {** this is what we excpect **}
242 | // import os
243 | // from delphivcl import *
244 | //
245 | // class FormTest(Form):
246 | //
247 | // def __init__(self, owner):
248 | // self.Comp1 = None
249 | // self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "UnitFormTest.pydfm"))
250 | //
251 | // def Event1(self, Param1, Param2):
252 | // pass
253 |
254 | Assert.IsTrue(LStrings.Count = 11);
255 | Assert.IsTrue(LStrings[0] = 'import os');
256 | Assert.IsTrue(LStrings[1] = 'from delphifmx import *');
257 | Assert.IsTrue(LStrings[2] = String.Empty);
258 | Assert.IsTrue(LStrings[3] = Format('class %s(Form):', [FFormModel.FormName]));
259 | Assert.IsTrue(LStrings[4] = String.Empty);
260 | Assert.IsTrue(LStrings[5] = sIdentation1 + 'def __init__(self, owner):');
261 | Assert.IsTrue(LStrings[6] = sIdentation2 + Format('self.%s = None', [
262 | FFormModel.ExportedComponents[0].ComponentName]));
263 | Assert.IsTrue(LStrings[7] = sIdentation2
264 | + Format('self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "%s%s"))', [
265 | FFormModel.FileName, TFormFile('').AsPythonFmx()]));
266 | Assert.IsTrue(LStrings[8] = String.Empty);
267 | Assert.IsTrue(LStrings[9] = sIdentation1 + Format('def %s(self, %s, %s):', [
268 | FFormModel.ExportedEvents[0].MethodName,
269 | FFormModel.ExportedEvents[0].MethodParams[0],
270 | FFormModel.ExportedEvents[0].MethodParams[1]]));
271 | Assert.IsTrue(LStrings[10] = sIdentation2 +'pass');
272 | finally
273 | LStrings.Free();
274 | end;
275 | end;
276 |
277 | procedure TFMXProducerTest.GenerateFormFileBin;
278 | begin
279 | //Save the project file
280 | FProducer.SavePyFormFileBin(FFormFileModel, FFormFileModel.Stream);
281 |
282 | //Check for the generated file
283 | var LFilePath := TPath.Combine(FFormFileModel.Directory, FFormFileModel.FormFile.AsPythonFmx());
284 | Assert.IsTrue(TFile.Exists(LFilePath));
285 |
286 | var LStream := TFileStream.Create(LFilePath, fmOpenRead or fmShareDenyNone);
287 | try
288 | var LReader := TReader.Create(LStream, 4096);
289 | try
290 | var LForm := TFmxForm.CreateNew(nil);
291 | try
292 | try
293 | LReader.ReadRootComponent(LForm);
294 | except
295 | on E: Exception do
296 | Assert.Fail(E.Message);
297 | end;
298 | finally
299 | LForm.Free();
300 | end;
301 | finally
302 | LReader.Free();
303 | end;
304 | finally
305 | LStream.Free();
306 | end;
307 | end;
308 |
309 | procedure TFMXProducerTest.GenerateFormFileTxt;
310 | begin
311 | //Save the project file
312 | FProducer.SavePyFormFileTxt(FFormFileModel, FFormFileModel.Stream);
313 |
314 | //Check for the generated file
315 | var LFilePath := TPath.Combine(FFormFileModel.Directory, FFormFileModel.FormFile.AsPythonFmx());
316 | Assert.IsTrue(TFile.Exists(LFilePath));
317 |
318 | var LInput := TFileStream.Create(LFilePath, fmOpenRead or fmShareDenyNone);
319 | try
320 | var LOutput := TMemoryStream.Create();
321 | try
322 | ObjectTextToBinary(LInput, LOutput);
323 | var LReader := TReader.Create(LOutput, 4096);
324 | try
325 | var LForm := TFmxForm.CreateNew(nil);
326 | try
327 | try
328 | LOutput.Position := 0;
329 | LReader.ReadRootComponent(LForm);
330 | except
331 | on E: Exception do
332 | Assert.Fail(E.Message);
333 | end;
334 | finally
335 | LForm.Free();
336 | end;
337 | finally
338 | LReader.Free();
339 | end;
340 | finally
341 | LOutput.Free();
342 | end;
343 | finally
344 | LInput.Free();
345 | end;
346 | end;
347 |
348 | initialization
349 | TDUnitX.RegisterTestFixture(TFMXProducerTest);
350 |
351 | end.
352 |
--------------------------------------------------------------------------------
/Tests/PythonExporterTest.dpr:
--------------------------------------------------------------------------------
1 | program PythonExporterTest;
2 |
3 | {$IFNDEF TESTINSIGHT}
4 | {$APPTYPE CONSOLE}
5 | {$ENDIF}
6 | {$STRONGLINKTYPES ON}
7 | uses
8 | System.SysUtils,
9 | {$IFDEF TESTINSIGHT}
10 | TestInsight.DUnitX,
11 | {$ELSE}
12 | DUnitX.Loggers.Console,
13 | DUnitX.Loggers.Xml.NUnit,
14 | {$ENDIF }
15 | DUnitX.TestFramework,
16 | VCL.Producer.Test in 'VCL.Producer.Test.pas',
17 | Data.VCLForm in 'data\Data.VCLForm.pas' {VclForm},
18 | Data.FMXForm in 'data\Data.FMXForm.pas' {FmxForm},
19 | FMX.Producer.Test in 'FMX.Producer.Test.pas';
20 |
21 | { keep comment here to protect the following conditional from being removed by the IDE when adding a unit }
22 |
23 | var
24 | runner : ITestRunner;
25 | results : IRunResults;
26 | logger : ITestLogger;
27 | nunitLogger : ITestLogger;
28 | begin
29 | {$IFDEF GUI}
30 | DUnitX.Loggers.GUI.VCL.Run();
31 | Exit;
32 | {$ENDIF}
33 | try
34 | //Check command line options, will exit if invalid
35 | TDUnitX.CheckCommandLine;
36 | //Create the runner
37 | runner := TDUnitX.CreateRunner;
38 | runner.UseRTTI := True;
39 |
40 | //Tell the runned how we will log this
41 | if TDUnitX.Options.ConsoleMode <> TDunitXConsoleMode.Off then begin
42 | logger := TDUnitXConsoleLogger.Create(TDUnitX.Options.ConsoleMode = TDunitXConsoleMode.Quiet);
43 | runner.AddLogger(logger);
44 | end;
45 |
46 | nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile);
47 | runner.AddLogger(nunitLogger);
48 |
49 | //We want to see the results
50 | TDUnitX.Options.ExitBehavior := TDUnitXExitBehavior.Pause;
51 |
52 | //Run tests
53 | results := runner.Execute;
54 | if not results.AllPassed then
55 | System.ExitCode := EXIT_ERRORS;
56 |
57 | {$IFNDEF CI}
58 | if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then
59 | begin
60 | System.Write('Done.. press key to quit.');
61 | System.Readln;
62 | end;
63 | {$ENDIF}
64 | except
65 | on E: Exception do
66 | System.Writeln(E.ClassName, ': ', E.Message);
67 | end;
68 |
69 | end.
70 |
--------------------------------------------------------------------------------
/Tests/VCL.Producer.Test.pas:
--------------------------------------------------------------------------------
1 | unit VCL.Producer.Test;
2 |
3 | interface
4 |
5 | uses
6 | DUnitX.TestFramework,
7 | PythonTools.Common,
8 | PythonTools.Producer,
9 | PythonTools.Producer.SimpleFactory,
10 | PythonTools.Model.Producer.Application,
11 | PythonTools.Model.Producer.Form,
12 | PythonTools.Model.Producer.FormFile;
13 |
14 | type
15 | [TestFixture]
16 | TVCLProducerTest = class
17 | private
18 | FProducer: IPythonCodeProducer;
19 | FApplicationModel: TApplicationProducerModel;
20 | FFormModel: TFormProducerModel;
21 | FFormFileModel: TFormFileProducerModel;
22 |
23 | function GetFilesDir(): string;
24 | function GetDataDir(): string;
25 |
26 | function BuildApplicationModel(): TApplicationProducerModel;
27 | function BuildFormModel(): TFormProducerModel;
28 | function BuildFormFileModel(): TFormFileProducerModel;
29 | public
30 | [Setup]
31 | procedure Setup;
32 | [TearDown]
33 | procedure TearDown;
34 |
35 | [Test]
36 | procedure CheckFormInheritance();
37 | [Test]
38 | procedure GenerateApplication();
39 | [Test]
40 | procedure GenerateForm();
41 | [Test]
42 | procedure GenerateFormFileBin();
43 | [Test]
44 | procedure GenerateFormFileTxt();
45 | end;
46 |
47 | implementation
48 |
49 | uses
50 | System.SysUtils, System.IOUtils, System.Classes, Vcl.Forms, Data.VCLForm;
51 |
52 | procedure TVCLProducerTest.Setup;
53 | begin
54 | FProducer := TProducerSimpleFactory.CreateProducer('VCL');
55 | FApplicationModel := BuildApplicationModel();
56 | FFormModel := BuildFormModel();
57 | FFormFileModel := BuildFormFileModel();
58 | end;
59 |
60 | procedure TVCLProducerTest.TearDown;
61 | begin
62 | FFormFileModel.Free();
63 | FFormModel.Free();
64 | FApplicationModel.Free();
65 | FProducer := nil;
66 | TDirectory.Delete(GetFilesDir(), true);
67 | end;
68 |
69 | function TVCLProducerTest.GetDataDir: string;
70 | begin
71 | Result := TDirectory.GetParent(TDirectory.GetParent(ExtractFileDir(ParamStr(0))));
72 | Result := TPath.Combine(Result, 'data');
73 | end;
74 |
75 | function TVCLProducerTest.GetFilesDir: string;
76 | begin
77 | Result := TPath.Combine(ExtractFileDir(ParamStr(0)), 'testfiles');
78 | if not TDirectory.Exists(Result) then
79 | TDirectory.CreateDirectory(Result);
80 | end;
81 |
82 | function TVCLProducerTest.BuildApplicationModel: TApplicationProducerModel;
83 | const
84 | UNIT_NAME = 'UnitProjectTest';
85 | FORM_NAME = 'FormTest';
86 | begin
87 | Result := TApplicationProducerModel.Create();
88 | try
89 | Result.Directory := GetFilesDir();
90 | Result.FileName := UNIT_NAME;
91 |
92 | Result.Title := 'Test';
93 | Result.MainForm := FORM_NAME;
94 |
95 | var LForms := TFormNameAndFileList.Create();
96 | try
97 | LForms.Add(TFormNameAndFile.Create(FORM_NAME, UNIT_NAME));
98 | Result.ImportedForms := LForms.ToArray();
99 | finally
100 | LForms.Free();
101 | end;
102 | except
103 | on E: Exception do begin
104 | FreeAndNil(Result);
105 | raise;
106 | end;
107 | end;
108 | end;
109 |
110 | function TVCLProducerTest.BuildFormFileModel: TFormFileProducerModel;
111 | begin
112 | Result := TFormFileProducerModel.Create();
113 | try
114 | Result.Directory := GetFilesDir();
115 | Result.FileName := 'Data.VCLForm';
116 | var LStream := TFileStream.Create(TPath.Combine(GetDataDir(), 'Data.VCLForm.dfm'), fmOpenRead);
117 | try
118 | Result.FormResource := LStream;
119 | Result.FormResource.Position := 0;
120 | finally
121 | LStream.Free();
122 | end;
123 | Result.Form := VclForm;
124 | Result.Mode := TFormFileMode.ffmPython;
125 | Result.FrameworkType := 'VCL';
126 | except
127 | on E: Exception do begin
128 | FreeAndNil(Result);
129 | raise;
130 | end;
131 | end;
132 | end;
133 |
134 | function TVCLProducerTest.BuildFormModel: TFormProducerModel;
135 | const
136 | UNIT_NAME = 'UnitFormTest';
137 | FORM_NAME = 'FormTest';
138 | begin
139 | Result := TFormProducerModel.Create();
140 | try
141 | Result.Directory := GetFilesDir();
142 | Result.FileName := UNIT_NAME;
143 |
144 | Result.FormName := FORM_NAME;
145 | Result.FormParentName := TForm.ClassName.Replace('T', '');
146 |
147 | var LExportCompList := TExportedComponentList.Create();
148 | try
149 | LExportCompList.Add(TExportedComponent.Create('Comp1'));
150 | Result.ExportedComponents := LExportCompList.ToArray();
151 | finally
152 | LExportCompList.Free();
153 | end;
154 |
155 | var LExporEvtList := TExportedEventList.Create();
156 | try
157 | LExporEvtList.Add(TExportedEvent.Create('Event1',
158 | TArray.Create('Param1', 'Param2')));
159 | Result.ExportedEvents := LExporEvtList.ToArray();
160 | finally
161 | LExporEvtList.Free();
162 | end;
163 | except
164 | on E: Exception do begin
165 | FreeAndNil(Result);
166 | raise;
167 | end;
168 | end;
169 | end;
170 |
171 | procedure TVCLProducerTest.CheckFormInheritance;
172 | begin
173 | Assert.IsTrue(FProducer.IsValidFormInheritance(TForm));
174 | end;
175 |
176 | procedure TVCLProducerTest.GenerateApplication;
177 | begin
178 | //Save the project file
179 | FProducer.SavePyApplicationFile(FApplicationModel, FApplicationModel.Stream);
180 | FApplicationModel.Stream.Position := 0;
181 |
182 | //Check for the generated file
183 | var LFilePath := TPath.Combine(FApplicationModel.Directory, FApplicationModel.FileName.AsPython());
184 | Assert.IsTrue(TFile.Exists(LFilePath));
185 |
186 | var LStrings := TStringList.Create();
187 | try
188 | LStrings.LoadFromStream(FApplicationModel.Stream);
189 |
190 | {** this is what we excpect **}
191 | // from delphivcl import *
192 | // from UnitFormTest import FormTest
193 | //
194 | // def main():
195 | // Application.Initialize()
196 | // Application.Title = 'Test'
197 | // MainForm = FormTest(Application)
198 | // MainForm.Show()
199 | // FreeConsole()
200 | // Application.Run()
201 | //
202 | // if __name__ == '__main__':
203 | // main()
204 |
205 | Assert.IsTrue(LStrings.Count = 13);
206 | Assert.IsTrue(LStrings[0] = 'from delphivcl import *');
207 | Assert.IsTrue(LStrings[1] = Format('from %s import %s', [
208 | FApplicationModel.ImportedForms[0].FileName,
209 | FApplicationModel.ImportedForms[0].FormName]));
210 | Assert.IsTrue(LStrings[2] = String.Empty);
211 | Assert.IsTrue(LStrings[3] = 'def main():');
212 | Assert.IsTrue(LStrings[4] = sIdentation1 + 'Application.Initialize()');
213 | Assert.IsTrue(LStrings[5] = sIdentation1 + Format('Application.Title = %s', [
214 | FApplicationModel.Title.QuotedString()]));
215 | Assert.IsTrue(LStrings[6] = sIdentation1 + Format('MainForm = %s(Application)', [
216 | FApplicationModel.MainForm]));
217 | Assert.IsTrue(LStrings[7] = sIdentation1 + 'MainForm.Show()');
218 | Assert.IsTrue(LStrings[8] = sIdentation1 + 'FreeConsole()');
219 | Assert.IsTrue(LStrings[9] = sIdentation1 + 'Application.Run()');
220 | Assert.IsTrue(LStrings[10] = String.Empty);
221 | Assert.IsTrue(LStrings[11] = 'if __name__ == ''__main__'':');
222 | Assert.IsTrue(LStrings[12] = sIdentation1 + 'main()');
223 | finally
224 | LStrings.Free();
225 | end;
226 | end;
227 |
228 | procedure TVCLProducerTest.GenerateForm;
229 | begin
230 | //Save the form file
231 | FProducer.SavePyForm(FFormModel, FFormFileModel, FFormModel.Stream);
232 | FFormModel.Stream.Position := 0;
233 |
234 | //Check for the generated file
235 | var LFilePath := TPath.Combine(FFormModel.Directory, FFormModel.FileName.AsPython());
236 | Assert.IsTrue(TFile.Exists(LFilePath));
237 |
238 | var LStrings := TStringList.Create();
239 | try
240 | LStrings.LoadFromStream(FFormModel.Stream);
241 | {** this is what we excpect **}
242 | // import os
243 | // from delphivcl import *
244 | //
245 | // class FormTest(Form):
246 | //
247 | // def __init__(self, owner):
248 | // self.Comp1 = None
249 | // self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "UnitFormTest.pydfm"))
250 | //
251 | // def Event1(self, Param1, Param2):
252 | // pass
253 |
254 | Assert.IsTrue(LStrings.Count = 11);
255 | Assert.IsTrue(LStrings[0] = 'import os');
256 | Assert.IsTrue(LStrings[1] = 'from delphivcl import *');
257 | Assert.IsTrue(LStrings[2] = String.Empty);
258 | Assert.IsTrue(LStrings[3] = Format('class %s(Form):', [FFormModel.FormName]));
259 | Assert.IsTrue(LStrings[4] = String.Empty);
260 | Assert.IsTrue(LStrings[5] = sIdentation1 + 'def __init__(self, owner):');
261 | Assert.IsTrue(LStrings[6] = sIdentation2 + Format('self.%s = None', [
262 | FFormModel.ExportedComponents[0].ComponentName]));
263 | Assert.IsTrue(LStrings[7] = sIdentation2
264 | + Format('self.LoadProps(os.path.join(os.path.dirname(os.path.abspath(__file__)), "%s%s"))', [
265 | FFormModel.FileName, TFormFile('').AsPythonDfm()]));
266 | Assert.IsTrue(LStrings[8] = String.Empty);
267 | Assert.IsTrue(LStrings[9] = sIdentation1 + Format('def %s(self, %s, %s):', [
268 | FFormModel.ExportedEvents[0].MethodName,
269 | FFormModel.ExportedEvents[0].MethodParams[0],
270 | FFormModel.ExportedEvents[0].MethodParams[1]]));
271 | Assert.IsTrue(LStrings[10] = sIdentation2 +'pass');
272 | finally
273 | LStrings.Free();
274 | end;
275 | end;
276 |
277 | procedure TVCLProducerTest.GenerateFormFileBin;
278 | begin
279 | //Save the project file
280 | FProducer.SavePyFormFileBin(FFormFileModel, FFormFileModel.Stream);
281 |
282 | //Check for the generated file
283 | var LFilePath := TPath.Combine(FFormFileModel.Directory, FFormFileModel.FormFile.AsPythonDfm());
284 | Assert.IsTrue(TFile.Exists(LFilePath));
285 |
286 | var LStream := TFileStream.Create(LFilePath, fmOpenRead or fmShareDenyNone);
287 | try
288 | var LReader := TReader.Create(LStream, 4096);
289 | try
290 | var LForm := TVclForm.CreateNew(nil);
291 | try
292 | try
293 | LReader.ReadRootComponent(LForm);
294 | except
295 | on E: Exception do
296 | Assert.Fail(E.Message);
297 | end;
298 | finally
299 | LForm.Free();
300 | end;
301 | finally
302 | LReader.Free();
303 | end;
304 | finally
305 | LStream.Free();
306 | end;
307 | end;
308 |
309 | procedure TVCLProducerTest.GenerateFormFileTxt;
310 | begin
311 | //Save the project file
312 | FProducer.SavePyFormFileTxt(FFormFileModel, FFormFileModel.Stream);
313 |
314 | //Check for the generated file
315 | var LFilePath := TPath.Combine(FFormFileModel.Directory, FFormFileModel.FormFile.AsPythonDfm());
316 | Assert.IsTrue(TFile.Exists(LFilePath));
317 |
318 | var LInput := TFileStream.Create(LFilePath, fmOpenRead or fmShareDenyNone);
319 | try
320 | var LOutput := TMemoryStream.Create();
321 | try
322 | ObjectTextToBinary(LInput, LOutput);
323 | var LReader := TReader.Create(LOutput, 4096);
324 | try
325 | var LForm := TVclForm.CreateNew(nil);
326 | try
327 | try
328 | LOutput.Position := 0;
329 | LReader.ReadRootComponent(LForm);
330 | except
331 | on E: Exception do
332 | Assert.Fail(E.Message);
333 | end;
334 | finally
335 | LForm.Free();
336 | end;
337 | finally
338 | LReader.Free();
339 | end;
340 | finally
341 | LOutput.Free();
342 | end;
343 | finally
344 | LInput.Free();
345 | end;
346 | end;
347 |
348 | initialization
349 | TDUnitX.RegisterTestFixture(TVCLProducerTest);
350 |
351 | end.
352 |
--------------------------------------------------------------------------------
/Tests/data/Data.FMXForm.fmx:
--------------------------------------------------------------------------------
1 | object FmxForm: TFmxForm
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form1'
5 | ClientHeight = 480
6 | ClientWidth = 640
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | end
12 |
--------------------------------------------------------------------------------
/Tests/data/Data.FMXForm.pas:
--------------------------------------------------------------------------------
1 | unit Data.FMXForm;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;
8 |
9 | type
10 | TFmxForm = class(TForm)
11 | private
12 | { Private declarations }
13 | public
14 | { Public declarations }
15 | end;
16 |
17 | var
18 | FmxForm: TFmxForm;
19 |
20 | implementation
21 |
22 | {$R *.fmx}
23 |
24 | initialization
25 | FmxForm := TFmxForm.Create(nil);
26 |
27 | finalization
28 | FmxForm.Free();
29 |
30 | end.
31 |
--------------------------------------------------------------------------------
/Tests/data/Data.VCLForm.dfm:
--------------------------------------------------------------------------------
1 | object VclForm: TVclForm
2 | Left = 0
3 | Top = 0
4 | Caption = 'VclForm'
5 | ClientHeight = 441
6 | ClientWidth = 624
7 | Color = clBtnFace
8 | Font.Charset = DEFAULT_CHARSET
9 | Font.Color = clWindowText
10 | Font.Height = -12
11 | Font.Name = 'Segoe UI'
12 | Font.Style = []
13 | PixelsPerInch = 96
14 | TextHeight = 15
15 | end
16 |
--------------------------------------------------------------------------------
/Tests/data/Data.VCLForm.pas:
--------------------------------------------------------------------------------
1 | unit Data.VCLForm;
2 |
3 | interface
4 |
5 | uses
6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
8 |
9 | type
10 | TVclForm = class(TForm)
11 | private
12 | { Private declarations }
13 | public
14 | { Public declarations }
15 | end;
16 |
17 | var
18 | VclForm: TVclForm;
19 |
20 | implementation
21 |
22 | {$R *.dfm}
23 |
24 | initialization
25 | VclForm := TVclForm.Create(nil);
26 |
27 | finalization
28 | VclForm.Free();
29 |
30 | end.
31 |
--------------------------------------------------------------------------------
/images/EmbarcaderoPython(154px).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/EmbarcaderoPython(154px).png
--------------------------------------------------------------------------------
/images/EmbarcaderoPython(16px).bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/EmbarcaderoPython(16px).bmp
--------------------------------------------------------------------------------
/images/EmbarcaderoPython(16px).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/EmbarcaderoPython(16px).png
--------------------------------------------------------------------------------
/images/EmbarcaderoPython(24px).bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/EmbarcaderoPython(24px).bmp
--------------------------------------------------------------------------------
/images/EmbarcaderoPython(24px).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/EmbarcaderoPython(24px).png
--------------------------------------------------------------------------------
/images/Export2Python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/Export2Python.png
--------------------------------------------------------------------------------
/images/ExportCurrentProject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/ExportCurrentProject.png
--------------------------------------------------------------------------------
/images/ExportForms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Embarcadero/Delphi4PythonExporter/e009e337ce844b591cc01430e6790cb9eadf2b2f/images/ExportForms.png
--------------------------------------------------------------------------------
/images/readme.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
--------------------------------------------------------------------------------