Compare commits

...

76 Commits

Author SHA1 Message Date
Vadim Lopatin ec29ced5b6
improve HDPI support 2024-03-08 11:46:42 +00:00
Grim Maple 1bd86c66cd Update code for dlangui 0.10.3 2023-05-18 22:57:40 +03:00
Grim Maple b822795449 Bump dcd version 2023-04-18 17:13:48 +03:00
Grim Maple aeb045e66e Fix logger 2023-04-18 16:58:51 +03:00
Grim Maple e18eaa2b5b
Merge pull request #428 from abstewart/master
Update dlangui dependency to version 0.10.2
2023-04-04 11:48:17 +03:00
abstewart ccac2ad2b9 update dlangui dependency to version 0.10.2 2023-04-03 16:31:32 -04:00
Grim Maple 72ea89b6ec Bump DCD version for tha sweet UFCS support.
Also, removed DCD submodule bacuse it's a dub dependency anyway. Closes #397
2022-10-22 14:42:16 +03:00
Grim Maple 8c072de2af Fix autocompletion crash; autocompletion cancel 2022-04-26 19:29:15 +03:00
Grim Maple 0dee6cb1f1 Add autocompletion on each key press 2022-04-22 23:35:54 +03:00
Grim Maple daeb6f58af Update dlangui dep 2022-04-16 16:18:34 +03:00
Grim Maple 61cda23311 Fix deprecations 2022-04-14 23:57:20 +03:00
Grim Maple 51728e70eb Update DCD 2022-04-06 22:27:22 +03:00
Grim Maple b511e32ca3 Fix autocomplete 2022-04-06 22:18:34 +03:00
Vadim Lopatin c566de2633
Merge pull request #406 from leh103/master
Fix for isuue #398
2019-08-09 11:51:23 +03:00
Lawrence Hemsley eac96a7d05 Fix for isuue #398 2019-03-09 15:12:27 -07:00
Vadim Lopatin 16abdd171b fix SDL build 2018-11-26 12:12:46 +03:00
Vadim Lopatin 4e64798b9b update version 2018-11-26 09:55:19 +03:00
Vadim Lopatin b5333788ae upgrade dlangui version 2018-11-26 09:54:40 +03:00
Vadim Lopatin 64cfd574b1 update version 2018-11-26 08:42:20 +03:00
Vadim Lopatin 98c8d835ea
Merge pull request #388 from sr-tream/master
Fix color codes. Now it compilable
2018-11-26 08:34:21 +03:00
SR_team 5b57d9eafe Fix color codes. Now it compilable 2018-10-31 16:06:21 +03:00
Vadim Lopatin 2af89ce369 fix errors; upgrade DCD deps 2018-10-05 09:37:00 +03:00
Vadim Lopatin 06949bef98 update version and dlangui dependency 2018-10-04 13:06:24 +03:00
Vadim Lopatin 1119c32e61
Merge pull request #383 from cschlote/fix-phobos-path-getcwd
Fix access to private std.path.getcwd
2018-10-02 15:02:08 +03:00
Carsten Schlote d89ca3e739 Fix access to private std.path.getcwd 2018-09-19 16:01:32 +02:00
Vadim Lopatin da20313a1b
Merge pull request #379 from WookeyBiscotti/caret_navigation_commands
Add caret navigation
2018-06-13 16:50:57 +03:00
Alex Savchenko 93545717ed Add caret navigation 2018-06-07 22:12:32 +03:00
Vadim Lopatin 0391aa9ae8 update dlangui deps; update version 2018-05-08 11:44:57 +03:00
Vadim Lopatin dbb731fa7b
Merge pull request #372 from Marko10-000/master
Add German language
2018-05-08 10:31:38 +03:00
Vadim Lopatin 6c32105caf
Merge pull request #374 from Zevenberge/feature/add_folder
Create a directory and package.d
2018-05-08 10:31:15 +03:00
Vadim Lopatin 634c024ab1
Merge pull request #371 from rjframe/installer
Add Inno Setup installer script.
2018-05-08 10:30:55 +03:00
Zevenberge 31d9771a08 Merge branch 'master' into feature/add_folder 2018-05-05 11:55:41 +02:00
Zevenberge 4640e093c3 Selects the new folder on creation. Also opens parent folder if not open 2018-05-05 11:55:16 +02:00
Marko Semet a542844b97 Improved German translation for QUESTION_NEW_WORKSPACE
Transformed sentence from feminine to masculine. "verwendet" seams to
sound better than "benutzt".
2018-04-20 12:48:23 +02:00
Marko Semet b4a9fbb431 German language 2018-04-10 14:46:36 +02:00
Ryan Frame ed64d56a79 Add inno setup installer script.
This will install DlangIDE, and optionally download and install DMD.
2018-04-10 07:20:07 -04:00
Vadim Lopatin d684feac14 update dlangui deps 2018-03-20 16:36:12 +03:00
Marco de Wild bf04e91293 Converted tabs to spaces 2017-12-29 14:17:13 +01:00
Marco de Wild 92990e5352 The newly added folder is now placed appropiately 2017-12-29 11:38:48 +01:00
Zevenberge 4f69a40530 Changed the UI options and added english terms 2017-12-23 18:42:19 +01:00
Zevenberge a92a253481 The new package also opens and it added to the tree 2017-12-23 18:26:46 +01:00
Zevenberge 87d5a88a0c Adding a default package.d now works 2017-12-23 18:09:04 +01:00
Zevenberge 85995f9baf Merge branch 'master' into feature/add_folder 2017-12-07 21:37:46 +01:00
Zevenberge 4634fcf90d Scaled the screen a bit better 2017-12-07 21:36:09 +01:00
Vadim Lopatin 582feeac53 fix deprecations 2017-12-03 20:58:28 +03:00
Vadim Lopatin 287c7cdb67 update dlangui 2017-12-03 15:11:48 +03:00
Zevenberge f4f1a6939c Removed action new source file on project root level
As the IDE no longer searches for the source folder, a file cannot be placed here.
2017-12-02 22:45:46 +01:00
Zevenberge 2e9304727d Update VisualD project to include the new file 2017-12-02 22:17:54 +01:00
Zevenberge 2cd4bc1416 Commented the folder creation at project root level
The files are project root are not shown (i.e. README files). Therefore, if you make a folder, it doesn't appear in the UI. The functionality is tested and works, but the scanning of root-level files should be implemented first (more importantly, a descision should be taken which files to show).
2017-12-02 22:07:46 +01:00
Zevenberge 39ac4deb5d The root ProjectFolder now has the name of the folder
It used to have the full file path of the dub.json file.
2017-12-02 21:50:21 +01:00
Zevenberge c1f4a3b1c2 Folder added to its parent without reloading the whole workspace
As we know the parant, we can simple add a child to it. There is no need to reload the workspace. I also took the liberty of renaming refreshWorkspace to updateTreeGraph, to avoid confusion between updating the tree graph and reloading the workspace from disk.
2017-12-02 21:49:08 +01:00
Zevenberge 2bf34ed691 A folder can now be created on all levels
It creates a folder below the folder/project that is selected. ProjectFolder is now no longer set when the project is selected; this allows folder creation at the highest level (i.e. myproj/views instead of myproj/source/views). It is created on disk, but doesn't show up in the workspace yet.
2017-11-30 21:21:24 +01:00
Zevenberge 3900fd4a34 Added new directory to the right-click menu 2017-11-30 18:57:09 +01:00
Vadim Lopatin f7cbb17a51 update dlangui version 2017-10-18 09:10:30 +03:00
Vadim Lopatin 76c91875bf update version 2017-10-16 13:34:14 +03:00
Vadim Lopatin 4487e2cc55 fix #350 2017-10-16 13:33:44 +03:00
Vadim Lopatin 1e63d6f1bc update readme 2017-10-12 11:32:12 +03:00
Vadim Lopatin 3d8cb03e49 update readme 2017-10-12 11:30:29 +03:00
Vadim Lopatin 178ed7d75c update readme 2017-10-12 11:26:07 +03:00
Vadim Lopatin 2f036d6407 update readme 2017-10-12 11:18:37 +03:00
Vadim Lopatin c9eaf3f9bb update readme 2017-10-12 11:16:36 +03:00
Vadim Lopatin 7069d5985f update README - dub based fetch and run instructions 2017-10-12 11:11:28 +03:00
Vadim Lopatin b412b9a037 DMD profiling on windows workaround 2017-10-10 10:34:36 +03:00
Vadim Lopatin f36056d37e DMD trace file parser - prepare sorted lists of functions - #344 2017-10-09 09:28:58 +03:00
Vadim Lopatin f620e3e286 DMD profiler trace.log viewer, part 1 - #344 2017-10-06 16:40:22 +03:00
Vadim Lopatin 645090ec31 fix #327 2017-10-05 14:55:05 +03:00
Vadim Lopatin 20fbdea809 fix #339 - disable File/Create/New File if no workspace and project opened 2017-10-05 13:46:04 +03:00
Vadim Lopatin 9c50cab5de new project context menu item for workspace - close #338 2017-10-02 13:12:34 +03:00
Vadim Lopatin ba97194bb3 Fix project detection for error location handling #337 2017-10-02 13:07:10 +03:00
Vadim Lopatin 325915097a setting to override screen DPI detected by platform - close #336 2017-09-29 10:58:18 +03:00
Vadim Lopatin 6fd6387df6 update readme 2017-09-28 13:16:53 +03:00
Vadim Lopatin b6628b7f4c update dark theme; fix fonts; fix console mode build 2017-09-28 13:11:59 +03:00
Vadim Lopatin ae58bec192 upgrade dlangui to fix freetype font issues 2017-09-28 10:32:30 +03:00
Vadim Lopatin 0cb3f2257a fix 64 bit builds 2017-09-27 18:47:04 +03:00
Vadim Lopatin 5b1e8925ac update version 2017-09-27 15:52:18 +03:00
Vadim Lopatin a7c203525c better fonts 2017-09-27 15:51:44 +03:00
47 changed files with 2465 additions and 540 deletions

4
.gitignore vendored
View File

@ -20,3 +20,7 @@ index.html
api.html
screenshots.html
*.log
*.userprefs
\.dlangidews\.wssettings

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "deps/DCD"]
path = deps/DCD
url = https://github.com/Hackerpilot/DCD.git

View File

@ -5,6 +5,18 @@ Dlang IDE
Cross platform D language IDE written using DlangUI library.
Screenshot of Default theme
![screenshot](http://buggins.github.io/dlangui/screenshots/screenshot-dlangide.png "screenshot")
Screenshot of Dark theme
![screenshot](http://buggins.github.io/dlangui/screenshots/screenshot-dlangide-dark.png "screenshot")
Screenshot of console mode (running in windows console)
![screenshot](http://buggins.github.io/dlangui/screenshots/screenshot-dlangide-console-win32.png "screenshot")
Currently supported features:
* Uses DUB (dub.json or dub.sdl) project format
@ -33,7 +45,6 @@ Source editor features:
* Select word by mouse double click
![screenshot](http://buggins.github.io/dlangui/screenshots/screenshot-dlangide.png "screenshot")
GitHub page: [https://github.com/buggins/dlangide](https://github.com/buggins/dlangide)
@ -44,6 +55,69 @@ DlangUI project GitHub page: [https://github.com/buggins/dlangui](https://github
Mago debugger GitHub page: [https://github.com/rainers/mago](https://github.com/rainers/mago)
Try DlangIDE
============
You can use DUB utility and DMD compiler to download, build and run recent version of DlangIDE from GIT repository.
Pre-requisites: install DMD from [https://dlang.org/download.html](https://dlang.org/download.html). In recent DMD packages, DUB utility is included.
Now you can fetch, build and run DlangIDE:
dub fetch dlangide
dub run --build=release dlangide
OSX build notes
---------------
On OSX you will need to install libSDL2, which is used as a default backend.
E.g. use homebrew or some other package manager to install it.
brew install sdl2
For troubleshooting of screen DPI detection (e.g. if everything is small on Retina display),
you can choose DPI manually in menu Edit / Preferences / Interface : Override screen DPI.
(This issue will be fixed soon).
Linux build notes
-----------------
On Linux will need to install libSDL2, which is used as a default backend.
If it's not yet installed, install it in order to run DlangIDE.
For debian/ubuntu use:
sudo apt-get install libsdl2-dev
For RPM based distributions:
sudo yum install SDL2-devel
Windows build notes
-------------------
Pre-built win32 binaries can be found in releases section.
As well, you can build it yourself.
Recent builds with dmd under windows have issues with crash in OPTILINK linker from DMD.
Workaround: add --arch=x86_mscoff or --arch=x86_64 to DUB commandline
Build 32bit version using microsoft linker and COFF object and library file format:
dub run --build=release --arch=x86_mscoff dlangide
Build 64bit version using microsoft linker:
dub run --build=release --arch=x86_64 dlangide
Note: unlike default --arch=x86, both x86_mscoff and x86_64 have a dependency on linker from Visual Studio C++ compiler toolchain.
Build tools
===========

1
deps/DCD vendored

@ -1 +0,0 @@
Subproject commit cbcc6faac3f820bb8e06ed132d82d13036e34d58

View File

@ -443,6 +443,7 @@
<Link>3rdparty\dsymbol\symbols.d</Link>
</Compile>
<Compile Include="src\dlangide\ui\terminal.d" />
<Compile Include="src\dlangide\ui\newfolder.d" />
</ItemGroup>
<ItemGroup>
<Folder Include="src\ddebug\gdb\" />

140
dlangide.iss Normal file
View File

@ -0,0 +1,140 @@
; Inno Setup script for DlangIDE.
; Installs DlangIDE and the Mago debugger, and optionally
; downloads and installs DMD.
[Setup]
AppName=DlangIDE
AppId=DlangIDE
; The following version numbers need to be updated on each release.
AppVerName=0.8.11
AppVersion=0.8.11
AppPublisher=Vadim Lopatin
AppPublisherURL=https://github.com/buggins/dlangui
AppSupportURL=https://github.com/buggins/dlangui
AppUpdatesURL=https://github.com/buggins/dlangui
AppCopyright=Copyright (C) 2015-2018 Vadim Lopatin
LicenseFile=LICENSE.txt
SetupMutex=DLangIDESetupMutex
; Require at least Windows 7.
MinVersion=6.1
DefaultDirName={pf}\DlangIDE
DefaultGroupName=DLangIDE
Compression=lzma2/normal
ShowComponentSizes=yes
AllowNetworkDrive=no
ChangesEnvironment=yes
ChangesAssociations=yes
[Types]
Name: "dlangide"; Description: "Install DlangIDE."; Flags: iscustom
[Components]
Name: "dlangide"; Description: "DlangIDE and tools"; Types: dlangide; Flags: fixed
Name: "dmd"; Description: "DMD compiler"; Types: dlangide; Check: IsCompilerNeeded;
[Files]
Source: "bin\dlangide.exe"; DestDir: "{app}"; Components: dlangide
Source: "bin\libfreetype-6.dll"; DestDir: "{app}"; Components: dlangide
Source: "bin\mago-mi.exe"; DestDir: "{app}"; Components: dlangide
Source: "views\res\mdpi\dlangui-shortcut1.ico"; DestDir: "{app}"; Components: dlangide
[Registry]
; Associate .dlangidews files with DlangIDE.
Root: HKCR; Subkey: ".dlangidews"; ValueType: String; ValueName: ""; ValueData: "DlangIDEProjectFile"; Tasks: associate; Flags: uninsdeletevalue
Root: HKCR; Subkey: "DlangIDEProjectFile"; ValueType: String; ValueName: ""; ValueData: "DlangIDE Project File"; Tasks: associate; Flags: uninsdeletekey
Root: HKCR; Subkey: "DlangIDEProjectFile\DefaultIcon"; ValueType: String; ValueName: ""; ValueData: "{app}\dlangui-shortcut1.ico"; Tasks: associate; Flags: uninsdeletekey
Root: HKCR; Subkey: "DlangIDEProjectFile\shell\open\command"; ValueType: String; ValueName: ""; ValueData: """{app}\dlangide.exe"" ""%1"""; Tasks: associate; Flags: uninsdeletekey
[Icons]
Name: "{commondesktop}\DlangIDE"; Filename: "{app}\dlangide.exe"; IconFileName: "{app}\dlangui-shortcut1.ico"; Tasks: desktopicon
[Tasks]
Name: desktopicon; Description: "Create a &desktop icon"; Components: dlangide; Flags: checkedonce unchecked
Name: associate; Description: "Associate DlangIDE &Workspace Files"; Components: dlangide; Flags: checkedonce
[Run]
Filename: "{tmp}\dmd-installer.exe"; StatusMsg: "Installing DMD..."; Components: dmd; Flags: 32bit; BeforeInstall: DownloadDMD
[Code]
{
See if we have a registry key for D or if the default installation directory
exists.
}
function IsCompilerNeeded(): Boolean;
begin
Result := not (RegKeyExists(HKCU, 'Software\DMD')
or DirExists(ExpandConstant('{sd}\D\dmd2')))
end;
{ Windows API function to download files from the Internet. }
function URLDownloadToFile(
pCaller: Integer;
szUrl: String;
szFileName: String;
dwReserved: Integer;
lpfnCB: Integer
): Integer;
#ifdef UNICODE
external 'URLDownloadToFileW@urlmon.dll';
#else
external 'URLDownloadToFileA@urlmon.dll';
#endif
{
Convenience procedure to download files; this hides parameters we don't care
about.
We assume the download is successful; if this fails, a later attempt to read
the file will display an error to the user.
}
procedure DownloadFile(url: String; dest: String);
begin
URLDownloadToFile(0, url, ExpandConstant(dest), 0, 0);
end;
procedure DownloadDMD();
var
dmdVersion: AnsiString;
#ifdef UNICODE
dmdVersionU: String;
#else
dmdVersionU: AnsiString;
#endif
begin
DownloadFile('http://downloads.dlang.org/releases/LATEST', '{tmp}\latest.txt');
if LoadStringFromFile(ExpandConstant('{tmp}\latest.txt'), dmdVersion) then
begin
#ifdef UNICODE
dmdVersionU := String(dmdVersion);
#else
dmdVersionU := dmdVersion;
#endif
DownloadFile(
'http://downloads.dlang.org/releases/2.x/'
+ dmdVersionU
+ '/dmd-'
+ dmdVersionU
+ '.exe',
'{tmp}\dmd-installer.exe')
end
else
MsgBox(
'Unable to download dmd installer.'
+ ' Please download and install from dlang.org.',
mbInformation, MB_OK);
end;

View File

@ -71,9 +71,9 @@
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>DebugInfo DCD</debugids>
<debugids>DCD</debugids>
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources</versionids>
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
@ -111,7 +111,7 @@
<multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj>
<mscoff>0</mscoff>
<mscoff>1</mscoff>
<trace>0</trace>
<quiet>0</quiet>
<verbose>0</verbose>
@ -174,9 +174,9 @@
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>DebugInfo DCD</debugids>
<debugids />
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources</versionids>
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
@ -214,7 +214,7 @@
<multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj>
<mscoff>1</mscoff>
<mscoff>0</mscoff>
<trace>0</trace>
<quiet>0</quiet>
<verbose>0</verbose>
@ -277,9 +277,9 @@
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>DebugInfo DCD</debugids>
<debugids>DCD</debugids>
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources</versionids>
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
@ -317,7 +317,7 @@
<multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj>
<mscoff>0</mscoff>
<mscoff>1</mscoff>
<trace>0</trace>
<quiet>0</quiet>
<verbose>0</verbose>
@ -380,9 +380,9 @@
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>DebugInfo DCD</debugids>
<debugids />
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources</versionids>
<versionids>EmbedStandardResources NO_OPENGL USE_FREETYPE</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
@ -618,6 +618,212 @@
<postBuildCommand />
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
</Config>
<Config name="DSFMLDebug" platform="Win32">
<obj>0</obj>
<link>0</link>
<lib>0</lib>
<subsystem>2</subsystem>
<multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj>
<mscoff>0</mscoff>
<trace>1</trace>
<quiet>0</quiet>
<verbose>0</verbose>
<vtls>0</vtls>
<vgc>0</vgc>
<symdebug>1</symdebug>
<optimize>0</optimize>
<cpu>0</cpu>
<isX86_64>0</isX86_64>
<isLinux>0</isLinux>
<isOSX>0</isOSX>
<isWindows>0</isWindows>
<isFreeBSD>0</isFreeBSD>
<isSolaris>0</isSolaris>
<scheduler>0</scheduler>
<useDeprecated>1</useDeprecated>
<errDeprecated>0</errDeprecated>
<useAssert>0</useAssert>
<useInvariants>0</useInvariants>
<useIn>0</useIn>
<useOut>0</useOut>
<useArrayBounds>0</useArrayBounds>
<noboundscheck>0</noboundscheck>
<useSwitchError>0</useSwitchError>
<useUnitTests>0</useUnitTests>
<useInline>0</useInline>
<release>0</release>
<preservePaths>0</preservePaths>
<warnings>0</warnings>
<infowarnings>0</infowarnings>
<checkProperty>0</checkProperty>
<genStackFrame>0</genStackFrame>
<pic>0</pic>
<cov>0</cov>
<nofloat>0</nofloat>
<Dversion>2</Dversion>
<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
<allinst>0</allinst>
<stackStomp>0</stackStomp>
<compiler>0</compiler>
<otherDMD>0</otherDMD>
<cccmd>$(CC) -c</cccmd>
<ccTransOpt>1</ccTransOpt>
<addDepImp>0</addDepImp>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(ProjectDir)/../dlangui/src $(ProjectDir)/../dlangui/3rdparty $(ProjectDir)/../dlangui/deps/DerelictGL3/source $(ProjectDir)/../dlangui/deps/DerelictUtil/source $(ProjectDir)/../dlangui/deps/DerelictFT/source $(ProjectDir)/../dlangui/deps/DerelictSDL2/source $(ProjectDir)/../dlangui/deps/libdparse/src $(ProjectDir)/../DerelictLLDB/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
<libname />
<doDocComments>0</doDocComments>
<docdir />
<docname />
<modules_ddoc />
<ddocfiles />
<doHdrGeneration>0</doHdrGeneration>
<hdrdir />
<hdrname />
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>KeyInput DCD</debugids>
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
<defaultlibname />
<debuglibname />
<moduleDepsFile />
<run>0</run>
<runargs />
<runCv2pdb>1</runCv2pdb>
<pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
<cv2pdbPre2043>0</cv2pdbPre2043>
<cv2pdbNoDemangle>0</cv2pdbNoDemangle>
<cv2pdbEnumType>0</cv2pdbEnumType>
<cv2pdbOptions />
<objfiles />
<linkswitches />
<libfiles />
<libpaths />
<deffile />
<resfile />
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
<useStdLibPath>1</useStdLibPath>
<cRuntime>2</cRuntime>
<privatePhobos>0</privatePhobos>
<additionalOptions />
<preBuildCommand />
<postBuildCommand />
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
</Config>
<Config name="DSFMLDebug" platform="x64">
<obj>0</obj>
<link>0</link>
<lib>0</lib>
<subsystem>2</subsystem>
<multiobj>0</multiobj>
<singleFileCompilation>0</singleFileCompilation>
<oneobj>0</oneobj>
<mscoff>0</mscoff>
<trace>1</trace>
<quiet>0</quiet>
<verbose>0</verbose>
<vtls>0</vtls>
<vgc>0</vgc>
<symdebug>1</symdebug>
<optimize>0</optimize>
<cpu>0</cpu>
<isX86_64>1</isX86_64>
<isLinux>0</isLinux>
<isOSX>0</isOSX>
<isWindows>0</isWindows>
<isFreeBSD>0</isFreeBSD>
<isSolaris>0</isSolaris>
<scheduler>0</scheduler>
<useDeprecated>1</useDeprecated>
<errDeprecated>0</errDeprecated>
<useAssert>0</useAssert>
<useInvariants>0</useInvariants>
<useIn>0</useIn>
<useOut>0</useOut>
<useArrayBounds>0</useArrayBounds>
<noboundscheck>0</noboundscheck>
<useSwitchError>0</useSwitchError>
<useUnitTests>0</useUnitTests>
<useInline>0</useInline>
<release>0</release>
<preservePaths>0</preservePaths>
<warnings>0</warnings>
<infowarnings>0</infowarnings>
<checkProperty>0</checkProperty>
<genStackFrame>0</genStackFrame>
<pic>0</pic>
<cov>0</cov>
<nofloat>0</nofloat>
<Dversion>2</Dversion>
<ignoreUnsupportedPragmas>0</ignoreUnsupportedPragmas>
<allinst>0</allinst>
<stackStomp>0</stackStomp>
<compiler>0</compiler>
<otherDMD>0</otherDMD>
<cccmd>$(CC) -c -v</cccmd>
<ccTransOpt>1</ccTransOpt>
<addDepImp>0</addDepImp>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(ProjectDir)/../dlangui/src $(ProjectDir)/../dlangui/3rdparty $(ProjectDir)/../dlangui/deps/DerelictGL3/source $(ProjectDir)/../dlangui/deps/DerelictUtil/source $(ProjectDir)/../dlangui/deps/DerelictFT/source $(ProjectDir)/../dlangui/deps/DerelictSDL2/source $(ProjectDir)/../dlangui/deps/libdparse/src $(ProjectDir)/../DerelictLLDB/source</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
<libname />
<doDocComments>0</doDocComments>
<docdir />
<docname />
<modules_ddoc />
<ddocfiles />
<doHdrGeneration>0</doHdrGeneration>
<hdrdir />
<hdrname />
<doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel>
<debugids>KeyInput DCD</debugids>
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources USE_FREETYPE NO_OPENGL</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
<defaultlibname />
<debuglibname />
<moduleDepsFile />
<run>0</run>
<runargs />
<runCv2pdb>1</runCv2pdb>
<pathCv2pdb>$(VisualDInstallDir)cv2pdb\cv2pdb.exe</pathCv2pdb>
<cv2pdbPre2043>0</cv2pdbPre2043>
<cv2pdbNoDemangle>0</cv2pdbNoDemangle>
<cv2pdbEnumType>0</cv2pdbEnumType>
<cv2pdbOptions />
<objfiles />
<linkswitches />
<libfiles />
<libpaths />
<deffile />
<resfile />
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
<useStdLibPath>1</useStdLibPath>
<cRuntime>2</cRuntime>
<privatePhobos>1</privatePhobos>
<additionalOptions />
<preBuildCommand />
<postBuildCommand />
<filesToClean>*.obj;*.cmd;*.build;*.json;*.dep</filesToClean>
</Config>
<Folder name="dlangide">
<Folder name="3rdparty">
<Folder name="containers">
@ -718,6 +924,7 @@
<Folder name="d">
<File path="src\dlangide\tools\d\dcdinterface.d" />
<File path="src\dlangide\tools\d\deditortool.d" />
<File path="src\dlangide\tools\d\dmdtrace.d" />
<File path="src\dlangide\tools\d\dparser.d" />
<File path="src\dlangide\tools\d\dsyntax.d" />
</Folder>
@ -726,10 +933,12 @@
<Folder name="ui">
<File path="src\dlangide\ui\commands.d" />
<File path="src\dlangide\ui\debuggerui.d" />
<File path="src\dlangide\ui\dmdprofilerview.d" />
<File path="src\dlangide\ui\dsourceedit.d" />
<File path="src\dlangide\ui\frame.d" />
<File path="src\dlangide\ui\homescreen.d" />
<File path="src\dlangide\ui\newfile.d" />
<File path="src\dlangide\ui\newfolder.d" />
<File path="src\dlangide\ui\newproject.d" />
<File path="src\dlangide\ui\outputpanel.d" />
<File path="src\dlangide\ui\searchPanel.d" />

View File

@ -12,9 +12,8 @@
"stringImportPaths": ["views"],
"dependencies": {
"dlangui": "==0.9.150",
"dsymbol": "~>0.2.9",
"dcd": "~>0.9.1"
"dlangui": "~>0.10.3",
"dcd": "~>0.16.0-beta.1"
},
"copyFiles-windows": [
@ -23,22 +22,26 @@
"libs-linux": ["z"],
"versions-windows": [
"USE_FREETYPE"
],
"configurations" : [
{
"name" : "default"
},
},
{
"name" : "minimal",
"subConfigurations" : {
"dlangui" : "minimal"
}
},
},
{
"name" : "console",
"subConfigurations" : {
"dlangui" : "console"
}
},
},
{
"name" : "x11",
"subConfigurations" : {

View File

@ -69,7 +69,7 @@ class BasicTypeX : Lexem {
in {
assert(isBasicTypeXToken(token));
}
body {
do {
_token = token;
}
}
@ -97,7 +97,7 @@ class TypeCtor : Lexem {
in {
assert(isTypeCtorToken(token));
}
body {
do {
_token = token;
}
}
@ -112,14 +112,14 @@ class TypeCtors : Lexem {
in {
assert(isTypeCtorToken(token));
}
body {
do {
_list ~= new TypeCtor(token);
}
public void append(Token token)
in {
assert(isTypeCtorToken(token));
}
body {
do {
_list ~= new TypeCtor(token);
}
}
@ -134,7 +134,7 @@ class Identifier : Lexem {
in {
assert(identifier.type == TokenType.IDENTIFIER);
}
body {
do {
_token = cast(IdentToken)identifier;
}
}
@ -157,14 +157,14 @@ class IdentifierList : Lexem {
in {
assert(ident.type == TokenType.IDENTIFIER);
}
body {
do {
_identifier = new Identifier(ident);
_identifierList = identifierList;
}
public this(TemplateInstance templateInstance, IdentifierList identifierList = null)
in {
}
body {
do {
_templateInstance = templateInstance;
_identifierList = identifierList;
}
@ -181,7 +181,7 @@ class TemplateInstance : Lexem {
public this()
in {
}
body {
do {
}
}
@ -207,7 +207,7 @@ class BasicType : Lexem {
public this()
in {
}
body {
do {
}
}
@ -228,7 +228,7 @@ class Typeof : Lexem {
public this(Expression expression)
in {
}
body {
do {
_expression = expression;
}
}
@ -245,7 +245,7 @@ class Type : Lexem {
public this()
in {
}
body {
do {
}
}
@ -259,7 +259,7 @@ class Expression : Lexem {
public this()
in {
}
body {
do {
}
}
@ -273,7 +273,7 @@ class AltDeclarator : Lexem {
public this()
in {
}
body {
do {
}
}

View File

@ -6,30 +6,48 @@ import std.conv;
import dlangide.ui.frame;
import dlangide.ui.commands;
import dlangide.workspace.workspace;
import std.experimental.logger;
static if(__VERSION__ > 2100)
{
import std.logger;
}
else
{
import std.experimental.logger;
}
mixin APP_ENTRY_POINT;
/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
//debug(TestDMDTraceParser) {
// import dlangide.tools.d.dmdtrace;
// long start = currentTimeMillis;
// DMDTraceLogParser parser = parseDMDTraceLog("trace.log");
// if (parser) {
// Log.d("trace.log is parsed ok in ", currentTimeMillis - start, " seconds");
// }
//}
debug(TestParser) {
import ddc.lexer.parser;
runParserTests();
}
version(Windows) {
static if(__VERSION__ > 2100) {
debug {
sharedLog = cast(shared)new FileLogger("dcd.log");
} else {
sharedLog = cast(shared)new NullLogger();
}
}
else
{
debug {
sharedLog = new FileLogger("dcd.log");
} else {
sharedLog = new NullLogger();
}
} else {
debug {
//sharedLog = new FileLogger("dcd.log");
} else {
sharedLog = new NullLogger();
}
}
//version (Windows) {
@ -50,7 +68,12 @@ extern (C) int UIAppMain(string[] args) {
// you can override antialiasing setting here
FontManager.minAnitialiasedFontSize = 0;
/// set font gamma (1.0 is neutral, < 1.0 makes glyphs lighter, >1.0 makes glyphs bolder)
FontManager.fontGamma = 0.8;
FontManager.fontGamma = 1.0;
version (NO_OPENGL) {
FontManager.subpixelRenderingMode = SubpixelRenderingMode.BGR;
} else {
FontManager.subpixelRenderingMode = SubpixelRenderingMode.None;
}
version (USE_OPENGL) {
// you can turn on subpixel font rendering (ClearType) here
FontManager.subpixelRenderingMode = SubpixelRenderingMode.None; //
@ -81,12 +104,12 @@ extern (C) int UIAppMain(string[] args) {
// set window icon
window.windowIcon = drawableCache.getImage("dlangui-logo1");
}
//Widget w = new Widget();
//pragma(msg, w.click.return_t, "", w.click.params_t);
IDEFrame frame = new IDEFrame(window);
// Open project, if it specified in command line
if (args.length > 1)
{

View File

@ -15,15 +15,10 @@ import std.experimental.allocator;
import std.experimental.allocator.mallocator;
import std.experimental.allocator.gc_allocator;
import server.autocomplete;
import common.messages;
import dcd.server.autocomplete;
import dcd.common.messages;
import dsymbol.modulecache;
//alias SharedASTAllocator = CAllocatorImpl!(Mallocator);
//alias SharedASTAllocator = CAllocatorImpl!(Mallocator);
//alias SharedASTAllocator = CSharedAllocatorImpl!(Mallocator);
alias SharedASTAllocator = ASTAllocator;
enum DCDResult : int {
SUCCESS,
NO_RESULT,
@ -92,11 +87,9 @@ class DCDTask {
}
class ModuleCacheAccessor {
import dsymbol.modulecache;
//protected ASTAllocator _astAllocator;
protected ModuleCache _moduleCache;
this(in string[] importPaths) {
_moduleCache = ModuleCache(new SharedASTAllocator);
_moduleCache = ModuleCache();
_moduleCache.addImportPaths(importPaths);
}
protected ModuleCache * getModuleCache(in string[] importPaths) {
@ -109,8 +102,6 @@ class ModuleCacheAccessor {
class DCDInterface : Thread {
import dsymbol.modulecache;
//protected ASTAllocator _astAllocator;
//protected ModuleCache * _moduleCache;
ModuleCacheAccessor _moduleCache;
protected BlockingQueue!DCDTask _queue;
@ -238,7 +229,7 @@ class DCDInterface : Thread {
override void performRequest() {
AutocompleteResponse response = getDoc(request, *getModuleCache(_importPaths));
result.docComments = response.docComments.dup;
//result.docComments = response.docComments.dup; TODO_GRIM: Fix
result.result = DCDResult.SUCCESS;
debug(DCD) Log.d("DCD doc comments:\n", result.docComments);
@ -318,11 +309,9 @@ class DCDInterface : Thread {
result.output.length = response.completions.length;
int i=0;
foreach(s;response.completions) {
char type = 0;
if (i < response.completionKinds.length)
type = response.completionKinds[i];
char type = s.kind;
result.output[i].kind = type;
result.output[i].name = to!dstring(s);
result.output[i].name = to!dstring(s.identifier);
i++;
}
if (response.completionType == "calltips") {
@ -364,6 +353,7 @@ int completionTypePriority(char t) {
return 3;
case 'k': // - keyword, built-in version, scope statement
return 20;
case 'F':
case 'f': // - function or method
return 2;
case 'g': // - enum name

View File

@ -117,6 +117,7 @@ class DEditorTool : EditorTool
auto destPos = byteOffsetToCaret(content, target);
_frame.currentEditor.setCaretPos(destPos.line,destPos.pos, true, true);
_frame.currentEditor.setFocus();
_frame.caretHistory.pushNewPosition();
break;
default:
break;

View File

@ -0,0 +1,415 @@
/// DMD trace.log parser
module dlangide.tools.d.dmdtrace;
/*
Based on d-profile-viewer: https://bitbucket.org/andrewtrotman/d-profile-viewer
Copyright (c) 2015-2016 eBay Software Foundation
Written by Andrew Trotman
Licensed under the 3-clause BSD license (see here:https://en.wikipedia.org/wiki/BSD_licenses)
*/
import dlangui.core.logger;
//import core.stdc.stdlib;
import std.file;
import std.stdio;
import std.string;
//import dlangide.tools.d.demangle;
import core.runtime;
import std.conv;
import std.algorithm;
import std.exception;
//import std.demangle;
import dlangide.ui.outputpanel;
import dlangide.builders.extprocess;
import dlangui.widgets.appframe;
import core.thread;
enum TraceSortOrder {
BY_FUNCTION_TIME,
BY_TOTAL_TIME,
BY_CALL_COUNT,
BY_NAME,
}
void sortFunctionNodes(FunctionNode[] nodes, TraceSortOrder sortOrder) {
import std.algorithm.sorting : sort;
final switch(sortOrder) {
case TraceSortOrder.BY_FUNCTION_TIME:
sort!((a,b) => a.function_time > b.function_time)(nodes);
break;
case TraceSortOrder.BY_TOTAL_TIME:
sort!((a,b) => a.function_and_descendant_time > b.function_and_descendant_time)(nodes);
break;
case TraceSortOrder.BY_CALL_COUNT:
sort!((a,b) => a.number_of_calls > b.number_of_calls)(nodes);
break;
case TraceSortOrder.BY_NAME:
sort!((a,b) => a.name < b.name)(nodes);
break;
}
}
class DMDTraceLogParser {
private string filename;
private string content;
private string[] lines;
private bool _cancelRequested;
FunctionNode[string] nodes;
FunctionNode[] nodesByFunctionTime;
FunctionNode[] nodesByTotalTime;
FunctionNode[] nodesByCallCount;
FunctionNode[] nodesByName;
//FunctionEdge[string] caller_graph;
//FunctionEdge[string] called_graph;
ulong ticks_per_second;
this(string fname) {
filename = fname;
}
void requestCancel() {
_cancelRequested = true;
}
private void splitLines(void[] buffer) {
lines.assumeSafeAppend;
content = cast(string)buffer;
int lineStart = 0;
for (int i = 0; i < content.length; i++) {
char ch = content.ptr[i];
if (ch == '\r' || ch == '\n') {
if (lineStart < i) {
lines ~= content[lineStart .. i];
}
lineStart = i + 1;
}
}
// append last line if any
if (lineStart < content.length)
lines ~= content[lineStart .. $];
}
bool load() {
void[] file;
try
{
file = read(filename);
}
catch (Exception ex)
{
Log.e("Cannot open trace file ", filename);
return false;
}
if (file.length == 0) {
Log.e("Trace log ", filename, " is empty");
return false;
}
Log.d("Opened file ", filename, " ", file.length, " bytes");
splitLines(file);
Log.d("Lines: ", lines.length);
return lines.length > 0;
}
bool parse() {
bool caller = true;
string function_name;
FunctionEdge[string] caller_graph;
FunctionEdge[string] called_graph;
ulong function_times;
ulong function_and_descendant;
ulong function_only;
foreach(i, line; lines) {
if (_cancelRequested)
return false;
if (line.length == 0) {
continue; // Ignore blank lines
} else if (line[0] == '=') { // Seperator between call graph and summary data
auto number = indexOfAny(line, "1234567890");
if (number < 0)
{
Log.e("Corrupt trace.log (can't compute ticks per second), please re-profile and try again");
return false;
}
auto space = indexOf(line[number .. $], ' ') + number;
ticks_per_second = to!ulong(line[number .. space]);
break;
} else if (line[0] == '-') { //Seperator between each function call graph
caller = true;
if (function_name.length != 0)
nodes[text(function_name)] = new FunctionNode(function_name,
function_times, function_and_descendant, function_only,
caller_graph, called_graph);
caller_graph = null;
called_graph = null;
} else if (line[0] == '\t')
{
// A function either calling or called by this function
/*
We can't assume a name starts with an '_' because it might be an extern "C" which hasn't been mangled.
We also can't assume the character encodin of what ever language that is so we look for the last tab
and asusme the identifier starts on the next character.
*/
// auto pos = indexOfAny(line, "_");
auto pos = lastIndexOf(line, '\t') + 1;
auto start_pos = indexOfAny(line, "1234567890");
if (start_pos < 0 || pos < 0 || pos < start_pos)
{
Log.e("Corrupt trace.log (call count is non-numeric), please re-profile and try again");
return false;
}
immutable times = to!ulong(line[start_pos .. pos - 1]);
auto name = line[pos .. $];
if (caller)
{
caller_graph[text(name)] = new FunctionEdge(name, times);
}
else
{
called_graph[text(name)] = new FunctionEdge(name, times);
}
}
/*
In the case of a call to a non-D function, the identifier might not start with an '_' (e.g. extern "C"). But, we can't know
how those identifiers are stored so we can't assume an encoding - and hence we must assume that what ever we have is correct.
*/
// else if (indexOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", line[0]) >= 0) //The name of the function were're currently examining the call graph for (seperates callers from called)
else //The name of the function were're currently examining the call graph for (seperates callers from called)
{
auto start_tab = indexOf(line, '\t');
auto middle_tab = indexOf(line[start_tab + 1 .. $], '\t') + start_tab + 1;
auto last_tab = indexOf(line[middle_tab + 1 .. $], '\t') + middle_tab + 1;
function_name = line[0 .. start_tab];
//if (function_name.length > 1024)
// Log.d("long function name: ", function_name);
function_times = to!ulong(line[start_tab + 1 .. middle_tab]);
function_and_descendant = to!ulong(line[middle_tab + 1 .. last_tab]);
function_only = to!ulong(line[last_tab + 1 .. $]);
caller = false;
}
}
if (function_name.length != 0)
{
nodes[text(function_name)] = new FunctionNode(function_name,
function_times, function_and_descendant, function_only, caller_graph, called_graph);
}
makeSorted();
return true;
}
void makeSorted() {
nodesByFunctionTime.reserve(nodes.length);
foreach(key, value; nodes) {
nodesByFunctionTime ~= value;
}
nodesByTotalTime = nodesByFunctionTime.dup;
nodesByCallCount = nodesByFunctionTime.dup;
nodesByName = nodesByFunctionTime.dup;
sortFunctionNodes(nodesByFunctionTime, TraceSortOrder.BY_FUNCTION_TIME);
sortFunctionNodes(nodesByTotalTime, TraceSortOrder.BY_TOTAL_TIME);
sortFunctionNodes(nodesByCallCount, TraceSortOrder.BY_CALL_COUNT);
sortFunctionNodes(nodesByName, TraceSortOrder.BY_NAME);
}
}
private __gshared static char[] demangleBuffer;
private string demangle(string mangled_name) {
import core.demangle : demangle;
//const (char) [] demangled_name;
string demangled_name; // = dlangide.tools.d.demangle.demangle(mangled_name);
//if (demangled_name[0] == '_') { // in the unlikely event that we fail to demangle, fall back to the phobos demangler
try {
static import core.demangle;
if (demangleBuffer.length < mangled_name.length + 16384)
demangleBuffer.length = mangled_name.length * 2 + 16384;
demangled_name = cast(string)core.demangle.demangle(mangled_name, demangleBuffer[]);
} catch (Exception e) {
demangled_name = mangled_name;
}
//}
if (demangled_name.length > 1024)
return demangled_name[0..1024] ~ "...";
return demangled_name.dup;
}
/*
CLASS FUNCTION_EDGE
-------------------
There's one of these objects for each function in program being profiled.
*/
class FunctionEdge
{
public:
string name; // the demangled name of the function
string mangled_name; // the mangled name
ulong calls; // number of times the function is called
public:
/*
THIS()
------
Constructor
*/
this(string mangled_name, ulong calls)
{
this.mangled_name = mangled_name;
this.name = demangle(mangled_name);
this.calls = calls;
}
}
/*
CLASS FUNCTION_NODE
-------------------
*/
class FunctionNode
{
public:
FunctionEdge[string] called_by;
FunctionEdge[string] calls_to;
string name;
string mangled_name;
ulong number_of_calls;
ulong function_and_descendant_time; // in cycles
ulong function_time; // in cycles
private:
/*
PERCENT()
---------
Compute top/bottom to 2 decimal places
*/
double percent(double top, double bottom)
{
return cast(double)(cast(size_t)((top / bottom * 100_00.0))) / 100.0;
}
/*
TO_US()
-------
Convert from ticks to micro-seconds
*/
size_t to_us(double ticks, double ticks_per_second)
{
return cast(size_t)(ticks / ticks_per_second * 1000 * 1000);
}
public:
/*
THIS()
------
*/
this(string mangled_name, ulong calls, ulong function_and_descendant_time,
ulong function_time, FunctionEdge[string] called_by, FunctionEdge[string] calls_to)
{
this.mangled_name = mangled_name;
this.name = demangle(mangled_name);
this.number_of_calls = calls;
this.function_and_descendant_time = function_and_descendant_time;
this.function_time = function_time;
this.called_by = called_by;
this.calls_to = calls_to;
}
}
DMDTraceLogParser parseDMDTraceLog(string filename) {
scope(exit) demangleBuffer = null;
DMDTraceLogParser parser = new DMDTraceLogParser(filename);
if (!parser.load())
return null;
if (!parser.parse())
return null;
return parser;
}
class DMDProfilerLogParserThread : Thread {
private DMDTraceLogParser _parser;
private bool _finished;
private bool _success;
this(string filename) {
super(&run);
_parser = new DMDTraceLogParser(filename);
}
@property bool finished() { return _finished; }
@property DMDTraceLogParser parser() { return _success ? _parser : null; }
void requestCancel() {
_parser.requestCancel();
}
void run() {
scope(exit) demangleBuffer = null;
if (!_parser.load()) {
_finished = true;
return;
}
if (!_parser.parse()) {
_finished = true;
return;
}
_success = true;
_finished = true;
// Done
}
}
alias DMDProfilerLogParserListener = void delegate(DMDTraceLogParser parser);
class DMDProfilerLogParserOperation : BackgroundOperationWatcher {
string _filename;
DMDProfilerLogParserListener _listener;
dstring _description;
DMDProfilerLogParserThread _thread;
DMDTraceLogParser _result;
this(AppFrame frame, string filename, OutputPanel log, DMDProfilerLogParserListener listener) {
super(frame);
_filename = filename;
_listener = listener;
_description = "Parsing DMD trace log file"d;
_thread = new DMDProfilerLogParserThread(filename);
_thread.start();
}
/// returns description of background operation to show in status line
override @property dstring description() { return _description; }
/// returns icon of background operation to show in status line
override @property string icon() { return "folder"; }
/// update background operation status
override void update() {
if (_finished) {
return;
}
if (_thread.finished) {
_thread.join();
_result = _thread.parser;
//_extprocess.kill();
//_extprocess.wait();
_finished = true;
return;
}
if (_cancelRequested) {
_thread.requestCancel();
_thread.join();
_result = _thread.parser;
//_extprocess.kill();
//_extprocess.wait();
_finished = true;
return;
}
super.update();
}
override void removing() {
super.removing();
//if (_exitCode != int.min && _listener)
_listener(_result);
}
}

View File

@ -6,6 +6,7 @@ import dlangui.widgets.editors;
enum IDEActions : int {
//ProjectOpen = 1010000,
FileNew = 1010000,
FileNewDirectory,
FileNewWorkspace,
FileNewProject,
FileOpen,
@ -71,6 +72,8 @@ enum IDEActions : int {
GetDocComments,
GetParenCompletion,
GotoLine,
GotoNextPosition,
GotoPrevPosition,
InsertCompletion,
FindInFiles,
@ -80,6 +83,8 @@ enum IDEActions : int {
ViewToggleTabPositionMarks,
ViewToggleToolbar,
ViewToggleStatusbar,
ToolsOpenDMDTraceLog,
}
__gshared static this() {
@ -98,6 +103,7 @@ const Action ACTION_PROJECT_FOLDER_COLLAPSE_ALL = new Action(IDEActions.ProjectF
const Action ACTION_FILE_WORKSPACE_CLOSE = new Action(IDEActions.CloseWorkspace, "MENU_FILE_WORKSPACE_CLOSE"c).disableByDefault();
const Action ACTION_FILE_NEW_DIRECTORY = new Action(IDEActions.FileNewDirectory, "MENU_FILE_NEW_DIRECTORY"c);
const Action ACTION_FILE_NEW_SOURCE_FILE = new Action(IDEActions.FileNew, "MENU_FILE_NEW_SOURCE_FILE"c, "document-new", KeyCode.KEY_N, KeyFlag.Control);
const Action ACTION_FILE_NEW_PROJECT = new Action(IDEActions.FileNewProject, "MENU_FILE_NEW_PROJECT"c);
const Action ACTION_FILE_NEW_WORKSPACE = new Action(IDEActions.FileNewWorkspace, "MENU_FILE_NEW_WORKSPACE"c);
@ -172,9 +178,13 @@ const Action ACTION_GET_DOC_COMMENTS = (new Action(IDEActions.GetDocComments, "
const Action ACTION_GO_TO_DEFINITION = (new Action(IDEActions.GoToDefinition, "GO_TO_DEFINITION"c, ""c, KeyCode.KEY_G, KeyFlag.Control)).addAccelerator(KeyCode.F12, 0).disableByDefault();
const Action ACTION_GET_COMPLETIONS = (new Action(IDEActions.GetCompletionSuggestions, "SHOW_COMPLETIONS"c, ""c, KeyCode.KEY_G, KeyFlag.Control|KeyFlag.Shift)).addAccelerator(KeyCode.SPACE, KeyFlag.Control).disableByDefault();
const Action ACTION_GET_PAREN_COMPLETION = (new Action(IDEActions.GetParenCompletion, "SHOW_PAREN_COMPLETION"c, ""c, KeyCode.SPACE, KeyFlag.Control|KeyFlag.Shift)).disableByDefault();
const Action ACTION_GO_TO_LINE = (new Action(IDEActions.GotoLine, "GO_TO_LINE"c, ""c, KeyCode.KEY_L, KeyFlag.Control|KeyFlag.Option)).disableByDefault();;
const Action ACTION_GO_TO_LINE = (new Action(IDEActions.GotoLine, "GO_TO_LINE"c, ""c, KeyCode.KEY_L, KeyFlag.Control|KeyFlag.Option)).disableByDefault();
const Action ACTION_GO_TO_PREV_POSITION = (new Action(IDEActions.GotoPrevPosition, "GO_TO_PREV_POSITION"c, ""c, KeyCode.LEFT, KeyFlag.Alt)).disableByDefault();
const Action ACTION_GO_TO_NEXT_POSITION = (new Action(IDEActions.GotoNextPosition, "GO_TO_NEXT_POSITION"c, ""c, KeyCode.RIGHT, KeyFlag.Alt)).disableByDefault();
const Action ACTION_FIND_TEXT = (new Action(IDEActions.FindInFiles, "FIND_IN_FILES"c, "edit-find"c, KeyCode.KEY_F, KeyFlag.Control | KeyFlag.Shift)).disableByDefault();
const Action ACTION_TOOLS_OPEN_DMD_TRACE_LOG = (new Action(IDEActions.ToolsOpenDMDTraceLog, "OPEN_DMD_TRACE_LOG"c));
const Action[] STD_IDE_ACTIONS = [
ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT,
@ -198,5 +208,7 @@ const Action[] STD_IDE_ACTIONS = [
ACTION_GET_COMPLETIONS,
ACTION_GET_PAREN_COMPLETION,
ACTION_GO_TO_LINE,
ACTION_GO_TO_PREV_POSITION,
ACTION_GO_TO_NEXT_POSITION,
ACTION_FIND_TEXT,
];

View File

@ -0,0 +1,301 @@
module dlangide.ui.dmdprofilerview;
import dlangui.widgets.layouts;
import dlangui.widgets.widget;
import dlangui.widgets.grid;
import dlangui.widgets.scroll;
import dlangui.widgets.controls;
import dlangide.ui.frame;
import dlangide.ui.commands;
import dlangui.core.i18n;
import dlangide.tools.d.dmdtrace;
class DMDProfilerView : WidgetGroupDefaultDrawing {
protected IDEFrame _frame;
protected DMDTraceLogParser _data;
protected TraceFunctionList _fullFunctionList;
this(string ID, IDEFrame frame, DMDTraceLogParser data) {
super(ID);
_frame = frame;
_data = data;
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
_fullFunctionList = new TraceFunctionList("FULL_FUNCTION_LIST", "All functions"d, _data.nodesByTotalTime, _data.ticks_per_second); // new TextWidget(null, "DMD profiler view"d);
addChild(_fullFunctionList);
}
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
override void layout(Rect rc) {
super.layout(rc);
applyMargins(rc);
applyPadding(rc);
Rect rc1 = rc;
rc1.right = rc1.left + rc.width / 2;
_fullFunctionList.layout(rc1);
}
/**
Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
*/
override void measure(int parentWidth, int parentHeight) {
_fullFunctionList.measure(parentWidth, parentHeight);
measuredContent(parentWidth, parentHeight, _fullFunctionList.measuredWidth, _fullFunctionList.measuredHeight);
}
}
class TraceFuncionGrid : StringGridWidgetBase {
protected FunctionNode[] _list;
protected UIString[] _colTitles;
protected ulong _ticksPerSecond;
this(string ID, FunctionNode[] list, ulong ticks_per_second) {
super(ID);
_ticksPerSecond = ticks_per_second;
_list = list;
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
fullColumnOnLeft(false);
fullRowOnTop(false);
resize(4, cast(int)list.length);
setColTitle(0, UIString.fromRaw("Function name"));
setColTitle(1, UIString.fromRaw("Called"));
setColTitle(2, UIString.fromRaw("F us"));
setColTitle(3, UIString.fromRaw("F+D us"));
showRowHeaders = false;
rowSelect = true;
minVisibleRows = 10;
minVisibleCols = 4;
}
private dchar[128] _numberFormatBuf;
dstring formatNumber(ulong v, dchar[] buffer) {
dchar[64] buf;
int k = 0;
if (!v) {
buf[k++] = '0';
} else {
while (v) {
buf[k++] = '0' + (cast(int)(v % 10));
v /= 10;
}
}
// reverse order
for (int i = 0; i < k; i++)
buffer[i] = buf[k - i - 1];
return cast(dstring)buffer[0..k];
}
auto formatDurationTicks(ulong n) {
ulong v = n * 1000000 / _ticksPerSecond;
return UIString.fromRaw(formatNumber(v, _numberFormatBuf[]));
}
/// get cell text
override UIString cellText(int col, int row) {
import std.conv : to;
if (row < 0 || row >= _list.length)
return UIString.fromRaw(""d);
FunctionNode entry = _list[row];
switch (col) {
case 0:
string fn = entry.name;
if (fn.length > 256)
fn = fn[0..256] ~ "...";
return UIString.fromRaw(fn.to!dstring);
case 1:
return UIString.fromRaw(formatNumber(entry.number_of_calls, _numberFormatBuf));
case 2:
return formatDurationTicks(entry.function_time);
case 3:
return formatDurationTicks(entry.function_and_descendant_time);
default:
return UIString.fromRaw(""d);
}
}
/// set cell text
override StringGridWidgetBase setCellText(int col, int row, UIString text) {
// do nothing
return this;
}
/// returns row header title
override UIString rowTitle(int row) {
return UIString.fromRaw(""d);
}
/// set row header title
override StringGridWidgetBase setRowTitle(int row, UIString title) {
return this;
}
/// returns row header title
override UIString colTitle(int col) {
return _colTitles[col];
}
/// set col header title
override StringGridWidgetBase setColTitle(int col, UIString title) {
_colTitles[col] = title;
return this;
}
void autofit() {
autoFitColumnWidths();
fillColumnWidth(0);
}
/// set new size
override void resize(int c, int r) {
if (c == cols && r == rows)
return;
int oldcols = cols;
int oldrows = rows;
super.resize(c, r);
_colTitles.length = c;
}
protected override Point measureCell(int x, int y) {
if (_customCellAdapter && _customCellAdapter.isCustomCell(x, y)) {
return _customCellAdapter.measureCell(x, y);
}
//Log.d("measureCell ", x, ", ", y);
FontRef fnt = font;
dstring txt;
if (x >= 0 && y >= 0)
txt = cellText(x, y);
else if (y < 0 && x >= 0)
txt = colTitle(x);
else if (y >= 0 && x < 0)
txt = rowTitle(y);
Point sz = fnt.textSize(txt);
if (sz.y < fnt.height)
sz.y = fnt.height;
return sz;
}
/// draw cell content
protected override void drawCell(DrawBuf buf, Rect rc, int col, int row) {
if (_customCellAdapter && _customCellAdapter.isCustomCell(col, row)) {
return _customCellAdapter.drawCell(buf, rc, col, row);
}
if (BACKEND_GUI)
rc.shrink(2, 1);
else
rc.right--;
FontRef fnt = font;
dstring txt = cellText(col, row);
Point sz = fnt.textSize(txt);
Align ha = Align.Right;
//if (sz.y < rc.height)
applyAlign(rc, sz, ha, Align.VCenter);
int offset = BACKEND_CONSOLE ? 0 : 1;
fnt.drawText(buf, rc.left + offset, rc.top + offset, txt, textColor);
}
/// draw cell content
protected override void drawHeaderCell(DrawBuf buf, Rect rc, int col, int row) {
if (BACKEND_GUI)
rc.shrink(2, 1);
else
rc.right--;
FontRef fnt = font;
dstring txt;
if (row < 0 && col >= 0)
txt = colTitle(col);
else if (row >= 0 && col < 0)
txt = rowTitle(row);
if (!txt.length)
return;
Point sz = fnt.textSize(txt);
Align ha = Align.Left;
if (col < 0)
ha = Align.Right;
//if (row < 0)
// ha = Align.HCenter;
applyAlign(rc, sz, ha, Align.VCenter);
int offset = BACKEND_CONSOLE ? 0 : 1;
uint cl = textColor;
cl = style.customColor("grid_cell_text_color_header", cl);
fnt.drawText(buf, rc.left + offset, rc.top + offset, txt, cl);
}
/// draw cell background
protected override void drawHeaderCellBackground(DrawBuf buf, Rect rc, int c, int r) {
bool selectedCol = (c == col) && !_rowSelect;
bool selectedRow = r == row;
bool selectedCell = selectedCol && selectedRow;
if (_rowSelect && selectedRow)
selectedCell = true;
if (!selectedCell && _multiSelect) {
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
}
// draw header cell background
DrawableRef dw = c < 0 ? _cellRowHeaderBackgroundDrawable : _cellHeaderBackgroundDrawable;
uint cl = _cellHeaderBackgroundColor;
if (c >= 0 || r >= 0) {
if (c < 0 && selectedRow) {
cl = _cellHeaderSelectedBackgroundColor;
dw = _cellRowHeaderSelectedBackgroundDrawable;
} else if (r < 0 && selectedCol) {
cl = _cellHeaderSelectedBackgroundColor;
dw = _cellHeaderSelectedBackgroundDrawable;
}
}
if (!dw.isNull)
dw.drawTo(buf, rc);
else
buf.fillRect(rc, cl);
static if (BACKEND_GUI) {
uint borderColor = _cellHeaderBorderColor;
buf.drawLine(Point(rc.right - 1, rc.bottom), Point(rc.right - 1, rc.top), _cellHeaderBorderColor); // vertical
buf.drawLine(Point(rc.left, rc.bottom - 1), Point(rc.right - 1, rc.bottom - 1), _cellHeaderBorderColor); // horizontal
}
}
/// draw cell background
protected override void drawCellBackground(DrawBuf buf, Rect rc, int c, int r) {
bool selectedCol = c == col;
bool selectedRow = r == row;
bool selectedCell = selectedCol && selectedRow;
if (_rowSelect && selectedRow)
selectedCell = true;
if (!selectedCell && _multiSelect) {
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
}
uint borderColor = _cellBorderColor;
if (c < fixedCols || r < fixedRows) {
// fixed cell background
buf.fillRect(rc, _fixedCellBackgroundColor);
borderColor = _fixedCellBorderColor;
}
static if (BACKEND_GUI) {
buf.drawLine(Point(rc.left, rc.bottom + 1), Point(rc.left, rc.top), borderColor); // vertical
buf.drawLine(Point(rc.left, rc.bottom - 1), Point(rc.right - 1, rc.bottom - 1), borderColor); // horizontal
}
if (selectedCell) {
static if (BACKEND_GUI) {
if (_rowSelect)
buf.drawFrame(rc, _selectionColorRowSelect, Rect(0,1,0,1), _cellBorderColor);
else
buf.drawFrame(rc, _selectionColor, Rect(1,1,1,1), _cellBorderColor);
} else {
if (_rowSelect)
buf.fillRect(rc, _selectionColorRowSelect);
else
buf.fillRect(rc, _selectionColor);
}
}
}
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
override void layout(Rect rc) {
super.layout(rc);
autofit();
}
}
class TraceFunctionList : VerticalLayout {
TraceFuncionGrid _grid;
this(string ID, dstring title, FunctionNode[] list, ulong ticks_per_second) {
super(ID);
addChild(new TextWidget("gridTitle", title).layoutWidth(FILL_PARENT));
_grid = new TraceFuncionGrid("FUNCTION_LIST", list, ticks_per_second);
addChild(_grid);
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
}
}

View File

@ -49,7 +49,7 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
onThemeChanged();
//setTokenHightlightColor(TokenCategory.Identifier, 0x206000); // no colors
MenuItem editPopupItem = new MenuItem(null);
editPopupItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_EDIT_UNDO,
editPopupItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_EDIT_UNDO,
ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT, ACTION_EDIT_TOGGLE_LINE_COMMENT,
ACTION_GET_COMPLETIONS, ACTION_GO_TO_DEFINITION, ACTION_DEBUG_TOGGLE_BREAKPOINT);
popupMenu = editPopupItem;
@ -125,12 +125,12 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
protected EditorTool _editorTool;
@property EditorTool editorTool() { return _editorTool; }
@property EditorTool editorTool(EditorTool tool) {
@property EditorTool editorTool(EditorTool tool) {
if (_editorTool && _editorTool !is tool) {
destroy(_editorTool);
_editorTool = null;
}
return _editorTool = tool;
return _editorTool = tool;
};
protected ProjectSourceFile _projectSourceFile;
@ -585,7 +585,7 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
_docsPopup.popupClosed = delegate(PopupWidget source) {
Log.d("Closed Docs popup");
_docsPopup = null;
//setFocus();
//setFocus();
};
_docsPopup.flags = PopupFlags.CloseOnClickOutside | PopupFlags.CloseOnMouseMoveOutside;
invalidate();
@ -641,7 +641,8 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
return;
}
if (suggestions.length == 1) {
// Only insert singular autocompletion if automatic autocomplete is turned off!
if (!_settings.autoAutoComplete && suggestions.length == 1) {
insertCompletion(suggestions[0]);
return;
}
@ -680,7 +681,7 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
popupPositionX,
popupPositionY + yOffset);
_completionPopup.setFocus();
_completionPopup.popupClosed = delegate(PopupWidget source) {
_completionPopup.popupClosed = delegate(PopupWidget source) {
setFocus();
_completionPopup = null;
};
@ -721,13 +722,25 @@ class DSourceEdit : SourceEdit, EditableContentMarksChangeListener {
super.handleFocusChange(focused, receivedFocusFromKeyboard);
}
private bool isAutoCompleteKey(ref KeyEvent event) {
if((event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_Z) ||
event.keyCode == KeyCode.KEY_PERIOD ||
event.keyCode == KeyCode.BACK ||
event.text == "_")
return true;
return false;
}
protected uint _lastKeyDownCode;
protected uint _periodKeyCode;
/// handle keys: support autocompletion after . press with delay
override bool onKeyEvent(KeyEvent event) {
if (event.action == KeyAction.KeyDown)
_lastKeyDownCode = event.keyCode;
if (event.action == KeyAction.Text && event.noModifiers && event.text==".") {
if(_settings.autoAutoComplete && isAutoCompleteKey(event) && !_completionPopup) {
window.dispatchAction(ACTION_GET_COMPLETIONS, this);
}
else if (event.action == KeyAction.Text && event.noModifiers && event.text==".") {
_periodKeyCode = _lastKeyDownCode;
startCompletionTimer();
} else {
@ -775,7 +788,7 @@ class CompletionPopupMenu : PopupMenu {
//maxHeight(400);
selectItem(0);
}
Point fullContentSizeWithBorders() {
measure(2000.pointsToPixels, 2000.pointsToPixels);
Point sz;
@ -790,7 +803,7 @@ class CompletionPopupMenu : PopupMenu {
MenuItem updateItems() {
MenuItem res = new MenuItem();
foreach(int i, dstring suggestion ; _suggestions) {
foreach(i, dstring suggestion ; _suggestions) {
if (_prefix.length && !suggestion.startsWith(_prefix))
continue;
string iconId;
@ -806,19 +819,12 @@ class CompletionPopupMenu : PopupMenu {
/// handle keys
override bool onKeyEvent(KeyEvent event) {
if (event.action == KeyAction.Text) {
_prefix ~= event.text;
MenuItem newItems = updateItems();
if (newItems.subitemCount == 0) {
// no matches anymore
_editor.onKeyEvent(event);
_editor.closeCompletionPopup(this);
return true;
} else {
_editor.onKeyEvent(event);
menuItems = newItems;
selectItem(0);
return true;
}
_editor.onKeyEvent(event);
_editor.closeCompletionPopup(this);
return true;
} else if (event.keyCode == KeyCode.ESCAPE) {
_editor.closeCompletionPopup(this);
return true;
} else if (event.action == KeyAction.KeyDown && event.keyCode == KeyCode.BACK && event.noModifiers) {
if (_prefix.length > _initialPrefix.length) {
_prefix.length = _prefix.length - 1;
@ -831,8 +837,8 @@ class CompletionPopupMenu : PopupMenu {
_editor.closeCompletionPopup(this);
}
return true;
} else if (event.action == KeyAction.KeyDown && event.keyCode == KeyCode.RETURN) {
} else if (event.action == KeyAction.KeyDown && event.keyCode == KeyCode.SPACE) {
} else if ((event.action == KeyAction.KeyDown && event.keyCode == KeyCode.RETURN) ||
(event.action == KeyAction.KeyDown && event.keyCode == KeyCode.SPACE)) {
}
return super.onKeyEvent(event);
}

View File

@ -21,6 +21,7 @@ import dlangide.ui.commands;
import dlangide.ui.wspanel;
import dlangide.ui.outputpanel;
import dlangide.ui.newfile;
import dlangide.ui.newfolder;
import dlangide.ui.newproject;
import dlangide.ui.dsourceedit;
import dlangide.ui.homescreen;
@ -36,6 +37,7 @@ import ddebug.common.execution;
import ddebug.common.nodebug;
import ddebug.common.debugger;
import ddebug.gdb.gdbinterface;
import dlangide.tools.d.dmdtrace;
import std.conv;
import std.utf;
@ -106,6 +108,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
window.onCanClose = &onCanClose;
window.onClose = &onWindowClose;
applySettings(_settings);
caretHistory = new CaretHistory;
}
~this() {
@ -147,31 +150,31 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
/// called when program execution is stopped
protected void onProgramExecutionStatus(ProgramExecution process, ExecutionStatus status, int exitCode) {
executeInUiThread(delegate() {
Log.d("onProgramExecutionStatus process: ", process.executableFile, " status: ", status, " exitCode: ", exitCode);
_execution = null;
// TODO: update state
switch(status) {
case ExecutionStatus.Error:
_logPanel.logLine("Cannot run program " ~ process.executableFile);
break;
case ExecutionStatus.Finished:
_logPanel.logLine("Program " ~ process.executableFile ~ " finished with exit code " ~ to!string(exitCode));
break;
case ExecutionStatus.Killed:
_logPanel.logLine("Program " ~ process.executableFile ~ " is killed");
break;
default:
_logPanel.logLine("Program " ~ process.executableFile ~ " is finished");
break;
}
_statusLine.setBackgroundOperationStatus(null, null);
});
Log.d("onProgramExecutionStatus process: ", process.executableFile, " status: ", status, " exitCode: ", exitCode);
_execution = null;
// TODO: update state
switch(status) {
case ExecutionStatus.Error:
_logPanel.logLine("Cannot run program " ~ process.executableFile);
break;
case ExecutionStatus.Finished:
_logPanel.logLine("Program " ~ process.executableFile ~ " finished with exit code " ~ to!string(exitCode));
break;
case ExecutionStatus.Killed:
_logPanel.logLine("Program " ~ process.executableFile ~ " is killed");
break;
default:
_logPanel.logLine("Program " ~ process.executableFile ~ " is finished");
break;
}
_statusLine.setBackgroundOperationStatus(null, null);
});
}
protected void handleBuildError(int result, Project project) {
ErrorPosition err = _logPanel.firstError;
if (err) {
onCompilerLogIssueClick(err.filename, err.line, err.pos);
onCompilerLogIssueClick(err.projectname, err.filename, err.line, err.pos);
}
}
@ -185,13 +188,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return;
}
buildProject(BuildOperation.Build, project, delegate(int result) {
if (!result) {
Log.i("Build completed successfully. Starting debug for project.");
debugProject(project);
} else {
handleBuildError(result, project);
}
});
if (!result) {
Log.i("Build completed successfully. Starting debug for project.");
debugProject(project);
} else {
handleBuildError(result, project);
}
});
}
void debugFinished(ProgramExecution process, ExecutionStatus status, int exitCode) {
@ -254,13 +257,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return;
}
buildProject(BuildOperation.Build, project, delegate(int result) {
if (!result) {
Log.i("Build completed successfully. Running program...");
runProject(project);
} else {
handleBuildError(result, project);
}
});
if (!result) {
Log.i("Build completed successfully. Running program...");
runProject(project);
} else {
handleBuildError(result, project);
}
});
}
protected void runProject(Project project) {
@ -387,16 +390,23 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
@property IDESettings settings() { return _settings; }
///
bool onCompilerLogIssueClick(dstring filename, int line, int column)
bool onCompilerLogIssueClick(dstring projectname, dstring filename, int line, int column)
{
Log.d("onCompilerLogIssueClick ", filename);
Log.d("onCompilerLogIssueClick project=", projectname, " file=", filename, " line=", line, " column=", column);
import std.conv:to;
openSourceFile(to!string(filename));
currentEditor().setCaretPos(line, 0);
currentEditor().setCaretPos(line, column);
string fname = to!string(filename);
//import std.path : isAbsolute;
ProjectSourceFile sourceFile = _wsPanel.findSourceFileItem(fname, isAbsolute(fname) ? true : false, projectname);
if (openSourceFile(fname, sourceFile)) {
Log.d("found source file");
if (sourceFile)
_wsPanel.selectItem(sourceFile);
caretHistory.pushNewPosition();
currentEditor().setCaretPos(line, 0);
currentEditor().setCaretPos(line, column);
caretHistory.pushNewPosition();
}
return true;
}
@ -409,6 +419,13 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
_tabs.renameTab(index, name);
}
}
bool tryOpenSourceFile(string filename) {
if (isSupportedSourceTextFileFormat(filename)) {
return openSourceFile(filename, null, true);
}
return false;
}
bool openSourceFile(string filename, ProjectSourceFile file = null, bool activate = true) {
if (!file && !filename)
@ -481,7 +498,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
HomeScreen home = new HomeScreen(HOME_SCREEN_ID, this);
_tabs.addTab(home, UIString.fromId("HOME"c), null, true);
_tabs.selectTab(HOME_SCREEN_ID, true);
auto _settings = new IDESettings(buildNormalizedPath(settingsDir, "settings.json"));
auto _settings = new IDESettings(buildNormalizedPath(settingsDir, "settings.json"));
// Auto open last workspace, if no workspace specified in command line and autoOpen flag set to true
const auto recentWorkspaces = settings.recentWorkspaces;
if (!openedWorkspace && recentWorkspaces.length > 0 && _settings.autoOpenLastProject())
@ -597,35 +614,35 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
// tab content is modified - ask for confirmation
auto header = UIString.fromId("HEADER_CLOSE_FILE"c);
window.showMessageBox(header ~ " " ~ toUTF32(baseName(tabId)), UIString.fromId("MSG_FILE_CONTENT_CHANGED"c),
[ACTION_SAVE, ACTION_SAVE_ALL, ACTION_DISCARD_CHANGES, ACTION_DISCARD_ALL, ACTION_CANCEL],
0, delegate(const Action result) {
if (result == StandardAction.Save) {
// save and close
ed.save();
askForUnsavedEdits(onConfirm);
} else if (result == StandardAction.DiscardChanges) {
// close, don't save
closeTab(tabId);
closeAllDocuments();
onConfirm();
} else if (result == StandardAction.SaveAll) {
ed.save();
for(;;) {
DSourceEdit editor = hasUnsavedEdits();
if (!editor)
break;
editor.save();
}
closeAllDocuments();
onConfirm();
} else if (result == StandardAction.DiscardAll) {
// close, don't save
closeAllDocuments();
onConfirm();
}
// else ignore
return true;
});
[ACTION_SAVE, ACTION_SAVE_ALL, ACTION_DISCARD_CHANGES, ACTION_DISCARD_ALL, ACTION_CANCEL],
0, delegate(const Action result) {
if (result == StandardAction.Save) {
// save and close
ed.save();
askForUnsavedEdits(onConfirm);
} else if (result == StandardAction.DiscardChanges) {
// close, don't save
closeTab(tabId);
closeAllDocuments();
onConfirm();
} else if (result == StandardAction.SaveAll) {
ed.save();
for(;;) {
DSourceEdit editor = hasUnsavedEdits();
if (!editor)
break;
editor.save();
}
closeAllDocuments();
onConfirm();
} else if (result == StandardAction.DiscardAll) {
// close, don't save
closeAllDocuments();
onConfirm();
}
// else ignore
return true;
});
}
protected void onTabClose(string tabId) {
@ -636,19 +653,19 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (d && d.content.modified) {
// tab content is modified - ask for confirmation
window.showMessageBox(UIString.fromId("HEADER_CLOSE_TAB"c), UIString.fromId("MSG_TAB_CONTENT_CHANGED"c) ~ ": " ~ toUTF32(baseName(tabId)),
[ACTION_SAVE, ACTION_DISCARD_CHANGES, ACTION_CANCEL],
0, delegate(const Action result) {
if (result == StandardAction.Save) {
// save and close
d.save();
closeTab(tabId);
} else if (result == StandardAction.DiscardChanges) {
// close, don't save
closeTab(tabId);
}
// else ignore
return true;
});
[ACTION_SAVE, ACTION_DISCARD_CHANGES, ACTION_CANCEL],
0, delegate(const Action result) {
if (result == StandardAction.Save) {
// save and close
d.save();
closeTab(tabId);
} else if (result == StandardAction.DiscardChanges) {
// close, don't save
closeTab(tabId);
}
// else ignore
return true;
});
} else {
closeTab(tabId);
}
@ -731,11 +748,11 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
fileNewItem.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_FILE_NEW_WORKSPACE, ACTION_FILE_NEW_PROJECT);
fileItem.add(fileNewItem);
fileItem.add(ACTION_FILE_OPEN_WORKSPACE, ACTION_FILE_OPEN,
ACTION_FILE_SAVE, ACTION_FILE_SAVE_AS, ACTION_FILE_SAVE_ALL, ACTION_FILE_WORKSPACE_CLOSE, ACTION_FILE_EXIT);
ACTION_FILE_SAVE, ACTION_FILE_SAVE_AS, ACTION_FILE_SAVE_ALL, ACTION_FILE_WORKSPACE_CLOSE, ACTION_FILE_EXIT);
MenuItem editItem = new MenuItem(new Action(2, "MENU_EDIT"));
editItem.add(ACTION_EDIT_COPY, ACTION_EDIT_PASTE,
ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO);
ACTION_EDIT_CUT, ACTION_EDIT_UNDO, ACTION_EDIT_REDO);
editItem.addSeparator();
editItem.add(ACTION_EDITOR_FIND, ACTION_EDITOR_FIND_NEXT, ACTION_EDITOR_FIND_PREV, ACTION_EDITOR_REPLACE, ACTION_FIND_TEXT, ACTION_EDITOR_TOGGLE_BOOKMARK);
editItem.addSeparator();
@ -756,7 +773,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
MenuItem navItem = new MenuItem(new Action(21, "MENU_NAVIGATE"));
navItem.add(ACTION_GO_TO_DEFINITION, ACTION_GET_COMPLETIONS, ACTION_GET_DOC_COMMENTS,
ACTION_GET_PAREN_COMPLETION, ACTION_EDITOR_GOTO_PREVIOUS_BOOKMARK,
ACTION_EDITOR_GOTO_NEXT_BOOKMARK, ACTION_GO_TO_LINE);
ACTION_EDITOR_GOTO_NEXT_BOOKMARK, ACTION_GO_TO_LINE, ACTION_GO_TO_PREV_POSITION, ACTION_GO_TO_NEXT_POSITION);
MenuItem projectItem = new MenuItem(new Action(21, "MENU_PROJECT"));
projectItem.add(ACTION_PROJECT_SET_STARTUP, ACTION_PROJECT_REFRESH, ACTION_PROJECT_UPDATE_DEPENDENCIES, ACTION_PROJECT_SETTINGS);
@ -786,19 +803,22 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
buildItem.addSeparator();
buildItem.add(ACTION_WORKSPACE_BUILD, ACTION_WORKSPACE_REBUILD, ACTION_WORKSPACE_CLEAN,
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN,
ACTION_RUN_WITH_RDMD);
ACTION_PROJECT_BUILD, ACTION_PROJECT_REBUILD, ACTION_PROJECT_CLEAN,
ACTION_RUN_WITH_RDMD);
MenuItem debugItem = new MenuItem(new Action(23, "MENU_DEBUG"));
debugItem.add(ACTION_DEBUG_START, ACTION_DEBUG_START_NO_DEBUG,
ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
ACTION_DEBUG_RESTART,
ACTION_DEBUG_STEP_INTO,
ACTION_DEBUG_STEP_OVER,
ACTION_DEBUG_STEP_OUT,
ACTION_DEBUG_TOGGLE_BREAKPOINT, ACTION_DEBUG_ENABLE_BREAKPOINT, ACTION_DEBUG_DISABLE_BREAKPOINT
);
ACTION_DEBUG_CONTINUE, ACTION_DEBUG_STOP, ACTION_DEBUG_PAUSE,
ACTION_DEBUG_RESTART,
ACTION_DEBUG_STEP_INTO,
ACTION_DEBUG_STEP_OVER,
ACTION_DEBUG_STEP_OUT,
ACTION_DEBUG_TOGGLE_BREAKPOINT, ACTION_DEBUG_ENABLE_BREAKPOINT, ACTION_DEBUG_DISABLE_BREAKPOINT
);
MenuItem toolsItem = new MenuItem(new Action(33, "MENU_TOOLS"c));
toolsItem.add(ACTION_TOOLS_OPEN_DMD_TRACE_LOG);
MenuItem windowItem = new MenuItem(new Action(3, "MENU_WINDOW"c));
//windowItem.add(new Action(30, "MENU_WINDOW_PREFERENCES"));
@ -813,6 +833,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
mainMenuItems.add(navItem);
mainMenuItems.add(buildItem);
mainMenuItems.add(debugItem);
mainMenuItems.add(toolsItem);
//mainMenuItems.add(viewItem);
mainMenuItems.add(windowItem);
mainMenuItems.add(helpItem);
@ -863,14 +884,14 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
tb = res.getOrAddToolbar("Edit");
tb.addButtons(ACTION_EDIT_COPY, ACTION_EDIT_PASTE, ACTION_EDIT_CUT, ACTION_SEPARATOR,
ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT);
ACTION_EDIT_UNDO, ACTION_EDIT_REDO, ACTION_EDIT_INDENT, ACTION_EDIT_UNINDENT);
tb = res.getOrAddToolbar("Debug");
tb.addButtons(ACTION_DEBUG_STOP, ACTION_DEBUG_CONTINUE, ACTION_DEBUG_PAUSE,
ACTION_DEBUG_RESTART,
ACTION_DEBUG_STEP_INTO,
ACTION_DEBUG_STEP_OVER,
ACTION_DEBUG_STEP_OUT,
);
ACTION_DEBUG_RESTART,
ACTION_DEBUG_STEP_INTO,
ACTION_DEBUG_STEP_OVER,
ACTION_DEBUG_STEP_OUT,
);
return res;
}
@ -892,6 +913,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
else
a.state = ACTION_STATE_DISABLE;
return true;
case IDEActions.FileNew:
a.state = (currentWorkspace && currentWorkspace.startupProject) ? ACTION_STATE_ENABLED : ACTION_STATE_DISABLE;
return true;
case IDEActions.HelpAbout:
case StandardAction.OpenUrl:
// always enabled
@ -967,6 +991,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.FileSaveAll:
case IDEActions.FileSaveAs:
case IDEActions.GotoLine:
case IDEActions.GotoPrevPosition:
case IDEActions.GotoNextPosition:
case EditorActions.Find:
case EditorActions.FindNext:
case EditorActions.FindPrev:
@ -994,6 +1020,50 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
}
static immutable TRACE_LOG_ID = "TRACE_LOG";
void showDMDTraceLog(DMDTraceLogParser data) {
import dlangide.ui.dmdprofilerview;
int index = _tabs.tabIndex(TRACE_LOG_ID);
if (index >= 0) {
_tabs.removeTab(TRACE_LOG_ID);
}
DMDProfilerView home = new DMDProfilerView(TRACE_LOG_ID, this, data);
_tabs.addTab(home, UIString.fromId("PROFILER_WINDOW"c), null, true);
_tabs.selectTab(TRACE_LOG_ID, true);
}
//void showDMDTraceLog()
void openDMDTraceLog(string filename) {
DMDProfilerLogParserOperation op = new DMDProfilerLogParserOperation(this, filename, _logPanel,
delegate(DMDTraceLogParser parser) {
if (parser) {
Log.d("Trace log is ready");
showDMDTraceLog(parser);
} else {
Log.e("Trace log is failed");
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_FAILED_TO_PARSE_FILE"c));
}
}
);
setBackgroundOperation(op);
}
void openDMDTraceLog() {
UIString caption;
caption = UIString.fromId("HEADER_OPEN_DMD_PROFILER_LOG"c);
FileDialog dlg = createFileDialog(caption);
dlg.addFilter(FileFilterEntry(UIString.fromId("PROFILER_LOG_FILES"c), "*.log"));
dlg.path = _settings.getRecentPath("FILE_OPEN_PATH");
dlg.dialogResult = delegate(Dialog d, const Action result) {
if (result.id == ACTION_OPEN.id) {
string filename = result.stringParam;
_settings.setRecentPath(dlg.path, "FILE_OPEN_PATH");
openDMDTraceLog(filename);
}
};
dlg.show();
}
FileDialog createFileDialog(UIString caption, int fileDialogFlags = DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.FileMustExist) {
FileDialog dlg = new FileDialog(caption, window, null, fileDialogFlags);
dlg.filetypeIcons[".d"] = "text-d";
@ -1018,15 +1088,18 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.HelpDonate:
Platform.instance.openURL(HELP_DONATION_URL);
return true;
case IDEActions.ToolsOpenDMDTraceLog:
openDMDTraceLog();
return true;
case IDEActions.HelpAbout:
//debug {
// testDCDFailAfterThreadCreation();
//}
dstring msg = "DLangIDE\n(C) Vadim Lopatin, 2014-2017\nhttp://github.com/buggins/dlangide\n"
~ "IDE for D programming language written in D\nUses DlangUI library "
~ DLANGUI_VERSION ~ " for GUI"d;
~ DLANGUI_VERSION ~ " for GUI"d;
window.showMessageBox(UIString.fromId("ABOUT"c) ~ " " ~ DLANGIDE_VERSION,
UIString.fromRaw(msg));
UIString.fromRaw(msg));
return true;
case IDEActions.BuildSetConfiguration:
// set build configuration
@ -1077,7 +1150,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
else
ed.editorTool = new DefaultEditorTool(this);
//openSourceFile(filename);
refreshWorkspace();
updateTreeGraph();
ProjectSourceFile file = _wsPanel.findSourceFileItem(filename, false);
if (file) {
ed.projectSourceFile = file;
@ -1149,7 +1222,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
buildProject(BuildOperation.Upgrade, cast(Project)a.objectParam);
return true;
case IDEActions.RefreshProject:
refreshWorkspace();
updateTreeGraph();
return true;
case IDEActions.RevealProjectInExplorer:
revealProjectInExplorer(cast(Project)a.objectParam);
@ -1159,8 +1232,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
return true;
case IDEActions.WindowCloseAllDocuments:
askForUnsavedEdits(delegate() {
closeAllDocuments();
});
closeAllDocuments();
});
return true;
case IDEActions.WindowShowHomeScreen:
showHomeScreen();
@ -1216,6 +1289,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.GoToDefinition:
if (currentEditor) {
Log.d("Trying to go to definition.");
caretHistory.pushNewPosition();
currentEditor.editorTool.goToDefinition(currentEditor(), currentEditor.caretPos);
}
return true;
@ -1225,31 +1299,45 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
Log.d("Go to line");
// Ask user for line
window.showInputBox(UIString.fromId("GO_TO_LINE"c), UIString.fromId("GO_TO_LINE"c), ""d, delegate(dstring s) {
try {
auto num = to!uint(s);
// Check line existence
if (num < 1 || num > currentEditor.content.length) {
try {
auto num = to!uint(s);
// Check line existence
if (num < 1 || num > currentEditor.content.length) {
currentEditor.setFocus();
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_NO_SUCH_LINE"c));
return;
}
// Go to line
caretHistory.pushNewPosition();
currentEditor.setCaretPos(num - 1, 0);
currentEditor.setFocus();
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_NO_SUCH_LINE"c));
return;
caretHistory.pushNewPosition();
}
// Go to line
currentEditor.setCaretPos(num - 1, 0);
currentEditor.setFocus();
}
catch (ConvException e) {
currentEditor.setFocus();
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_NUMBER"c));
}
});
catch (ConvException e) {
currentEditor.setFocus();
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_NUMBER"c));
}
});
}
return true;
case IDEActions.GotoPrevPosition:
if (currentEditor) {
Log.d("Go to prev position");
caretHistory.moveToPrev();
}
return true;
case IDEActions.GotoNextPosition:
if (currentEditor) {
Log.d("Go to next position");
caretHistory.moveToNext();
}
return true;
case IDEActions.GetDocComments:
Log.d("Trying to get doc comments.");
currentEditor.editorTool.getDocComments(currentEditor, currentEditor.caretPos, delegate(string[] results) {
if (results.length)
currentEditor.showDocCommentsPopup(results);
});
if (results.length)
currentEditor.showDocCommentsPopup(results);
});
return true;
case IDEActions.GetParenCompletion:
Log.d("Trying to get paren completion.");
@ -1258,9 +1346,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
case IDEActions.GetCompletionSuggestions:
Log.d("Getting auto completion suggestions.");
currentEditor.editorTool.getCompletions(currentEditor, currentEditor.caretPos, delegate(dstring[] results, string[] icons, CompletionTypes type) {
if (currentEditor)
currentEditor.showCompletionPopup(results, icons, type);
});
if (currentEditor)
currentEditor.showCompletionPopup(results, icons, type);
});
return true;
case IDEActions.EditPreferences:
showPreferences();
@ -1305,7 +1393,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
createNewProject(false);
return true;
case IDEActions.FileNew:
addProjectItem(cast(Object)a.objectParam);
addFile(cast(Object)a.objectParam);
return true;
case IDEActions.FileNewDirectory:
addDirectory(cast(Object)a.objectParam);
return true;
case IDEActions.ProjectFolderRemoveItem:
removeProjectItem(a.objectParam);
@ -1343,9 +1434,9 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
currentWorkspace.save();
}
askForUnsavedEdits(delegate() {
setWorkspace(null);
showHomeScreen();
});
setWorkspace(null);
showHomeScreen();
});
}
void onBreakpointListChanged(ProjectSourceFile sourcefile, Breakpoint[] breakpoints) {
@ -1373,7 +1464,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (cast(Workspace)obj) {
Workspace ws = cast(Workspace)obj;
ws.refresh();
refreshWorkspace();
updateTreeGraph();
} else if (cast(Project)obj) {
project = cast(Project)obj;
} else if (cast(ProjectFolder)obj) {
@ -1392,7 +1483,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
if (project) {
project.refresh();
refreshWorkspace();
updateTreeGraph();
}
}
@ -1406,29 +1497,74 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (!project)
return;
window.showMessageBox(UIString.fromId("HEADER_REMOVE_FILE"c),
UIString.fromId("QUESTION_REMOVE_FILE"c) ~ " " ~ srcfile.name ~ "?",
[ACTION_YES, ACTION_NO],
1, delegate(const Action result) {
if (result == StandardAction.Yes) {
// save and close
import std.file : remove;
closeTab(srcfile.filename);
try {
remove(srcfile.filename);
} catch (Exception e) {
Log.e("Cannot remove file");
}
project.refresh();
refreshWorkspace();
UIString.fromId("QUESTION_REMOVE_FILE"c) ~ " " ~ srcfile.name ~ "?",
[ACTION_YES, ACTION_NO],
1, delegate(const Action result) {
if (result == StandardAction.Yes) {
// save and close
import std.file : remove;
closeTab(srcfile.filename);
try {
remove(srcfile.filename);
} catch (Exception e) {
Log.e("Cannot remove file");
}
// else ignore
return true;
});
project.refresh();
updateTreeGraph();
}
// else ignore
return true;
});
}
private void addFile(Object obj) {
Dialog createNewFileDialog(Project project, ProjectFolder folder) {
NewFileDlg dialog = new NewFileDlg(this, project, folder);
dialog.dialogResult = delegate(Dialog dlg, const Action result) {
if (result.id == ACTION_FILE_NEW_SOURCE_FILE.id) {
FileCreationResult res = cast(FileCreationResult)result.objectParam;
if (res) {
//res.project.reload();
res.project.refresh();
updateTreeGraph();
tryOpenSourceFile(res.filename);
}
}
};
return dialog;
}
addProjectItem(&createNewFileDialog, obj);
}
private void addDirectory(Object obj) {
Dialog createNewDirectoryDialog(Project project, ProjectFolder folder) {
NewFolderDialog dialog = new NewFolderDialog(this, project, folder);
dialog.dialogResult = delegate(Dialog dlg, const Action result) {
if(result.id == ACTION_FILE_NEW_DIRECTORY.id) {
FileCreationResult res = cast(FileCreationResult)result.objectParam;
if (res) {
ProjectFolder newFolder = new ProjectFolder(res.filename);
if(folder) {
folder.addChild(newFolder);
folder.sortItems;
newFolder.refresh();
if(newFolder.childCount > 0){
tryOpenSourceFile(newFolder.child(0).filename);
}
}
updateTreeGraph();
_wsPanel.selectItem(newFolder);
}
}
};
return dialog;
}
addProjectItem(&createNewDirectoryDialog, obj);
}
/// add new file to project
void addProjectItem(Object obj) {
private void addProjectItem(Dialog delegate(Project, ProjectFolder) dialogFactory, Object obj) {
if (currentWorkspace is null)
return;
if (obj is null && _wsPanel !is null && !currentEditorSourceFile) {
@ -1440,7 +1576,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
ProjectFolder folder;
if (cast(Project)obj) {
project = cast(Project)obj;
folder = project.firstSourceFolder;
folder = project.items;
import std.stdio;
writeln("Root filename:", folder.filename);
for(int i = 0; i < folder.childCount; i++) {
writeln("Child [", i, "]: ", folder.child(i).filename);
}
} else if (cast(ProjectFolder)obj) {
folder = cast(ProjectFolder)obj;
project = folder.project;
@ -1455,21 +1596,8 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
project = srcfile.project;
}
}
if (project && folder && project.workspace is currentWorkspace) {
NewFileDlg dlg = new NewFileDlg(this, project, folder);
dlg.dialogResult = delegate(Dialog dlg, const Action result) {
if (result.id == ACTION_FILE_NEW_SOURCE_FILE.id) {
FileCreationResult res = cast(FileCreationResult)result.objectParam;
if (res) {
//res.project.reload();
res.project.refresh();
refreshWorkspace();
if (isSupportedSourceTextFileFormat(res.filename)) {
openSourceFile(res.filename, null, true);
}
}
}
};
if (project && project.workspace is currentWorkspace) {
Dialog dlg = dialogFactory(project, folder);
dlg.show();
}
}
@ -1490,12 +1618,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
if (currentWorkspace is null || res.workspace !is currentWorkspace) {
// open new workspace
setWorkspace(res.workspace);
refreshWorkspace();
updateTreeGraph();
hideHomeScreen();
} else {
// project added to current workspace
loadProject(res.project);
refreshWorkspace();
updateTreeGraph();
hideHomeScreen();
}
}
@ -1575,6 +1703,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
currentTheme.fontFace = newFontFace;
needUpdateTheme = true;
}
if (overrideScreenDPI != settings.screenDpiOverride) {
overrideScreenDPI = settings.screenDpiOverride;
needUpdateTheme = true;
}
if (oldFontSize != settings.uiFontSize) {
currentTheme.fontSize = settings.uiFontSize;
needUpdateTheme = true;
@ -1612,21 +1744,21 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
WorkspaceFile[] files = currentWorkspace.files();
for (int i; i < files.length; i++)
with (files[i])
{
// Opening file
if (openSourceFile(filename))
{
// Opening file
if (openSourceFile(filename))
{
auto index = _tabs.tabIndex(filename);
if (index < 0)
continue;
// file is opened in tab
auto source = cast(DSourceEdit)_tabs.tabBody(filename);
if (!source)
continue;
// Caret position
source.setCaretPos(column, row, true, true);
}
auto index = _tabs.tabIndex(filename);
if (index < 0)
continue;
// file is opened in tab
auto source = cast(DSourceEdit)_tabs.tabBody(filename);
if (!source)
continue;
// Caret position
source.setCaretPos(column, row, true, true);
}
}
}
void saveListOfOpenedFiles() {
@ -1653,12 +1785,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
Workspace ws = new Workspace(this);
if (ws.load(filename)) {
askForUnsavedEdits(delegate() {
setWorkspace(ws);
hideHomeScreen();
// Write workspace to recent workspaces list
_settings.updateRecentWorkspace(filename);
restoreListOfOpenedFiles();
});
setWorkspace(ws);
hideHomeScreen();
// Write workspace to recent workspaces list
_settings.updateRecentWorkspace(filename);
restoreListOfOpenedFiles();
});
} else {
window.showMessageBox(UIString.fromId("ERROR_OPEN_WORKSPACE"c).value, UIString.fromId("ERROR_OPENING_WORKSPACE"c).value);
return;
@ -1683,21 +1815,21 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
window.showMessageBox(UIString.fromId("MSG_OPEN_PROJECT"c), UIString.fromId("QUESTION_NEW_WORKSPACE"c),
[ACTION_ADD_TO_CURRENT_WORKSPACE, ACTION_CREATE_NEW_WORKSPACE, ACTION_CANCEL], 0, delegate(const Action result) {
if (result.id == IDEActions.CreateNewWorkspace) {
// new ws
createNewWorkspaceForExistingProject(project);
hideHomeScreen();
} else if (result.id == IDEActions.AddToCurrentWorkspace) {
// add to current
currentWorkspace.addProject(project);
loadProject(project);
currentWorkspace.save();
refreshWorkspace();
hideHomeScreen();
}
return true;
});
[ACTION_ADD_TO_CURRENT_WORKSPACE, ACTION_CREATE_NEW_WORKSPACE, ACTION_CANCEL], 0, delegate(const Action result) {
if (result.id == IDEActions.CreateNewWorkspace) {
// new ws
createNewWorkspaceForExistingProject(project);
hideHomeScreen();
} else if (result.id == IDEActions.AddToCurrentWorkspace) {
// add to current
currentWorkspace.addProject(project);
loadProject(project);
currentWorkspace.save();
updateTreeGraph();
hideHomeScreen();
}
return true;
});
} else {
// new workspace file
createNewWorkspaceForExistingProject(project);
@ -1708,7 +1840,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
}
void refreshWorkspace() {
void updateTreeGraph() {
_logPanel.logLine("Refreshing workspace");
_wsPanel.reloadItems();
closeRemovedDocuments();
@ -1774,7 +1906,7 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
void refreshProject(Project project) {
if (currentWorkspace && project.loadSelections()) {
currentWorkspace.cleanupUnusedDependencies();
refreshWorkspace();
updateTreeGraph();
}
}
@ -1840,10 +1972,10 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
}
Builder op = new Builder(this, project, _logPanel, project.projectConfiguration, currentWorkspace.buildConfiguration, buildOp,
dubExecutable, dubAdditionalParams,
toolchain,
arch,
listener);
dubExecutable, dubAdditionalParams,
toolchain,
arch,
listener);
setBackgroundOperation(op);
}
@ -1902,12 +2034,12 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
/// return false to prevent closing
bool onCanClose() {
askForUnsavedEdits(delegate() {
if (currentWorkspace) {
// Remember opened files
saveListOfOpenedFiles();
}
window.close();
});
if (currentWorkspace) {
// Remember opened files
saveListOfOpenedFiles();
}
window.close();
});
return false;
}
/// called when main window is closing
@ -1917,5 +2049,58 @@ class IDEFrame : AppFrame, ProgramExecutionStatusListener, BreakpointListChangeL
Log.i("onWindowClose()");
stopExecution();
}
static struct CaretPosition {
string filePath;
uint line;
uint pos;
};
class CaretHistory {
private CaretPosition[] caretHistory;
private int currentPos = -1;
private bool checkIfCurentPosIsCurrentHistoryPos() {
if (caretHistory.length == 0) {
return false;
}
return currentEditor.caretPos.line == caretHistory[currentPos].line &&
currentEditor.caretPos.pos == caretHistory[currentPos].pos;
}
void pushNewPosition() {
if (!checkIfCurentPosIsCurrentHistoryPos()) {
pushNewPosition(currentEditor().filename, currentEditor.caretPos.line, currentEditor.caretPos.pos);
}
}
void pushNewPosition(string filePath, uint line, uint pos) {
if (caretHistory.length != 0) {
caretHistory = caretHistory[0..currentPos + 1];
}
caretHistory ~= CaretPosition(filePath, line, pos);
++currentPos;
}
void moveToNext() {
if (currentPos + 1 < caretHistory.length) {
++currentPos;
openSourceFile(caretHistory[currentPos].filePath);
currentEditor.setCaretPos(caretHistory[currentPos].line, caretHistory[currentPos].pos);
currentEditor.setFocus();
}
}
void moveToPrev() {
if (currentPos > 0) {
--currentPos;
openSourceFile(caretHistory[currentPos].filePath);
currentEditor.setCaretPos(caretHistory[currentPos].line, caretHistory[currentPos].pos);
currentEditor.setFocus();
}
}
}
CaretHistory caretHistory;
}

View File

@ -25,7 +25,6 @@ class HomeScreen : ScrollWidget {
import dlangide.ui.frame;
//styleId = STYLE_EDIT_BOX;
_frame = frame;
uint linkColor = currentTheme.customColor("link_color", 0x2020FF);
_content = new HorizontalLayout("HOME_SCREEN_BODY");
_content.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
VerticalLayout _column1 = new VerticalLayout();
@ -35,11 +34,11 @@ class HomeScreen : ScrollWidget {
_column2.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT).padding(Rect(pad, pad, pad, pad));
_content.addChild(_column1);
_content.addChild(_column2);
_column1.addChild((new TextWidget(null, "Dlang IDE "d ~ DLANGIDE_VERSION)).fontSize(32).textColor(linkColor));
_column1.addChild((new TextWidget(null, UIString.fromId("DESCRIPTION"c))).fontSize(20));
_column1.addChild((new TextWidget(null, UIString.fromId("COPYRIGHT"c))).fontSize(22).textColor(linkColor));
_column1.addChild((new TextWidget(null, "Dlang IDE "d ~ DLANGIDE_VERSION)).styleId("HOME_SCREEN_TITLE"));
_column1.addChild((new TextWidget(null, UIString.fromId("DESCRIPTION"c))).styleId("HOME_SCREEN_TITLE2"));
_column1.addChild((new TextWidget(null, UIString.fromId("COPYRIGHT"c))).styleId("HOME_SCREEN_TITLE2"));
_column1.addChild(new VSpacer());
_column1.addChild((new TextWidget(null, UIString.fromId("START_WITH"c))).fontSize(20).textColor(linkColor));
_column1.addChild((new TextWidget(null, UIString.fromId("START_WITH"c))).styleId("HOME_SCREEN_TITLE"));
_startItems = new VerticalLayout();
_recentItems = new VerticalLayout();
_startItems.addChild(new ImageTextButton(ACTION_FILE_OPEN_WORKSPACE));
@ -49,7 +48,7 @@ class HomeScreen : ScrollWidget {
_column1.addChild(new VSpacer());
// Recent workspaces
_column1.addChild((new TextWidget(null, UIString.fromId("RECENT"c))).fontSize(20).textColor(linkColor));
_column1.addChild((new TextWidget(null, UIString.fromId("RECENT"c))).styleId("HOME_SCREEN_TITLE"));
string[] recentWorkspaces = _frame.settings.recentWorkspaces;
if (recentWorkspaces.length) {
foreach(fn; recentWorkspaces) {
@ -65,8 +64,9 @@ class HomeScreen : ScrollWidget {
// Useful links
_column1.addChild(new VSpacer());
_column2.addChild((new TextWidget(null, UIString.fromId("USEFUL_LINKS"c))).fontSize(20).textColor(linkColor));
_column2.addChild((new TextWidget(null, UIString.fromId("USEFUL_LINKS"c))).styleId("HOME_SCREEN_TITLE"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("D_LANG"c).value, "http://dlang.org/"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_DOWNLOADS"c).value, "https://dlang.org/download.html"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DUB_REP"c).value, "http://code.dlang.org/"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_UI"c).value, "https://github.com/buggins/dlangui"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_IDE"c).value, "https://github.com/buggins/dlangide"));
@ -75,7 +75,7 @@ class HomeScreen : ScrollWidget {
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_VIBED"c).value, "http://vibed.org/"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_FORUM"c).value, "http://forum.dlang.org/"));
_column1.addChild(new VSpacer());
_column2.addChild((new TextWidget(null, UIString.fromId("DLANG_IDE_DONATE"c))).fontSize(20).textColor(linkColor));
_column2.addChild((new TextWidget(null, UIString.fromId("DLANG_IDE_DONATE"c))).styleId("HOME_SCREEN_TITLE"));
_column2.addChild(new UrlImageTextButton(null, UIString.fromId("DLANG_IDE_DONATE_PAYPAL"c).value, HELP_DONATION_URL));
_column2.addChild(new VSpacer());

View File

@ -40,7 +40,7 @@ class NewFileDlg : Dialog {
string[] _sourcePaths;
this(IDEFrame parent, Project currentProject, ProjectFolder folder) {
super(UIString.fromId("OPTION_NEW_SOURCE_FILE"c), parent.window,
DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
_ide = parent;
_icon = "dlangui-logo1";
this._project = currentProject;
@ -60,34 +60,34 @@ class NewFileDlg : Dialog {
try {
content = parseML(q{
VerticalLayout {
id: vlayout
id: vlayout
padding: Rect { 5, 5, 5, 5 }
layoutWidth: fill; layoutHeight: fill
layoutWidth: fill; layoutHeight: fill
HorizontalLayout {
layoutWidth: fill; layoutHeight: fill
layoutWidth: fill; layoutHeight: fill
VerticalLayout {
margins: 5
layoutWidth: 50%; layoutHeight: fill
margins: 5
layoutWidth: 50%; layoutHeight: fill
TextWidget { text: OPTION_PROJECT_TEMPLATE }
StringListWidget {
id: projectTemplateList
layoutWidth: wrap; layoutHeight: fill
id: projectTemplateList
layoutWidth: wrap; layoutHeight: fill
}
}
VerticalLayout {
margins: 5
layoutWidth: 50%; layoutHeight: fill
margins: 5
layoutWidth: 50%; layoutHeight: fill
TextWidget { text: OPTION_TEMPLATE_DESCR }
EditBox {
id: templateDescription; readOnly: true
layoutWidth: fill; layoutHeight: fill
id: templateDescription; readOnly: true
layoutWidth: fill; layoutHeight: fill
}
}
}
TableLayout {
margins: 5
colCount: 2
layoutWidth: fill; layoutHeight: wrap
margins: 5
colCount: 2
layoutWidth: fill; layoutHeight: wrap
TextWidget { text: NAME }
EditLine { id: edName; text: "newfile"; layoutWidth: fill }
TextWidget { text: LOCATION }
@ -97,7 +97,7 @@ class NewFileDlg : Dialog {
TextWidget { text: OPTION_FILE_PATH }
EditLine { id: edFilePath; text: ""; layoutWidth: fill; readOnly: true }
}
TextWidget { id: statusText; text: ""; layoutWidth: fill; textColor: #FF0000 }
TextWidget { id: statusText; text: ""; layoutWidth: fill; textColor: 0xFF0000 }
}
});
} catch (Exception e) {
@ -105,7 +105,7 @@ class NewFileDlg : Dialog {
throw e;
}
_projectTemplateList = content.childById!StringListWidget("projectTemplateList");
_templateDescription = content.childById!EditBox("templateDescription");
_edFileName = content.childById!EditLine("edName");
@ -198,29 +198,6 @@ class NewFileDlg : Dialog {
ProjectTemplate _currentTemplate;
ProjectTemplate[] _templates;
static bool isSubdirOf(string path, string basePath) {
if (path.equal(basePath))
return true;
if (path.length > basePath.length + 1 && path.startsWith(basePath)) {
char ch = path[basePath.length];
return ch == '/' || ch == '\\';
}
return false;
}
bool findSource(string path, ref string sourceFolderPath, ref string relativePath) {
foreach(dir; _sourcePaths) {
if (isSubdirOf(path, dir)) {
sourceFolderPath = dir;
relativePath = path[sourceFolderPath.length .. $];
if (relativePath.length > 0 && (relativePath[0] == '\\' || relativePath[0] == '/'))
relativePath = relativePath[1 .. $];
return true;
}
}
return false;
}
bool setError(dstring msg) {
_statusText.text = msg;
return msg.empty;
@ -242,25 +219,12 @@ class NewFileDlg : Dialog {
if (_currentTemplate.kind == FileKind.MODULE || _currentTemplate.kind == FileKind.PACKAGE) {
string sourcePath, relativePath;
if (!findSource(_location, sourcePath, relativePath))
if (!findSource(_sourcePaths, _location, sourcePath, relativePath))
return setError("Location is outside of source path");
if (!isValidModuleName(filename))
return setError("Invalid file name");
_moduleName = filename;
char[] buf;
foreach(c; relativePath) {
char ch = c;
if (ch == '/' || ch == '\\')
ch = '.';
else if (ch == '.')
ch = '_';
if (ch == '.' && (buf.length == 0 || buf[$-1] == '.'))
continue; // skip duplicate .
buf ~= ch;
}
if (buf.length && buf[$-1] == '.')
buf.length--;
_packageName = buf.dup;
_moduleName = filename;
_packageName = getPackageName(sourcePath, relativePath);
string m;
if (_currentTemplate.kind == FileKind.MODULE) {
m = !_packageName.empty ? _packageName ~ '.' ~ _moduleName : _moduleName;
@ -284,20 +248,10 @@ class NewFileDlg : Dialog {
private FileCreationResult _result;
bool createItem() {
try {
if (_currentTemplate.kind == FileKind.MODULE) {
string txt = "module " ~ _packageName ~ ";\n\n" ~ _currentTemplate.srccode;
write(_fullPathName, txt);
} else if (_currentTemplate.kind == FileKind.PACKAGE) {
string txt = "module " ~ _packageName ~ ";\n\n" ~ _currentTemplate.srccode;
write(_fullPathName, txt);
} else {
write(_fullPathName, _currentTemplate.srccode);
}
} catch (Exception e) {
Log.e("Cannot create file", e);
if(!createFile(_fullPathName, _currentTemplate.kind, _packageName, _currentTemplate.srccode)) {
return setError("Cannot create file");
}
_result = new FileCreationResult(_project, _fullPathName);
return true;
}
@ -338,22 +292,22 @@ class NewFileDlg : Dialog {
void initTemplates() {
_templates ~= new ProjectTemplate("Empty module"d, "Empty D module file."d, ".d",
"\n", FileKind.MODULE);
"\n", FileKind.MODULE);
_templates ~= new ProjectTemplate("Package"d, "D package."d, ".d",
"\n", FileKind.PACKAGE);
"\n", FileKind.PACKAGE);
_templates ~= new ProjectTemplate("Text file"d, "Empty text file."d, ".txt",
"\n", FileKind.TEXT);
"\n", FileKind.TEXT);
_templates ~= new ProjectTemplate("JSON file"d, "Empty json file."d, ".json",
"{\n}\n", FileKind.TEXT);
"{\n}\n", FileKind.TEXT);
_templates ~= new ProjectTemplate("Vibe-D Diet Template file"d, "Empty Vibe-D Diet Template."d, ".dt",
q{
doctype html
html
head
title Hello, World
body
h1 Hello World
}, FileKind.TEXT);
q{
doctype html
html
head
title Hello, World
body
h1 Hello World
}, FileKind.TEXT);
}
}
@ -377,3 +331,67 @@ class ProjectTemplate {
this.kind = kind;
}
}
bool createFile(string fullPathName, FileKind fileKind, string packageName, string sourceCode) {
try {
if (fileKind == FileKind.MODULE) {
string txt = "module " ~ packageName ~ ";\n\n" ~ sourceCode;
write(fullPathName, txt);
} else if (fileKind == FileKind.PACKAGE) {
string txt = "module " ~ packageName ~ ";\n\n" ~ sourceCode;
write(fullPathName, txt);
} else {
write(fullPathName, sourceCode);
}
return true;
}
catch(Exception e) {
Log.e("Cannot create file", e);
return false;
}
}
string getPackageName(string path, string[] sourcePaths){
string sourcePath, relativePath;
if(!findSource(sourcePaths, path, sourcePath, relativePath)) return "";
return getPackageName(sourcePath, relativePath);
}
string getPackageName(string sourcePath, string relativePath){
char[] buf;
foreach(c; relativePath) {
char ch = c;
if (ch == '/' || ch == '\\')
ch = '.';
else if (ch == '.')
ch = '_';
if (ch == '.' && (buf.length == 0 || buf[$-1] == '.'))
continue; // skip duplicate .
buf ~= ch;
}
if (buf.length && buf[$-1] == '.')
buf.length--;
return buf.dup;
}
private bool findSource(string[] sourcePaths, string path, ref string sourceFolderPath, ref string relativePath) {
foreach(dir; sourcePaths) {
if (isSubdirOf(path, dir)) {
sourceFolderPath = dir;
relativePath = path[sourceFolderPath.length .. $];
if (relativePath.length > 0 && (relativePath[0] == '\\' || relativePath[0] == '/'))
relativePath = relativePath[1 .. $];
return true;
}
}
return false;
}
private bool isSubdirOf(string path, string basePath) {
if (path.equal(basePath))
return true;
if (path.length > basePath.length + 1 && path.startsWith(basePath)) {
char ch = path[basePath.length];
return ch == '/' || ch == '\\';
}
return false;
}

186
src/dlangide/ui/newfolder.d Normal file
View File

@ -0,0 +1,186 @@
module dlangide.ui.newfolder;
import std.array : empty;
import std.file : mkdir, exists;
import std.path : buildPath, buildNormalizedPath;
import std.utf : toUTF32;
import dlangui.core.logger;
import dlangui.core.stdaction;
import dlangui.dialogs.dialog;
import dlangui.dml.parser;
import dlangui.widgets.controls;
import dlangui.widgets.editors;
import dlangui.widgets.widget;
import dlangide.ui.commands;
import dlangide.ui.frame;
import dlangide.ui.newfile;
import dlangide.workspace.project;
class NewFolderDialog : Dialog {
private {
IDEFrame _ide;
Project _project;
ProjectFolder _folder;
string _location;
}
this(IDEFrame parent, Project currentProject, ProjectFolder folder) {
super(UIString.fromId("OPTION_NEW_SOURCE_FILE"c), parent.window,
DialogFlag.Modal | DialogFlag.Popup, 800, 0);
layoutWidth = FILL_PARENT;
_ide = parent;
_icon = "dlangui-logo1";
this._project = currentProject;
this._folder = folder;
if (folder){
_location = folder.filename;
}
else {
_location = currentProject.dir;
}
}
override void initialize() {
super.initialize();
Widget content;
try {
content = parseML(q{
VerticalLayout {
id: vlayout
padding: Rect { 5, 5, 5, 5 }
layoutWidth: fill; layoutHeight: wrap
TableLayout {
margins: 5
colCount: 2
layoutWidth: fill; layoutHeight: wrap
TextWidget { text: NAME }
EditLine { id: fileName; text: "newfolder"; layoutWidth: fill }
CheckBox { id: makePackage }
TextWidget { text: OPTION_MAKE_PACKAGE}
}
TextWidget { id: statusText; text: ""; layoutWidth: fill; textColor: 0xFF0000 }
}
});
} catch (Exception e) {
Log.e("Exceptin while parsing DML", e);
throw e;
}
_edFileName = content.childById!EditLine("fileName");
_edMakePackage = content.childById!CheckBox("makePackage");
_statusText = content.childById!TextWidget("statusText");
_edFileName.enterKey.connect(&onEnterKey);
_edFileName.setDefaultPopupMenu();
_edFileName.contentChange = delegate (EditableContent source) {
updateValues(source.text);
validate();
};
addChild(content);
addChild(createButtonsPanel([ACTION_FILE_NEW_DIRECTORY, ACTION_CANCEL], 0, 0));
updateValues(_edFileName.text);
}
override void onShow() {
super.onShow();
_edFileName.selectAll();
_edFileName.setFocus();
}
protected bool onEnterKey(EditWidgetBase editor) {
if (!validate())
return false;
close(_buttonActions[0]);
return true;
}
private bool validate() {
if (!isValidModuleName(_fileName))
return setError("Invalid folder name");
return setError(null);
}
private void updateValues(dstring fileName) {
_fileName = toUTF8(fileName);
}
private bool setError(dstring msg) {
_statusText.text = msg;
return msg.empty;
}
private {
EditLine _edFileName;
CheckBox _edMakePackage;
TextWidget _statusText;
string _fileName = "newfile";
FileCreationResult _result;
bool shouldMakePackage() @property {
return _edMakePackage.checked;
}
string fullPathName() @property {
return buildNormalizedPath(_location, _fileName);
}
}
private bool createItem() {
string fullPathName = this.fullPathName;
if(exists(fullPathName))
return setError("Folder already exists");
if(!makeDirectory(fullPathName)) return false;
if(shouldMakePackage) {
if(!makePackageFile(fullPathName)) {
return false;
}
}
_result = new FileCreationResult(_project, fullPathName);
return true;
}
private bool makeDirectory(string fullPathName) {
try {
mkdir(fullPathName);
return true;
} catch (Exception e) {
Log.e("Cannot create folder", e);
return setError("Cannot create folder");
}
}
private bool makePackageFile(string fullPathName) {
string packageName = getPackageName(fullPathName, _project.sourcePaths);
if(packageName.empty) {
Log.e("Could not determing package name for ", fullPathName);
return false;
}
if(!createFile(fullPathName.buildPath("package.d"), FileKind.PACKAGE, packageName, null)) {
Log.e("Could not create package file in folder ", fullPathName);
return false;
}
return true;
}
override void close(const Action action) {
Action newaction = action.clone();
if (action.id == IDEActions.FileNewDirectory) {
if (!validate()) {
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_PARAMETERS"c));
return;
}
if (!createItem()) {
window.showMessageBox(UIString.fromId("ERROR"c), UIString.fromId("ERROR_INVALID_PARAMETERS"c));
return;
}
newaction.objectParam = _result;
}
super.close(newaction);
}
}

View File

@ -38,7 +38,7 @@ class NewProjectDlg : Dialog {
IDEFrame _ide;
this(IDEFrame parent, bool newWorkspace, Workspace currentWorkspace, string dir) {
super(newWorkspace ? UIString.fromId("OPTION_NEW_WORKSPACE"c) : UIString.fromId("OPTION_NEW_PROJECT"c), parent.window,
super(newWorkspace ? UIString.fromId("OPTION_NEW_WORKSPACE"c) : UIString.fromId("OPTION_NEW_PROJECT"c), parent.window,
DialogFlag.Modal | DialogFlag.Resizable | DialogFlag.Popup, 500, 400);
_ide = parent;
_icon = "dlangui-logo1";
@ -64,8 +64,8 @@ class NewProjectDlg : Dialog {
margins: 5
layoutWidth: 25%; layoutHeight: fill
TextWidget { text: OPTION_PROJECT_TEMPLATE }
StringListWidget {
id: projectTemplateList
StringListWidget {
id: projectTemplateList
layoutWidth: wrap; layoutHeight: fill
}
}
@ -73,8 +73,8 @@ class NewProjectDlg : Dialog {
margins: 5
layoutWidth: 40%; layoutHeight: fill
TextWidget { text: OPTION_TEMPLATE_DESCR }
EditBox {
id: templateDescription; readOnly: true
EditBox {
id: templateDescription; readOnly: true
layoutWidth: fill; layoutHeight: fill
}
}
@ -82,7 +82,7 @@ class NewProjectDlg : Dialog {
layoutWidth: 35%; layoutHeight: fill
margins: 5
TextWidget { text: OPTION_DIRECTORY_LAYOUT }
EditBox {
EditBox {
id: directoryLayout; readOnly: true
layoutWidth: fill; layoutHeight: fill
}
@ -362,13 +362,13 @@ class NewProjectDlg : Dialog {
project.name = toUTF32(_projectName);
if (!project.save())
return setError("Cannot save project");
project.content.setString("targetName", _projectName);
project.content.setting.setString("targetName", _projectName);
if (_currentTemplate.isLibrary) {
project.content.setString("targetType", "staticLibrary");
project.content.setString("targetPath", "lib");
project.content.setting.setString("targetType", "staticLibrary");
project.content.setting.setString("targetPath", "lib");
} else {
project.content.setString("targetType", "executable");
project.content.setString("targetPath", "bin");
project.content.setting.setString("targetType", "executable");
project.content.setting.setString("targetPath", "bin");
}
if (_currentTemplate.json)
project.content.merge(_currentTemplate.json);
@ -500,7 +500,7 @@ extern (C) int UIAppMain(string[] args) {
};
// show message box with content of editors
window.mainWidget.childById!Button("btnOk").click = delegate(Widget w) {
window.showMessageBox(UIString.fromId("MSG_OK_BUTTON"c),
window.showMessageBox(UIString.fromId("MSG_OK_BUTTON"c),
UIString.fromId("EDITOR_CONTENT"c) ~ "\nEdit1: "d ~ edit1.text ~ "\nEdit2: "d ~ edit2.text);
return true;
};

View File

@ -25,14 +25,16 @@ enum ENABLE_INTERNAL_TERMINAL_TEST = false;
/// event listener to navigate by error/warning position
interface CompilerLogIssueClickHandler {
bool onCompilerLogIssueClick(dstring filename, int line, int column);
bool onCompilerLogIssueClick(dstring projectname, dstring filename, int line, int column);
}
class ErrorPosition {
dstring projectname;
dstring filename;
int line;
int pos;
this(dstring fn, int l, int p) {
this(dstring pname, dstring fn, int l, int p) {
projectname = pname;
filename = fn;
line = l;
pos = p;
@ -182,14 +184,16 @@ class CompilerLogWidget : LogWidget {
if (col < 0)
col = 0;
}
dstring projectname = findProjectForLine(line).to!dstring;
if (filename.startsWith("../") || filename.startsWith("..\\")) {
import dlangui.core.types : toUTF8;
string fn = filename.toUTF8;
resolveRelativePath(fn, line);
filename = fn.toUTF32;
}
return new ErrorPosition(filename, row, col);
return new ErrorPosition(projectname, filename, row, col);
}
return null;
}
@ -220,17 +224,17 @@ class CompilerLogWidget : LogWidget {
}
void resolveRelativePath(ref string path, int line) {
import std.path : getcwd, absolutePath;
Log.d("resolveRelativePath ", path, " current directory: ", getcwd);
import std.path : absolutePath;
Log.d("resolveRelativePath ", path);
string prjName = findProjectForLine(line);
if (prjName) {
Log.d("Error is in project ", prjName);
}
string base = _baseDirectory;
if (!base)
base = getcwd;
// TODO: select proper base
path = absolutePath(path, base);
path = absolutePath(path, base);
else
path = absolutePath(path);
Log.d("converted to absolute path: ", path);
}
///
@ -242,49 +246,11 @@ class CompilerLogWidget : LogWidget {
auto errorPos = errorFromLine(_caretPos.line);
if (errorPos) {
if (compilerLogIssueClickHandler.assigned) {
compilerLogIssueClickHandler(errorPos.filename, errorPos.line, errorPos.pos);
compilerLogIssueClickHandler(errorPos.projectname, errorPos.filename, errorPos.line, errorPos.pos);
}
}
auto logLine = this.content.line(this._caretPos.line);
//src\tetris.d(49): Error: found 'return' when expecting ';' following statement
auto match = matchFirst(logLine, ctr);
if(!match.empty) {
if (compilerLogIssueClickHandler.assigned) {
import std.conv:to;
int row = 0;
try {
row = to!int(match[2]) - 1;
} catch (Exception e) {
row = 0;
}
if (row < 0)
row = 0;
int col = 0;
if (match[3]) {
try {
col = to!int(match[3]) - 1;
} catch (Exception e) {
col = 0;
}
if (col < 0)
col = 0;
}
import dlangui.core.types : toUTF8;
string filename = match[1].toUTF8;
if (filename.startsWith("../") || filename.startsWith("..\\")) {
resolveRelativePath(filename, _caretPos.line);
}
compilerLogIssueClickHandler(filename.toUTF32, row, col);
}
}
return true;
return false;
}
return super.onMouseEvent(event);
}
}
@ -457,10 +423,10 @@ class OutputPanel : DockWindow {
_logWidget.text = ""d;
}
private bool onIssueClick(dstring fn, int line, int column)
private bool onIssueClick(dstring projectname, dstring fn, int line, int column)
{
if (compilerLogIssueClickHandler.assigned) {
compilerLogIssueClickHandler(fn, line, column);
compilerLogIssueClickHandler(projectname, fn, line, column);
}
return true;

View File

@ -352,9 +352,11 @@ class SearchWidget : TabWidget {
line--;
if (line == 0) {
if (_frame.openSourceFile(matchList.filename)) {
_frame.caretHistory.pushNewPosition();
_frame.currentEditor.setCaretPos(match.line, to!int(match.col));
_frame.currentEditor.setTextToHighlight(_findText.text, makeSearchFlags);
_frame.currentEditor.setFocus();
_frame.caretHistory.pushNewPosition();
}
return true;
}
@ -370,11 +372,11 @@ SearchMatchList findMatches(in string filename, in dstring searchString) {
SearchMatchList match;
match.filename = filename;
foreach(int lineIndex, dstring line; content.lines) {
foreach(lineIndex, dstring line; content.lines) {
auto colIndex = line.indexOf(searchString);
if (colIndex != -1) {
match.matches ~= SearchMatch(lineIndex, colIndex, line);
match.matches ~= SearchMatch(cast(int)lineIndex, colIndex, line);
}
}
return match;

View File

@ -62,41 +62,43 @@ StringListValue[] createIntValueList(int[] values, dstring suffix = ""d) {
/// create DlangIDE settings pages tree
SettingsPage createSettingsPages() {
import std.conv : to;
// Root page
SettingsPage res = new SettingsPage("", UIString.fromRaw(""d));
// UI settings page
SettingsPage ui = res.addChild("interface", UIString.fromId("OPTION_INTERFACE"c));
ui.addStringComboBox("interface/theme", UIString.fromId("OPTION_THEME"c), [
StringListValue("ide_theme_default", "OPTION_DEFAULT"c),
StringListValue("ide_theme_default", "OPTION_DEFAULT"c),
StringListValue("ide_theme_dark", "OPTION_DARK"c)]);
ui.addStringComboBox("interface/language", UIString.fromId("OPTION_LANGUAGE"c), [
StringListValue("en", "MENU_VIEW_LANGUAGE_EN"c),
StringListValue("ru", "MENU_VIEW_LANGUAGE_RU"c),
StringListValue("en", "MENU_VIEW_LANGUAGE_EN"c),
StringListValue("ru", "MENU_VIEW_LANGUAGE_RU"c),
StringListValue("es", "MENU_VIEW_LANGUAGE_ES"c),
StringListValue("cs", "MENU_VIEW_LANGUAGE_CS"c)]);
StringListValue("de", "MENU_VIEW_LANGUAGE_DE"c),
StringListValue("cs", "MENU_VIEW_LANGUAGE_CS"c)]);
// UI font faces
ui.addStringComboBox("interface/uiFontFace", UIString.fromId("OPTION_FONT_FACE"c),
ui.addStringComboBox("interface/uiFontFace", UIString.fromId("OPTION_FONT_FACE"c),
createFaceList(false));
ui.addIntComboBox("interface/uiFontSize", UIString.fromId("OPTION_FONT_SIZE"c),
ui.addIntComboBox("interface/uiFontSize", UIString.fromId("OPTION_FONT_SIZE"c),
createIntValueList([6,7,8,9,10,11,12,14,16,18,20,22,24,26,28,30,32]));
ui.addIntComboBox("interface/hintingMode", UIString.fromId("OPTION_FONT_HINTING"c), [StringListValue(0, "OPTION_FONT_HINTING_NORMAL"c),
StringListValue(1, "OPTION_FONT_HINTING_FORCE"c),
ui.addIntComboBox("interface/hintingMode", UIString.fromId("OPTION_FONT_HINTING"c), [StringListValue(0, "OPTION_FONT_HINTING_NORMAL"c),
StringListValue(1, "OPTION_FONT_HINTING_FORCE"c),
StringListValue(2, "OPTION_FONT_HINTING_DISABLED"c), StringListValue(3, "OPTION_FONT_HINTING_LIGHT"c)]);
ui.addIntComboBox("interface/minAntialiasedFontSize", UIString.fromId("OPTION_FONT_ANTIALIASING"c),
[StringListValue(0, "OPTION_FONT_ANTIALIASING_ALWAYS_ON"c),
StringListValue(12, "12"d),
StringListValue(14, "14"d),
StringListValue(16, "16"d),
StringListValue(20, "20"d),
StringListValue(24, "24"d),
StringListValue(32, "32"d),
StringListValue(48, "48"d),
ui.addIntComboBox("interface/minAntialiasedFontSize", UIString.fromId("OPTION_FONT_ANTIALIASING"c),
[StringListValue(0, "OPTION_FONT_ANTIALIASING_ALWAYS_ON"c),
StringListValue(12, "12"d),
StringListValue(14, "14"d),
StringListValue(16, "16"d),
StringListValue(20, "20"d),
StringListValue(24, "24"d),
StringListValue(32, "32"d),
StringListValue(48, "48"d),
StringListValue(255, "OPTION_FONT_ANTIALIASING_ALWAYS_OFF"c)]);
ui.addFloatComboBox("interface/fontGamma", UIString.fromId("OPTION_FONT_GAMMA"c),
ui.addFloatComboBox("interface/fontGamma", UIString.fromId("OPTION_FONT_GAMMA"c),
[
StringListValue(500, "0.5 "d),
StringListValue(600, "0.6 "d),
@ -107,16 +109,30 @@ SettingsPage createSettingsPages() {
StringListValue(950, "0.95 "d),
StringListValue(1000, "1.0 "d),
StringListValue(1050, "1.05 "d),
StringListValue(1100, "1.1 "d),
StringListValue(1150, "1.15 "d),
StringListValue(1200, "1.2 "d),
StringListValue(1250, "1.25 "d),
StringListValue(1300, "1.3 "d),
StringListValue(1400, "1.4 "d),
StringListValue(1500, "1.5 "d),
StringListValue(1700, "1.7 "d),
StringListValue(1100, "1.1 "d),
StringListValue(1150, "1.15 "d),
StringListValue(1200, "1.2 "d),
StringListValue(1250, "1.25 "d),
StringListValue(1300, "1.3 "d),
StringListValue(1400, "1.4 "d),
StringListValue(1500, "1.5 "d),
StringListValue(1700, "1.7 "d),
StringListValue(2000, "2.0 "d)]);
ui.addIntComboBox("interface/screenDpiOverride", UIString.fromId("OPTION_SCREEN_DPI_OVERRIDE"c),
[StringListValue(0, UIString.fromId("OPTION_SCREEN_DPI_OVERRIDE_NONE"c).value ~ " ("d ~ to!dstring(systemScreenDPI) ~ ")"d),
StringListValue(72, "72"d),
StringListValue(96, "96"d),
StringListValue(120, "120"d),
StringListValue(140, "140"d),
StringListValue(150, "150"d),
StringListValue(150, "180"d),
StringListValue(150, "200"d),
StringListValue(150, "250"d),
StringListValue(300, "300"d),
StringListValue(400, "400"d),
StringListValue(600, "600"d)]);
SettingsPage ed = res.addChild("editors", UIString.fromId("OPTION_EDITORS"c));
SettingsPage texted = ed.addChild("editors/textEditor", UIString.fromId("OPTION_TEXT_EDITORS"c));
@ -131,6 +147,7 @@ SettingsPage createSettingsPages() {
texted.addCheckbox("editors/textEditor/smartIndentsAfterPaste", UIString.fromId("OPTION_SMART_INDENTS_PASTE"c));
texted.addCheckbox("editors/textEditor/showWhiteSpaceMarks", UIString.fromId("OPTION_SHOW_SPACES"c));
texted.addCheckbox("editors/textEditor/showTabPositionMarks", UIString.fromId("OPTION_SHOW_TABS"c));
texted.addCheckbox("editors/textEditor/autoAutoComplete", UIString.fromId("OPTION_AUTO_AUTOCOMPLETE"c));
// Common page
SettingsPage common = res.addChild("common", UIString.fromId("OPTION_COMMON"c));
@ -176,14 +193,14 @@ SettingsPage createProjectSettingsPages() {
SettingsPage build = res.addChild("build", UIString.fromId("OPTION_BUILD"c));
build.addStringComboBox("build/toolchain", UIString.fromId("OPTION_TOOLCHAIN"c), [
StringListValue("default", UIString.fromId("OPTION_DEFAULT"c)),
StringListValue("dmd", "DMD"d),
StringListValue("ldc", "LDC"d),
StringListValue("ldmd", "LDMD"d),
StringListValue("default", UIString.fromId("OPTION_DEFAULT"c)),
StringListValue("dmd", "DMD"d),
StringListValue("ldc", "LDC"d),
StringListValue("ldmd", "LDMD"d),
StringListValue("gdc", "GDC"d)]);
build.addStringComboBox("build/arch", UIString.fromId("OPTION_ARCHITECTURE"c), [
StringListValue("default", UIString.fromId("OPTION_DEFAULT"c)),
StringListValue("x86", "x86"d),
StringListValue("default", UIString.fromId("OPTION_DEFAULT"c)),
StringListValue("x86", "x86"d),
StringListValue("x86_64", "x86_64"d),
StringListValue("arm", "arm"d),
StringListValue("arm64", "arm64"d),

View File

@ -44,6 +44,9 @@ class WorkspacePanel : DockWindow {
if (projectItem) {
TreeItem item = _tree.findItemById(projectItem.filename);
if (item) {
if (item.parent && !item.parent.isFullyExpanded)
_tree.items.toggleExpand(item.parent);
_tree.makeItemVisible(item);
_tree.selectItem(item);
return true;
}
@ -89,7 +92,8 @@ class WorkspacePanel : DockWindow {
_tree.popupMenu = &onTreeItemPopupMenu;
_workspacePopupMenu = new MenuItem();
_workspacePopupMenu.add(ACTION_PROJECT_FOLDER_REFRESH,
_workspacePopupMenu.add(ACTION_FILE_NEW_PROJECT,
ACTION_PROJECT_FOLDER_REFRESH,
ACTION_FILE_WORKSPACE_CLOSE,
ACTION_PROJECT_FOLDER_EXPAND_ALL,
ACTION_PROJECT_FOLDER_COLLAPSE_ALL
@ -98,7 +102,7 @@ class WorkspacePanel : DockWindow {
_projectPopupMenu = new MenuItem();
_projectPopupMenu.add(ACTION_PROJECT_SET_STARTUP,
ACTION_PROJECT_FOLDER_REFRESH,
ACTION_FILE_NEW_SOURCE_FILE,
//ACTION_FILE_NEW_DIRECTORY,
//ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_BUILD,
ACTION_PROJECT_REBUILD,
@ -112,14 +116,17 @@ class WorkspacePanel : DockWindow {
);
_folderPopupMenu = new MenuItem();
_folderPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_REFRESH, ACTION_PROJECT_FOLDER_OPEN_ITEM,
_folderPopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE,
ACTION_FILE_NEW_DIRECTORY,
ACTION_PROJECT_FOLDER_REFRESH, ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_FOLDER_EXPAND_ALL, ACTION_PROJECT_FOLDER_COLLAPSE_ALL
//ACTION_PROJECT_FOLDER_REMOVE_ITEM,
//ACTION_PROJECT_FOLDER_RENAME_ITEM
);
_filePopupMenu = new MenuItem();
_filePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE, ACTION_PROJECT_FOLDER_REFRESH,
_filePopupMenu.add(ACTION_FILE_NEW_SOURCE_FILE,
ACTION_PROJECT_FOLDER_REFRESH,
ACTION_PROJECT_FOLDER_OPEN_ITEM,
ACTION_PROJECT_FOLDER_REMOVE_ITEM,
//ACTION_PROJECT_FOLDER_RENAME_ITEM
@ -182,9 +189,9 @@ class WorkspacePanel : DockWindow {
return cast(ProjectItem)obj;
}
ProjectSourceFile findSourceFileItem(string filename, bool fullFileName=true) {
ProjectSourceFile findSourceFileItem(string filename, bool fullFileName=true, dstring projectName=null) {
if (_workspace)
return _workspace.findSourceFileItem(filename, fullFileName);
return _workspace.findSourceFileItem(filename, fullFileName, projectName);
return null;
}

View File

@ -7,7 +7,7 @@ import dlangui.graphics.fonts;
import std.algorithm : equal;
const AVAILABLE_THEMES = ["ide_theme_default", "ide_theme_dark"];
const AVAILABLE_LANGUAGES = ["en", "ru", "es", "cs"];
const AVAILABLE_LANGUAGES = ["en", "ru", "es", "cs", "de"];
class IDESettings : SettingsFile {
@ -23,6 +23,7 @@ class IDESettings : SettingsFile {
ed.setBooleanDef("smartIndentsAfterPaste", true);
ed.setBooleanDef("showWhiteSpaceMarks", true);
ed.setBooleanDef("showTabPositionMarks", true);
ed.setBooleanDef("autoAutoComplete", true);
ed.setStringDef("fontFace", "Default");
ed.setIntegerDef("fontSize", 11);
Setting ui = uiSettings();
@ -32,9 +33,10 @@ class IDESettings : SettingsFile {
ui.setIntegerDef("minAntialiasedFontSize", 0);
ui.setFloatingDef("fontGamma", 0.8);
ui.setStringDef("uiFontFace", "Default");
ui.setIntegerDef("uiFontSize", 10);
ui.setIntegerDef("uiFontSize", 11);
ui.setBooleanDef("showToolbar", true);
ui.setBooleanDef("showStatusbar", true);
ui.setIntegerDef("screenDpiOverride", 0);
version (Windows) {
debuggerSettings.setStringDef("executable", "mago-mi");
} else {
@ -58,7 +60,7 @@ class IDESettings : SettingsFile {
/// override to do something after loading - e.g. set defaults
override void afterLoad() {
}
@property Setting editorSettings() {
Setting res = _setting.objectByPath("editors/textEditor", true);
return res;
@ -129,6 +131,17 @@ class IDESettings : SettingsFile {
return this;
}
/// to allow overriding detected screen DPI
@property int screenDpiOverride() {
return cast(int)uiSettings.getInteger("screenDpiOverride", 0);
}
/// to allow overriding detected screen DPI
@property IDESettings screenDpiOverride(int newDpi) {
uiSettings.setInteger("screenDpiOverride", newDpi);
return this;
}
/// UI font face
@property string uiFontFace() {
return uiSettings.getString("uiFontFace", "Default");
@ -159,6 +172,16 @@ class IDESettings : SettingsFile {
return this;
}
/// Text editor setting, true if auto-complete is triggered on each key press
@property bool autoAutoComplete() {
return editorSettings.getBoolean("autoAutoComplete", true);
}
///
@property IDESettings autoAutoComplete(bool v) {
editorSettings.setBoolean("autoAutoComplete", v);
return this;
}
/// true if smart indents are enabled
@property bool smartIndents() { return editorSettings.getBoolean("smartIndents", true); }
/// set smart indents enabled flag
@ -305,7 +328,7 @@ class IDESettings : SettingsFile {
obj["recentWorkspaces"] = list;
save();
}
@property bool autoOpenLastProject() {
Setting obj =_setting.objectByPath("common", true);
return obj.getBoolean("autoOpenLastProject", false);

View File

@ -11,6 +11,7 @@ import std.file;
import std.path;
import std.process;
import std.utf;
import std.ascii : isAlphaNum;
string[] includePath;
@ -311,19 +312,19 @@ struct ProjectConfiguration {
string name;
/// type, for libraries one can run tests, for apps - execute them
Type type;
/// How to display default configuration in ui
immutable static string DEFAULT_NAME = "default";
/// Default project configuration
immutable static ProjectConfiguration DEFAULT = ProjectConfiguration(DEFAULT_NAME, Type.Default);
/// Type of configuration
enum Type {
Default,
Executable,
Library
}
private static Type parseType(string s)
{
switch(s)
@ -335,7 +336,7 @@ struct ProjectConfiguration {
default: return Type.Default;
}
}
/// parsing from setting file
static ProjectConfiguration[] load(Setting s)
{
@ -422,7 +423,7 @@ class Project : WorkspaceItem {
includePath ~= obj.str;
}
_items = new ProjectFolder(fname);
_items = new ProjectFolder(fname.dirName);
_dependencyVersion = dependencyVersion;
_isDependency = _dependencyVersion.length > 0;
_projectFile = new SettingsFile(fname);
@ -490,7 +491,7 @@ class Project : WorkspaceItem {
/// name
override @property void name(dstring s) {
super.name(s);
_projectFile.setString("name", toUTF8(s));
_projectFile.setting.setString("name", toUTF8(s));
}
/// name
@ -501,7 +502,7 @@ class Project : WorkspaceItem {
/// name
override @property void description(dstring s) {
super.description(s);
_projectFile.setString("description", toUTF8(s));
_projectFile.setting.setString("description", toUTF8(s));
}
/// returns project's own source paths
@ -576,12 +577,12 @@ class Project : WorkspaceItem {
if (!isExecutable)
return null;
string exename = toUTF8(name);
exename = _projectFile.getString("targetName", exename);
exename = _projectFile.setting.getString("targetName", exename);
// TODO: use targetName
version (Windows) {
exename = exename ~ ".exe";
}
string targetPath = _projectFile.getString("targetPath", null);
string targetPath = _projectFile.setting.getString("targetPath", null);
string exePath;
if (targetPath.length)
exePath = buildNormalizedPath(_filename.dirName, targetPath, exename); // int $targetPath directory
@ -607,8 +608,8 @@ class Project : WorkspaceItem {
return settings.runInExternalConsole;
}
ProjectFolder findItems(string[] srcPaths) {
auto folder = new ProjectFolder(_filename);
private ProjectFolder findItems(string[] srcPaths) {
auto folder = new ProjectFolder(_filename.dirName);
folder.project = this;
foreach(customPath; srcPaths) {
string path = relativeToAbsolutePath(customPath);
@ -685,10 +686,10 @@ class Project : WorkspaceItem {
protected string[] findSourcePaths() {
string[] res;
res.assumeSafeAppend;
string[] srcPaths = _projectFile.getStringArray("sourcePaths");
string[] srcPaths = _projectFile.setting.getStringArray("sourcePaths");
foreach(s; srcPaths)
addRelativePathIfExists(res, s);
Setting configs = _projectFile.objectByPath("configurations");
Setting configs = _projectFile.setting.objectByPath("configurations");
if (configs) {
for (int i = 0; i < configs.length; i++) {
Setting s = configs[i];
@ -710,7 +711,7 @@ class Project : WorkspaceItem {
void processSubpackages() {
import dlangui.core.files;
_subPackages.length = 0;
Setting subPackages = _projectFile.settingByPath("subPackages", SettingType.ARRAY, false);
Setting subPackages = _projectFile.setting.settingByPath("subPackages", SettingType.ARRAY, false);
if (subPackages) {
string p = _projectFile.filename.dirName;
for(int i = 0; i < subPackages.length; i++) {
@ -761,7 +762,7 @@ class Project : WorkspaceItem {
//
_mainSourceFile = null;
try {
_name = toUTF32(_projectFile.getString("name"));
_name = toUTF32(_projectFile.setting.getString("name"));
_originalName = _name;
if (_baseProjectName) {
_name = _baseProjectName ~ ":" ~ _name;
@ -770,7 +771,7 @@ class Project : WorkspaceItem {
_name ~= "-"d;
_name ~= toUTF32(_dependencyVersion.startsWith("~") ? _dependencyVersion[1..$] : _dependencyVersion);
}
_description = toUTF32(_projectFile.getString("description"));
_description = toUTF32(_projectFile.setting.getString("description"));
Log.d(" project name: ", _name);
Log.d(" project description: ", _description);
@ -786,7 +787,7 @@ class Project : WorkspaceItem {
if (!_isDependency)
loadSelections();
_configurations = ProjectConfiguration.load(_projectFile);
_configurations = ProjectConfiguration.load(_projectFile.setting);
Log.i("Project configurations: ", _configurations);
@ -842,7 +843,7 @@ class Project : WorkspaceItem {
_dependencies = newdeps;
return false;
}
Setting versions = selectionsFile.objectByPath("versions");
Setting versions = selectionsFile.setting.objectByPath("versions");
if (!versions.isObject) {
_dependencies = newdeps;
return false;
@ -934,19 +935,19 @@ class DubPackageFinder {
bool isValidProjectName(in string s) pure {
if (s.empty)
return false;
return reduce!q{ a && (b == '_' || b == '-' || std.ascii.isAlphaNum(b)) }(true, s);
return reduce!((a, b) => a && (b == '_' || b == '-' || isAlphaNum(b)))(true, s);
}
bool isValidModuleName(in string s) pure {
if (s.empty)
return false;
return reduce!q{ a && (b == '_' || std.ascii.isAlphaNum(b)) }(true, s);
return reduce!((a, b) => a && (b == '_' || isAlphaNum(b)))(true, s);
}
bool isValidFileName(in string s) pure {
if (s.empty)
return false;
return reduce!q{ a && (b == '_' || b == '.' || b == '-' || std.ascii.isAlphaNum(b)) }(true, s);
return reduce!((a, b) => a && (b == '_' || b == '.' || b == '-' || isAlphaNum(b)))(true, s);
}
unittest {

View File

@ -54,9 +54,9 @@ class Workspace : WorkspaceItem {
protected Project[] _projects;
protected SettingsFile _workspaceFile;
protected WorkspaceSettings _settings;
protected IDEFrame _frame;
this(IDEFrame frame, string fname = WORKSPACE_EXTENSION) {
super(fname);
_workspaceFile = new SettingsFile(fname);
@ -74,9 +74,9 @@ class Workspace : WorkspaceItem {
}
@property Setting includePath(){
Setting res = _workspaceFile.objectByPath("includePath", true);
Setting res = _workspaceFile.setting.objectByPath("includePath", true);
return res;
}
}
@property Project[] projects() { return _projects; }
@ -91,19 +91,19 @@ class Workspace : WorkspaceItem {
protected Project _startupProject;
@property Project startupProject() { return _startupProject; }
@property void startupProject(Project project) {
@property void startupProject(Project project) {
if (_startupProject is project)
return;
_startupProject = project;
_settings.startupProjectName = toUTF8(project.name);
_frame.updateProjectConfigurations();
}
/// Last opened files in workspace
@property WorkspaceFile[] files() {
return _settings.files();
}
/// Last opened files in workspace
@property void files(WorkspaceFile[] fs) {
_settings.files(fs);
@ -159,7 +159,7 @@ class Workspace : WorkspaceItem {
updateBreakpointFiles(res);
return res;
}
void setSourceFileBreakpoints(ProjectSourceFile file, Breakpoint[] breakpoints) {
_settings.setProjectBreakpoints(toUTF8(file.project.name), file.projectFilePath, breakpoints);
}
@ -169,7 +169,7 @@ class Workspace : WorkspaceItem {
updateBookmarkFiles(res);
return res;
}
void setSourceFileBookmarks(ProjectSourceFile file, EditorBookmark[] bookmarks) {
_settings.setProjectBookmarks(toUTF8(file.project.name), file.projectFilePath, bookmarks);
}
@ -180,7 +180,7 @@ class Workspace : WorkspaceItem {
updateBreakpointFiles(res);
return res;
}
protected void fillStartupProject() {
string s = _settings.startupProjectName;
if ((!_startupProject || !_startupProject.name.toUTF8.equal(s)) && _projects.length) {
@ -198,8 +198,10 @@ class Workspace : WorkspaceItem {
}
/// tries to find source file in one of projects, returns found project source file item, or null if not found
ProjectSourceFile findSourceFileItem(string filename, bool fullFileName=true) {
ProjectSourceFile findSourceFileItem(string filename, bool fullFileName=true, dstring projectName = null) {
foreach (Project p; _projects) {
if (projectName && p.name != projectName)
continue;
ProjectSourceFile res = p.findSourceFileItem(filename, fullFileName);
if (res)
return res;
@ -310,13 +312,13 @@ class Workspace : WorkspaceItem {
if (nf && !_name.empty) // cut off last comma
_name = _name[ 0 .. $ - 1 ];
if (df && !_description.empty) // cut off last delimiter
_description = _description[ 0 .. $ - 3 ];
_description = _description[ 0 .. $ - 3 ];
}
_workspaceFile.setString("name", toUTF8(_name));
_workspaceFile.setString("description", toUTF8(_description));
_workspaceFile.setting.setString("name", toUTF8(_name));
_workspaceFile.setting.setString("description", toUTF8(_description));
Log.d("workspace name: ", _name);
Log.d("workspace description: ", _description);
Setting projects = _workspaceFile.objectByPath("projects", true);
Setting projects = _workspaceFile.setting.objectByPath("projects", true);
projects.clear(SettingType.OBJECT);
foreach (Project p; _projects) {
if (p.isDependency)
@ -344,8 +346,8 @@ class Workspace : WorkspaceItem {
return false;
}
_settings.load(filename ~ WORKSPACE_SETTINGS_EXTENSION);
_name = toUTF32(_workspaceFile["name"].str);
_description = toUTF32(_workspaceFile["description"].str);
_name = toUTF32(_workspaceFile.setting["name"].str);
_description = toUTF32(_workspaceFile.setting["description"].str);
Log.d("workspace name: ", _name);
Log.d("workspace description: ", _description);
if (_name.empty()) {
@ -353,7 +355,7 @@ class Workspace : WorkspaceItem {
return false;
}
auto originalStartupProjectName = _settings.startupProjectName;
Setting projects = _workspaceFile.objectByPath("projects", true);
Setting projects = _workspaceFile.setting.objectByPath("projects", true);
foreach(string key, Setting value; projects) {
string path = value.str;
Log.d("project: ", key, " path:", path);

View File

@ -1 +1 @@
v0.8.1
v0.8.17

View File

@ -4,3 +4,4 @@ res/i18n/en.ini
res/i18n/ru.ini
res/i18n/es.ini
res/i18n/cs.ini
res/i18n/de.ini

View File

@ -4,4 +4,11 @@
fontFamily="SansSerif"
textColor="#E0E0E0"
>
<style id="HOME_SCREEN_TITLE"
textColor="#60A0FF"
/>
<style id="HOME_SCREEN_TITLE2"
textColor="#60A0FF"
/>
</theme>

View File

@ -42,5 +42,13 @@
<drawable id="debug-step-over" value="{'↓' #0000FF}"/>
<drawable id="debug-step-out" value="{'↑' #0000FF}"/>
<style id="HOME_SCREEN_TITLE"
textColor="#2020FF"
/>
<style id="HOME_SCREEN_TITLE2"
textColor="#2020FF"
/>
</theme>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -80,6 +80,7 @@ MENU_VIEW_LANGUAGE_EN=English
MENU_VIEW_LANGUAGE_RU=Русский
MENU_VIEW_LANGUAGE_CS=Čeština
MENU_VIEW_LANGUAGE_ES=Spanish
MENU_VIEW_LANGUAGE_DE=Deutsch
MENU_VIEW_THEME=&Téma
MENU_VIEW_THEME_DEFAULT=&Default
MENU_VIEW_THEME_CUSTOM1=&Custom 1

268
views/res/i18n/de.ini Normal file
View File

@ -0,0 +1,268 @@
ABOUT=Über DlangIDE
HOME=DlangIDE Home
DESCRIPTION=D-Sprach-IDE geschrieben in D
COPYRIGHT=(c) Vadim Lopatin 2017
START_WITH=Starten mit:
RECENT=Kürzlich:
NO_RECENT=Keine kürzlich verwendete Einträge
USEFUL_LINKS=Nützliche Links:
D_LANG=D Programmiersprache
DUB_REP=DUB Repository
DLANG_DOWNLOADS=D-Compiler downloaden
DLANG_UI=DLangUI auf GitHub
DLANG_IDE=DLangIDE auf GitHub
DLANG_IDE_HELP=DLangIDE Onlinedokumentation
DLANG_TOUR=DLang Tour
DLANG_VIBED=Vibe-D
DLANG_FORUM=Dlang Forum
DLANG_IDE_DONATE=DlangIDE unterstützen
DLANG_IDE_DONATE_PAYPAL=Spenden über PayPal
EXIT=Beenden
PROFILER_WINDOW=Profiler
ALL_FILES=Alle Dateien
SOURCE_FILES=Quelldateien
WORKSPACE_AND_PROJECT_FILES=Workspace- und Projektdateien
IDE_FILES=DlangIDE Dateien
PROFILER_LOG_FILES=DMD Profiler Logs
EDITOR_CONTENT=Editorinhalte
LOCATION=Position
NAME=Name
MENU_FILE=Datei
MENU_FILE_NEW=Erstelle
MENU_FILE_NEW_SOURCE_FILE=Neue Datei
MENU_FILE_NEW_PROJECT=Neues Projekt
MENU_FILE_NEW_WORKSPACE=Neue Workspace
MENU_FILE_OPEN=Öffne Datei...
MENU_FILE_OPEN_WORKSPACE=Öffne Projekt oder Workspace...
MENU_FILE_OPEN_RECENT=Öffne kürzlich
MENU_FILE_SAVE=&Speichern
MENU_FILE_SAVE_AS=&Speichern unter...
MENU_FILE_SAVE_ALL=Alles &speichern
MENU_FILE_WORKSPACE_CLOSE=Schließe Workspace
MENU_FILE_EXIT=Beende
MENU_EDIT=&Editieren
MENU_EDIT_COPY=Kopieren
MENU_EDIT_PASTE=Einfügen
MENU_EDIT_CUT=Ausschneiden
MENU_EDIT_UNDO=Rückgängig
MENU_EDIT_REDO=Wiederherstellen
MENU_EDIT_INDENT=Block einrücken
MENU_EDIT_UNINDENT=Block ausrücken
MENU_EDIT_TOGGLE_LINE_COMMENT=Zeilenkommentare umschalten
MENU_EDIT_TOGGLE_BLOCK_COMMENT=Blockkommentare umschalten
MENU_EDIT_ADVANCED=Erweitert...
MENU_EDIT_PREFERENCES=Einstellungen
MENU_VIEW=Ansicht
MENU_VIEW_SHOW_WHITESPACE_MARKS=Zeige Leerzeichenmarkierungen an
MENU_VIEW_SHOW_TAB_POSITIONS=Tabpositionsmarkierungen
MENU_VIEW_SHOW_TOOLBAR=Zeige Toolbar an
MENU_VIEW_SHOW_STATUSBAR=Zeige Statusbar an
MENU_PROJECT=&Projekt
MENU_PROJECT_CONFIGURATIONS=Projekt konfigurieren
MENU_PROJECT_SET_AS_STARTUP=Als Startprojekt setzen
MENU_PROJECT_SETTINGS=Projekteinstellungen
MENU_PROJECT_REFRESH=Workspace-Einträge aktualisieren
MENU_PROJECT_UPDATE_DEPENDENCIES=Abhänigkeiten aktualisieren
MENU_NAVIGATE=&Navigation
GO_TO_DEFINITION=Gehe zu Definition
SHOW_COMPLETIONS=Autovervollständigung anzeigen
SHOW_DOC_COMMENTS=Dokumentation anzeigen
SHOW_PAREN_COMPLETION=Autrufvorschläge
GO_TO_LINE=Gehe zu Zeile
FIND_IN_FILES=Finde in Dateien...
MENU_BUILD_CONFIGURATIONS=Build-Konfigurationen
MENU_BUILD_CONFIGURATION=Build-Konfiguration
MENU_BUILD=&Build
MENU_BUILD_WORKSPACE_BUILD=Baue Workspace
MENU_BUILD_WORKSPACE_REBUILD=Baue erneut Workspace
MENU_BUILD_WORKSPACE_CLEAN=Säubere Workspace
MENU_BUILD_PROJECT_BUILD=Baue Projekt
MENU_BUILD_PROJECT_REBUILD=Baue erneut Projekt
MENU_BUILD_PROJECT_CLEAN=Säubere Projekt
MENU_BUILD_RUN_WITH_RDMD=Starte mit rdmd
MENU_BUILD_CONFIGURATION=Build-Type
MENU_PROJECT_CONFIGURATION=Projektkonfiguration
MENU_DEBUG=&Debug
MENU_DEBUG_START_DEBUGGING=Starte debuggen
MENU_DEBUG_START_NO_DEBUGGING=Starte ohne debuggen
MENU_DEBUG_CONTINUE=Debuggen fortfahren
MENU_DEBUG_STOP=Stop
MENU_DEBUG_PAUSE=Pause
MENU_DEBUG_RESTART=Neustart
MENU_DEBUG_STEP_INTO=Springe hinein
MENU_DEBUG_STEP_OVER=Springe hinweg
MENU_DEBUG_STEP_OUT=Springe heraus
MENU_DEBUG_BREAKPOINT_TOGGLE=Haltepunkt umschalten
MENU_DEBUG_BREAKPOINT_ENABLE=Aktiviere Haltepunkt
MENU_DEBUG_BREAKPOINT_DISABLE=Deaktiviere Haltepunkt
MENU_WINDOW=Fenster
MENU_WINDOW_PREFERENCES=Einstellungen
MENU_WINDOW_CLOSE_DOCUMENT=Schließe Dokument
MENU_WINDOW_CLOSE_ALL_DOCUMENTS=Schließe alle Dokumente
MENU_WINDOW_SHOW_HOME_SCREEN=Zeige Homescreen
MENU_WINDOW_SHOW_WORKSPACE_EXPLORER=Workspace-Explorer
MENU_WINDOW_SHOW_LOG_WINDOW=Log-Fenster
MENU_HELP=&Hilfe
MENU_HELP_VIEW_HELP=Online Hilfe
MENU_HELP_ABOUT=Über
MENU_HELP_DONATE=Spenden über PayPal
MENU_VIEW=Anzeige
MENU_VIEW_LANGUAGE=Oberflächensprache
MENU_VIEW_LANGUAGE_EN=English
MENU_VIEW_LANGUAGE_RU=Русский
MENU_VIEW_LANGUAGE_CS=Čeština
MENU_VIEW_LANGUAGE_ES=Spanish
MENU_VIEW_LANGUAGE_DE=Deutsch
MENU_VIEW_THEME=&Theme
MENU_VIEW_THEME_DEFAULT=Standart
MENU_VIEW_THEME_CUSTOM1=&Custom 1
MENU_TOOLS=Tools
OPEN_DMD_TRACE_LOG=Öffne DMD Profiler-Log
TAB_LONG_LIST=Lange Liste
TAB_BUTTONS=Knopf
TAB_ANIMATION=Animation
TAB_TABLE_LAYOUT=Tabellenlayout
TAB_EDITORS=Editoren
MENU_PROJECT_FOLDER_ADD_ITEM=Hinzufügen...
MENU_PROJECT_FOLDER_OPEN_ITEM=Öffnen
MENU_PROJECT_FOLDER_REMOVE_ITEM=Umbenennen
MENU_PROJECT_FOLDER_RENAME_ITEM=Umbenennen...
MENU_PROJECT_FOLDER_REFRESH=Aktualisieren
MENU_PROJECT_REVEAL_IN_EXPLORER=Zeige im Dateimanager an
MENU_PROJECT_FOLDER_EXPAND_ALL=Alles ausklappen
MENU_PROJECT_FOLDER_COLLAPSE_ALL=Alles einklappen
HEADER_SETTINGS=DlangIDE Einstellungen
HEADER_OPEN_WORKSPACE_OR_PROJECT=Öffne Workspace oder Projekt
HEADER_OPEN_TEXT_FILE=Öffne Textdatei
HEADER_OPEN_DMD_PROFILER_LOG=Öffne DMD Profiler Logdatei
HEADER_CLOSE_FILE=Schließe Datei
HEADER_CLOSE_TAB=Schließe Tab
HEADER_PROJECT_SETTINGS=Projekteinstellungen
HEADER_REMOVE_FILE=Entferne Datei
HEADER_SAVE_FILE_AS=Speichere Datei unter
OPTION_ADD_TO_CURRENT_WORKSPACE=Füge zur momentaner Wokrspace hinzu
OPTION_ARCHITECTURE=Architektur
OPTION_AUTO_OPEN_LAST_PROJECT=Öffne automatisch das letzte Projekt
OPTION_BUILD=Build
OPTION_COMMAND_LINE=Kommandozeilenargumente
OPTION_COMMON=Standard
OPTION_CREATE_NEW_SOLUTION=Erstelle neue Ansicht
OPTION_CREATE_NEW_WORKSPACE=Erstelle neue Workspace
OPTION_CREATE_SUBDIRECTORY_FOR_PROJECT=Erstelle einen Unterordner für das Projekt
OPTION_CREATE_SUBDIRECTORY_FOR_WORKSPACE=Erstelle einen Unterordner für die Workspace
OPTION_DARK=Dunkel
OPTION_DEBUGGER=Debugger
OPTION_DEBUGGER_EXECUTABLE=Debugger-Anwendung
OPTION_DEFAULT=Standard
OPTION_DIRECTORY_LAYOUT=Ordneransicht
OPTION_DMD_EXECUTABLE=DMD-Anwendung
OPTION_DUB_ADDITIONAL_PARAMS=DUB zusätzliche Parameter
OPTION_DUB_EXECUTABLE=DUB-Anwendung
OPTION_EDITORS=Editoren
OPTION_INTERFACE=Interface
OPTION_FILE_PATH=Dateipfad
OPTION_FONT_ANTIALIASING=Minimale Schriftgröße für Antialiasing
OPTION_FONT_ANTIALIASING_ALWAYS_OFF=Immer AUS
OPTION_FONT_ANTIALIASING_ALWAYS_ON=Immer AN
OPTION_FONT_HINTING=Schrift-Hinting
OPTION_FONT_HINTING_DISABLED=Abgeschaltet
OPTION_FONT_HINTING_FORCE=Erzwinge automatische Hints
OPTION_FONT_HINTING_NORMAL=Normal
OPTION_FONT_HINTING_LIGHT=LIGHT
OPTION_FONT_FACE=Schriftart
OPTION_FONT_SIZE=Schriftgröße
OPTION_FONT_GAMMA=Schrift-Gamma
OPTION_SCREEN_DPI_OVERRIDE=Überschreibe Bildschirm DPI
OPTION_SCREEN_DPI_OVERRIDE_NONE=Standard Bildschirm DPI
OPTION_GDC_EXECUTABLE=GDC-Anwendung
OPTION_LANGUAGE=Sprache
OPTION_LDC2_EXECUTABLE=LDC2-Anwendung
OPTION_LDMD2_EXECUTABLE=LDMD2-Anwendung
OPTION_MODULE_NAME=Modulname
OPTION_NEW_PROJECT=Neues Projekt
OPTION_NEW_SOURCE_FILE=Neue Quelldatei
OPTION_NEW_WORKSPACE=Neue Workspace
OPTION_PROJECT_NAME=Projektname
OPTION_PROJECT_TEMPLATE=Projektvorlage
OPTION_RDMD_ADDITIONAL_PARAMS=rdmd zusätzliche Parameter
OPTION_RDMD_EXECUTABLE=rdmd-Anwendung
OPTION_RUN_IN_EXTERNAL_CONSOLE=Starte in externen Konsole
OPTION_RUN_DEBUG=Starte und debugge
OPTION_SHOW_SPACES=Zeige Leerzeichenmarkierungen an
OPTION_SHOW_TABS=Zeige Tabpositionsmarkierungen an
OPTION_SMART_INDENTS=Schlaues Einrücken
OPTION_SMART_INDENTS_PASTE=Schlaues Einrücken nach Einfügen
OPTION_TAB=Tabgröße
OPTION_TEMPLATE_DESCR=Vorlagenbeschreibung
OPTION_TEXT_EDITORS=Texteditor
OPTION_TERMINAL=Terminal
OPTION_TERMINAL_EXECUTABLE=Terminal-Anwendung
OPTION_THEME=Theme
OPTION_TOOLCHAIN=Toolchain
OPTION_TOOLCHAINS=Toolchains
OPTION_VERBOSE=Verbose
OPTION_WORKING_DIR=Arbeitsverzeichnis
OPTION_WORKSPACE_NAME=Workspace-Name
OPTION_USE_SPACES=Nutze Leerzeichen für Tabs
ERROR=Fehler
ERROR_CANNOT_CREATE_PROJECT=Projekte konnte nicht erstellt werden
ERROR_CANNOT_DEBUG_PROJECT=Projekt konnte nicht gedebuggt werden
ERROR_CANNOT_FIND_EXEC=Ausführbare Datei nicht gefunden
ERROR_CANNOT_RUN_PROJECT=Projekt konnte nicht gestartet werden
ERROR_FAILED_CREATE_PROJECT=Projekt konnte nicht erstllt werden
ERROR_STARTUP_PROJECT_ABSENT=Kein Startprojekt angegeben
ERROR_INVALID_NUMBER=Unzulässige Nummer
ERROR_INVALID_PARAMETERS=Ungültiger Parameter
ERROR_INVALID_WORKSPACE_FILE=Ungültige Workspace-Datei
ERROR_INVALID_WS_OR_PROJECT_FILE=Diese Datei ist keine gültige Workspace-/Projektdatei
ERROR_NO_DEBUGGER=Kein Debugger in den Einstellungen angegeben
ERROR_NO_SUCH_LINE=Keine solche Zeile
ERROR_OPEN_FILE=Datei konnte nicht geöffnet werden
ERROR_OPEN_PROJECT=Projekt konnte nicht geöffnet werden
ERROR_OPEN_WORKSPACE=Workspace konnte nicht geöffnet werden
ERROR_OPENING_FILE=Datei konnte nicht geöffnet werden
ERROR_OPENING_PROJECT=Ein Fehler trat auf beim öffnen des Projekts
ERROR_OPENING_WORKSPACE=Ein Fehler trat auf beim öffnen der Workspace
ERROR_FAILED_TO_PARSE_TRACE_LOG_FILE=Fehler beim Verarbeiten vom Trace-Log
MSG_FILE_CONTENT_CHANGED=Dateiinhalt hat sich verändert.
MSG_TAB_CONTENT_CHANGED=Tabinhalt hat sich verändert
MSG_OK_BUTTON=OK-Knopf gedrückt
MSG_OPEN_PROJECT=Öffne Projekt
MSG_PROJECT_ALREADY_OPENED=Projekt ist schon in der Workspace
MSG_SELECT_DIR=Ordner auswählen
MSG_STARTING=Starte
MSG_STARTING_DEBUGGER=Starte Debugger für
MSG_TRY_OPEN_PROJECT=Versuche Projekt zu öffnen von
DEBUGGING=debugge...
RUNNING=läuft...
QUESTION_CREATE_DIR=Der Zielpfad existiert nicht. Soll der Ordner angelegt werden?
QUESTION_NEW_WORKSPACE=Soll ein neuer Workspace anglegt werden oder der momentane verwendet werden?
QUESTION_REMOVE_FILE=Soll die Datei gelöscht werden
BUILD_OP_DESCRIPTION_BUILD=Baue Projekt {projectName}...
BUILD_OP_DESCRIPTION_CLEAN=Säubere Projekt {projectName}...
BUILD_OP_DESCRIPTION_REBUILD=Baue erneut Projekt {projectName}...
BUILD_OP_DESCRIPTION_RUN=Starte Projekt {projectName}...
BUILD_OP_DESCRIPTION_UPGRADE=Aktualisiere Pakte für das Projekt {projectName}...

View File

@ -8,6 +8,7 @@ NO_RECENT=No recent items
USEFUL_LINKS=Useful Links:
D_LANG=D Programming Language
DUB_REP=DUB repository
DLANG_DOWNLOADS=Download D compiler
DLANG_UI=DLangUI on GitHub
DLANG_IDE=DLangIDE on GitHub
DLANG_IDE_HELP=DLangIDE online documentation
@ -18,10 +19,13 @@ DLANG_IDE_DONATE=Support DlangIDE
DLANG_IDE_DONATE_PAYPAL=Donate via PayPal
EXIT=Exit
PROFILER_WINDOW=Profiler
ALL_FILES=All files
SOURCE_FILES=Source files
WORKSPACE_AND_PROJECT_FILES=Workspace and project files
IDE_FILES=DlangIDE files
PROFILER_LOG_FILES=DMD Profiler Logs
EDITOR_CONTENT=Editors content
LOCATION=Location
@ -30,6 +34,7 @@ NAME=Name
MENU_FILE=&File
MENU_FILE_NEW=&Create
MENU_FILE_NEW_SOURCE_FILE=New file
MENU_FILE_NEW_DIRECTORY=New directory
MENU_FILE_NEW_PROJECT=New project
MENU_FILE_NEW_WORKSPACE=New workspace
MENU_FILE_OPEN=&Open file...
@ -73,6 +78,8 @@ SHOW_COMPLETIONS=Get autocompletions
SHOW_DOC_COMMENTS=Show documentation
SHOW_PAREN_COMPLETION=Call hints
GO_TO_LINE=Go to line
GO_TO_PREV_POSITION=Go to previous position
GO_TO_NEXT_POSITION=Go to next position
FIND_IN_FILES=Find in files...
@ -122,10 +129,14 @@ MENU_VIEW_LANGUAGE_EN=English
MENU_VIEW_LANGUAGE_RU=Русский
MENU_VIEW_LANGUAGE_CS=Čeština
MENU_VIEW_LANGUAGE_ES=Spanish
MENU_VIEW_LANGUAGE_DE=Deutsch
MENU_VIEW_THEME=&Theme
MENU_VIEW_THEME_DEFAULT=&Default
MENU_VIEW_THEME_CUSTOM1=&Custom 1
MENU_TOOLS=Tools
OPEN_DMD_TRACE_LOG=Open DMD profiler log
TAB_LONG_LIST=Long list
TAB_BUTTONS=Buttons
TAB_ANIMATION=Animation
@ -144,6 +155,7 @@ MENU_PROJECT_FOLDER_COLLAPSE_ALL=Collapse all
HEADER_SETTINGS=DlangIDE settings
HEADER_OPEN_WORKSPACE_OR_PROJECT=Open Workspace or Project
HEADER_OPEN_TEXT_FILE=Open Text File
HEADER_OPEN_DMD_PROFILER_LOG=Open DMD Profiler Log File
HEADER_CLOSE_FILE=Close file
HEADER_CLOSE_TAB=Close tab
HEADER_PROJECT_SETTINGS=project settings
@ -182,10 +194,13 @@ OPTION_FONT_HINTING_LIGHT=LIGHT
OPTION_FONT_FACE=Font face
OPTION_FONT_SIZE=Font face
OPTION_FONT_GAMMA=Font gamma
OPTION_SCREEN_DPI_OVERRIDE=Override screen DPI
OPTION_SCREEN_DPI_OVERRIDE_NONE=Use screen DPI
OPTION_GDC_EXECUTABLE=GDC executable
OPTION_LANGUAGE=Language
OPTION_LDC2_EXECUTABLE=LDC2 executable
OPTION_LDMD2_EXECUTABLE=LDMD2 executable
OPTION_MAKE_PACKAGE=Create package.d
OPTION_MODULE_NAME=Module name
OPTION_NEW_PROJECT=New project
OPTION_NEW_SOURCE_FILE=New source file
@ -212,6 +227,7 @@ OPTION_VERBOSE=Verbose
OPTION_WORKING_DIR=Working directory
OPTION_WORKSPACE_NAME=Workspace name
OPTION_USE_SPACES=Use spaces for tabs
OPTION_AUTO_AUTOCOMPLETE=Automatically suggest auto completion
ERROR=Error
ERROR_CANNOT_CREATE_PROJECT=Cannot create project
@ -232,6 +248,7 @@ ERROR_OPEN_WORKSPACE=Cannot open workspace
ERROR_OPENING_FILE=Failed to open file
ERROR_OPENING_PROJECT=Error occured while opening project
ERROR_OPENING_WORKSPACE=Error occured while opening workspace
ERROR_FAILED_TO_PARSE_TRACE_LOG_FILE=Failed to parse trace log file
MSG_FILE_CONTENT_CHANGED=Content of this file has been changed.
MSG_TAB_CONTENT_CHANGED=Content of tab has been changed

View File

@ -49,6 +49,7 @@ MENU_VIEW_LANGUAGE_ES=Spanish
MENU_VIEW_LANGUAGE_EN=English
MENU_VIEW_LANGUAGE_RU=Русский
MENU_VIEW_LANGUAGE_CS=Čeština
MENU_VIEW_LANGUAGE_DE=Deutsch
MENU_VIEW_THEME=&Tema
MENU_VIEW_THEME_DEFAULT=&Por Defecto
MENU_VIEW_THEME_CUSTOM1=&Personalizado 1

View File

@ -8,6 +8,7 @@ NO_RECENT=Нет недавно открытых файлов/проектов
USEFUL_LINKS=Полезные ссылки:
D_LANG=Язык программирования D
DUB_REP=Хранилище DUB
DLANG_DOWNLOADS=Скачать компилятор D
DLANG_UI=DLangUI на GitHub
DLANG_IDE=DLangIDE на GitHub
DLANG_IDE_HELP=DLangIDE документация
@ -18,10 +19,13 @@ DLANG_IDE_DONATE=Поддержать DlangIDE
DLANG_IDE_DONATE_PAYPAL=PayPal
EXIT=Выход
PROFILER_WINDOW=Профилировщик
ALL_FILES=Все файлы
SOURCE_FILES=Исходники
WORKSPACE_AND_PROJECT_FILES=Файлы проектов и раб. прост.
IDE_FILES=Файлы DlangIDE
PROFILER_LOG_FILES=Файды DMD Profiler
EDITOR_CONTENT=Содержимое редактора
LOCATION=Место
@ -121,10 +125,14 @@ MENU_VIEW_LANGUAGE_ES=Spanish
MENU_VIEW_LANGUAGE_EN=English
MENU_VIEW_LANGUAGE_RU=Русский
MENU_VIEW_LANGUAGE_CS=Čeština
MENU_VIEW_LANGUAGE_DE=Deutsch
MENU_VIEW_THEME=&Тема
MENU_VIEW_THEME_DEFAULT=Стандартная
MENU_VIEW_THEME_CUSTOM1=Пример 1
MENU_TOOLS=Инструменты
OPEN_DMD_TRACE_LOG=Открыть лог DMD profiler
TAB_LONG_LIST=Длинный список
TAB_BUTTONS=Кнопки
TAB_ANIMATION=Анимация
@ -143,6 +151,7 @@ MENU_PROJECT_FOLDER_COLLAPSE_ALL=Свернуть все
HEADER_SETTINGS=DlangIDE настройки
HEADER_OPEN_WORKSPACE_OR_PROJECT=Открыть рабочее пространство или проект
HEADER_OPEN_TEXT_FILE=Открыть текстовый файл
HEADER_OPEN_DMD_PROFILER_LOG=Открыть файл DMD Profiler Log
HEADER_CLOSE_FILE=Закрыть файл
HEADER_CLOSE_TAB=Закрыть вкладку
HEADER_PROJECT_SETTINGS=настройки проекта
@ -180,6 +189,8 @@ OPTION_FONT_HINTING_LIGHT=Частично
OPTION_FONT_HINTING_NORMAL=Нормально
OPTION_FONT_FACE=Имя шрифта
OPTION_FONT_GAMMA=Контрастность шрифта
OPTION_SCREEN_DPI_OVERRIDE=Подмена DPI экрана
OPTION_SCREEN_DPI_OVERRIDE_NONE=Не менять DPI
OPTION_GDC_EXECUTABLE=Исполняемый файл GDC
OPTION_LANGUAGE=Язык
OPTION_LDC2_EXECUTABLE=Исполняемый файл LDC2
@ -210,6 +221,7 @@ OPTION_VERBOSE=Показать подробности
OPTION_WORKING_DIR=Рабочий каталог
OPTION_WORKSPACE_NAME=Имя рабочего пространства
OPTION_USE_SPACES=Использовать пробелы вместо табуляции
OPTION_AUTO_AUTOCOMPLETE=Автоматически предлагать дополнение кода
ERROR=Ошибка
ERROR_CANNOT_CREATE_PROJECT=Не могу создать проект
@ -230,6 +242,7 @@ ERROR_OPEN_WORKSPACE=Невозможно открыть рабочее прос
ERROR_OPENING_FILE=Ошибка открытия файла
ERROR_OPENING_PROJECT=Ошибка в ходе открытия проекта
ERROR_OPENING_WORKSPACE=Ошибка в ходе открытия рабочего пространства
ERROR_FAILED_TO_PARSE_TRACE_LOG_FILE=Не удалось обработать файл DMD trace log
MSG_FILE_CONTENT_CHANGED=Содержимое этого файла изменено.
MSG_TAB_CONTENT_CHANGED=Содержимое вкладки изменено

View File

@ -22,4 +22,15 @@
<color id="build_log_deprecation_color" value="#F05080"/>
<drawable id="btn_check" value="btn_check_dark"/>
<style id="HOME_SCREEN_TITLE"
fontSize="160%"
textColor="#60A0FF"
/>
<style id="HOME_SCREEN_TITLE2"
fontSize="120%"
textColor="#60A0FF"
/>
</theme>

View File

@ -26,8 +26,17 @@
<style id="TOOLBAR_HOST"
backgroundImageId="#eceffa"
/>
/>
<style id="HOME_SCREEN_TITLE"
textColor="#2040FF"
fontSize="160%"
/>
<style id="HOME_SCREEN_TITLE2"
textColor="#2040FF"
fontSize="120%"
/>
</theme>

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 B

View File

@ -4,8 +4,15 @@ res/i18n/en.ini
res/i18n/ru.ini
res/i18n/es.ini
res/i18n/cs.ini
res/i18n/de.ini
res/hdpi/hdpi_configure.png
res/hdpi/hdpi_debug-run.png
res/hdpi/hdpi_debug-pause.png
res/hdpi/hdpi_debug-stop.png
res/hdpi/hdpi_debug-restart.png
res/hdpi/hdpi_debug-step-into.png
res/hdpi/hdpi_debug-step-out.png
res/hdpi/hdpi_debug-step-over.png
res/hdpi/hdpi_document-close.png
res/hdpi/hdpi_document-open-recent.png
res/hdpi/hdpi_document-open.png