mirror of https://github.com/KLayout/klayout.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
38b2e7828c
34
Changelog
34
Changelog
|
|
@ -1,46 +1,46 @@
|
|||
0.25.1 (2018-02-23):
|
||||
* Enhancements: build compatibility with MacOS, Qt 5.9.
|
||||
Qt 4.6+4.7 supported as well with restrictions:
|
||||
* Enhancements: build compatibility with MacOS and Qt 5.9.
|
||||
Qt 4.6 supported now as well with one restriction:
|
||||
the package installation feature is not working.
|
||||
* Bugfix: Package manager
|
||||
* Bugfixs: Package manager
|
||||
- Remove button wasn't enabled if multiple packages were selected
|
||||
- A potential crash ob removing packages was fixed
|
||||
* Enhancement: 64 bit coordinate support enabled on Windows builds
|
||||
* Further bugfixes: See links
|
||||
- https://github.com/klayoutmatthias/klayout/issues/21 (Autorun(-early) doesn't seem to run when lym files are inside a package)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/24 (Text insert dialog possible)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/24 (Text insert dialog bug - Ok button isn't working)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/26 (Exceptions are reported every time they propagate up in the call chain in the ruby debugger)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/28 (CIF format detection failed)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/30 (Writer options dialog non-functional on a fresh configuration)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/32 (rounding issue with instance properties)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/32 (Rounding issue with instance properties)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/33 (Plugin factory not working when using with Python)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/36 (hardening against destruction of object inside event handler)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/36 (Hardening against destruction of object inside event handler)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/39 (Action cannot be reassigned)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/40 (Crash in Python binding)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/41 (Polygon#touches? issue)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/42 (headless mode support with Qt5/-zz)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/43 (crash when using Qt specific command line options)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/42 (Headless mode support with Qt5/-zz)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/43 (Crash when using Qt specific command line options)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/44 (Transformation constructor with x,y not working)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/45 (Partial selection does not capture instance)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/48 (Cancel does not reset current tool)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/51 (Segmentation fault on return to main window and other opportunities)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/53 (unreadable 'about' text)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/59 (async download of package index and details)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/53 (Unreadable 'about' text)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/62 (QXmlSimpleReader#parse cannot be called)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/63 (wrong output on DRC non_interacting with empty second input)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/64 (crash on exit)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/63 (Wrong output on DRC non_interacting with empty second input)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/64 (Crash on exit)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/68 (OASIS reader issue with degenerated shapes)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/69 (DRC: 'inside' does not merge shapes of second input)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/71 (target cell argument is required)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/71 (Target cell argument is required)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/72 (Edges/Region NOT issue)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/73 (allow 'change layers' on PCells which support a single layer parameter)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/74 (small-corner boolean issue)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/73 (Allow 'change layers' on PCells which support a single layer parameter)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/74 (Small-corner boolean issue)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/75 (Python PCell issue when parameters are called 'layer')
|
||||
- https://github.com/klayoutmatthias/klayout/issues/79 (Replace function enabled also for read-only macros)
|
||||
* Further enhancements: see links
|
||||
- https://github.com/klayoutmatthias/klayout/issues/29 (permissive mode for OASIS writer on odd-width paths)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/29 (Permissive mode for OASIS writer on odd-width paths)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/59 (Async download of package index and details)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/66 (Authentication dialog indicates retry)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/77 (copy_tree works in non-editable mode too)
|
||||
- https://github.com/klayoutmatthias/klayout/issues/77 (Layout#copy_tree now works in non-editable mode too)
|
||||
|
||||
0.25 (2017-11-04):
|
||||
* Enhancement: Menu customization
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
*.pyc
|
||||
|
|
@ -62,7 +62,7 @@ $ ./build4mac.py -r mp24 -p mp36
|
|||
```
|
||||
$ ./build4mac.py -r mp24 -p mp36 -Y
|
||||
```
|
||||
* [-Y|--DEPOLY] option deploys KLayout's dylibs and executables only.
|
||||
* [-Y|--DEPLOY] option deploys KLayout's dylibs and executables only.
|
||||
That is, paths to other modules (Ruby, Python, and Qt5 Frameworks) remain unchanged (absolute paths in your development environment).
|
||||
|
||||
5. Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your "/Applications" directory for installation.
|
||||
|
|
@ -84,4 +84,25 @@ $ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
|
|||
```
|
||||
|
||||
By: Kazzz (January 16, 2018)
|
||||
|
||||
# 5. Alternative building options
|
||||
### 5.1 Python 3.6 from brew, Qt 5.9.4 from offline installer
|
||||
|
||||
Homebrew's installation of python3 places a `Python.framework` in `/usr/local/opt/python/Frameworks/Python.framework/`, which you can use to build KLayout from. Qt can be downloaded for [offline installation](https://www1.qt.io/offline-installers/). You can place it in your home folder: e.g. `/home/username/Qt5.9.4/`. Given these two dependencies, you can successfully compile KLayout with the following commands:
|
||||
|
||||
```
|
||||
# Build step
|
||||
./build4mac.py -p B36 -q Qt5Custom
|
||||
|
||||
# Deploy step
|
||||
./build4mac.py -p B36 -q Qt5Custom -y # normal deploy
|
||||
./build4mac.py -p B36 -q Qt5Custom -y -v 3 2>&1 | tee qt5.pkg.macos-HighSierra-release.log # deploy with debug options
|
||||
|
||||
# Packaging step
|
||||
./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m -q Qt594
|
||||
|
||||
```
|
||||
|
||||
PS: If you get a syntax error in one of ruby's libraries because it is not compatible with C++11, do not fret. You only have to change one offending file.
|
||||
|
||||
[End of File]
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Relevant KLayout version: 0.25.1
|
|||
to deploy executables and libraries under "klayout.app" bundle.
|
||||
The buddy command line tools (strm*) will also be deployed.
|
||||
$ ./build4mac.py -r mp24 -p mp36 -Y
|
||||
* [-Y|--DEPOLY] option deploys KLayout's dylibs and executables only.
|
||||
* [-Y|--DEPLOY] option deploys KLayout's dylibs and executables only.
|
||||
That is, paths to other modules (Ruby, Python, and Qt5 Frameworks)
|
||||
remain unchanged (absolute paths in your development environment).
|
||||
(5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your
|
||||
|
|
|
|||
|
|
@ -18,6 +18,21 @@
|
|||
<string>APPL</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${VERSION}</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${VERSION}</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>gds</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>${ICONFILE}</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
-------------------------------------------------------------------------------------------------
|
||||
(*
|
||||
* Template File:
|
||||
* macbuild/Resources/template-KLayoutDMG.applescript
|
||||
*
|
||||
* Actual AppleScrip File to be generated:
|
||||
* macbuild/Resources/KLayoutDMG.applescript
|
||||
*
|
||||
* Description:
|
||||
* A template AppleScript to make a fancy DMG installer of KLayout
|
||||
* (http://www.klayout.de/index.php) bundles.
|
||||
* "makeDMG4mac.py" will read this template and generate the actual AppleScript to execute.
|
||||
* Values to be found and replaced by "makeDMG4mac.py" are marked by ${KEYWORD}.
|
||||
*
|
||||
* The background image was designed using Logoist2 (http://www.syniumsoftware.com/en/logoist)
|
||||
* and exported to a PNG file of 1000 x 700 pix size.
|
||||
*-----------------------------------------------------------------------------------------------
|
||||
* This is a derivative work of Ref. 2) below. Refer to "macbuild/LICENSE" file.
|
||||
* Ref.
|
||||
* 1) https://el-tramo.be/guides/fancy-dmg/
|
||||
* 2) https://github.com/andreyvit/create-dmg.git
|
||||
*)
|
||||
-------------------------------------------------------------------------------------------------
|
||||
on run (volumeName) -- most likely, the volume name is "KLayout"
|
||||
tell application "Finder"
|
||||
tell disk (volumeName as string)
|
||||
-- [1] Open the volume
|
||||
open
|
||||
|
||||
-- [2] Set the key coordinates and windows size
|
||||
-- The size of given background PNG image is 1000 x 700 pix
|
||||
-- ORGX = [50] pix
|
||||
-- ORGY = [100] pix
|
||||
-- WIN_WIDTH = [1000] pix
|
||||
-- WIN_HEIGHT = [700] pix
|
||||
set posMargin to 50
|
||||
set negMargin to 10
|
||||
set theTopLeftX to 50
|
||||
set theTopLeftY to 100
|
||||
set theWidth to 1000
|
||||
set theHeight to 700
|
||||
set theBottomRightX to (theTopLeftX + theWidth + posMargin)
|
||||
set theBottomRightY to (theTopLeftY + theHeight + posMargin)
|
||||
|
||||
-- [3] Set the full path to .DS_Store file
|
||||
set dotDSStore to "/Volumes/KLayout/.DS_Store"
|
||||
|
||||
-- [4] Set global view options
|
||||
tell container window
|
||||
set current view to icon view
|
||||
set toolbar visible to false
|
||||
set statusbar visible to false
|
||||
set statusbar visible to false
|
||||
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX, theBottomRightY}
|
||||
set position of every item to {theTopLeftX + 150, theTopLeftY + 350}
|
||||
end tell
|
||||
|
||||
-- [5] Set icon view options
|
||||
set opts to the icon view options of container window
|
||||
tell opts
|
||||
set icon size to 80
|
||||
set text size to 16
|
||||
set arrangement to not arranged
|
||||
end tell
|
||||
|
||||
-- [6] Set the background PNG image (1000 x 700 pix) file name stored
|
||||
set background picture of opts to file ".background:KLayoutDMG-Back.png"
|
||||
|
||||
-- [7] Set positions of each icon
|
||||
-- ITEM_1 = klayout.app {960, 140}
|
||||
-- ITEM_2 = klayout.scripts {610, 140}
|
||||
-- ITEM_3 = Applications {790, 140}
|
||||
set position of item "klayout.app" to {960, 140}
|
||||
set position of item "klayout.scripts" to {610, 140}
|
||||
set position of item "Applications" to {790, 140}
|
||||
|
||||
-- [8] Update the contents of container
|
||||
close
|
||||
open
|
||||
update without registering applications
|
||||
|
||||
-- [9] Force save the negatively resized window size
|
||||
delay 2
|
||||
tell container window
|
||||
set statusbar visible to false
|
||||
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX - negMargin, theBottomRightY - negMargin}
|
||||
end tell
|
||||
update without registering applications
|
||||
end tell
|
||||
|
||||
-- [10] Restore back the original window size
|
||||
delay 2
|
||||
tell disk (volumeName as string)
|
||||
tell container window
|
||||
set statusbar visible to false
|
||||
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX, theBottomRightY}
|
||||
end tell
|
||||
update without registering applications
|
||||
end tell
|
||||
|
||||
-- [11] Wait for some time so that "Finder" can complete writing to .DS_Store file
|
||||
delay 3
|
||||
set elapsedTime to 0
|
||||
set ejected to false
|
||||
repeat while ejected is false
|
||||
delay 1
|
||||
set elapsedTime to elapsedTime + 1
|
||||
if (do shell script "[ -f " & dotDSStore & " ]; echo $?") = "0" then set ejected to true
|
||||
end repeat
|
||||
log "### Elapsed <" & elapsedTime & "> [sec] for writing .DS_Store file."
|
||||
end tell
|
||||
end run
|
||||
|
||||
--
|
||||
-- End of file
|
||||
--
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[Paths]
|
||||
Plugins = ../PlugIns
|
||||
Imports = ../Resources/qml
|
||||
Qml2Imports = ../Resources/qml
|
||||
|
|
@ -65,9 +65,9 @@ def SetGlobals():
|
|||
Usage += " : 'nil' = not to support the script language | \n"
|
||||
Usage += " : 'Sys' = using the OS standard script language | \n"
|
||||
Usage += " : Refer to 'macbuild/build4mac_env.py' for details | \n"
|
||||
Usage += " [-q|--qt <type>] : type=['Qt4MacPorts', 'Qt5MacPorts'] | qt5macports \n"
|
||||
Usage += " [-r|--ruby <type>] : type=['nil', 'Sys', 'Src24', 'MP24'] | sys \n"
|
||||
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36'] | sys \n"
|
||||
Usage += " [-q|--qt <type>] : type=['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Custom'] | qt5macports \n"
|
||||
Usage += " [-r|--ruby <type>] : type=['nil', 'Sys', 'Src24', 'MP24', 'B25'] | sys \n"
|
||||
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B36'] | sys \n"
|
||||
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
|
||||
Usage += " [-m|--make <option>] : option passed to 'make' | -j4 \n"
|
||||
Usage += " [-d|--debug] : enable debug mode build | disabled \n"
|
||||
|
|
@ -239,7 +239,7 @@ def ParseCommandLineArguments():
|
|||
quit()
|
||||
|
||||
# Determine Qt type
|
||||
candidates = [ i.upper() for i in ['Qt4MacPorts', 'Qt5MacPorts'] ]
|
||||
candidates = [ i.upper() for i in ['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Custom'] ]
|
||||
ModuleQt = ""
|
||||
index = 0
|
||||
for item in candidates:
|
||||
|
|
@ -250,6 +250,9 @@ def ParseCommandLineArguments():
|
|||
elif index == 1:
|
||||
ModuleQt = 'Qt5MacPorts'
|
||||
break
|
||||
elif index == 2:
|
||||
ModuleQt = 'Qt5Custom'
|
||||
break
|
||||
else:
|
||||
index += 1
|
||||
if ModuleQt == "":
|
||||
|
|
@ -262,7 +265,7 @@ def ParseCommandLineArguments():
|
|||
NonOSStdLang = False
|
||||
|
||||
# Determine Ruby type
|
||||
candidates = [ i.upper() for i in ['nil', 'Sys', 'Src24', 'MP24'] ]
|
||||
candidates = [ i.upper() for i in ['nil', 'Sys', 'Src24', 'MP24', 'B25'] ]
|
||||
ModuleRuby = ""
|
||||
index = 0
|
||||
for item in candidates:
|
||||
|
|
@ -288,6 +291,9 @@ def ParseCommandLineArguments():
|
|||
elif index == 3:
|
||||
ModuleRuby = 'Ruby24MacPorts'
|
||||
NonOSStdLang = True
|
||||
elif index == 4:
|
||||
ModuleRuby = 'Ruby25Brew'
|
||||
NonOSStdLang = True
|
||||
else:
|
||||
index += 1
|
||||
if ModuleRuby == "":
|
||||
|
|
@ -297,7 +303,7 @@ def ParseCommandLineArguments():
|
|||
quit()
|
||||
|
||||
# Determine Python type
|
||||
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36'] ]
|
||||
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B36'] ]
|
||||
ModulePython = ""
|
||||
index = 0
|
||||
for item in candidates:
|
||||
|
|
@ -326,6 +332,9 @@ def ParseCommandLineArguments():
|
|||
elif index == 4:
|
||||
ModulePython = 'Python36MacPorts'
|
||||
NonOSStdLang = True
|
||||
elif index == 5:
|
||||
ModulePython = 'Python36Brew'
|
||||
NonOSStdLang = True
|
||||
else:
|
||||
index += 1
|
||||
if ModulePython == "":
|
||||
|
|
@ -427,6 +436,20 @@ def RunMainBuildBash():
|
|||
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
|
||||
parameters += " \\\n -bin %s" % MacBinDir
|
||||
parameters += " \\\n -build %s" % MacBuildDir
|
||||
elif ModuleQt == 'Qt5Custom':
|
||||
parameters += " \\\n -qt5"
|
||||
parameters += " \\\n -qmake %s" % Qt5Custom['qmake']
|
||||
MacPkgDir = "./qt5.pkg.macos-%s-%s" % (Platform, mode)
|
||||
MacBinDir = "./qt5.bin.macos-%s-%s" % (Platform, mode)
|
||||
MacBuildDir = "./qt5.build.macos-%s-%s" % (Platform, mode)
|
||||
MacBuildLog = "./qt5.build.macos-%s-%s.log" % (Platform, mode)
|
||||
AbsMacPkgDir = "%s/qt5.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
|
||||
AbsMacBinDir = "%s/qt5.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
|
||||
AbsMacBuildDir = "%s/qt5.build.macos-%s-%s" % (ProjectDir, Platform, mode)
|
||||
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
|
||||
parameters += " \\\n -bin %s" % MacBinDir
|
||||
parameters += " \\\n -build %s" % MacBuildDir
|
||||
parameters += " \\\n -rpath %s" % "@executable_path/../Frameworks"
|
||||
|
||||
# (C) want Qt bindings with Ruby scripts?
|
||||
if NoQtBindings:
|
||||
|
|
@ -524,9 +547,9 @@ def DeployBinariesForBundle():
|
|||
if not DeploymentF and not DeploymentP:
|
||||
return 1
|
||||
if DeploymentF and NonOSStdLang:
|
||||
print( "!!! You chose <-y|--deploy> while using non-OS-standard script language.", file=sys.stderr )
|
||||
print( "WARNING!!! You chose <-y|--deploy> while using non-OS-standard script language.", file=sys.stderr )
|
||||
print( " Use <-Y|--DEPLOY> instead", file=sys.stderr )
|
||||
return 1
|
||||
#return 1
|
||||
if not os.path.isfile(MacBuildLog):
|
||||
print( "!!! Build log file <%s> does not present !!!" % MacBuildLog, file=sys.stderr )
|
||||
return 1
|
||||
|
|
@ -629,7 +652,7 @@ def DeployBinariesForBundle():
|
|||
# e.g. [ 'libklayout_lay', '0', '25', '0', 'dylib' ]
|
||||
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
|
||||
shutil.copy2( item, nameStyle3 )
|
||||
os.chmod( nameStyle3, 0755 )
|
||||
os.chmod( nameStyle3, 0o0755 )
|
||||
#-------------------------------------------------------------------
|
||||
# (B) Then get inter-library dependencies
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -676,17 +699,20 @@ def DeployBinariesForBundle():
|
|||
shutil.copy2( sourceDir0 + "/PkgInfo", targetDir0 ) # this file is not mandatory
|
||||
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
|
||||
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
|
||||
shutil.copy2( sourceDir2 + "/qt.conf", targetDirM )
|
||||
|
||||
os.chmod( targetDir0 + "/PkgInfo", 0644 )
|
||||
os.chmod( targetDir0 + "/Info.plist", 0644 )
|
||||
os.chmod( targetDirM + "/klayout", 0755 )
|
||||
os.chmod( targetDirR + "/klayout.icns", 0644 )
|
||||
|
||||
os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
|
||||
os.chmod( targetDir0 + "/Info.plist", 0o0644 )
|
||||
os.chmod( targetDirM + "/klayout", 0o0755 )
|
||||
os.chmod( targetDirM + "/qt.conf", 0o0644 )
|
||||
os.chmod( targetDirR + "/klayout.icns", 0o0644 )
|
||||
|
||||
buddies = glob.glob( sourceDir3 + "/strm*" )
|
||||
for item in buddies:
|
||||
shutil.copy2( item, targetDirB )
|
||||
buddy = os.path.basename(item)
|
||||
os.chmod( targetDirB + "/" + buddy, 0755 )
|
||||
os.chmod( targetDirB + "/" + buddy, 0o0755 )
|
||||
|
||||
|
||||
print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." )
|
||||
|
|
@ -729,10 +755,15 @@ def DeployBinariesForBundle():
|
|||
deploytool = Qt5MacPorts['deploy']
|
||||
app_bundle = "klayout.app"
|
||||
options = macdepQtOpt + verbose
|
||||
elif ModuleQt == 'Qt5Custom':
|
||||
deploytool = Qt5Custom['deploy']
|
||||
app_bundle = "klayout.app"
|
||||
options = macdepQtOpt + verbose
|
||||
|
||||
os.chdir(ProjectDir)
|
||||
os.chdir(MacPkgDir)
|
||||
command = "%s %s %s" % ( deploytool, app_bundle, options )
|
||||
print(command)
|
||||
if subprocess.call( command, shell=True ) != 0:
|
||||
msg = "!!! Failed to deploy applications on OSX !!!"
|
||||
print( msg, file=sys.stderr )
|
||||
|
|
@ -834,10 +865,10 @@ def DeployScriptBundles():
|
|||
shutil.copy2( resourceDir + "/klayout-red.icns", targetDirRE )
|
||||
shutil.copy2( resourceDir + "/klayout-blue.icns", targetDirRV )
|
||||
|
||||
os.chmod( targetDirME + "/KLayoutEditor.sh", 0755 )
|
||||
os.chmod( targetDirMV + "/KLayoutViewer.sh", 0755 )
|
||||
os.chmod( targetDirRE + "/klayout-red.icns", 0644 )
|
||||
os.chmod( targetDirRV + "/klayout-blue.icns", 0644 )
|
||||
os.chmod( targetDirME + "/KLayoutEditor.sh", 0o0755 )
|
||||
os.chmod( targetDirMV + "/KLayoutViewer.sh", 0o0755 )
|
||||
os.chmod( targetDirRE + "/klayout-red.icns", 0o0644 )
|
||||
os.chmod( targetDirRV + "/klayout-blue.icns", 0o0644 )
|
||||
|
||||
tmpfileE = ProjectDir + "/macbuild/Resources/Info.plist.template"
|
||||
keydicE = { 'exe': 'KLayoutEditor.sh', 'icon': 'klayout-red.icns', 'bname': 'klayout', 'ver': Version }
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ XcodeToolChain = { 'nameID': '/usr/bin/install_name_tool -id ',
|
|||
#-----------------------------------------------------
|
||||
# [1] Qt
|
||||
#-----------------------------------------------------
|
||||
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts' ]
|
||||
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts', 'Qt5Custom' ]
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Whereabout of different components of Qt4
|
||||
|
|
@ -41,11 +41,23 @@ Qt5MacPorts = { 'qmake' : '/opt/local/libexec/qt5/bin/qmake',
|
|||
'deploy': '/opt/local/libexec/qt5/bin/macdeployqt'
|
||||
}
|
||||
|
||||
# # Qt5 from Brew
|
||||
# # [Key Type Name] = 'Qt5Brew'
|
||||
# Qt5Brew = { 'qmake' : '/usr/local/Cellar/qt5/5.10.0_1/bin/qmake',
|
||||
# 'deploy': '/usr/local/Cellar/qt5/5.10.0_1/bin/macdeployqt'
|
||||
# }
|
||||
|
||||
# Qt5 Custom (https://www1.qt.io/offline-installers/)
|
||||
# [Key Type Name] = 'Qt5Custom'
|
||||
Qt5Custom = { 'qmake' : '~/Qt5.9.4/5.9.4/clang_64/bin/qmake',
|
||||
'deploy': '~/Qt5.9.4/5.9.4/clang_64/bin/macdeployqt'
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
# [2] Ruby
|
||||
#-----------------------------------------------------
|
||||
Rubies = [ 'nil', 'RubyYosemite', 'RubyElCapitan', 'RubySierra', 'RubyHighSierra' ]
|
||||
Rubies += [ 'Ruby24SrcBuild', 'Ruby24MacPorts' ]
|
||||
Rubies += [ 'Ruby24SrcBuild', 'Ruby24MacPorts', 'Ruby24Brew' ]
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Whereabout of different components of Ruby
|
||||
|
|
@ -94,6 +106,13 @@ Ruby24MacPorts = { 'exe': '/opt/local/bin/ruby2.4',
|
|||
'lib': '/opt/local/lib/libruby.2.4.dylib'
|
||||
}
|
||||
|
||||
# Ruby 2.5 from Brew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# [Key Type Name] = 'Brew25'
|
||||
Ruby25Brew = { 'exe': '/usr/local/bin/ruby',
|
||||
'inc': '/usr/local/include/ruby-2.5.0',
|
||||
'lib': '/usr/local/lib/libruby.2.5.0.dylib'
|
||||
}
|
||||
|
||||
# Consolidated dictionary kit for Ruby
|
||||
RubyDictionary = { 'nil' : None,
|
||||
'RubyYosemite' : RubyYosemite,
|
||||
|
|
@ -101,14 +120,15 @@ RubyDictionary = { 'nil' : None,
|
|||
'RubySierra' : RubySierra,
|
||||
'RubyHighSierra': RubyHighSierra,
|
||||
'Ruby24SrcBuild': Ruby24SrcBuild,
|
||||
'Ruby24MacPorts': Ruby24MacPorts
|
||||
'Ruby24MacPorts': Ruby24MacPorts,
|
||||
'Ruby25Brew' : Ruby25Brew
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
# [3] Python
|
||||
#-----------------------------------------------------
|
||||
Pythons = [ 'nil', 'PythonYosemite', 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra' ]
|
||||
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts' ]
|
||||
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts', 'Python36Brew' ]
|
||||
|
||||
#-----------------------------------------------------
|
||||
# Whereabout of different components of Python
|
||||
|
|
@ -170,6 +190,13 @@ Python36MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versi
|
|||
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6m.dylib'
|
||||
}
|
||||
|
||||
# Python 3.6 from Brew *+*+*+ EXPERIMENTAL *+*+*+
|
||||
# [Key Type Name] = 'pybrew'
|
||||
Python36Brew= { 'exe': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/bin/python3.6m' ,
|
||||
'inc': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/include/python3.6m',
|
||||
'lib': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/lib/libpython3.6m.dylib'
|
||||
}
|
||||
|
||||
# Consolidated dictionary kit for Python
|
||||
PythonDictionary= { 'nil' : None,
|
||||
'PythonYosemite' : PythonYosemite,
|
||||
|
|
@ -178,7 +205,8 @@ PythonDictionary= { 'nil' : None,
|
|||
'PythonHighSierra': PythonHighSierra,
|
||||
'Anaconda27' : Anaconda27,
|
||||
'Anaconda36' : Anaconda36,
|
||||
'Python36MacPorts': Python36MacPorts
|
||||
'Python36MacPorts': Python36MacPorts,
|
||||
'Python36Brew' : Python36Brew,
|
||||
}
|
||||
|
||||
#-----------------------------------------------------
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -143,7 +143,7 @@ def SetChangeLibIdentificationName( executable, relativedir ):
|
|||
otoolOut = os.popen( otoolCm ).read()
|
||||
exedepdic = DecomposeLibraryDependency( executable + ":\n" + otoolOut )
|
||||
keys = exedepdic.keys()
|
||||
deplibs = exedepdic[ keys[0] ]
|
||||
deplibs = exedepdic[ list(keys)[0] ]
|
||||
|
||||
for lib in deplibs:
|
||||
#-----------------------------------------------------------
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -883,20 +883,31 @@ struct JoinEdgesCluster
|
|||
void finish ()
|
||||
{
|
||||
std::multimap<db::Point, iterator> objects_by_p1;
|
||||
std::multiset<db::Point> p2;
|
||||
std::multimap<db::Point, iterator> objects_by_p2;
|
||||
for (iterator o = begin (); o != end (); ++o) {
|
||||
if (o->first->p1 () != o->first->p2 ()) {
|
||||
objects_by_p1.insert (std::make_pair (o->first->p1 (), o));
|
||||
p2.insert (o->first->p2 ());
|
||||
objects_by_p2.insert (std::make_pair (o->first->p2 (), o));
|
||||
}
|
||||
}
|
||||
|
||||
while (! p2.empty ()) {
|
||||
while (! objects_by_p2.empty ()) {
|
||||
|
||||
tl_assert (! objects_by_p1.empty ());
|
||||
|
||||
// Find the beginning of a new sequence
|
||||
std::multimap<db::Point, iterator>::iterator j = objects_by_p1.begin ();
|
||||
std::multimap<db::Point, iterator>::iterator j0 = objects_by_p1.begin ();
|
||||
std::multimap<db::Point, iterator>::iterator j = j0;
|
||||
do {
|
||||
std::multimap<db::Point, iterator>::iterator jj = objects_by_p2.find (j->first);
|
||||
if (jj == objects_by_p2.end ()) {
|
||||
break;
|
||||
} else {
|
||||
j = objects_by_p1.find (jj->second->first->p1 ());
|
||||
tl_assert (j != objects_by_p1.end ());
|
||||
}
|
||||
} while (j != j0);
|
||||
|
||||
iterator i = j->second;
|
||||
|
||||
// determine a sequence
|
||||
|
|
@ -906,12 +917,22 @@ struct JoinEdgesCluster
|
|||
|
||||
do {
|
||||
|
||||
// record the next point
|
||||
pts.push_back (i->first->p2 ());
|
||||
std::multiset<db::Point>::iterator ip2 = p2.find (i->first->p2 ());
|
||||
tl_assert (ip2 != p2.end ());
|
||||
p2.erase (ip2);
|
||||
|
||||
// remove the edge as it's taken
|
||||
std::multimap<db::Point, iterator>::iterator jj;
|
||||
for (jj = objects_by_p2.find (i->first->p2 ()); jj != objects_by_p2.end () && jj->first == i->first->p2 (); ++jj) {
|
||||
if (jj->second == i) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
tl_assert (jj != objects_by_p2.end () && jj->second == i);
|
||||
objects_by_p2.erase (jj);
|
||||
objects_by_p1.erase (j);
|
||||
|
||||
// process along the edge to the next one
|
||||
// TODO: this chooses any solution in case of forks. Choose a specific one?
|
||||
j = objects_by_p1.find (i->first->p2 ());
|
||||
if (j != objects_by_p1.end ()) {
|
||||
i = j->second;
|
||||
|
|
|
|||
|
|
@ -311,7 +311,40 @@ TEST(6)
|
|||
EXPECT_EQ (r.to_string (), "(-20,-20;-20,220;120,220;120,-20/-10,-10;110,-10;110,210;-10,210)");
|
||||
}
|
||||
|
||||
TEST(7)
|
||||
TEST(6b)
|
||||
{
|
||||
// Ticket #90: order of edges as input to the edge collector should not matter
|
||||
|
||||
db::Edges e;
|
||||
e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200)));
|
||||
e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0)));
|
||||
e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200)));
|
||||
e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200)));
|
||||
|
||||
db::Region r;
|
||||
e.extended (r, 0, 0, 20, 0, true);
|
||||
EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0)");
|
||||
}
|
||||
|
||||
TEST(6c)
|
||||
{
|
||||
// A more complex scenario with forks
|
||||
|
||||
db::Edges e;
|
||||
e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200)));
|
||||
e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0)));
|
||||
e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200)));
|
||||
e.insert (db::Edge (db::Point (0, -100), db::Point (0, -200)));
|
||||
e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200)));
|
||||
e.insert (db::Edge (db::Point (0, -200), db::Point (200, -200)));
|
||||
e.insert (db::Edge (db::Point (250, -200), db::Point (350, 0)));
|
||||
|
||||
db::Region r;
|
||||
e.extended (r, 0, 0, 20, 0, true);
|
||||
EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(0,-200;0,-100;20,-100;20,-180;200,-180;200,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0);(250,-200;232,-191;332,9;350,0)");
|
||||
}
|
||||
|
||||
TEST(7)
|
||||
{
|
||||
db::Edges e;
|
||||
e.insert (db::Edge (db::Point (0, 0), db::Point (0, 200)));
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<epilog/>
|
||||
<doc/>
|
||||
<autorun>true</autorun>
|
||||
<autorun-early>false</autorun-early>
|
||||
<autorun-early>true</autorun-early>
|
||||
<shortcut/>
|
||||
<show-in-menu>false</show-in-menu>
|
||||
<group-name/>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ QMAKE_CXXFLAGS_WARN_ON += \
|
|||
-Wno-long-long \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-deprecated-declarations \
|
||||
-Wno-reserved-user-defined-literal \
|
||||
|
||||
QT += network xml sql
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MacroEditorSetupDialog</class>
|
||||
<widget class="QDialog" name="MacroEditorSetupDialog">
|
||||
<class>MacroEditorSetupPage</class>
|
||||
<widget class="QWidget" name="MacroEditorSetupPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
|
|
@ -452,10 +452,71 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="stop_on_exception">
|
||||
<property name="text">
|
||||
<string>Ask whether to stop in debugger on exception</string>
|
||||
<widget class="QGroupBox" name="stop_on_exception">
|
||||
<property name="title">
|
||||
<string>As&k whether to stop in debugger on exception</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Don't stop inside these files:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QPushButton" name="clear_el">
|
||||
<property name="text">
|
||||
<string>Clear List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="QListWidget" name="exception_list">
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
@ -475,16 +536,6 @@
|
|||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
|
@ -495,38 +546,5 @@
|
|||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MacroEditorSetupDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>MacroEditorSetupDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -20,7 +20,6 @@ HEADERS = \
|
|||
layLogViewerDialog.h \
|
||||
layMacroEditorDialog.h \
|
||||
layMacroEditorPage.h \
|
||||
layMacroEditorSetupDialog.h \
|
||||
layMacroEditorTree.h \
|
||||
layMacroPropertiesDialog.h \
|
||||
layMacroVariableView.h \
|
||||
|
|
@ -57,7 +56,8 @@ HEADERS = \
|
|||
layLibraryController.h \
|
||||
layFontController.h \
|
||||
layNativePlugin.h \
|
||||
laySystemPaths.h
|
||||
laySystemPaths.h \
|
||||
layMacroEditorSetupPage.h
|
||||
|
||||
FORMS = \
|
||||
ClipDialog.ui \
|
||||
|
|
@ -69,7 +69,6 @@ FORMS = \
|
|||
LayoutStatistics.ui \
|
||||
LogViewerDialog.ui \
|
||||
MacroEditorDialog.ui \
|
||||
MacroEditorSetupDialog.ui \
|
||||
MacroPropertiesDialog.ui \
|
||||
MacroTemplateSelectionDialog.ui \
|
||||
MainConfigPage.ui \
|
||||
|
|
@ -106,7 +105,8 @@ FORMS = \
|
|||
SaltGrainPropertiesDialog.ui \
|
||||
SaltGrainTemplateSelectionDialog.ui \
|
||||
SaltManagerInstallConfirmationDialog.ui \
|
||||
CustomizeMenuConfigPage.ui
|
||||
CustomizeMenuConfigPage.ui \
|
||||
MacroEditorSetupPage.ui
|
||||
|
||||
SOURCES = \
|
||||
gsiDeclLayApplication.cc \
|
||||
|
|
@ -125,7 +125,6 @@ SOURCES = \
|
|||
layLogViewerDialog.cc \
|
||||
layMacroEditorDialog.cc \
|
||||
layMacroEditorPage.cc \
|
||||
layMacroEditorSetupDialog.cc \
|
||||
layMacroEditorTree.cc \
|
||||
layMacroPropertiesDialog.cc \
|
||||
layMacroVariableView.cc \
|
||||
|
|
@ -161,7 +160,8 @@ SOURCES = \
|
|||
layLibraryController.cc \
|
||||
layFontController.cc \
|
||||
layNativePlugin.cc \
|
||||
laySystemPaths.cc
|
||||
laySystemPaths.cc \
|
||||
layMacroEditorSetupPage.cc
|
||||
|
||||
RESOURCES = layBuildInMacros.qrc \
|
||||
layHelpResources.qrc \
|
||||
|
|
|
|||
|
|
@ -1391,6 +1391,35 @@ GuiApplication::force_update_app_menu ()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
// By Thomas Lima (March 7, 2018)
|
||||
//
|
||||
// This event interceptor catches MacOS "Open With" event, and KLayout should respond
|
||||
// similarly to the Drop event in MainWindow::dropEvent.
|
||||
//
|
||||
// This particular implementation always creates a new window.
|
||||
//
|
||||
// This was implemented with the inspiration of http://doc.qt.io/qt-5/qfileopenevent.html
|
||||
bool
|
||||
GuiApplication::event (QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FileOpen) {
|
||||
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
|
||||
if (mp_mw)
|
||||
{
|
||||
const std::string tech = mp_mw->initial_technology();
|
||||
const std::string file = tl::to_string (openEvent->file());
|
||||
const int mode = 1; // open in new window
|
||||
mp_mw->load_layout (file, tech, mode);
|
||||
mp_mw->add_mru (file, tech);
|
||||
}
|
||||
}
|
||||
|
||||
return QApplication::event(event);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
GuiApplication::exec ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QEventLoop>
|
||||
#ifdef __APPLE__
|
||||
# include <QEvent>
|
||||
#endif
|
||||
|
||||
#include "gsi.h"
|
||||
|
||||
|
|
@ -438,6 +441,14 @@ public:
|
|||
*/
|
||||
void force_update_app_menu ();
|
||||
|
||||
/**
|
||||
* @brief Handles MacOS file open
|
||||
* This function is used to process the "Open With" event sent by MacOS.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
bool event (QEvent *event);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void setup ();
|
||||
virtual void shutdown ();
|
||||
|
|
|
|||
|
|
@ -22,10 +22,11 @@
|
|||
|
||||
|
||||
#include "ui_MacroTemplateSelectionDialog.h"
|
||||
#include "layConfigurationDialog.h"
|
||||
#include "layMacroController.h"
|
||||
#include "layMacroEditorTree.h"
|
||||
#include "layMacroEditorDialog.h"
|
||||
#include "layMacroEditorSetupDialog.h"
|
||||
#include "layMacroEditorSetupPage.h"
|
||||
#include "layMacroPropertiesDialog.h"
|
||||
#include "layFileDialog.h"
|
||||
#include "layMainWindow.h"
|
||||
|
|
@ -58,6 +59,9 @@
|
|||
#include <QHeaderView>
|
||||
#include <QResource>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
const std::string cfg_macro_editor_styles ("macro-editor-styles");
|
||||
const std::string cfg_macro_editor_save_all_on_run ("macro-editor-save-all-on-run");
|
||||
const std::string cfg_macro_editor_stop_on_exception ("macro-editor-stop-on-exception");
|
||||
|
|
@ -74,9 +78,7 @@ const std::string cfg_macro_editor_current_macro ("macro-editor-current-macro");
|
|||
const std::string cfg_macro_editor_active_macro ("macro-editor-active-macro");
|
||||
const std::string cfg_macro_editor_watch_expressions ("macro-editor-watch-expressions");
|
||||
const std::string cfg_macro_editor_debugging_enabled ("macro-editor-debugging-enabled");
|
||||
|
||||
namespace lay
|
||||
{
|
||||
const std::string cfg_macro_editor_ignore_exception_list ("macro-editor-ignore-exception-list");
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// Implementation of the macro template selection dialog
|
||||
|
|
@ -225,8 +227,10 @@ public:
|
|||
|
||||
static lay::MacroEditorDialog *s_macro_editor_instance = 0;
|
||||
|
||||
MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection *root)
|
||||
MacroEditorDialog::MacroEditorDialog (lay::MainWindow *mw, lym::MacroCollection *root)
|
||||
: QDialog (0 /*show as individual top widget*/, Qt::Window),
|
||||
lay::Plugin (mw, true),
|
||||
mp_plugin_root (mw),
|
||||
mp_root (root),
|
||||
m_first_show (true), m_in_processing (false), m_debugging_on (true),
|
||||
mp_run_macro (0),
|
||||
|
|
@ -245,6 +249,7 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection
|
|||
m_eval_context (-1),
|
||||
m_process_events_interval (0.0),
|
||||
m_window_closed (true),
|
||||
m_needs_update (true),
|
||||
m_ntab (8),
|
||||
m_nindent (2),
|
||||
m_save_all_on_run (false),
|
||||
|
|
@ -598,6 +603,8 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection
|
|||
if (! s_macro_editor_instance) {
|
||||
s_macro_editor_instance = this;
|
||||
}
|
||||
|
||||
config_setup ();
|
||||
}
|
||||
|
||||
MacroEditorDialog::~MacroEditorDialog ()
|
||||
|
|
@ -716,6 +723,113 @@ MacroEditorDialog::current_macro_tree ()
|
|||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::config_finalize ()
|
||||
{
|
||||
if (m_needs_update) {
|
||||
|
||||
for (int i = 0; i < tabWidget->count (); ++i) {
|
||||
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->widget (i));
|
||||
if (page) {
|
||||
page->set_ntab (m_ntab);
|
||||
page->set_nindent (m_nindent);
|
||||
page->apply_attributes ();
|
||||
page->set_font (m_font_family, m_font_size);
|
||||
}
|
||||
}
|
||||
|
||||
refresh_file_watcher ();
|
||||
|
||||
m_needs_update = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MacroEditorDialog::configure (const std::string &name, const std::string &value)
|
||||
{
|
||||
// Reads the dynamic configuration
|
||||
|
||||
if (name == cfg_macro_editor_styles) {
|
||||
|
||||
if (m_styles != value) {
|
||||
m_styles = value;
|
||||
m_needs_update = true;
|
||||
}
|
||||
m_highlighters.load (value);
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_save_all_on_run) {
|
||||
tl::from_string (value, m_save_all_on_run);
|
||||
return true;
|
||||
} else if (name == cfg_macro_editor_stop_on_exception) {
|
||||
tl::from_string (value, m_stop_on_exception);
|
||||
return true;
|
||||
} else if (name == cfg_macro_editor_file_watcher_enabled) {
|
||||
|
||||
bool en = m_file_watcher_enabled;
|
||||
tl::from_string (value, en);
|
||||
if (en != m_file_watcher_enabled) {
|
||||
m_file_watcher_enabled = en;
|
||||
m_needs_update = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_font_family) {
|
||||
|
||||
if (m_font_family != value) {
|
||||
m_font_family = value;
|
||||
m_needs_update = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_font_size) {
|
||||
|
||||
int v = m_font_size;
|
||||
tl::from_string (value, v);
|
||||
if (v != m_font_size) {
|
||||
m_font_size = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_tab_width) {
|
||||
|
||||
int v = m_ntab;
|
||||
tl::from_string (value, v);
|
||||
if (v != m_ntab) {
|
||||
m_ntab = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_indent) {
|
||||
|
||||
int v = m_nindent;
|
||||
tl::from_string (value, v);
|
||||
if (v != m_nindent) {
|
||||
m_nindent = v;
|
||||
m_needs_update = true;
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (name == cfg_macro_editor_ignore_exception_list) {
|
||||
|
||||
m_ignore_exception_list.clear ();
|
||||
tl::Extractor ex (value.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string f;
|
||||
ex.read_word_or_quoted (f);
|
||||
ex.test (";");
|
||||
m_ignore_exception_list.insert (f);
|
||||
}
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return lay::Plugin::configure (name, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::showEvent (QShowEvent *)
|
||||
{
|
||||
|
|
@ -726,29 +840,19 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
|
||||
m_window_closed = false;
|
||||
|
||||
// read configuration
|
||||
std::string styles;
|
||||
if (MainWindow::instance ()->config_get (cfg_macro_editor_styles, styles)) {
|
||||
m_highlighters.load (styles);
|
||||
}
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_save_all_on_run, m_save_all_on_run);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_stop_on_exception, m_stop_on_exception);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_file_watcher_enabled, m_file_watcher_enabled);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_font_family, m_font_family);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_font_size, m_font_size);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_tab_width, m_ntab);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_indent, m_nindent);
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_debugging_enabled, m_debugging_on);
|
||||
// read debugger environment from configuration
|
||||
|
||||
mp_plugin_root->config_get (cfg_macro_editor_debugging_enabled, m_debugging_on);
|
||||
|
||||
std::string ws;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_window_state, ws);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_window_state, ws);
|
||||
lay::restore_dialog_state (this, ws);
|
||||
|
||||
input_field->clear ();
|
||||
|
||||
try {
|
||||
std::string hi;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_console_mru, hi);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_console_mru, hi);
|
||||
tl::Extractor ex (hi.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string h;
|
||||
|
|
@ -770,7 +874,7 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
}
|
||||
|
||||
std::string ci;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_console_interpreter, ci);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_console_interpreter, ci);
|
||||
if (ci == "ruby") {
|
||||
pythonLangSel->setChecked (false);
|
||||
rubyLangSel->setChecked (true);
|
||||
|
|
@ -784,7 +888,7 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
m_watch_expressions.clear ();
|
||||
|
||||
std::string we;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_watch_expressions, we);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_watch_expressions, we);
|
||||
tl::Extractor ex (we.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
|
|
@ -806,7 +910,7 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
|
||||
try {
|
||||
std::string om;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_open_macros, om);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_open_macros, om);
|
||||
tl::Extractor ex (om.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string h;
|
||||
|
|
@ -818,7 +922,7 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
} catch (...) { }
|
||||
|
||||
std::string am;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_active_macro, am);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_active_macro, am);
|
||||
if (! am.empty ()) {
|
||||
lym::Macro *macro = mp_root->find_macro (am);
|
||||
if (macro) {
|
||||
|
|
@ -829,7 +933,7 @@ MacroEditorDialog::showEvent (QShowEvent *)
|
|||
dbgOn->setChecked (m_debugging_on);
|
||||
|
||||
std::string cm;
|
||||
MainWindow::instance ()->config_get (cfg_macro_editor_current_macro, cm);
|
||||
mp_plugin_root->config_get (cfg_macro_editor_current_macro, cm);
|
||||
if (! cm.empty ()) {
|
||||
// this will make that macro the current one
|
||||
editor_for_file (cm);
|
||||
|
|
@ -866,10 +970,10 @@ void
|
|||
MacroEditorDialog::closeEvent (QCloseEvent *)
|
||||
{
|
||||
// save the debugging enabled state
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_debugging_enabled, m_debugging_on);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_debugging_enabled, m_debugging_on);
|
||||
|
||||
// save the window state
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_window_state, lay::save_dialog_state (this));
|
||||
mp_plugin_root->config_set (cfg_macro_editor_window_state, lay::save_dialog_state (this));
|
||||
|
||||
// save the console history (at maximum the last 200 entries)
|
||||
std::string hi;
|
||||
|
|
@ -879,7 +983,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
|
|||
}
|
||||
hi += tl::to_quoted_string (tl::to_string (input_field->itemText (i)));
|
||||
}
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_console_mru, hi);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_console_mru, hi);
|
||||
|
||||
// save the open macro list
|
||||
std::string om;
|
||||
|
|
@ -892,7 +996,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
|
|||
om += tl::to_quoted_string (page->macro ()->path ());
|
||||
}
|
||||
}
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_open_macros, om);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_open_macros, om);
|
||||
|
||||
// save the watch expressions
|
||||
std::string we;
|
||||
|
|
@ -908,15 +1012,15 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
|
|||
we += ":";
|
||||
we += tl::to_quoted_string (i->second);
|
||||
}
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_watch_expressions, we);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_watch_expressions, we);
|
||||
|
||||
// save the active (run) macro
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_active_macro, mp_run_macro ? mp_run_macro->path () : std::string ());
|
||||
mp_plugin_root->config_set (cfg_macro_editor_active_macro, mp_run_macro ? mp_run_macro->path () : std::string ());
|
||||
|
||||
// save the current macro
|
||||
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->currentWidget ());
|
||||
std::string cm = page && page->macro () ? page->macro ()->path () : std::string ();
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_current_macro, cm);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_current_macro, cm);
|
||||
|
||||
// save the current interpreter in the console
|
||||
std::string ci;
|
||||
|
|
@ -925,7 +1029,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *)
|
|||
} else if (pythonLangSel->isChecked ()) {
|
||||
ci = "python";
|
||||
}
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_console_interpreter, ci);
|
||||
mp_plugin_root->config_set (cfg_macro_editor_console_interpreter, ci);
|
||||
|
||||
// stop execution when the window is closed
|
||||
m_in_exec = false;
|
||||
|
|
@ -1914,73 +2018,9 @@ MacroEditorDialog::setup_button_clicked ()
|
|||
return;
|
||||
}
|
||||
|
||||
// fill data
|
||||
|
||||
lay::MacroEditorSetupDialogData data;
|
||||
data.tab_width = m_ntab;
|
||||
data.indent = m_nindent;
|
||||
data.save_all_on_run = m_save_all_on_run;
|
||||
data.stop_on_exception = m_stop_on_exception;
|
||||
data.file_watcher_enabled = m_file_watcher_enabled;
|
||||
data.font_family = m_font_family;
|
||||
data.font_size = m_font_size;
|
||||
|
||||
if (m_highlighters.basic_attributes ()) {
|
||||
data.basic_attributes.assign (*m_highlighters.basic_attributes ());
|
||||
}
|
||||
for (MacroEditorHighlighters::const_iterator a = m_highlighters.begin (); a != m_highlighters.end (); ++a) {
|
||||
data.specific_attributes.push_back (std::make_pair (a->first, GenericSyntaxHighlighterAttributes (& data.basic_attributes)));
|
||||
data.specific_attributes.back ().second.assign (a->second);
|
||||
}
|
||||
|
||||
lay::MacroEditorSetupDialog dialog (this);
|
||||
if (dialog.exec_dialog (data)) {
|
||||
|
||||
m_ntab = data.tab_width;
|
||||
m_nindent = data.indent;
|
||||
m_stop_on_exception = data.stop_on_exception;
|
||||
m_file_watcher_enabled = data.file_watcher_enabled;
|
||||
m_font_family = data.font_family;
|
||||
m_font_size = data.font_size;
|
||||
|
||||
if (m_highlighters.basic_attributes ()) {
|
||||
m_highlighters.basic_attributes ()->assign (data.basic_attributes);
|
||||
}
|
||||
|
||||
for (MacroEditorHighlighters::iterator a = m_highlighters.begin (); a != m_highlighters.end (); ++a) {
|
||||
for (std::vector< std::pair<std::string, GenericSyntaxHighlighterAttributes> >::const_iterator i = data.specific_attributes.begin (); i != data.specific_attributes.end (); ++i) {
|
||||
if (i->first == a->first) {
|
||||
a->second.assign (i->second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_save_all_on_run = data.save_all_on_run;
|
||||
|
||||
for (int i = 0; i < tabWidget->count (); ++i) {
|
||||
MacroEditorPage *page = dynamic_cast<MacroEditorPage *> (tabWidget->widget (i));
|
||||
if (page) {
|
||||
page->set_ntab (m_ntab);
|
||||
page->set_nindent (m_nindent);
|
||||
page->apply_attributes ();
|
||||
page->set_font (m_font_family, m_font_size);
|
||||
}
|
||||
}
|
||||
|
||||
// write configuration
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_styles, m_highlighters.to_string ());
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_save_all_on_run, m_save_all_on_run);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_file_watcher_enabled, m_file_watcher_enabled);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_stop_on_exception, m_stop_on_exception);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_tab_width, m_ntab);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_indent, m_nindent);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_font_family, m_font_family);
|
||||
MainWindow::instance ()->config_set (cfg_macro_editor_font_size, m_font_size);
|
||||
MainWindow::instance ()->config_end ();
|
||||
|
||||
lay::ConfigurationDialog config_dialog (this, mp_plugin_root, "MacroEditor");
|
||||
if (config_dialog.exec ()) {
|
||||
refresh_file_watcher ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2253,12 +2293,12 @@ MacroEditorDialog::ensure_writeable_collection_selected ()
|
|||
}
|
||||
|
||||
static std::vector<std::pair<std::string, std::string> >
|
||||
get_custom_paths ()
|
||||
get_custom_paths (lay::PluginRoot *root)
|
||||
{
|
||||
std::vector <std::pair<std::string, std::string> > paths;
|
||||
|
||||
std::string mp;
|
||||
MainWindow::instance ()->config_get (cfg_custom_macro_paths, mp);
|
||||
root->config_get (cfg_custom_macro_paths, mp);
|
||||
|
||||
try {
|
||||
|
||||
|
|
@ -2281,7 +2321,7 @@ get_custom_paths ()
|
|||
}
|
||||
|
||||
static void
|
||||
set_custom_paths (const std::vector<std::pair<std::string, std::string> > &paths)
|
||||
set_custom_paths (lay::PluginRoot *root, const std::vector<std::pair<std::string, std::string> > &paths)
|
||||
{
|
||||
std::string mp;
|
||||
|
||||
|
|
@ -2295,7 +2335,7 @@ set_custom_paths (const std::vector<std::pair<std::string, std::string> > &paths
|
|||
mp += p->second;
|
||||
}
|
||||
|
||||
MainWindow::instance ()->config_set (cfg_custom_macro_paths, mp);
|
||||
root->config_set (cfg_custom_macro_paths, mp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2494,7 +2534,7 @@ BEGIN_PROTECTED
|
|||
|
||||
std::string cat = current_macro_tree ()->category ();
|
||||
|
||||
std::vector <std::pair<std::string, std::string> > paths = get_custom_paths ();
|
||||
std::vector <std::pair<std::string, std::string> > paths = get_custom_paths (mp_plugin_root);
|
||||
std::string new_path = tl::to_string (QFileInfo (new_dir).absoluteFilePath ());
|
||||
paths.push_back (std::make_pair (new_path, cat));
|
||||
|
||||
|
|
@ -2503,7 +2543,7 @@ BEGIN_PROTECTED
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("The selected directory is already installed as custom location")));
|
||||
}
|
||||
|
||||
set_custom_paths (paths);
|
||||
set_custom_paths (mp_plugin_root, paths);
|
||||
|
||||
if (c->has_autorun ()) {
|
||||
if (QMessageBox::question (this, QObject::tr ("Run Macros"), QObject::tr ("The selected folder has macros configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
|
||||
|
|
@ -2538,7 +2578,7 @@ BEGIN_PROTECTED
|
|||
throw tl::Exception (tl::to_string (QObject::tr ("Select tree location to remove")));
|
||||
}
|
||||
|
||||
std::vector <std::pair <std::string, std::string> > paths = get_custom_paths ();
|
||||
std::vector <std::pair <std::string, std::string> > paths = get_custom_paths (mp_plugin_root);
|
||||
|
||||
bool found = false;
|
||||
|
||||
|
|
@ -2560,7 +2600,7 @@ BEGIN_PROTECTED
|
|||
mp_root->erase (collection);
|
||||
|
||||
// save the new paths
|
||||
set_custom_paths (paths);
|
||||
set_custom_paths (mp_plugin_root, paths);
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
|
@ -2809,10 +2849,34 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
|
|||
return;
|
||||
}
|
||||
|
||||
if (QMessageBox::critical (this, QObject::tr ("Exception Caught"),
|
||||
tl::to_qstring (tl::to_string (QObject::tr ("Caught the following exception:\n")) + emsg + " (Class " + eclass + ")\n\n" + tl::to_string (QObject::tr ("Press 'Ok' to continue and 'Cancel' to stop in the debugger"))),
|
||||
QMessageBox::Cancel, QMessageBox::Ok) == QMessageBox::Ok) {
|
||||
std::string p;
|
||||
if (file_id > 0 && file_id <= m_file_to_widget.size () && m_file_to_widget [file_id - 1].first) {
|
||||
p = m_file_to_widget [file_id - 1].first->path ();
|
||||
if (m_ignore_exception_list.find (p) != m_ignore_exception_list.end ()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int res = QMessageBox::critical (this, QObject::tr ("Exception Caught"),
|
||||
tl::to_qstring (tl::to_string (QObject::tr ("Caught the following exception:\n")) + emsg + " (Class " + eclass + ")\n\n" + tl::to_string (QObject::tr ("Press 'Ok' to continue.\nPress 'Ignore' to ignore this and future exceptions from this file.\nPress 'Cancel' to stop in the debugger"))),
|
||||
QMessageBox::Cancel | QMessageBox::Ok | QMessageBox::Ignore,
|
||||
QMessageBox::Ok);
|
||||
|
||||
if (res == QMessageBox::Ok) {
|
||||
|
||||
return;
|
||||
|
||||
} else if (res == QMessageBox::Ignore) {
|
||||
|
||||
std::string il;
|
||||
il += tl::to_quoted_string (p);
|
||||
for (std::set<std::string>::const_iterator i = m_ignore_exception_list.begin (); i != m_ignore_exception_list.end (); ++i) {
|
||||
il += ";";
|
||||
il += tl::to_quoted_string (*i);
|
||||
}
|
||||
mp_plugin_root->config_set (cfg_macro_editor_ignore_exception_list, il);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
write_str (emsg.c_str (), OS_stderr);
|
||||
|
|
@ -3399,6 +3463,12 @@ class MacroEditorPluginDeclaration
|
|||
: public lay::PluginDeclaration
|
||||
{
|
||||
public:
|
||||
virtual lay::ConfigPage *config_page (QWidget *parent, std::string &title) const
|
||||
{
|
||||
title = tl::to_string (QObject::tr ("Application|Macro Development IDE"));
|
||||
return new MacroEditorSetupPage (parent);
|
||||
}
|
||||
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
{
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_macro_editor_styles, ""));
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "ui_MacroEditorDialog.h"
|
||||
#include "layMacroEditorPage.h"
|
||||
#include "layMacroController.h"
|
||||
#include "layPlugin.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
#include "tlTimer.h"
|
||||
#include "tlFileSystemWatcher.h"
|
||||
|
|
@ -50,11 +51,34 @@ class QTreeWidgetItem;
|
|||
namespace lay
|
||||
{
|
||||
|
||||
extern const std::string cfg_macro_editor_styles;
|
||||
extern const std::string cfg_macro_editor_save_all_on_run;
|
||||
extern const std::string cfg_macro_editor_stop_on_exception;
|
||||
extern const std::string cfg_macro_editor_file_watcher_enabled;
|
||||
extern const std::string cfg_macro_editor_font_family;
|
||||
extern const std::string cfg_macro_editor_font_size;
|
||||
extern const std::string cfg_macro_editor_tab_width;
|
||||
extern const std::string cfg_macro_editor_indent;
|
||||
extern const std::string cfg_macro_editor_window_state;
|
||||
extern const std::string cfg_macro_editor_console_mru;
|
||||
extern const std::string cfg_macro_editor_console_interpreter;
|
||||
extern const std::string cfg_macro_editor_open_macros;
|
||||
extern const std::string cfg_macro_editor_current_macro;
|
||||
extern const std::string cfg_macro_editor_active_macro;
|
||||
extern const std::string cfg_macro_editor_watch_expressions;
|
||||
extern const std::string cfg_macro_editor_debugging_enabled;
|
||||
extern const std::string cfg_macro_editor_ignore_exception_list;
|
||||
|
||||
class MacroEditorTree;
|
||||
class BrowserPanel;
|
||||
class MainWindow;
|
||||
|
||||
class MacroEditorDialog
|
||||
: public QDialog, public gsi::Console, private Ui::MacroEditorDialog, public gsi::ExecutionHandler
|
||||
: public QDialog,
|
||||
public lay::Plugin,
|
||||
public gsi::Console,
|
||||
public gsi::ExecutionHandler,
|
||||
private Ui::MacroEditorDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
@ -74,7 +98,7 @@ public:
|
|||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
MacroEditorDialog (QWidget *parent, lym::MacroCollection *root);
|
||||
MacroEditorDialog (lay::MainWindow *parent, lym::MacroCollection *root);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
|
|
@ -262,7 +286,10 @@ private:
|
|||
lym::Macro *new_macro ();
|
||||
void do_search_edited ();
|
||||
void select_trace (size_t index);
|
||||
bool configure (const std::string &name, const std::string &value);
|
||||
void config_finalize ();
|
||||
|
||||
lay::PluginRoot *mp_plugin_root;
|
||||
lym::MacroCollection *mp_root;
|
||||
bool m_first_show;
|
||||
bool m_in_processing;
|
||||
|
|
@ -294,10 +321,13 @@ private:
|
|||
double m_process_events_interval;
|
||||
tl::Clock m_last_process_events;
|
||||
bool m_window_closed;
|
||||
bool m_needs_update;
|
||||
std::string m_styles;
|
||||
int m_ntab;
|
||||
int m_nindent;
|
||||
bool m_save_all_on_run;
|
||||
bool m_stop_on_exception;
|
||||
std::set<std::string> m_ignore_exception_list;
|
||||
bool m_file_watcher_enabled;
|
||||
std::string m_font_family;
|
||||
int m_font_size;
|
||||
|
|
|
|||
|
|
@ -21,15 +21,114 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "layMacroEditorSetupDialog.h"
|
||||
#include "layMacroEditorSetupPage.h"
|
||||
#include "layMacroEditorPage.h"
|
||||
#include "layMacroEditorDialog.h"
|
||||
#include "layGenericSyntaxHighlighter.h"
|
||||
|
||||
#include "lymMacro.h"
|
||||
|
||||
#include "tlString.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
struct MacroEditorSetupDialogData
|
||||
{
|
||||
MacroEditorSetupDialogData ()
|
||||
: basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
GenericSyntaxHighlighterAttributes basic_attributes;
|
||||
std::vector <std::pair <std::string, GenericSyntaxHighlighterAttributes> > specific_attributes;
|
||||
int tab_width;
|
||||
int indent;
|
||||
bool save_all_on_run;
|
||||
bool stop_on_exception;
|
||||
bool file_watcher_enabled;
|
||||
std::string font_family;
|
||||
int font_size;
|
||||
std::set <std::string> ignore_exceptions_list;
|
||||
|
||||
void setup (lay::PluginRoot *root)
|
||||
{
|
||||
lay::MacroEditorHighlighters highlighters (0);
|
||||
std::string styles;
|
||||
root->config_get (cfg_macro_editor_styles, styles);
|
||||
highlighters.load (styles);
|
||||
|
||||
if (highlighters.basic_attributes ()) {
|
||||
basic_attributes.assign (*highlighters.basic_attributes ());
|
||||
}
|
||||
for (lay::MacroEditorHighlighters::const_iterator a = highlighters.begin (); a != highlighters.end (); ++a) {
|
||||
specific_attributes.push_back (std::make_pair (a->first, GenericSyntaxHighlighterAttributes (& basic_attributes)));
|
||||
specific_attributes.back ().second.assign (a->second);
|
||||
}
|
||||
|
||||
root->config_get (cfg_macro_editor_save_all_on_run, save_all_on_run);
|
||||
root->config_get (cfg_macro_editor_file_watcher_enabled, file_watcher_enabled);
|
||||
root->config_get (cfg_macro_editor_stop_on_exception, stop_on_exception);
|
||||
root->config_get (cfg_macro_editor_tab_width, tab_width);
|
||||
root->config_get (cfg_macro_editor_indent, indent);
|
||||
root->config_get (cfg_macro_editor_font_family, font_family);
|
||||
root->config_get (cfg_macro_editor_font_size, font_size);
|
||||
|
||||
std::string il;
|
||||
root->config_get (cfg_macro_editor_ignore_exception_list, il);
|
||||
ignore_exceptions_list.clear ();
|
||||
tl::Extractor ex (il.c_str ());
|
||||
while (! ex.at_end ()) {
|
||||
std::string f;
|
||||
ex.read_word_or_quoted (f);
|
||||
ex.test (";");
|
||||
ignore_exceptions_list.insert (f);
|
||||
}
|
||||
}
|
||||
|
||||
void commit (lay::PluginRoot *root)
|
||||
{
|
||||
lay::MacroEditorHighlighters highlighters (0);
|
||||
|
||||
if (highlighters.basic_attributes ()) {
|
||||
highlighters.basic_attributes ()->assign (basic_attributes);
|
||||
}
|
||||
|
||||
for (MacroEditorHighlighters::iterator a = highlighters.begin (); a != highlighters.end (); ++a) {
|
||||
for (std::vector< std::pair<std::string, GenericSyntaxHighlighterAttributes> >::const_iterator i = specific_attributes.begin (); i != specific_attributes.end (); ++i) {
|
||||
if (i->first == a->first) {
|
||||
a->second.assign (i->second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write configuration
|
||||
|
||||
root->config_set (cfg_macro_editor_styles, highlighters.to_string ());
|
||||
root->config_set (cfg_macro_editor_save_all_on_run, save_all_on_run);
|
||||
root->config_set (cfg_macro_editor_file_watcher_enabled, file_watcher_enabled);
|
||||
root->config_set (cfg_macro_editor_stop_on_exception, stop_on_exception);
|
||||
root->config_set (cfg_macro_editor_tab_width, tab_width);
|
||||
root->config_set (cfg_macro_editor_indent, indent);
|
||||
root->config_set (cfg_macro_editor_font_family, font_family);
|
||||
root->config_set (cfg_macro_editor_font_size, font_size);
|
||||
|
||||
std::string il;
|
||||
for (std::set<std::string>::const_iterator i = ignore_exceptions_list.begin (); i != ignore_exceptions_list.end (); ++i) {
|
||||
if (! il.empty ()) {
|
||||
il += ";";
|
||||
}
|
||||
il += tl::to_quoted_string (*i);
|
||||
}
|
||||
root->config_set (cfg_macro_editor_ignore_exception_list, il);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
update_item (QListWidgetItem *item, QTextCharFormat format)
|
||||
{
|
||||
|
|
@ -38,8 +137,8 @@ update_item (QListWidgetItem *item, QTextCharFormat format)
|
|||
item->setData (Qt::BackgroundRole, format.background ());
|
||||
}
|
||||
|
||||
MacroEditorSetupDialog::MacroEditorSetupDialog (QWidget *parent)
|
||||
: QDialog (parent), mp_data (0)
|
||||
MacroEditorSetupPage::MacroEditorSetupPage (QWidget *parent)
|
||||
: lay::ConfigPage (parent), mp_data (0)
|
||||
{
|
||||
setupUi (this);
|
||||
|
||||
|
|
@ -52,22 +151,49 @@ MacroEditorSetupDialog::MacroEditorSetupDialog (QWidget *parent)
|
|||
connect (background_color_button, SIGNAL (color_changed (QColor)), this, SLOT (color_changed (QColor)));
|
||||
connect (font_sel, SIGNAL (currentFontChanged (const QFont &)), this, SLOT (update_font ()));
|
||||
connect (font_size, SIGNAL (valueChanged (int)), this, SLOT (update_font ()));
|
||||
connect (clear_el, SIGNAL (clicked ()), this, SLOT (clear_exception_list ()));
|
||||
}
|
||||
|
||||
MacroEditorSetupPage::~MacroEditorSetupPage ()
|
||||
{
|
||||
delete mp_data;
|
||||
mp_data = 0;
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::color_changed (QColor)
|
||||
MacroEditorSetupPage::color_changed (QColor)
|
||||
{
|
||||
commit_attributes (styles_list->currentItem ());
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::cb_changed (int)
|
||||
MacroEditorSetupPage::cb_changed (int)
|
||||
{
|
||||
commit_attributes (styles_list->currentItem ());
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupPage::clear_exception_list ()
|
||||
{
|
||||
if (mp_data) {
|
||||
mp_data->ignore_exceptions_list.clear ();
|
||||
update_ignore_exception_list ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupPage::update_ignore_exception_list ()
|
||||
{
|
||||
if (mp_data) {
|
||||
exception_list->clear ();
|
||||
for (std::set<std::string>::const_iterator i = mp_data->ignore_exceptions_list.begin (); i != mp_data->ignore_exceptions_list.end (); ++i) {
|
||||
exception_list->addItem (tl::to_qstring (*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::update_font ()
|
||||
MacroEditorSetupPage::update_font ()
|
||||
{
|
||||
QFont f;
|
||||
f.setFamily (font_sel->currentFont().family ());
|
||||
|
|
@ -76,26 +202,30 @@ MacroEditorSetupDialog::update_font ()
|
|||
styles_list->setFont (f);
|
||||
}
|
||||
|
||||
int
|
||||
MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data)
|
||||
void
|
||||
MacroEditorSetupPage::setup (PluginRoot *root)
|
||||
{
|
||||
mp_data = &data;
|
||||
delete mp_data;
|
||||
mp_data = new MacroEditorSetupDialogData ();
|
||||
mp_data->setup (root);
|
||||
|
||||
tab_width->setValue (data.tab_width);
|
||||
indent->setValue (data.indent);
|
||||
save_all_cb->setChecked (data.save_all_on_run);
|
||||
stop_on_exception->setChecked (data.stop_on_exception);
|
||||
watch_files->setChecked (data.file_watcher_enabled);
|
||||
update_ignore_exception_list ();
|
||||
|
||||
if (data.font_size <= 0) {
|
||||
data.font_size = font ().pointSize ();
|
||||
data.font_family = "Monospace";
|
||||
tab_width->setValue (mp_data->tab_width);
|
||||
indent->setValue (mp_data->indent);
|
||||
save_all_cb->setChecked (mp_data->save_all_on_run);
|
||||
stop_on_exception->setChecked (mp_data->stop_on_exception);
|
||||
watch_files->setChecked (mp_data->file_watcher_enabled);
|
||||
|
||||
if (mp_data->font_size <= 0) {
|
||||
mp_data->font_size = font ().pointSize ();
|
||||
mp_data->font_family = "Monospace";
|
||||
}
|
||||
|
||||
QFont f;
|
||||
f.setFamily (tl::to_qstring (data.font_family));
|
||||
f.setFamily (tl::to_qstring (mp_data->font_family));
|
||||
font_sel->setCurrentFont (f);
|
||||
font_size->setValue (data.font_size);
|
||||
font_size->setValue (mp_data->font_size);
|
||||
|
||||
styles_list->blockSignals (true);
|
||||
|
||||
|
|
@ -103,18 +233,18 @@ MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data)
|
|||
|
||||
std::map <int, QString> basic_names;
|
||||
|
||||
for (GenericSyntaxHighlighterAttributes::const_iterator a = data.basic_attributes.begin (); a != data.basic_attributes.end (); ++a) {
|
||||
for (GenericSyntaxHighlighterAttributes::const_iterator a = mp_data->basic_attributes.begin (); a != mp_data->basic_attributes.end (); ++a) {
|
||||
QListWidgetItem *item = new QListWidgetItem (styles_list);
|
||||
QString n = tl::to_qstring (tl::to_string (QObject::tr ("(basic)")) + " ") + a->first;
|
||||
item->setText (n);
|
||||
item->setData (Qt::UserRole, -1);
|
||||
item->setData (Qt::UserRole + 1, a->second);
|
||||
basic_names.insert (std::make_pair (a->second, n));
|
||||
update_item (item, data.basic_attributes.format_for (a->second));
|
||||
update_item (item, mp_data->basic_attributes.format_for (a->second));
|
||||
}
|
||||
|
||||
int na = 0;
|
||||
for (std::vector <std::pair <std::string, GenericSyntaxHighlighterAttributes> >::const_iterator sa = data.specific_attributes.begin (); sa != data.specific_attributes.end (); ++sa, ++na) {
|
||||
for (std::vector <std::pair <std::string, GenericSyntaxHighlighterAttributes> >::const_iterator sa = mp_data->specific_attributes.begin (); sa != mp_data->specific_attributes.end (); ++sa, ++na) {
|
||||
|
||||
QString l = tl::to_qstring ("(" + sa->first + ") ");
|
||||
|
||||
|
|
@ -137,30 +267,32 @@ MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data)
|
|||
|
||||
update_attributes (styles_list->currentItem ());
|
||||
update_font ();
|
||||
}
|
||||
|
||||
int r = QDialog::exec ();
|
||||
if (r) {
|
||||
|
||||
if (styles_list->currentItem ()) {
|
||||
commit_attributes (styles_list->currentItem ());
|
||||
}
|
||||
|
||||
data.tab_width = tab_width->value ();
|
||||
data.indent = indent->value ();
|
||||
data.save_all_on_run = save_all_cb->isChecked ();
|
||||
data.stop_on_exception = stop_on_exception->isChecked ();
|
||||
data.file_watcher_enabled = watch_files->isChecked ();
|
||||
|
||||
data.font_family = tl::to_string (font_sel->currentFont ().family ());
|
||||
data.font_size = font_size->value ();
|
||||
|
||||
void
|
||||
MacroEditorSetupPage::commit (PluginRoot *root)
|
||||
{
|
||||
if (styles_list->currentItem ()) {
|
||||
commit_attributes (styles_list->currentItem ());
|
||||
}
|
||||
|
||||
return r;
|
||||
if (mp_data) {
|
||||
|
||||
mp_data->tab_width = tab_width->value ();
|
||||
mp_data->indent = indent->value ();
|
||||
mp_data->save_all_on_run = save_all_cb->isChecked ();
|
||||
mp_data->stop_on_exception = stop_on_exception->isChecked ();
|
||||
mp_data->file_watcher_enabled = watch_files->isChecked ();
|
||||
|
||||
mp_data->font_family = tl::to_string (font_sel->currentFont ().family ());
|
||||
mp_data->font_size = font_size->value ();
|
||||
|
||||
mp_data->commit (root);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous)
|
||||
MacroEditorSetupPage::current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous)
|
||||
{
|
||||
if (previous) {
|
||||
commit_attributes (previous);
|
||||
|
|
@ -170,7 +302,7 @@ MacroEditorSetupDialog::current_attribute_changed (QListWidgetItem *current, QLi
|
|||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::commit_attributes (QListWidgetItem *to_item)
|
||||
MacroEditorSetupPage::commit_attributes (QListWidgetItem *to_item)
|
||||
{
|
||||
if (! to_item) {
|
||||
return;
|
||||
|
|
@ -252,7 +384,7 @@ MacroEditorSetupDialog::commit_attributes (QListWidgetItem *to_item)
|
|||
}
|
||||
|
||||
void
|
||||
MacroEditorSetupDialog::update_attributes (QListWidgetItem *from_item)
|
||||
MacroEditorSetupPage::update_attributes (QListWidgetItem *from_item)
|
||||
{
|
||||
if (from_item) {
|
||||
|
||||
|
|
@ -21,60 +21,43 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef HDR_layMacroEditorSetupDialog
|
||||
#define HDR_layMacroEditorSetupDialog
|
||||
#ifndef HDR_layMacroEditorSetupPage
|
||||
#define HDR_layMacroEditorSetupPage
|
||||
|
||||
#include "layGenericSyntaxHighlighter.h"
|
||||
#include "lymMacro.h"
|
||||
#include "ui_MacroEditorSetupDialog.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <vector>
|
||||
#include "layPlugin.h"
|
||||
#include "ui_MacroEditorSetupPage.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
struct MacroEditorSetupDialogData
|
||||
{
|
||||
MacroEditorSetupDialogData ()
|
||||
: basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
GenericSyntaxHighlighterAttributes basic_attributes;
|
||||
std::vector <std::pair <std::string, GenericSyntaxHighlighterAttributes> > specific_attributes;
|
||||
int tab_width;
|
||||
int indent;
|
||||
bool save_all_on_run;
|
||||
bool stop_on_exception;
|
||||
bool file_watcher_enabled;
|
||||
std::string font_family;
|
||||
int font_size;
|
||||
};
|
||||
struct MacroEditorSetupDialogData;
|
||||
|
||||
/**
|
||||
* @brief The dialog for editing the properties of the debugger/editor
|
||||
*/
|
||||
class MacroEditorSetupDialog
|
||||
: public QDialog, private Ui::MacroEditorSetupDialog
|
||||
class MacroEditorSetupPage
|
||||
: public lay::ConfigPage, private Ui::MacroEditorSetupPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroEditorSetupDialog (QWidget *parent);
|
||||
MacroEditorSetupPage (QWidget *parent);
|
||||
~MacroEditorSetupPage ();
|
||||
|
||||
int exec_dialog (MacroEditorSetupDialogData &data);
|
||||
virtual void setup (PluginRoot *root);
|
||||
virtual void commit (PluginRoot *root);
|
||||
|
||||
protected slots:
|
||||
void current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void cb_changed (int n);
|
||||
void color_changed (QColor c);
|
||||
void update_font ();
|
||||
void clear_exception_list ();
|
||||
|
||||
private:
|
||||
void commit_attributes (QListWidgetItem *to_item);
|
||||
void update_attributes (QListWidgetItem *from_item);
|
||||
void update_ignore_exception_list ();
|
||||
|
||||
MacroEditorSetupDialogData *mp_data;
|
||||
};
|
||||
|
|
@ -1318,19 +1318,6 @@ MainWindow::about_to_exec ()
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
edt::combine_mode_type cm = edt::CM_Add;
|
||||
config_get (edt::cfg_edit_combine_mode, cm, edt::CMConverter ());
|
||||
if (lay::ApplicationBase::instance ()->is_editable () && cm != edt::CM_Add) {
|
||||
lay::TipDialog td (QApplication::activeWindow (),
|
||||
tl::to_string (QObject::tr ("The background combination mode of the shape editor is set to some other mode than 'Add'.\n"
|
||||
"This can be confusing, because a shape may not be drawn as expected.\n\nTo switch back to normal mode, choose 'Add' for the background combination mode in the toolbar.")),
|
||||
"has-non-add-edit-combine-mode");
|
||||
if (td.exec_dialog ()) {
|
||||
// Don't bother the user with more dialogs.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -70,8 +70,22 @@ main (int argc, char **argv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
run_test (tl::TestBase *t, bool editable, bool slow, int repeat)
|
||||
{
|
||||
for (int i = 0; i < repeat; ++i) {
|
||||
if (repeat > 1) {
|
||||
ut::noctrl << "Repeat iteration " << i + 1 << " of " << repeat;
|
||||
}
|
||||
if (! t->do_test (editable, slow)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
run_tests (const std::vector<tl::TestBase *> &selected_tests, bool editable, bool non_editable, bool slow, lay::ApplicationBase &app, bool gsi_coverage, const std::vector<std::string> &class_names_vector)
|
||||
run_tests (const std::vector<tl::TestBase *> &selected_tests, bool editable, bool non_editable, bool slow, int repeat, lay::ApplicationBase &app, bool gsi_coverage, const std::vector<std::string> &class_names_vector)
|
||||
{
|
||||
std::set<std::string> class_names;
|
||||
class_names.insert (class_names_vector.begin (), class_names_vector.end ());
|
||||
|
|
@ -129,7 +143,7 @@ run_tests (const std::vector<tl::TestBase *> &selected_tests, bool editable, boo
|
|||
tl::Timer timer;
|
||||
timer.start();
|
||||
|
||||
if (! (*t)->do_test (e != 0, slow)) {
|
||||
if (! run_test (*t, e != 0, slow, repeat)) {
|
||||
|
||||
ut::ctrl << "</system-out>";
|
||||
|
||||
|
|
@ -414,6 +428,7 @@ main_cont (int &argc, char **argv)
|
|||
bool verbose = false;
|
||||
bool debug_mode = false;
|
||||
bool continue_flag = false;
|
||||
int repeat = 1;
|
||||
|
||||
tl::CommandLineOptions cmd;
|
||||
cmd << tl::arg ("-a", &xml_format, "Provide XML output format (JUnit format)")
|
||||
|
|
@ -428,11 +443,12 @@ main_cont (int &argc, char **argv)
|
|||
<< tl::arg ("-s", &slow, "Includes slow (long runner) tests")
|
||||
<< tl::arg ("-v", &verbose, "Provides verbose output")
|
||||
<< tl::arg ("-g", &gsi_coverage, "Produces a GSI test coverage statistics")
|
||||
<< tl::arg ("*-gg=class", &class_names, "Produces a specific GDS coverage statistics"
|
||||
<< tl::arg ("-r=n", &repeat, "Repeat the tests n times each")
|
||||
<< tl::arg ("*-gg=class", &class_names, "Produces a specific GDS coverage statistics",
|
||||
"With this specification, coverage will be printed for this specific class. "
|
||||
"This option can be used multiple times to add more classes."
|
||||
)
|
||||
<< tl::arg ("-x=test", &exclude_test_list, "Exclude the following tests"
|
||||
<< tl::arg ("-x=test", &exclude_test_list, "Exclude the following tests",
|
||||
"This option can be given multiple times or with a comma-separated list "
|
||||
"of pattern. Test tests matching one of the exclude pattern "
|
||||
"are not executed."
|
||||
|
|
@ -509,7 +525,7 @@ main_cont (int &argc, char **argv)
|
|||
selected_tests = &tl::TestRegistrar::instance()->tests ();
|
||||
}
|
||||
|
||||
result = run_tests (*selected_tests, editable, non_editable, slow, app, gsi_coverage, class_names);
|
||||
result = run_tests (*selected_tests, editable, non_editable, slow, repeat, app, gsi_coverage, class_names);
|
||||
|
||||
ut::ctrl << "</testsuites>";
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue