Переглянути джерело

Merge pull request #219 from bgrabitmap/dev-lazpaint

Dev lazpaint 7.1.6
circular17 4 роки тому
батько
коміт
81493e19eb
100 змінених файлів з 6694 додано та 1410 видалено
  1. 5 13
      .gitignore
  2. 145 62
      Makefile
  3. 74 0
      configure
  4. 70 0
      configure.bat
  5. 35 0
      create_orig
  6. 5 0
      debian/changelog
  7. 35 0
      debian/control
  8. 119 0
      debian/copyright
  9. 26 0
      debian/rules
  10. 1 0
      debian/source/format
  11. 5 0
      debian/upstream/metadata
  12. 3 0
      debian/watch
  13. BIN
      lazpaint/buttons/biplane48.lzp
  14. BIN
      lazpaint/buttons/biplane48.png
  15. BIN
      lazpaint/buttons/capflat48.png
  16. BIN
      lazpaint/buttons/capround48.lzp
  17. BIN
      lazpaint/buttons/capround48.png
  18. BIN
      lazpaint/buttons/capsquare48.png
  19. BIN
      lazpaint/buttons/joinbevel48.png
  20. BIN
      lazpaint/buttons/joinmiter48.png
  21. BIN
      lazpaint/buttons/joinround48.lzp
  22. BIN
      lazpaint/buttons/joinround48.png
  23. BIN
      lazpaint/buttons/layers48.lzp
  24. BIN
      lazpaint/buttons/layers48.png
  25. BIN
      lazpaint/buttons/new_geometric48.lzp
  26. BIN
      lazpaint/buttons/new_geometric48.png
  27. BIN
      lazpaint/buttons/phonghcylinder48.png
  28. BIN
      lazpaint/buttons/phongvcone48.lzp
  29. BIN
      lazpaint/buttons/phongvcone48.png
  30. BIN
      lazpaint/buttons/phongvcylinder48.png
  31. BIN
      lazpaint/buttons/swapcolor48.lzp
  32. BIN
      lazpaint/buttons/swapcolor48.png
  33. BIN
      lazpaint/buttons/textfont48.lzp
  34. BIN
      lazpaint/buttons/textfont48.png
  35. BIN
      lazpaint/buttons/textphong48.lzp
  36. BIN
      lazpaint/buttons/textphong48.png
  37. BIN
      lazpaint/buttons/texture_simple.png
  38. 26 4
      lazpaint/dialog/color/uadjustcurves.pas
  39. 8 0
      lazpaint/dialog/ublendop.lfm
  40. 3 1
      lazpaint/dialog/ublendop.pas
  41. 210 191
      lazpaint/dialog/ubrowseimages.lfm
  42. 59 2
      lazpaint/dialog/ubrowseimages.pas
  43. 27 1
      lazpaint/dialog/ucanvassize.pas
  44. 18 14
      lazpaint/dialog/uchoosecolorinterface.pas
  45. 116 46
      lazpaint/dialog/ulayerstackinterface.pas
  46. 27 1
      lazpaint/dialog/unewimage.pas
  47. 1 1
      lazpaint/dialog/uobject3d.lfm
  48. 2 2
      lazpaint/dialog/uobject3d.pas
  49. 28 2
      lazpaint/dialog/uresample.pas
  50. 40 3
      lazpaint/image/uimage.pas
  51. 140 75
      lazpaint/image/uimageaction.pas
  52. 2 0
      lazpaint/image/uimagediff.pas
  53. 53 0
      lazpaint/image/uimagestate.pas
  54. 119 43
      lazpaint/lazpaint.lpi
  55. 9 2
      lazpaint/lazpaintdialogs.inc
  56. 1 1
      lazpaint/lazpaintembeddedpack.lpk
  57. 132 25
      lazpaint/lazpaintinstance.pas
  58. 432 620
      lazpaint/lazpaintmainform.lfm
  59. 177 57
      lazpaint/lazpaintmainform.pas
  60. 9 4
      lazpaint/lazpainttype.pas
  61. 72 29
      lazpaint/maintoolbar.inc
  62. 213 0
      lazpaint/ns_url_request.pas
  63. 8 4
      lazpaint/release/bin/i18n/lazpaint.ar.po
  64. 8 4
      lazpaint/release/bin/i18n/lazpaint.bg.po
  65. 8 4
      lazpaint/release/bin/i18n/lazpaint.cs.po
  66. 8 4
      lazpaint/release/bin/i18n/lazpaint.de.po
  67. 8 4
      lazpaint/release/bin/i18n/lazpaint.es.po
  68. 8 4
      lazpaint/release/bin/i18n/lazpaint.fi.po
  69. 8 4
      lazpaint/release/bin/i18n/lazpaint.fr.po
  70. 10 6
      lazpaint/release/bin/i18n/lazpaint.ja.po
  71. 8 4
      lazpaint/release/bin/i18n/lazpaint.kab.po
  72. 8 4
      lazpaint/release/bin/i18n/lazpaint.lv.po
  73. 8 4
      lazpaint/release/bin/i18n/lazpaint.nl.po
  74. 3595 0
      lazpaint/release/bin/i18n/lazpaint.pl.po
  75. 8 4
      lazpaint/release/bin/i18n/lazpaint.po
  76. 8 4
      lazpaint/release/bin/i18n/lazpaint.pt_BR.po
  77. 8 4
      lazpaint/release/bin/i18n/lazpaint.ru.po
  78. 8 4
      lazpaint/release/bin/i18n/lazpaint.sv.po
  79. 8 4
      lazpaint/release/bin/i18n/lazpaint.zh_CN.po
  80. 1 1
      lazpaint/release/debian/applications/lazpaint.desktop
  81. 27 0
      lazpaint/release/debian/debian/changelog
  82. 8 7
      lazpaint/release/debian/debian/control
  83. 25 9
      lazpaint/release/debian/makedeb.sh
  84. 8 4
      lazpaint/release/debian/man/man1/lazpaint.1
  85. BIN
      lazpaint/release/debian/pixmaps/lazpaint.png
  86. 2 2
      lazpaint/release/macOS/LazPaint.app/Contents/Info.plist
  87. 1 1
      lazpaint/release/macOS/makedmg.sh
  88. 1 1
      lazpaint/release/stable/pad_file.xml
  89. 0 0
      lazpaint/release/windows/dcraw/dcraw64.exe
  90. 4 4
      lazpaint/release/windows/lazpaint.iss
  91. 3 3
      lazpaint/release/windows/stage.bat
  92. 32 17
      lazpaint/tools/utool.pas
  93. 9 2
      lazpaint/tools/utoolbasic.pas
  94. 3 2
      lazpaint/tools/utooltext.pas
  95. 15 0
      lazpaint/uchoosecolor.pas
  96. 8 3
      lazpaint/uclipboard.pas
  97. 6 2
      lazpaint/ucommandline.pas
  98. 57 4
      lazpaint/uconfig.pas
  99. 311 82
      lazpaint/udarktheme.pas
  100. 1 1
      lazpaint/ufileextensions.pas

+ 5 - 13
.gitignore

@@ -9,27 +9,16 @@ __pycache__
 *.res
 *.lrt
 /lazpaint/*.lrj
-
 lazpaint/backup/
-
 *.lrj
-
 vectoredit/vectoredit
-
 vectoredit/backup/
-
 lazpaint/test_embedded/backup/
-
 lazpaint/test_embedded/project1
-
 lazpaint/dialog/filter/backup/
-
 lazpaint/release/bin/lazpaint
-
 lazpaint/tools/backup/
-
 lazpaint/image/backup/
-
 lazpaint/dialog/backup/
 .DS_Store
 lazpaint/release/bin/lazpaint.app
@@ -39,7 +28,10 @@ lazpaint/release/windows/lazpaint64
 lazpaint/release/bin/i18n/lazpaint32.*
 lazpaint/release/bin/i18n/lazpaint_x64.*
 /lazpaint/dialog/color/backup
-
 resources/createresource/backup/
-
 lazpaint/units/
+/bgracontrols
+/bgrabitmap
+
+*.deb
+lazpaint/release/debian/lazpaint*_no_install.tar.gz

+ 145 - 62
Makefile

@@ -1,101 +1,184 @@
-prefix = /usr/local
-USER_DIR = $(DESTDIR)$(prefix)
-BIN_DIR = $(USER_DIR)/bin
-SHARE_DIR=$(USER_DIR)/share
-RESOURCE_DIR=$(SHARE_DIR)/lazpaint
-DOC_DIR=$(SHARE_DIR)/doc/lazpaint
-SOURCE_BIN_DIR=lazpaint/release/bin
-SOURCE_SCRIPT_DIR=resources/scripts
-SOURCE_DEBIAN_DIR=lazpaint/release/debian
-PO_FILES:=$(shell find "$(SOURCE_BIN_DIR)/i18n" -maxdepth 1 -type f -name *.po -printf "\"%f\" ")
-MODEL_FILES:=$(shell find "$(SOURCE_BIN_DIR)/models" -maxdepth 1 -type f -printf "\"%f\" ")
-SCRIPT_FILES:=$(shell find "$(SOURCE_SCRIPT_DIR)" -maxdepth 1 -type f -name *.py -printf "\"%f\" ")
-SCRIPT_RUNTIME_FILES:=$(shell find "$(SOURCE_SCRIPT_DIR)/lazpaint" -maxdepth 1 -type f -name *.py -printf "\"%f\" ")
+# On Linux, TARGET can be Gtk2 (default) or Qt5
+# On FreeBSD, TARGET can be Gtk2 (default) or Qt5
+# On Windows, TARGET can be Win32 (default) or Qt5
+
+BGRABITMAP_DIR := bgrabitmap/bgrabitmap
+BGRACONTROLS_DIR := bgracontrols
 
 ifeq ($(OS),Windows_NT)     # true for Windows_NT or later
+  SHELL := C:/Windows/System32/cmd.exe /c
+  UNAME := Windows
   COPY := winmake\copyfile
   REMOVE := winmake\remove
   REMOVEDIR := winmake\removedir
+  CREATEDIR := winmake\createdir
+  ECHOFILE := type
   THEN := &
   RUN :=
+  NOERROR :=
 else
+  UNAME := $(shell uname)
+  ifeq ($(UNAME),FreeBSD)
+    SHELL := /usr/local/bin/bash
+  else
+    SHELL := /bin/bash
+  endif
   COPY := cp
   REMOVE := rm -f
   REMOVEDIR := rm -rf
+  CREATEDIR := mkdir -p
+  ECHOFILE := cat
   THEN := ;
   RUN := ./
+  NOERROR := 2>/dev/null
+endif
+
+lazdir := $(shell $(ECHOFILE) lazdir $(NOERROR))
+fpcbin := $(shell $(ECHOFILE) fpcbin $(NOERROR))
+package := lazpaint
+
+ifeq ($(UNAME),Linux)
+  TARGET ?= Gtk2
+  prefix := $(shell $(ECHOFILE) prefix $(NOERROR))
+  ifeq ($(MULTIBIN),1)
+    package := lazpaint-$(shell echo $(TARGET) | tr A-Z a-z)
+    prefix := /../$(package)$(prefix)
+  endif
+  USER_DIR = $(DESTDIR)$(prefix)
+  BIN_DIR = $(USER_DIR)/bin
+  SHARE_DIR=$(USER_DIR)/share
+  RESOURCE_DIR=$(SHARE_DIR)/lazpaint
+  ICON_DIR=$(SHARE_DIR)/icons/hicolor
+  SOURCE_BIN_DIR=lazpaint/release/bin
+  SOURCE_SCRIPT_DIR=resources/scripts
+  SOURCE_ICON_DIR=resources/icon
+  SOURCE_DEBIAN_UPSTREAM=lazpaint/release/debian
+  ICON:=lazpaint/lazpaint.ico
+  ICONS=$(shell identify $(ICON) | awk -F '[[]|[]] | ' '{ printf "[%s]=%s ", $$2, $$4 }')
+  EXTRACTED_ICONS_DIR=resources/icon
+  EXTRACTED_ICONS=16x16 24x24 32x32 48x48 96x96 128x128 256x256
+  PO_FILES:=$(shell find "$(SOURCE_BIN_DIR)/i18n" -maxdepth 1 -type f -name *.po -printf "\"%f\" ")
+  MODEL_FILES:=$(shell find "$(SOURCE_BIN_DIR)/models" -maxdepth 1 -type f -printf "\"%f\" ")
+  SCRIPT_FILES:=$(shell find "$(SOURCE_SCRIPT_DIR)" -maxdepth 1 -type f -name *.py -printf "\"%f\" ")
+  SCRIPT_RUNTIME_FILES:=$(shell find "$(SOURCE_SCRIPT_DIR)/lazpaint" -maxdepth 1 -type f -name *.py -printf "\"%f\" ")
+  
+  LAZARUSDIRECTORIES:="-Fu$(lazdir)/*" "-Fi$(lazdir)/*" "-Fu$(lazdir)/components/printers/unix" "-Fi$(lazdir)/components/printers/unix" "-Fu$(lazdir)/packager/registration" "-Fi$(lazdir)/packager/registration" "-Fu$(lazdir)/components/*" "-Fi$(lazdir)/components/*" "-Fu$(lazdir)/lcl/forms" "-Fi$(lazdir)/lcl/forms" "-Fu$(lazdir)/lcl/widgetset" "-Fi$(lazdir)/lcl/widgetset" "-Fu$(lazdir)/interfaces/*" "-Fi$(lazdir)/interfaces/*" "-Fu$(lazdir)/lcl/nonwin32" "-Fi$(lazdir)/lcl/nonwin32" "-Fu$(lazdir)/lcl/interfaces/gtk2" "-Fi$(lazdir)/lcl/interfaces/gtk2" "-Fu$(lazdir)/lcl/components/*" "-Fi$(lazdir)/lcl/components/*" "-Fu$(lazdir)/lcl/include" "-Fi$(lazdir)/lcl/include" "-Fu$(lazdir)/lcl" "-Fi$(lazdir)/lcl"
+endif
+
+ifeq ($(UNAME),FreeBSD)
+  TARGET ?= Gtk2
+  LAZARUSDIRECTORIES:="-Fu$(lazdir)/*" "-Fi$(lazdir)/*" "-Fu$(lazdir)/components/printers/unix" "-Fi$(lazdir)/components/printers/unix" "-Fu$(lazdir)/packager/registration" "-Fi$(lazdir)/packager/registration" "-Fu$(lazdir)/components/*" "-Fi$(lazdir)/components/*" "-Fu$(lazdir)/lcl/forms" "-Fi$(lazdir)/lcl/forms" "-Fu$(lazdir)/lcl/widgetset" "-Fi$(lazdir)/lcl/widgetset" "-Fu$(lazdir)/interfaces/*" "-Fi$(lazdir)/interfaces/*" "-Fu$(lazdir)/lcl/nonwin32" "-Fi$(lazdir)/lcl/nonwin32" "-Fu$(lazdir)/lcl/interfaces/gtk2" "-Fi$(lazdir)/lcl/interfaces/gtk2" "-Fu$(lazdir)/lcl/components/*" "-Fi$(lazdir)/lcl/components/*" "-Fu$(lazdir)/lcl/include" "-Fi$(lazdir)/lcl/include" "-Fu$(lazdir)/lcl" "-Fi$(lazdir)/lcl"
+endif
+
+ifeq ($(UNAME),Windows)
+  TARGET ?= Win32
+  LAZARUSDIRECTORIES:="-Fu$(lazdir)/*" "-Fi$(lazdir)/*" "-Fu$(lazdir)/components/printers/win32" "-Fi$(lazdir)/components/printers/win32" "-Fu$(lazdir)/packager/registration" "-Fi$(lazdir)/packager/registration" "-Fu$(lazdir)/components/*" "-Fi$(lazdir)/components/*" "-Fu$(lazdir)/lcl/forms" "-Fi$(lazdir)/lcl/forms" "-Fu$(lazdir)/lcl/widgetset" "-Fi$(lazdir)/lcl/widgetset" "-Fu$(lazdir)/interfaces/*" "-Fi$(lazdir)/interfaces/*" "-Fu$(lazdir)/lcl/interfaces/win32" "-Fi$(lazdir)/lcl/interfaces/win32" "-Fu$(lazdir)/lcl/components/*" "-Fi$(lazdir)/lcl/components/*" "-Fu$(lazdir)/lcl/include" "-Fi$(lazdir)/lcl/include" "-Fu$(lazdir)/lcl" "-Fi$(lazdir)/lcl"
+endif
+
+# determine buildmode/interface
+BUILDMODE:=Release
+INTERFACE:=LCL$(shell echo $(TARGET) | tr A-Z a-z)
+ifeq ($(TARGET),Qt5)
+  BUILDMODE:=ReleaseQt5
+endif
+
+# Lazarus custom packages explicitely compiled
+ifeq "$(FOREIGN_LPK)" "1"
+  FOREIGN_PACKAGES=$(BGRABITMAP_DIR)/bgrabitmappack.lpk $(BGRACONTROLS_DIR)/bgracontrols.lpk
 endif
 
 all: compile
 
-install: 
-ifeq ($(OS),Windows_NT)     # true for Windows_NT or later
-	echo Under Windows, use installation generated by InnoSetup with lazpaint/release/windows/lazpaint.iss
-else ifeq ($(shell uname),Linux)
-	install -D "$(SOURCE_BIN_DIR)/lazpaint" "$(BIN_DIR)/lazpaint"
-	for f in $(PO_FILES); do install -D "$(SOURCE_BIN_DIR)/i18n/$$f" "${RESOURCE_DIR}/i18n/$$f"; done
-	for f in $(MODEL_FILES); do install -D "$(SOURCE_BIN_DIR)/models/$$f" "${RESOURCE_DIR}/models/$$f"; done
-	for f in $(SCRIPT_FILES); do install -D "$(SOURCE_SCRIPT_DIR)/$$f" "${RESOURCE_DIR}/scripts/$$f"; done
-	for f in $(SCRIPT_RUNTIME_FILES); do install -D "$(SOURCE_SCRIPT_DIR)/lazpaint/$$f" "${RESOURCE_DIR}/scripts/lazpaint/$$f"; done
-	install -D "$(SOURCE_DEBIAN_DIR)/applications/lazpaint.desktop" "$(SHARE_DIR)/applications/lazpaint.desktop"
-	install -D "$(SOURCE_DEBIAN_DIR)/pixmaps/lazpaint.png" "$(SHARE_DIR)/pixmaps/lazpaint.png"
+install: prefix
+ifeq ($(UNAME),Windows) 
+	echo "Under Windows, use installation generated by InnoSetup with lazpaint/release/windows/lazpaint.iss"
+endif
+
+ifeq ($(UNAME),Linux)
+	install -D "$(SOURCE_BIN_DIR)/$(package)" "$(BIN_DIR)/lazpaint"
+	for f in $(PO_FILES); do install -D --mode=0644 "$(SOURCE_BIN_DIR)/i18n/$$f" "$(RESOURCE_DIR)/i18n/$$f"; done
+	for f in $(MODEL_FILES); do install -D --mode=0644 "$(SOURCE_BIN_DIR)/models/$$f" "${RESOURCE_DIR}/models/$$f"; done
+	for f in $(SCRIPT_FILES); do install -D --mode=0644 "$(SOURCE_SCRIPT_DIR)/$$f" "${RESOURCE_DIR}/scripts/$$f"; done
+	for f in $(SCRIPT_RUNTIME_FILES); do install -D --mode=0644 "$(SOURCE_SCRIPT_DIR)/lazpaint/$$f" "${RESOURCE_DIR}/scripts/lazpaint/$$f"; done
+	install -D "$(SOURCE_DEBIAN_UPSTREAM)/applications/lazpaint.desktop" "$(SHARE_DIR)/applications/lazpaint.desktop"
+	install -D "$(EXTRACTED_ICONS_DIR)/48x48.png" "$(SHARE_DIR)/pixmaps/lazpaint.png"
+	for s in $(EXTRACTED_ICONS); do install -D --mode=0644 "$(EXTRACTED_ICONS_DIR)/$$s.png" "$(ICON_DIR)/$$s/apps/lazpaint.png"; done
 	install -d "$(SHARE_DIR)/man/man1"
-	gzip -9 -n -c "$(SOURCE_DEBIAN_DIR)/man/man1/lazpaint.1" >"$(SHARE_DIR)/man/man1/lazpaint.1.gz"
+	gzip -9 -n -c "$(SOURCE_DEBIAN_UPSTREAM)/man/man1/lazpaint.1" >"$(SHARE_DIR)/man/man1/lazpaint.1.gz"
 	chmod 0644 "$(SHARE_DIR)/man/man1/lazpaint.1.gz"
-	install -d "$(DOC_DIR)"
-	gzip -9 -n -c "$(SOURCE_DEBIAN_DIR)/debian/changelog" >"$(DOC_DIR)/changelog.gz"
-	chmod 0644 "$(DOC_DIR)/changelog.gz"
-	install "$(SOURCE_DEBIAN_DIR)/debian/copyright" "$(DOC_DIR)/copyright"
-	install "$(SOURCE_BIN_DIR)/readme.txt" "$(DOC_DIR)/README"
-else
-	echo Unhandled OS
 endif
 
-uninstall: 
-ifeq ($(OS),Windows_NT)     # true for Windows_NT or later
-	echo Under Windows, go to Add/Remove programs
-else ifeq ($(shell uname),Linux)
+uninstall: prefix
+ifeq ($(UNAME),Windows) 
+	echo "Under Windows, go to Add/Remove programs to uninstall"
+endif
+
+ifeq ($(UNAME),Linux)
 	$(REMOVE) $(BIN_DIR)/lazpaint
 	$(REMOVEDIR) $(RESOURCE_DIR)
-	$(REMOVEDIR) $(DOC_DIR)
 	$(REMOVE) "$(SHARE_DIR)/applications/lazpaint.desktop"
 	$(REMOVE) "$(SHARE_DIR)/pixmaps/lazpaint.png"
+	for s in $(EXTRACTED_ICONS); do $(REMOVE) $(ICON_DIR)/$$s/apps/lazpaint.png; done
 	$(REMOVE) "$(SHARE_DIR)/man/man1/lazpaint.1.gz"
-else
-	echo Unhandled OS
 endif
 
-clean: clean_lazpaintcontrols clean_vectoredit clean_lazpaint
+distclean: clean clean_configure
+clean: clean_bgrabitmap clean_bgracontrols clean_lazpaint
 
-clean_lazpaintcontrols:
-	$(REMOVEDIR) "lazpaintcontrols/lib"
-	$(REMOVEDIR) "lazpaintcontrols/backup"
+clean_configure:
+	$(REMOVE) "prefix"
+	$(REMOVE) "lazdir"
+	$(REMOVE) "fpcbin"
+
+clean_icons:
+	$(REMOVEDIR) "icons"
+
+clean_bgrabitmap:
+	$(REMOVEDIR) "$(BGRABITMAP_DIR)/lib"
+	$(REMOVEDIR) "$(BGRABITMAP_DIR)/backup"
 
-clean_vectoredit:
-	$(REMOVEDIR) "vectoredit/lib"
-	$(REMOVEDIR) "vectoredit/backup"
+clean_bgracontrols:
+	$(REMOVEDIR) "$(BGRACONTROLS_DIR)/lib"
+	$(REMOVEDIR) "$(BGRACONTROLS_DIR)/backup"
 
 clean_lazpaint:
+	$(REMOVEDIR) "lazpaintcontrols/lib"
 	$(REMOVEDIR) "lazpaint/debug"
 	$(REMOVEDIR) "lazpaint/release/lib"
 	$(REMOVE) "lazpaint/lazpaint.res"
-	$(REMOVE) "lazpaint/release/bin/lazpaint"
+ifeq ($(UNAME),Windows)
+	$(REMOVE) "lazpaint/release/bin/lazpaint.exe"
 	$(REMOVE) "lazpaint/release/bin/lazpaint32.exe"
-	$(REMOVE) "lazpaint/release/bin/lazpaint_x64.exe"
+	$(REMOVE) "lazpaint/release/bin/lazpaint64.exe"
+else
+	$(REMOVE) "lazpaint/release/bin/lazpaint"
+	$(REMOVE) "lazpaint/release/bin/lazpaint32"
+	$(REMOVE) "lazpaint/release/bin/lazpaint64"
+	$(REMOVE) "lazpaint/release/bin/lazpaint-gtk2"
+	$(REMOVE) "lazpaint/release/bin/lazpaint-qt5"
+endif
 	$(REMOVEDIR) "lazpaint/backup"
-	$(REMOVEDIR) "lazpaint/dialog/backup"
-	$(REMOVEDIR) "lazpaint/image/backup"
-	$(REMOVEDIR) "lazpaint/tablet/backup"
 	$(REMOVEDIR) "lazpaint/test_embedded/backup"
-	$(REMOVEDIR) "lazpaint/tools/backup"
-
-compile: lazpaintcontrols vectoredit lazpaint
-lazbuild:
-	#lazbuild will determine what to recompile
-lazpaintcontrols: lazbuild lazpaintcontrols/lazpaintcontrols.lpk
-	lazbuild lazpaintcontrols/lazpaintcontrols.lpk
-vectoredit: lazbuild vectoredit/vectoredit.lpi
-	lazbuild vectoredit/vectoredit.lpi
-lazpaint: lazbuild lazpaint/lazpaint.lpi
-	lazbuild lazpaint/lazpaint.lpi
+
+compile: lazdir lazpaint
+force:
+	#lazbuild or fpc will determine what to recompile
+
+lazpaint: force $(FOREIGN_PACKAGES) lazpaintcontrols/lazpaintcontrols.lpk lazpaint/lazpaint.lpi
+ifeq "$(lazdir)" ""
+	lazbuild --build-mode=$(BUILDMODE) $(FOREIGN_PACKAGES) lazpaintcontrols/lazpaintcontrols.lpk lazpaint/lazpaint.lpi
+else
+	$(COPY) "resources/lazpaint.res" "lazpaint/lazpaint.res"
+	$(CREATEDIR) "lazpaint/release/lib"
+	cd lazpaint $(THEN) $(fpcbin) -orelease/lazpaint -Fu./buttons -Fi./buttons -Fu./image -Fi./image -Fu./cursors -Fi./cursors -Fu./buttons -Fi./buttons -Fu./* -Fi./* -Fu../$(BGRACONTROLS_DIR) -Fi../$(BGRACONTROLS_DIR) -Fu../$(BGRABITMAP_DIR) -Fi../$(BGRABITMAP_DIR) $(LAZARUSDIRECTORIES) -MObjFPC -Scgi -Cg -OoREGVAR -Xs -XX -l -vewnhibq -O3 -CX -vi -FUrelease/lib/ -dLCL -d$(INTERFACE) lazpaint.lpr
+endif
+ifeq ($(MULTIBIN),1)
+	mv "$(SOURCE_BIN_DIR)/lazpaint" "$(SOURCE_BIN_DIR)/$(package)"
+endif
+
+icons:
+ifneq ($(UNAME),Windows)
+	$(CREATEDIR) -p icons
+	declare -A icons=($(ICONS)); for i in "$${!icons[@]}"; do convert $(ICON)[$$i] $(SOURCE_ICON_DIR)/$${icons[$$i]}.png; done
+endif
 

+ 74 - 0
configure

@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+echo For help type: ./configure --help
+args=("$@")
+haserror=false
+defaultfpc=fpc
+wantedfpc=$defaultfpc
+if [ -f "debian/CONFIGURE_DEFAULT_FPCBIN" ]; then
+	wantedfpc=$(cat debian/CONFIGURE_DEFAULT_FPCBIN)
+fi
+defaultprefix=/usr/local
+wantedprefix=$defaultprefix
+if [ -f "debian/CONFIGURE_DEFAULT_LAZDIR" ]; then
+	wantedlazdir=$(cat debian/CONFIGURE_DEFAULT_LAZDIR)
+else
+	wantedlazdir=
+fi
+for param in "${args[@]}"
+do
+	if [ "$param" == "-h" ] || [ "$param" == "--help" ]; then
+		echo "Usage: ./configure [OPTIONS]"
+		echo ""
+		echo "    --prefix=PREFIX"
+		echo "        Specifies the install prefix."
+		echo "        By default prefix is \"$defaultprefix\"" 
+		echo "        For packages use \"/usr\""
+		echo ""
+		echo "    --lazdir=BASE_DIRECTORY_OF_LAZARUS"
+		echo "        Specifies to compile with FPC using the specified Lazarus sources."
+		echo "        Otherwise lazbuild will be used."
+		echo ""
+		echo "    --fpcbin=FPC_BINARY"
+		echo "        Specifies the command to call Free Pascal Compiler."
+		echo "        Default is \"$defaultfpc\""
+		exit 0
+	elif [ "${param:0:9}" == "--prefix=" ]; then
+		wantedprefix=${param:9}
+	elif [ "${param:0:9}" == "--lazdir=" ]; then
+		wantedlazdir=${param:9}
+	elif [ "${param:0:9}" == "--fpcbin=" ]; then
+		wantedfpc=${param:9}
+	else
+		echo "Warning: unknown option $param"
+	fi
+done
+echo "Prefix set to: $wantedprefix"
+echo $wantedprefix >prefix
+if [ "$wantedlazdir" == "" ]; then
+	echo "Using lazbuild"
+	rm -f lazdir
+	touch lazdir
+	rm -f fpcbin
+else
+	echo "Using FPC with Lazarus source: $wantedlazdir"
+	if [ ! -d "$wantedlazdir" ]; then
+		echo "Error: directory not found!"
+		haserror=true
+	elif [ ! -d "$wantedlazdir/lcl" ]; then
+		echo "Warning: it does not seem to be the directory of Lazarus!"
+	fi
+	echo $wantedlazdir >lazdir
+	echo "Compiler set to: $wantedfpc"
+	rm -f fpcbin
+	echo $wantedfpc >fpcbin
+fi
+if [ "$haserror" = true ]; then
+	exit 1
+else
+	if [ "$(uname)" == "FreeBSD" ]; then
+		echo "You can now type: gmake"
+	else
+		echo "You can now type: make"
+	fi
+	exit 0
+fi

+ 70 - 0
configure.bat

@@ -0,0 +1,70 @@
+@echo off
+echo For help type: configure /?
+set defaultfpc=fpc
+set wantedfpc=%defaultfpc%
+set wantedlazdir=
+
+:nextparam
+set param=%~1
+if "%param%" == "" goto endparam
+if "%param%" == "--help" goto showhelp
+if "%param%" == "-h" goto showhelp
+if "%param%" == "/help" goto showhelp
+if "%param%" == "/?" goto showhelp
+if "%param:~0,9%" == "--lazdir=" (
+	set wantedlazdir=%param:~9%
+) else if "%param%" == "--lazdir" (
+	set wantedlazdir=%~2
+	shift
+) else if "%param:~0,9%" == "--fpcbin=" (
+	set wantedfpc=%param:~9%
+) else if "%param%" == "--fpcbin" (
+	set wantedfpc=%~2
+	shift
+) else (
+	echo Error: unknown option %param%
+	exit /b 1
+)
+
+shift
+goto nextparam
+:endparam
+
+if exist fpcbin del fpcbin
+<nul set /p ".=%wantedlazdir%" >lazdir
+if "%wantedlazdir%" == "" (
+	echo Using lazbuild
+	lazbuild -h > NUL 2> NUL
+	if errorlevel 1 (
+		echo Error: Lazarus needs to be in the PATH
+		exit /b 1
+	)
+) else (
+	echo Using FPC with Lazarus source: %wantedlazdir%
+	if not exist "%wantedlazdir%\" (
+		echo Error: directory not found
+		exit /b 1
+	) else if not exist "%wantedlazdir%\lcl\" (
+		echo Warning: it does not seem to be the directory of Lazarus!
+	)
+	<nul set /p ".=%wantedfpc%" >fpcbin
+	%wantedfpc% -h > NUL 2> NUL
+	if errorlevel 1 (
+		echo Error: FPC needs to be in the PATH
+		exit /b 1
+	)
+)
+
+echo You can now type: make
+exit /b 0
+
+:showhelp
+echo Usage: configure [OPTIONS]
+echo.
+echo     --lazdir=BASE_DIRECTORY_OF_LAZARUS
+echo         Specifies to compile with FPC using the specified Lazarus sources.
+echo         Otherwise lazbuild will be used.
+echo.
+echo     --fpcbin=FPC_BINARY
+echo         Specifies the command to call Free Pascal Compiler.
+echo         Default is %defaultfpc%

+ 35 - 0
create_orig

@@ -0,0 +1,35 @@
+#!/bin/bash
+dirname=${PWD##*/}
+if ! [[ "$dirname" =~ ^lazpaint-[0-9]+(\.[0-9]+)*$ ]]; then
+    echo "Parent folder name must be \"lazpaint-#[.#][.#]\" but is \"$dirname\" instead"
+    echo "where #[.#][.#] is the app version number"
+    exit 1
+fi
+if ! [ -d bgrabitmap ] || ! [ -d bgracontrols ]; then
+    echo "Cannot find bgrabitmap or bgracontrols subdirectories."
+    exit 1
+fi
+if [ -d bgrabitmap/test ] || [ -d lazpaint/release/windows ]; then
+    echo "Lazarus custom packages have not been pruned. Call ./prune_lpk first"
+    exit 1
+fi
+archive=${dirname/-/_}.orig.tar.gz
+read -p "Create \"../${archive}\" file (y/n)?" -n 1 -r
+echo
+if [[ $REPLY =~ ^[Yy]$ ]]
+then
+    make distclean
+
+    cd ..
+    tar --exclude=./${dirname}/debian --exclude-vcs -zcvf ${archive} ./${dirname}
+    cd "$dirname"
+    echo "Done creating ../${archive}"
+    echo
+    read -p "Launch \"debuild -us -uc\" on the package now (y/n)?" -n 1 -r
+    echo
+    if [[ $REPLY =~ ^[Yy]$ ]]
+    then
+    	debuild -us -uc
+    fi
+fi
+

+ 5 - 0
debian/changelog

@@ -0,0 +1,5 @@
+lazpaint (7.1.5-1) unstable; urgency=medium
+
+  * Initial release. (Closes: #972503)
+
+ -- Johann ELSASS <[email protected]>  Tue, 3 Nov 2020 12:26:00 +0100

+ 35 - 0
debian/control

@@ -0,0 +1,35 @@
+Source: lazpaint
+Section: graphics
+Priority: optional
+Maintainer: Johann ELSASS <[email protected]>
+Uploaders: Gürkan Myczko <[email protected]>
+Build-Depends: fpc, lcl, lazarus, libqt5pas-dev, debhelper-compat (= 13)
+Rules-Requires-Root: no
+Standards-Version: 4.5.0
+Homepage: https://wiki.freepascal.org/LazPaint
+Vcs-Git: https://github.com/bgrabitmap/lazpaint-upstream.git
+Vcs-Browser: https://github.com/bgrabitmap/lazpaint-upstream
+
+Package: lazpaint-gtk2
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Conflicts: lazpaint, lazpaint-gtk3, lazpaint-qt4, lazpaint-qt5
+Description: Image editor with raster and vector layers (gtk2)
+ Can read layered files (lzp, ora, pdn, oXo, flat psd), multi-images (gif,
+ ico, tiff), flat files (bmp, jpeg, pcx, png, tga, webp, xpm, xwd),
+ raw images (dng, cr2, nef, arw...), vectorial (svg), 3D (obj). Has drawing
+ tools, vector shapes, phong shading, curve adjustments, filters, render
+ some textures, Python scripting.
+ Uses Gtk2 widgetset.
+
+Package: lazpaint-qt5
+Conflicts: lazpaint, lazpaint-gtk2, lazpaint-gtk3, lazpaint-qt4
+Architecture: any
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Description: Image editor with raster and  vector layers (qt5)
+ Can read layered files (lzp, ora, pdn, oXo, flat psd), multi-images (gif,
+ ico, tiff), flat files (bmp, jpeg, pcx, png, tga, webp, xpm, xwd),
+ raw images (dng, cr2, nef, arw...), vectorial (svg), 3D (obj). Has drawing
+ tools, vector shapes, phong shading, curve adjustments, filters, render
+ some textures, Python scripting.
+ Uses Qt5 widgetset.

+ 119 - 0
debian/copyright

@@ -0,0 +1,119 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: lazpaint
+Upstream-Contact: Johann ELSASS <[email protected]>
+Source: https://github.com/bgrabitmap/lazpaint-upstream/releases
+
+Files: *
+Copyright: 2011-2019 Johann ELSASS <[email protected]>
+License: GPL-3+
+
+Files: debian/*
+Copyright: 2011-2020 Johann ELSASS <[email protected]>
+License: GPL-3+
+
+Files: bgracontrols/*
+Copyright: 2012 Krzysztof Dibowski <[email protected]>
+License: LGPL-3-linking-exception
+
+Files: bgracontrols/bgraimagemanipulation.pas
+Copyright: 2011 Emerson Cavalcanti
+License: LGPL-3-linking-exception
+
+Files: bgrabitmap/*
+Copyright: 2016 Johann ELSASS
+License: LGPL-3-linking-exception
+
+Files: bgrabitmap/bgrareadtiff.pas bgrabitmap/bgrawritetiff.pas
+Copyright: 2012-2013 by the Free Pascal development team
+License: LGPL-3-linking-exception
+
+Files: bgrabitmap/bgrareadpsd.pas
+Copyright: 2008 by the Free Pascal development team
+License: LGPL-3-linking-exception
+
+Files: bgrabitmap/libwebp.pas
+Copyright: 2010 Google Inc.
+License: BSD-3-Clause
+
+Files: bgrabitmap/bgrawritepng.pas bgrabitmap/bgrareadpng.pas
+Copyright: 2003 by the Free Pascal development team
+License: LGPL-3-linking-exception
+
+Files: bgrabitmap/bgrareadtga.pas bgrabitmap/bgrareadbmp.pas
+Copyright: 2003 by Mazen NEIFER of the Free Pascal development team
+License: LGPL-3-linking-exception
+
+License: LGPL-3-linking-exception
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; version 3, with the following modification:
+ .
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,
+ and to copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the terms
+ and conditions of the license of that module. An independent module is a
+ module which is not derived from or based on this library. If you modify this
+ library, you may extend this exception to your version of the library, but
+ you are not obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ .
+ On Debian systems, the full text of the GNU Lesser General Public
+ License version 3 can be found in the file
+ '/usr/share/common-licenses/LGPL-3'.
+
+License: BSD-3-Clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ .
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ .
+ Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ .
+ Neither the name of Google nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior
+ written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+License: GPL-3+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version. 
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ .
+ On Debian systems, the full text of the GNU General Public
+ License version 3 can be found in the file
+ '/usr/share/common-licenses/GPL-3'.

+ 26 - 0
debian/rules

@@ -0,0 +1,26 @@
+#!/usr/bin/make -f
+#DH_VERBOSE = 1
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+%:
+	dh $@ --no-parallel
+	
+override_dh_auto_build:
+	dh_auto_build --no-parallel -- MULTIBIN=1 TARGET=Gtk2 FOREIGN_LPK=1
+	dh_auto_build --no-parallel -- MULTIBIN=1 TARGET=Qt5 FOREIGN_LPK=1
+
+override_dh_auto_install:
+	dh_auto_install --no-parallel -- MULTIBIN=1 TARGET=Gtk2 FOREIGN_LPK=1
+	dh_auto_install --no-parallel -- MULTIBIN=1 TARGET=Qt5 FOREIGN_LPK=1
+
+override_dh_auto_clean:
+	dh_auto_clean --no-parallel -- MULTIBIN=1 TARGET=Gtk2 FOREIGN_LPK=1
+	dh_auto_clean --no-parallel -- MULTIBIN=1 TARGET=Qt5 FOREIGN_LPK=1

+ 1 - 0
debian/source/format

@@ -0,0 +1 @@
+3.0 (quilt)

+ 5 - 0
debian/upstream/metadata

@@ -0,0 +1,5 @@
+Bug-Database: https://github.com/bgrabitmap/lazpaint/issues
+Bug-Submit: https://github.com/bgrabitmap/lazpaint/issues/new
+Repository: https://github.com/bgrabitmap/lazpaint.git
+Repository-Browse: https://github.com/bgrabitmap/lazpaint
+

+ 3 - 0
debian/watch

@@ -0,0 +1,3 @@
+version=4
+opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/lazpaint-$1\.tar\.gz/ \
+  https://github.com/bgrabitmap/lazpaint/tags .*/v?(\d\S+)\.tar\.gz

BIN
lazpaint/buttons/biplane48.lzp


BIN
lazpaint/buttons/biplane48.png


BIN
lazpaint/buttons/capflat48.png


BIN
lazpaint/buttons/capround48.lzp


BIN
lazpaint/buttons/capround48.png


BIN
lazpaint/buttons/capsquare48.png


BIN
lazpaint/buttons/joinbevel48.png


BIN
lazpaint/buttons/joinmiter48.png


BIN
lazpaint/buttons/joinround48.lzp


BIN
lazpaint/buttons/joinround48.png


BIN
lazpaint/buttons/layers48.lzp


BIN
lazpaint/buttons/layers48.png


BIN
lazpaint/buttons/new_geometric48.lzp


BIN
lazpaint/buttons/new_geometric48.png


BIN
lazpaint/buttons/phonghcylinder48.png


BIN
lazpaint/buttons/phongvcone48.lzp


BIN
lazpaint/buttons/phongvcone48.png


BIN
lazpaint/buttons/phongvcylinder48.png


BIN
lazpaint/buttons/swapcolor48.lzp


BIN
lazpaint/buttons/swapcolor48.png


BIN
lazpaint/buttons/textfont48.lzp


BIN
lazpaint/buttons/textfont48.png


BIN
lazpaint/buttons/textphong48.lzp


BIN
lazpaint/buttons/textphong48.png


BIN
lazpaint/buttons/texture_simple.png


+ 26 - 4
lazpaint/dialog/color/uadjustcurves.pas

@@ -62,6 +62,7 @@ type
     FInstance: TLazPaintCustomInstance;
     FFilterConnector: TFilterConnector;
     FPreviousGraphWidth, FPreviousGraphHeight: integer;
+    FPreviousDarkTheme: boolean;
     FGraphBackgroundLeft, FGraphBackgroundBottom: TBGRABitmap;
     FPoint0,FPoint1: TPointF;
     FNbGrid: integer;
@@ -96,6 +97,7 @@ type
     procedure SetPointCoord(AIndex: integer; ACoord: TPointF);
     function RemovePoint(AIndex :integer): boolean;
     procedure SetPosterize(AValue: boolean);
+    procedure ThemeChanged(Sender: TObject);
     procedure TryRemovePoint;
     procedure PreviewNeeded;
     function NeedHistogram(ATab: integer): boolean;
@@ -162,7 +164,8 @@ begin
   if (Bitmap.Width <> FPreviousGraphWidth) or
    (Bitmap.Height <> FPreviousGraphHeight) or
     (FGraphBackgroundLeft = nil) or (FGraphBackgroundBottom = nil) or
-    (FHueTabPrecomputed <> HueTabSelected) then
+    (FHueTabPrecomputed <> HueTabSelected)  or
+    (FPreviousDarkTheme <> (assigned(FInstance) and FInstance.DarkTheme)) then
       RecomputeGraphBackground(Bitmap.Width,Bitmap.Height);
   if (FGraphBackgroundLeft = nil) or (FGraphBackgroundBottom = nil) then exit;
   Bitmap.PutImage(0,0,FGraphBackgroundLeft,dmSet);
@@ -506,7 +509,7 @@ const maxValueX = 1; maxValueY = 1.20;
 var
   th, w, leftMargin, bottomMargin, rightMargin, i: integer;
   labels: array of string;
-  axesColor : TBGRAPixel;
+  axesColor , backgroundColor: TBGRAPixel;
   Bitmap: TBGRABitmap;
   totalLabelLength,maxLabelLength: integer;
 
@@ -553,8 +556,16 @@ begin
   FTickSize := th div 4;
   if FTickSize = 0 then exit;
 
-  Bitmap := TBGRABitmap.Create(AWidth,AHeight,BGRAWhite);
-  axesColor := BGRA(76,84,96);
+  if assigned(FInstance) and FInstance.DarkTheme then
+  begin
+    backgroundColor := BGRABlack;
+    axesColor := clSilver;
+  end else
+  begin
+    backgroundColor := BGRAWhite;
+    axesColor := BGRA(76,84,96);
+  end;
+  Bitmap := TBGRABitmap.Create(AWidth,AHeight,backgroundColor);
   FGridColor := axesColor;
   FGridColor.alpha := 128;
   Bitmap.FontQuality := fqFineAntialiasing;
@@ -597,6 +608,7 @@ begin
   FHueTabPrecomputed:= HueTabSelected;
   FPreviousGraphWidth:= AWidth;
   FPreviousGraphHeight:= AHeight;
+  FPreviousDarkTheme := assigned(FInstance) and FInstance.DarkTheme;
 end;
 
 function TFAdjustCurves.CoordToBitmap(x, y: single): TPointF;
@@ -797,6 +809,14 @@ begin
   end;
 end;
 
+procedure TFAdjustCurves.ThemeChanged(Sender: TObject);
+begin
+  if FInstance.DarkTheme then
+    vsChart.Color := clBlack
+    else vsChart.Color := clWhite;
+  vsChart.DiscardBitmap;
+end;
+
 procedure TFAdjustCurves.TryRemovePoint;
 begin
   if RemovePoint(FSelectedPoint) then
@@ -1005,6 +1025,7 @@ begin
   end;
   try
     FInstance := AInstance;
+    FInstance.RegisterThemeListener(@ThemeChanged, true);
     EnsureCurveExist(tempParameters,'Red');
     EnsureCurveExist(tempParameters,'Green');
     EnsureCurveExist(tempParameters,'Blue');
@@ -1045,6 +1066,7 @@ begin
     CopyCurveIfNonTrivial(tempParameters,'Lightness');
 
   finally
+    FInstance.RegisterThemeListener(@ThemeChanged, false);
     FreeAndNil(FFilterConnector);
     tempParameters.Free;
     FInstance := nil;

+ 8 - 0
lazpaint/dialog/ublendop.lfm

@@ -160,6 +160,14 @@ object FBlendOp: TFBlendOp
       'LinearExclusion'
       'LinearSubtract'
       'Divide'
+      'LinearHue'
+      'LinearColor'
+      'LinearLightness'
+      'LinearSaturation'
+      'CorrectedHue'
+      'CorrectedColor'
+      'CorrectedLightness'
+      'CorrectedSaturation'
     )
     ItemHeight = 80
     OnDblClick = ListBox_BlendDblClick

+ 3 - 1
lazpaint/dialog/ublendop.pas

@@ -361,7 +361,7 @@ procedure TFBlendOp.ListBox_DrawBlendItem(Control: TWinControl; Index: Integer;
   ARect: TRect; State: TOwnerDrawState);
 var
   background,preview,over: TBGRABitmap;
-  w,h, checkerSize: integer;
+  w,h, checkerSize, shadowOfs: integer;
   BlendStr: string;
   fx: TBGRATextEffect;
   scaling: Double;
@@ -388,6 +388,8 @@ begin
     preview.Free;
     if odSelected in State then DrawPatternHighlight(background);
     fx := TBGRATextEffect.Create(BlendStr,'Arial',Max(DoScaleY(round(12*scaling),OriginalDPI),h div 10),true);
+    shadowOfs := round(DoScaleX(round(10*scaling), OriginalDPI)/10);
+    fx.DrawShadow(background,1+shadowOfs,1+shadowOfs,DoScaleX(round(2*scaling), OriginalDPI),BGRABlack);
     fx.DrawOutline(background,1,1,BGRABlack);
     fx.Draw(background,1,1,BGRAWhite);
     fx.Free;

+ 210 - 191
lazpaint/dialog/ubrowseimages.lfm

@@ -1,5 +1,5 @@
 object FBrowseImages: TFBrowseImages
-  Left = 376
+  Left = 110
   Height = 300
   Top = 101
   Width = 684
@@ -20,17 +20,17 @@ object FBrowseImages: TFBrowseImages
   LCLVersion = '2.0.10.0'
   object Panel1: TPanel
     Left = 464
-    Height = 300
-    Top = 0
+    Height = 227
+    Top = 73
     Width = 220
     Align = alClient
-    ClientHeight = 300
+    ClientHeight = 227
     ClientWidth = 220
     ParentFont = False
     TabOrder = 1
     object Label_Status: TLabel
       Left = 3
-      Height = 15
+      Height = 14
       Top = 5
       Width = 3
       Caption = '.'
@@ -39,7 +39,7 @@ object FBrowseImages: TFBrowseImages
     end
     object vsPreview: TBGRAVirtualScreen
       Left = 3
-      Height = 270
+      Height = 197
       Top = 26
       Width = 214
       Alignment = taLeftJustify
@@ -51,21 +51,22 @@ object FBrowseImages: TFBrowseImages
     end
     object ListBox_RecentDirs: TListBox
       Left = 3
-      Height = 269
+      Height = 196
       Top = 26
       Width = 212
       Anchors = [akTop, akLeft, akRight, akBottom]
       ItemHeight = 0
       OnClick = ListBox_RecentDirsClick
       ParentFont = False
-      ScrollWidth = 263
+      ScrollWidth = 210
       TabOrder = 1
+      TopIndex = -1
     end
     object CheckBox_UseDirectoryOnStartup: TCheckBox
       Left = 56
-      Height = 19
+      Height = 23
       Top = 3
-      Width = 168
+      Width = 196
       Caption = 'Use this directory on startup'
       ParentFont = False
       TabOrder = 0
@@ -74,209 +75,227 @@ object FBrowseImages: TFBrowseImages
   end
   object Splitter1: TSplitter
     Left = 458
-    Height = 300
-    Top = 0
+    Height = 227
+    Top = 73
     Width = 6
     MinSize = 64
   end
   object Panel2: TPanel
     Left = 0
-    Height = 300
-    Top = 0
+    Height = 227
+    Top = 73
     Width = 458
     Align = alLeft
-    ClientHeight = 300
+    ClientHeight = 227
     ClientWidth = 458
     ParentFont = False
     TabOrder = 2
-    object Panel3: TPanel
+    object vsList: TBGRAVirtualScreen
       Left = 1
-      Height = 73
+      Height = 225
       Top = 1
       Width = 456
-      Align = alTop
-      ClientHeight = 73
-      ClientWidth = 456
+      Align = alClient
+      Alignment = taLeftJustify
+      Color = clWindow
+      ParentColor = False
       ParentFont = False
       TabOrder = 0
-      object ToolBar1: TToolBar
-        Left = 1
-        Height = 33
-        Top = 2
-        Width = 198
-        Align = alNone
-        ButtonHeight = 32
-        ButtonWidth = 32
-        EdgeBorders = []
-        Images = ImageListToolbar
-        ParentFont = False
-        ParentShowHint = False
-        ShowHint = True
-        TabOrder = 3
-        object ToolButton_GoUp: TToolButton
-          Left = 145
-          Hint = 'Go one directory up'
-          Top = 0
-          ImageIndex = 0
-          OnClick = ToolButton_GoUpClick
-        end
-        object ToolButton_ViewBigIcon: TToolButton
-          Left = 73
-          Hint = 'Show big icons'
-          Top = 0
-          ImageIndex = 2
-          OnClick = ToolButton_ViewBigIconClick
-        end
-        object ToolButton_ViewDetails: TToolButton
-          Left = 37
-          Hint = 'Show details and preview'
-          Top = 0
-          ImageIndex = 3
-          OnClick = ToolButton_ViewDetailsClick
-        end
-        object ToolButton_OpenSelectedFiles: TToolButton
-          Left = 1
-          Hint = 'Open selected files'
-          Top = 0
-          Enabled = False
-          ImageIndex = 5
-          OnClick = ToolButton_OpenSelectedFilesClick
-        end
-        object Tool_SelectDrive: TToolButton
-          Left = 109
-          Hint = 'Select drive'
-          Top = 0
-          ImageIndex = 6
-          OnClick = Tool_SelectDriveClick
-          Visible = False
-        end
-        object ToolButton_CreateFolderOrContainer: TToolButton
-          Left = 1
-          Hint = 'Create folder or container'
-          Top = 32
-          ImageIndex = 8
-          OnClick = ToolButton_CreateFolderOrContainerClick
-        end
+      TabStop = True
+    end
+  end
+  object Panel3: TPanel
+    Left = 0
+    Height = 73
+    Top = 0
+    Width = 684
+    Align = alTop
+    ClientHeight = 73
+    ClientWidth = 684
+    ParentFont = False
+    TabOrder = 3
+    object ToolBar1: TToolBar
+      Left = 1
+      Height = 33
+      Top = 2
+      Width = 198
+      Align = alNone
+      ButtonHeight = 32
+      ButtonWidth = 32
+      EdgeBorders = []
+      Images = ImageListToolbar
+      ParentFont = False
+      ParentShowHint = False
+      ShowHint = True
+      TabOrder = 3
+      object ToolButton_GoUp: TToolButton
+        Left = 145
+        Hint = 'Go one directory up'
+        Top = 0
+        ImageIndex = 0
+        OnClick = ToolButton_GoUpClick
       end
-      object Edit_Filename: TEdit
-        Left = 224
-        Height = 23
-        Top = 40
-        Width = 224
-        Anchors = [akTop, akLeft, akRight]
-        OnChange = Edit_FilenameChange
-        ParentFont = False
-        TabOrder = 2
+      object ToolButton_ViewBigIcon: TToolButton
+        Left = 73
+        Hint = 'Show big icons'
+        Top = 0
+        ImageIndex = 2
+        OnClick = ToolButton_ViewBigIconClick
       end
-      object DirectoryEdit1: TEdit
-        Left = 200
-        Height = 23
-        Top = 5
-        Width = 248
-        Anchors = [akTop, akLeft, akRight]
-        OnChange = DirectoryEdit1Change
-        ParentFont = False
-        TabOrder = 0
+      object ToolButton_ViewDetails: TToolButton
+        Left = 37
+        Hint = 'Show details and preview'
+        Top = 0
+        ImageIndex = 3
+        OnClick = ToolButton_ViewDetailsClick
       end
-      object ComboBox_FileExtension: TBCComboBox
-        Left = 6
-        Height = 27
-        Top = 40
-        Width = 210
-        ItemIndex = -1
-        ArrowSize = 8
-        ArrowWidth = 16
-        FocusBorderOpacity = 0
-        GlobalOpacity = 255
-        MemoryUsage = bmuHigh
-        Rounding.RoundX = 3
-        Rounding.RoundY = 3
-        StateClicked.Background.Gradient1.StartColor = clBtnShadow
-        StateClicked.Background.Gradient1.EndColor = clBtnFace
-        StateClicked.Background.Gradient1.GradientType = gtLinear
-        StateClicked.Background.Gradient1.Point2YPercent = 250
-        StateClicked.Background.Gradient2.StartColor = clBtnShadow
-        StateClicked.Background.Gradient2.EndColor = clBtnText
-        StateClicked.Background.Gradient2.GradientType = gtLinear
-        StateClicked.Background.Gradient2.Point2YPercent = 100
-        StateClicked.Background.Gradient1EndPercent = 70
-        StateClicked.Background.Style = bbsGradient
-        StateClicked.Border.Color = clBtnShadow
-        StateClicked.Border.LightOpacity = 100
-        StateClicked.Border.LightWidth = 1
-        StateClicked.Border.Style = bboSolid
-        StateClicked.FontEx.Color = clBtnText
-        StateClicked.FontEx.FontQuality = fqFineAntialiasing
-        StateClicked.FontEx.Shadow = False
-        StateClicked.FontEx.ShadowRadius = 5
-        StateClicked.FontEx.ShadowOffsetX = 5
-        StateClicked.FontEx.ShadowOffsetY = 5
-        StateClicked.FontEx.Style = []
-        StateClicked.FontEx.TextAlignment = bcaLeftCenter
-        StateClicked.FontEx.PaddingLeft = 3
-        StateHover.Background.Gradient1.StartColor = clBtnFace
-        StateHover.Background.Gradient1.EndColor = clBtnHighlight
-        StateHover.Background.Gradient1.GradientType = gtLinear
-        StateHover.Background.Gradient1.Point2YPercent = 150
-        StateHover.Background.Gradient2.StartColor = clBtnFace
-        StateHover.Background.Gradient2.EndColor = clBtnShadow
-        StateHover.Background.Gradient2.GradientType = gtLinear
-        StateHover.Background.Gradient2.Point2YPercent = 100
-        StateHover.Background.Gradient1EndPercent = 85
-        StateHover.Background.Style = bbsGradient
-        StateHover.Border.Color = clBtnShadow
-        StateHover.Border.LightOpacity = 200
-        StateHover.Border.LightWidth = 1
-        StateHover.Border.Style = bboSolid
-        StateHover.FontEx.Color = clBtnText
-        StateHover.FontEx.FontQuality = fqFineAntialiasing
-        StateHover.FontEx.Shadow = False
-        StateHover.FontEx.ShadowRadius = 5
-        StateHover.FontEx.ShadowOffsetX = 5
-        StateHover.FontEx.ShadowOffsetY = 5
-        StateHover.FontEx.Style = []
-        StateHover.FontEx.TextAlignment = bcaLeftCenter
-        StateHover.FontEx.PaddingLeft = 3
-        StateNormal.Background.Gradient1.StartColor = clBtnFace
-        StateNormal.Background.Gradient1.EndColor = clBtnHighlight
-        StateNormal.Background.Gradient1.GradientType = gtLinear
-        StateNormal.Background.Gradient1.Point2YPercent = 150
-        StateNormal.Background.Gradient2.StartColor = clBtnFace
-        StateNormal.Background.Gradient2.EndColor = clBtnShadow
-        StateNormal.Background.Gradient2.GradientType = gtLinear
-        StateNormal.Background.Gradient2.Point2YPercent = 100
-        StateNormal.Background.Gradient1EndPercent = 70
-        StateNormal.Background.Style = bbsGradient
-        StateNormal.Border.Color = clBtnShadow
-        StateNormal.Border.LightOpacity = 200
-        StateNormal.Border.LightWidth = 1
-        StateNormal.Border.Style = bboSolid
-        StateNormal.FontEx.Color = clBtnText
-        StateNormal.FontEx.FontQuality = fqFineAntialiasing
-        StateNormal.FontEx.Shadow = False
-        StateNormal.FontEx.ShadowRadius = 5
-        StateNormal.FontEx.ShadowOffsetX = 5
-        StateNormal.FontEx.ShadowOffsetY = 5
-        StateNormal.FontEx.Style = []
-        StateNormal.FontEx.TextAlignment = bcaLeftCenter
-        StateNormal.FontEx.PaddingLeft = 3
-        StaticButton = False
-        OnChange = ComboBox_FileExtensionChange
-        TabOrder = 1
+      object ToolButton_OpenSelectedFiles: TToolButton
+        Left = 1
+        Hint = 'Open selected files'
+        Top = 0
+        Enabled = False
+        ImageIndex = 5
+        OnClick = ToolButton_OpenSelectedFilesClick
+      end
+      object Tool_SelectDrive: TToolButton
+        Left = 109
+        Hint = 'Select drive'
+        Top = 0
+        ImageIndex = 6
+        OnClick = Tool_SelectDriveClick
+        Visible = False
+      end
+      object ToolButton_CreateFolderOrContainer: TToolButton
+        Left = 1
+        Hint = 'Create folder or container'
+        Top = 32
+        ImageIndex = 8
+        OnClick = ToolButton_CreateFolderOrContainerClick
       end
     end
-    object vsList: TBGRAVirtualScreen
-      Left = 1
-      Height = 225
-      Top = 74
-      Width = 456
-      Align = alClient
-      Alignment = taLeftJustify
-      Color = clWindow
-      ParentColor = False
+    object Edit_Filename: TEdit
+      Left = 288
+      Height = 27
+      Top = 40
+      Width = 388
+      Anchors = [akTop, akLeft, akRight]
+      OnChange = Edit_FilenameChange
       ParentFont = False
+      TabOrder = 2
+    end
+    object DirectoryEdit1: TEdit
+      Left = 200
+      Height = 27
+      Top = 5
+      Width = 476
+      Anchors = [akTop, akLeft, akRight]
+      OnChange = DirectoryEdit1Change
+      ParentFont = False
+      TabOrder = 0
+    end
+    object ComboBox_FileExtension: TBCComboBox
+      Left = 6
+      Height = 27
+      Top = 40
+      Width = 274
+      ItemIndex = -1
+      ArrowSize = 8
+      ArrowWidth = 16
+      FocusBorderOpacity = 0
+      GlobalOpacity = 255
+      MemoryUsage = bmuHigh
+      Rounding.RoundX = 3
+      Rounding.RoundY = 3
+      StateClicked.Background.Gradient1.StartColor = clBtnShadow
+      StateClicked.Background.Gradient1.EndColor = clBtnFace
+      StateClicked.Background.Gradient1.GradientType = gtLinear
+      StateClicked.Background.Gradient1.Point1XPercent = 50
+      StateClicked.Background.Gradient1.Point1YPercent = 100
+      StateClicked.Background.Gradient1.Point2XPercent = 0
+      StateClicked.Background.Gradient1.Point2YPercent = 250
+      StateClicked.Background.Gradient2.StartColor = clBtnShadow
+      StateClicked.Background.Gradient2.EndColor = clBtnText
+      StateClicked.Background.Gradient2.GradientType = gtLinear
+      StateClicked.Background.Gradient2.Point1XPercent = 0
+      StateClicked.Background.Gradient2.Point1YPercent = 0
+      StateClicked.Background.Gradient2.Point2XPercent = 0
+      StateClicked.Background.Gradient2.Point2YPercent = 100
+      StateClicked.Background.Gradient1EndPercent = 70
+      StateClicked.Background.Style = bbsGradient
+      StateClicked.Border.Color = clBtnShadow
+      StateClicked.Border.LightOpacity = 100
+      StateClicked.Border.LightWidth = 1
+      StateClicked.Border.Style = bboSolid
+      StateClicked.FontEx.Color = clBtnText
+      StateClicked.FontEx.FontQuality = fqFineAntialiasing
+      StateClicked.FontEx.Shadow = False
+      StateClicked.FontEx.ShadowRadius = 5
+      StateClicked.FontEx.ShadowOffsetX = 5
+      StateClicked.FontEx.ShadowOffsetY = 5
+      StateClicked.FontEx.Style = []
+      StateClicked.FontEx.TextAlignment = bcaLeftCenter
+      StateClicked.FontEx.PaddingLeft = 3
+      StateHover.Background.Gradient1.StartColor = clBtnFace
+      StateHover.Background.Gradient1.EndColor = clBtnHighlight
+      StateHover.Background.Gradient1.GradientType = gtLinear
+      StateHover.Background.Gradient1.Point1XPercent = 50
+      StateHover.Background.Gradient1.Point1YPercent = 100
+      StateHover.Background.Gradient1.Point2XPercent = 0
+      StateHover.Background.Gradient1.Point2YPercent = 150
+      StateHover.Background.Gradient2.StartColor = clBtnFace
+      StateHover.Background.Gradient2.EndColor = clBtnShadow
+      StateHover.Background.Gradient2.GradientType = gtLinear
+      StateHover.Background.Gradient2.Point1XPercent = 0
+      StateHover.Background.Gradient2.Point1YPercent = 0
+      StateHover.Background.Gradient2.Point2XPercent = 0
+      StateHover.Background.Gradient2.Point2YPercent = 100
+      StateHover.Background.Gradient1EndPercent = 85
+      StateHover.Background.Style = bbsGradient
+      StateHover.Border.Color = clBtnShadow
+      StateHover.Border.LightOpacity = 200
+      StateHover.Border.LightWidth = 1
+      StateHover.Border.Style = bboSolid
+      StateHover.FontEx.Color = clBtnText
+      StateHover.FontEx.FontQuality = fqFineAntialiasing
+      StateHover.FontEx.Shadow = False
+      StateHover.FontEx.ShadowRadius = 5
+      StateHover.FontEx.ShadowOffsetX = 5
+      StateHover.FontEx.ShadowOffsetY = 5
+      StateHover.FontEx.Style = []
+      StateHover.FontEx.TextAlignment = bcaLeftCenter
+      StateHover.FontEx.PaddingLeft = 3
+      StateNormal.Background.Gradient1.StartColor = clBtnFace
+      StateNormal.Background.Gradient1.EndColor = clBtnHighlight
+      StateNormal.Background.Gradient1.GradientType = gtLinear
+      StateNormal.Background.Gradient1.Point1XPercent = 0
+      StateNormal.Background.Gradient1.Point1YPercent = 0
+      StateNormal.Background.Gradient1.Point2XPercent = 0
+      StateNormal.Background.Gradient1.Point2YPercent = 150
+      StateNormal.Background.Gradient2.StartColor = clBtnFace
+      StateNormal.Background.Gradient2.EndColor = clBtnShadow
+      StateNormal.Background.Gradient2.GradientType = gtLinear
+      StateNormal.Background.Gradient2.Point1XPercent = 50
+      StateNormal.Background.Gradient2.Point1YPercent = 100
+      StateNormal.Background.Gradient2.Point2XPercent = 0
+      StateNormal.Background.Gradient2.Point2YPercent = 100
+      StateNormal.Background.Gradient1EndPercent = 70
+      StateNormal.Background.Style = bbsGradient
+      StateNormal.Border.Color = clBtnShadow
+      StateNormal.Border.LightOpacity = 200
+      StateNormal.Border.LightWidth = 1
+      StateNormal.Border.Style = bboSolid
+      StateNormal.FontEx.Color = clBtnText
+      StateNormal.FontEx.FontQuality = fqFineAntialiasing
+      StateNormal.FontEx.Shadow = False
+      StateNormal.FontEx.ShadowRadius = 5
+      StateNormal.FontEx.ShadowOffsetX = 5
+      StateNormal.FontEx.ShadowOffsetY = 5
+      StateNormal.FontEx.Style = []
+      StateNormal.FontEx.TextAlignment = bcaLeftCenter
+      StateNormal.FontEx.PaddingLeft = 3
+      StaticButton = False
+      OnChange = ComboBox_FileExtensionChange
       TabOrder = 1
-      TabStop = True
     end
   end
   object ImageList128: TImageList

+ 59 - 2
lazpaint/dialog/ubrowseimages.pas

@@ -70,6 +70,7 @@ type
     procedure SetCurrentDirectory(AValue: string);
     function AdaptExtension: boolean;
     procedure ShellListView1SelectionChanged(Sender: TObject);
+    procedure ThemeChanged(Sender: TObject);
   private
     FLazPaintInstance: TLazPaintCustomInstance;
     FDefaultExtension: string;
@@ -81,6 +82,7 @@ type
     FIsSaveDialog: boolean;
     FOverwritePrompt: boolean;
     ShellListView1: TLCShellListView;
+    FUpdateListBounds: boolean;
     FInFormShow: boolean;
     FChosenImage: TImageEntry;
     FPreview: TImagePreview;
@@ -123,6 +125,7 @@ type
     procedure SelectCurrentDir;
     procedure UpdatePreview(AFilename:string); overload;
     procedure UpdatePreview; overload;
+    procedure UpdateTheme;
     procedure ShowPreview;
     procedure HidePreview;
     procedure UpdateConstraints;
@@ -143,6 +146,7 @@ type
     ShowRememberStartupDirectory: boolean;
     function GetChosenImage: TImageEntry;
     procedure FreeChosenImage;
+    function ShowModal: Integer; override;
     property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
     property Filename: string read FFilename;
     property SelectedFileCount: integer read GetSelectedFileCount;
@@ -273,8 +277,10 @@ begin
 
   ScaleControl(Panel1, OriginalDPI, 0,0, true);
   ScaleControl(Panel2, OriginalDPI, 0,0, true);
+  ScaleControl(Panel3, OriginalDPI, 0,0, true);
+
+  UpdateTheme;
 
-  DarkThemeInstance.Apply(ComboBox_FileExtension, False, 0.40);
   vsList.BitmapAutoScale:= false;
 
   bmp := TBitmap.Create;
@@ -319,6 +325,8 @@ end;
 
 procedure TFBrowseImages.FormDestroy(Sender: TObject);
 begin
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
   ShellListView1.VirtualScreenFreed;
   FreeAndNil(ShellListView1);
   FreeAndNil(FChosenImage.bmp);
@@ -378,6 +386,11 @@ begin
     ResetDirectory(false, true);
     SelectFile(Edit_Filename.Text);
     Key := 0;
+  end else
+  if (KEY = VK_ESCAPE) then
+  begin
+    Close;
+    Key := 0;
   end;
 end;
 
@@ -614,7 +627,11 @@ begin
     end;
     AddToCache(newFilenames, newLastModifications, ShellListView1.LargeIconSize);
   end;
-  vsList.SetBounds(vsList.Left, vsList.Top, Panel2.Width, Panel2.Height-Panel3.Height);
+  if FUpdateListBounds then
+  begin
+    vsList.SetBounds(vsList.Left, vsList.Top, Panel2.Width, Panel2.Height-Panel3.Height);
+    FUpdateListBounds := false;
+  end;
   ShellListView1.Update;
   Timer1.Enabled:= true;
 end;
@@ -741,6 +758,11 @@ begin
   UpdateToolButtonOpen;
 end;
 
+procedure TFBrowseImages.ThemeChanged(Sender: TObject);
+begin
+  UpdateTheme;
+end;
+
 procedure TFBrowseImages.UpdateToolButtonOpen;
 var chosenFilename: string;
 begin
@@ -810,7 +832,11 @@ end;
 procedure TFBrowseImages.SetLazPaintInstance(AValue: TLazPaintCustomInstance);
 begin
   if FLazPaintInstance=AValue then Exit;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
   FLazPaintInstance:=AValue;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
   if Assigned(FPreview) then
     FPreview.LazPaintInstance := AValue;
 end;
@@ -969,6 +995,11 @@ begin
   end;
 end;
 
+procedure TFBrowseImages.UpdateTheme;
+begin
+  DarkThemeInstance.Apply(ComboBox_FileExtension, DarkThemeInstance.IsSystemDarkTheme, 0.40);
+end;
+
 procedure TFBrowseImages.ShowPreview;
 begin
   if FInShowPreview or Panel1.Visible then exit;
@@ -1001,6 +1032,7 @@ begin
     Panel2.Constraints.MaxWidth := ClientWidth-Splitter1.Width-64
   else
     Panel2.Constraints.MaxWidth := 0;
+  FUpdateListBounds := true;
 end;
 
 procedure TFBrowseImages.ViewDetails;
@@ -1259,5 +1291,30 @@ begin
   FreeAndNil(FChosenImage.bmp);
 end;
 
+function TFBrowseImages.ShowModal: Integer;
+var
+  mainHidden: Boolean;
+begin
+  mainHidden := FLazPaintInstance.Hide;
+  try
+    {$IFDEF LCLqt5}
+    Show;
+    ModalResult := mrNone;
+    repeat
+      Application.ProcessMessages;
+      Sleep(50);
+    until (ModalResult <> mrNone) or not Visible;
+    if Visible then Hide;
+    if ModalResult = mrNone then
+      result := mrAbort
+      else result := ModalResult;
+    {$ELSE}
+    Result:=inherited ShowModal;
+    {$ENDIf}
+  finally
+    if mainHidden then FLazPaintInstance.Show;
+  end;
+end;
+
 end.
 

+ 27 - 1
lazpaint/dialog/ucanvassize.pas

@@ -36,15 +36,19 @@ type
     procedure vsPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
   private
     { private declarations }
+    FLazPaintInstance: TLazPaintCustomInstance;
     FIgnoreInput: boolean;
     FMUnit: integer;
     function GetSelectedAnchor: string;
+    procedure SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+    procedure ThemeChanged(Sender: TObject);
   public
     { public declarations }
-    LazPaintInstance: TLazPaintCustomInstance;
     canvasSizeResult: TLayeredBitmapAndSelection;
     repeatImage: boolean;
+    destructor Destroy; override;
     property SelectedAnchor: string read GetSelectedAnchor;
+    property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
   end;
 
 function ComputeNewCanvasSize(AInstance: TLazPaintCustomInstance; AWidth,AHeight: integer;
@@ -381,6 +385,28 @@ begin
     result := ComboBox_Anchor.Items[ComboBox_Anchor.ItemIndex];
 end;
 
+procedure TFCanvasSize.SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+begin
+  if FLazPaintInstance=AValue then Exit;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  FLazPaintInstance:=AValue;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
+end;
+
+procedure TFCanvasSize.ThemeChanged(Sender: TObject);
+begin
+  vsPreview.DiscardBitmap;
+end;
+
+destructor TFCanvasSize.Destroy;
+begin
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  inherited Destroy;
+end;
+
 {$R *.lfm}
 
 end.

+ 18 - 14
lazpaint/dialog/uchoosecolorinterface.pas

@@ -729,15 +729,8 @@ begin
   DarkThemeInstance.Apply(BCButton_AddToPalette, FDarkTheme);
   DarkThemeInstance.Apply(BCButton_RemoveFromPalette, FDarkTheme);
   DarkThemeInstance.Apply(LColor, FDarkTheme);
-  if DarkTheme then
-  begin
-    FFormBackgroundColor := clDarkBtnFace;
-    FFormTextColor := clLightText;
-  end else
-  begin
-    FFormBackgroundColor := clForm;
-    FFormTextColor := clWindowText;
-  end;
+  FFormBackgroundColor := DarkThemeInstance.GetColorForm(FDarkTheme);
+  FFormTextColor := DarkThemeInstance.GetColorButtonText(FDarkTheme);
   Container.Color := FFormBackgroundColor;
   vsColorView.Color := FFormBackgroundColor;
   vsColorView.DiscardBitmap;
@@ -747,6 +740,7 @@ procedure TChooseColorInterface.UpdateButtonLayout;
 var
   iconSize: Integer;
   tmpIcon: TBitmap;
+  scaling, invScaling: single;
 begin
   FButtonSize := round(FBarWidth);
   BCButton_AddToPalette.Width := FButtonSize;
@@ -770,17 +764,23 @@ begin
     BCButton_RemoveFromPalette.Left := BCButton_AddToPalette.Left + BCButton_AddToPalette.Width;
     BCButton_RemoveFromPalette.Top := round(FMargin / 2);
   end;
-  iconSize := FButtonSize-4;
-  if not Assigned(BCButton_AddToPalette.Glyph) or (BCButton_AddToPalette.Glyph.Width <> iconSize) then
+  scaling := Container.GetCanvasScaleFactor;
+  iconSize := round((FButtonSize-4)*scaling);
+  invScaling := 1/scaling;
+  if not Assigned(BCButton_AddToPalette.Glyph) or (BCButton_AddToPalette.Glyph.Width <> iconSize)
+     or (BCButton_AddToPalette.GlyphScale <> invScaling) then
   begin
     tmpIcon:= MakeAddIcon(iconSize);
     BCButton_AddToPalette.Glyph.Assign(tmpIcon);
+    BCButton_AddToPalette.GlyphScale:= invScaling;
     tmpIcon.Free;
   end;
-  if not Assigned(BCButton_RemoveFromPalette.Glyph) or (BCButton_RemoveFromPalette.Glyph.Width <> iconSize) then
+  if not Assigned(BCButton_RemoveFromPalette.Glyph) or (BCButton_RemoveFromPalette.Glyph.Width <> iconSize)
+     or (BCButton_RemoveFromPalette.GlyphScale <> invScaling) then
   begin
     tmpIcon:= MakeRemoveIcon(iconSize);
     BCButton_RemoveFromPalette.Glyph.Assign(tmpIcon);
+    BCButton_RemoveFromPalette.GlyphScale:= invScaling;
     tmpIcon.Free;
   end;
 end;
@@ -1052,13 +1052,17 @@ begin
   BCButton_AddToPalette := TBCButton.Create(vsColorView);
   BCButton_AddToPalette.Parent := vsColorView;
   BCButton_AddToPalette.OnClick := @BCButton_AddToPaletteClick;
+  BCButton_AddToPalette.Hint := rsAddToPalette;
+  BCButton_AddToPalette.ShowHint := true;
   BCButton_RemoveFromPalette := TBCButton.Create(vsColorView);
   BCButton_RemoveFromPalette.Parent := vsColorView;
   BCButton_RemoveFromPalette.OnClick := @BCButton_RemoveFromPaletteClick;
+  BCButton_RemoveFromPalette.Hint := rsRemoveFromPalette;
+  BCButton_RemoveFromPalette.ShowHint := true;
   ApplyTheme;
 
-  EColor.Font.Height := FontEmHeightSign * DoScaleY(11, OriginalDPI, FDPI) + 1;
-  LColor.Font.Height := FontEmHeightSign * DoScaleY(11, OriginalDPI, FDPI) + 1;
+  EColor.Font.Height := FontEmHeightSign * (DoScaleY(11, OriginalDPI, FDPI) + 1);
+  LColor.Font.Height := FontEmHeightSign * (DoScaleY(11, OriginalDPI, FDPI) + 1);
   EColor.Text:= '#FFFFFF';
   LColor.Visible := true;
   LColor.Caption := '#FFFFFF';

+ 116 - 46
lazpaint/dialog/ulayerstackinterface.pas

@@ -7,7 +7,7 @@ interface
 
 uses
   Classes, SysUtils, Controls, ComCtrls, ExtCtrls, BGRAVirtualScreen, BCComboBox,
-  BGRABitmap, BGRABitmapTypes, BGRAGraphics,
+  BGRABitmap, BGRABitmapTypes, BGRAGraphics, Menus,
   LazPaintType, UDarkTheme, UVolatileScrollBar, UImageObservation;
 
 type
@@ -30,7 +30,7 @@ type
     LazPaintInstance: TLazPaintCustomInstance;
     Container: TWinControl;
     BGRALayerStack: TBGRAVirtualScreen;
-    TimerScroll: TTimer;
+    TimerScroll, TimerQuery: TTimer;
     PanelToolbar: TPanel;
     Toolbar: TToolbar;
     ComboBox_BlendOp: TBCComboBox;
@@ -45,6 +45,7 @@ type
       WheelDelta: Integer; {%H-}MousePos: TPoint; var Handled: Boolean);
     procedure BGRALayerStack_Redraw(Sender: TObject; Bitmap: TBGRABitmap);
     procedure ComboBox_BlendOpChange(Sender: TObject);
+    procedure TimerQuery_Timer(Sender: TObject);
     procedure TimerScroll_Timer(Sender: TObject);
     procedure Toolbar_Resize(Sender: TObject);
     procedure ToolSelectBlendOperation_Click(Sender: TObject);
@@ -54,10 +55,9 @@ type
   protected
     FDPI: integer;
     FScaling: Double;
-    FSysColorSelection: Boolean;
     FDarkTheme: boolean;
     FScrollStackItemIntoView: Boolean;
-    FUpdatingComboBlendOp: Boolean;
+    FUpdatingComboBlendOp, FQuerySelectBlendOp: Boolean;
     FPartialRedraw: Boolean;
     FRenaming: Boolean;
     FDontUpdateStack: Boolean;
@@ -74,8 +74,12 @@ type
     FMovingItemBitmap: TBGRABitmap;
     FMovingItemSourceIndex: integer;
     FMovingItemMousePos, FMovingItemMouseOrigin, FMovingItemOrigin: TPoint;
+    FRightClickOrigin: TPoint;
     FTimerScrollDeltaY: integer;
     FInHandleSelectLayer: Boolean;
+    FLayerMenu: TPopupMenu;
+    FQueryLayerMenu: boolean;
+    FLayerMenuCoord: TPoint;
     procedure ApplyThemeAndDPI;
     procedure SetDPI(AValue: integer);
     procedure SetDarkTheme(AValue: boolean);
@@ -83,13 +87,14 @@ type
     function GetTextColor(ASelected: boolean): TColor;
     procedure UpdateComboBlendOp;
     procedure SelectBlendOp;
+    procedure QuerySelectBlendOp;
     procedure SetZoomFactor(AValue: single);
     function DrawLayerItem(ABitmap: TBGRABitmap; ALayerPos: TPoint; ALayerIndex: integer; ASelected: boolean): TDrawLayerItemResult;
     procedure DrawLayerStack(ABitmap: TBGRABitmap; ALayout: boolean; AUpdateItem: Integer);
     procedure ComputeLayout(ABitmap: TBGRABitmap);
     procedure ComputeScrolling(AWithHorzScrollBar,AWithVertScrollBar: boolean);
     procedure DoScrollVertically(AAmount: integer);
-    procedure HandleSelectLayer(i,x,y: integer);
+    function HandleSelectLayer(i,x,y: integer; AStartMoving: boolean = true): boolean;
     procedure HandleChangeLayerOpacity(X,{%H-}Y: integer);
     procedure UpdateLayerStackItem(AIndex: integer);
     procedure NeedCheckers;
@@ -98,6 +103,7 @@ type
     destructor Destroy; override;
     procedure AddButton(AAction: TBasicAction);
     procedure AddButton(ACaption: string; AImageIndex: integer; AOnClick: TNotifyEvent);
+    procedure AddLayerMenu(AAction: TBasicAction);
     procedure ScrollToItem(AIndex: integer; AUpdateStack: boolean = true);
     procedure InvalidateStack(AScrollIntoView: boolean);
     function GetWidthFor(AButtonCount: integer): integer;
@@ -130,6 +136,8 @@ procedure TLayerStackInterface.ComboBox_BlendOpChange(Sender: TObject);
 var blendOp: TBlendOperation;
   itemStr: string;
 begin
+  if Assigned(LazPaintInstance) then
+    LazPaintInstance.ExitColorEditor;
   if not FUpdatingComboBlendOp then
   begin
     if ComboBox_BlendOp.ItemIndex <> -1 then
@@ -146,12 +154,30 @@ begin
         if LazPaintInstance.Image.CurrentLayerIndex = 0 then
           LazPaintInstance.ToolManager.ToolPopup(tpmBlendOpBackground);
         FDontUpdateStack := false;
+        FQuerySelectBlendOp:= false;
       end else
-        SelectBlendOp;
+        QuerySelectBlendOp;
     end;
   end;
 end;
 
+procedure TLayerStackInterface.TimerQuery_Timer(Sender: TObject);
+begin
+  if FQuerySelectBlendOp then
+  begin
+    FQuerySelectBlendOp := false;
+    SelectBlendOp;
+  end else
+  if FQueryLayerMenu then
+  begin
+    FQueryLayerMenu := false;
+    with FLayerMenuCoord do
+      FLayerMenu.PopUp(X, Y);
+  end
+  else
+    TimerQuery.Enabled:= false;
+end;
+
 procedure TLayerStackInterface.TimerScroll_Timer(Sender: TObject);
 begin
   TimerScroll.Enabled := False;
@@ -175,6 +201,7 @@ procedure TLayerStackInterface.BGRALayerStack_MouseDown(Sender: TObject;
 var i: integer;
   str: string;
 begin
+  if Assigned(LazPaintInstance) then LazPaintInstance.ExitColorEditor;
   X := round(X*FScaling);
   Y := round(Y*FScaling);
   if PtInRect(Point(X,Y),FScrollButtonRect) then exit;
@@ -238,7 +265,9 @@ begin
         end;
         exit;
       end;
-  end;
+  end else
+  if Button = mbRight then
+    FRightClickOrigin := Point(X,Y);
 end;
 
 procedure TLayerStackInterface.BGRALayerStack_MouseMove(Sender: TObject;
@@ -279,7 +308,7 @@ end;
 
 procedure TLayerStackInterface.BGRALayerStack_MouseUp(Sender: TObject;
   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
-var destinationIndex, prevIndex: integer;
+var destinationIndex, prevIndex, i: integer;
   indexF: single;
   res: TModalResult;
   topmostInfo: TTopMostInfo;
@@ -332,6 +361,23 @@ begin
       FInHandleSelectLayer := false;
       FAskTransferSelectionLayerIndex := -1;
     end;
+  end else
+  if (Button = mbRight) and (Abs(X - FRightClickOrigin.X) <= 2) and
+    (Abs(Y - FRightClickOrigin.Y) <= 2) then
+  begin
+    for i := 0 to high(FLayerInfo) do
+      if IsPointInPolygon(FLayerInfo[i].RightPart.PreviewPts,pointF(FRightClickOrigin.x,FRightClickOrigin.y),true) then
+      begin
+        if HandleSelectLayer(i,x,y,false) then
+        begin
+          FQueryLayerMenu := true;
+          FLayerMenuCoord := BGRALayerStack.ClientToScreen(Point(
+            round(FRightClickOrigin.X / FScaling),
+            round(FRightClickOrigin.Y / FScaling)));
+          TimerQuery.Enabled:= true;
+        end;
+        exit;
+      end;
   end;
 end;
 
@@ -378,10 +424,16 @@ begin
                         LazPaintInstance.Image.LayerOffset[ALayerIndex].Y,
                         LazPaintInstance.Image.LayerBitmap[ALayerIndex].Width,
                         LazPaintInstance.Image.LayerBitmap[ALayerIndex].Height);
-  reducedBounds.Left := round(reducedBounds.Left*reduced.Width/LazPaintInstance.Image.Width);
-  reducedBounds.Top := round(reducedBounds.Top*reduced.Height/LazPaintInstance.Image.Height);
-  reducedBounds.Right := round(reducedBounds.Right*reduced.Width/LazPaintInstance.Image.Width);
-  reducedBounds.Bottom := round(reducedBounds.Bottom*reduced.Height/LazPaintInstance.Image.Height);
+  if LazPaintInstance.Image.Width <> 0 then
+  begin
+    reducedBounds.Left := round(reducedBounds.Left*reduced.Width/LazPaintInstance.Image.Width);
+    reducedBounds.Right := round(reducedBounds.Right*reduced.Width/LazPaintInstance.Image.Width);
+  end;
+  if LazPaintInstance.Image.Height <> 0 then
+  begin
+    reducedBounds.Top := round(reducedBounds.Top*reduced.Height/LazPaintInstance.Image.Height);
+    reducedBounds.Bottom := round(reducedBounds.Bottom*reduced.Height/LazPaintInstance.Image.Height);
+  end;
   reduced.StretchPutImage(reducedBounds, LazPaintInstance.Image.LayerBitmap[ALayerIndex], dmDrawWithTransparency);
 
   result.PreviewPts[0].y += 0.5;
@@ -622,7 +674,8 @@ begin
     end;
     inc(layerPos.Y, FLayerRectHeight);
   end;
-  ABitmap.HorizLine(0, 0, ABitmap.Width-1, clDarkBtnFace, dmDrawWithTransparency, 32768);
+  ABitmap.HorizLine(0, 0, ABitmap.Width-1, DarkThemeInstance.GetColorButtonFace(DarkTheme),
+    dmDrawWithTransparency, 32768);
 
   prevClip := ABitmap.ClipRect;
   if (clipping.right > clipping.left) and (clipping.bottom > clipping.top) then
@@ -772,9 +825,10 @@ begin
   end;
 end;
 
-procedure TLayerStackInterface.HandleSelectLayer(i, x, y: integer);
+function TLayerStackInterface.HandleSelectLayer(i, x, y: integer; AStartMoving: boolean): boolean;
 var prevIndex: integer;
 begin
+  result := false;
   FInHandleSelectLayer := true;
   if (i < LazPaintInstance.Image.NbLayers) then
   begin
@@ -789,11 +843,15 @@ begin
     begin
       FRenaming := false;
       UpdateLayerStackItem(prevIndex);
-      FMovingItemStart := true;
-      FMovingItemSourceIndex := i;
-      FMovingItemMouseOrigin := point(x,y);
-      FMovingItemMousePos := point(x,y);
+      if AStartMoving then
+      begin
+        FMovingItemStart := true;
+        FMovingItemSourceIndex := i;
+        FMovingItemMouseOrigin := point(x,y);
+        FMovingItemMousePos := point(x,y);
+      end;
       UpdateLayerStackItem(i);
+      result := true;
     end;
   end;
   FInHandleSelectLayer := false;
@@ -866,6 +924,7 @@ var
 begin
   if FUpdatingComboBlendOp then exit;
   FUpdatingComboBlendOp := true;
+  FQuerySelectBlendOp:= false;
   blendOps := TStringList.Create;
   selectedStr := '';
   blendOps.AddStrings(ComboBox_BlendOp.Items);
@@ -921,13 +980,23 @@ begin
     LazPaintInstance.ToolManager.ToolPopup(tpmBlendOpBackground);
 end;
 
+procedure TLayerStackInterface.QuerySelectBlendOp;
+begin
+  TimerQuery.Enabled := true;
+  FQuerySelectBlendOp := true;
+end;
+
 procedure TLayerStackInterface.ToolZoomLayerStackIn_Click(Sender: TObject);
 begin
+  if Assigned(LazPaintInstance) then
+    LazPaintInstance.ExitColorEditor;
   ZoomFactor := ZoomFactor * 1.3;
 end;
 
 procedure TLayerStackInterface.ToolZoomLayerStackOut_Click(Sender: TObject);
 begin
+  if Assigned(LazPaintInstance) then
+    LazPaintInstance.ExitColorEditor;
   ZoomFactor := ZoomFactor / 1.3;
 end;
 
@@ -939,9 +1008,9 @@ begin
   Toolbar.Images := LazPaintInstance.Icons[iconSize];
   Toolbar.ButtonWidth:= iconSize + DoScaleX(4, OriginalDPI, DPI);
   Toolbar.ButtonHeight:= iconSize + DoScaleY(4, OriginalDPI, DPI);
+  FLayerMenu.Images := LazPaintInstance.Icons[DoScaleX(20,OriginalDPI)];
   ComboBox_BlendOp.Width := Toolbar.ButtonWidth*7;
   ComboBox_BlendOp.Height := Toolbar.ButtonHeight;
-  FSysColorSelection:= BGRADiff(ColorToBGRA(clHighlight), clDarkBtnFace)>=64;
   DarkThemeInstance.Apply(PanelToolbar, DarkTheme);
   BGRALayerStack.Color:= GetBackColor(False);
   BGRALayerStack.DiscardBitmap;
@@ -949,10 +1018,7 @@ begin
   if PanelToolbar.BevelOuter <> bvNone then dec(spacing, PanelToolbar.BevelWidth);
   PanelToolbar.ChildSizing.TopBottomSpacing:= spacing;
   PanelToolbar.ChildSizing.LeftRightSpacing:= spacing;
-  if DarkTheme then
-    Container.Color := clDarkBtnFace
-  else
-    Container.Color := clBtnFace;
+  Container.Color := DarkThemeInstance.GetColorButtonFace(DarkTheme);
 end;
 
 procedure TLayerStackInterface.SetDPI(AValue: integer);
@@ -1020,6 +1086,14 @@ begin
   TimerScroll.Enabled := false;
   TimerScroll.Interval := 30;
   TimerScroll.OnTimer:=@TimerScroll_Timer;
+  TimerQuery := TTimer.Create(Container);
+  TimerQuery.Enabled := false;
+  TimerQuery.Interval := 200;
+  TimerQuery.OnTimer:=@TimerQuery_Timer;
+  FQuerySelectBlendOp:= false;
+
+  FLayerMenu := TPopupMenu.Create(AContainer);
+  FQueryLayerMenu:= false;
 
   ApplyThemeAndDPI;
   LazPaintInstance.Image.OnImageChanged.AddObserver(@LazPaint_ImageChanged);
@@ -1048,19 +1122,9 @@ end;
 
 function TLayerStackInterface.GetTextColor(ASelected: boolean): TColor;
 begin
-  if DarkTheme and not (ASelected and FSysColorSelection) then
-  begin
-    if ASelected then
-      result := clBlack
-    else
-      result := clLightText;
-  end else
-  begin
-    if ASelected then
-      result := ColorToBGRA(clHighlightText)
-    else
-      result := ColorToBGRA(clWindowText);
-  end;
+  if ASelected then
+    result := DarkThemeInstance.GetColorHighlightText(DarkTheme)
+    else result := DarkThemeInstance.GetColorEditableText(DarkTheme);
 end;
 
 procedure TLayerStackInterface.AddButton(ACaption: string;
@@ -1076,6 +1140,15 @@ begin
   button.OnClick := AOnClick;
 end;
 
+procedure TLayerStackInterface.AddLayerMenu(AAction: TBasicAction);
+var
+  item: TMenuItem;
+begin
+  item := TMenuItem.Create(FLayerMenu);
+  item.Action := AAction;
+  FLayerMenu.Items.Add(item);
+end;
+
 procedure TLayerStackInterface.ScrollToItem(AIndex: integer; AUpdateStack: boolean);
 begin
   FScrollPos.X := 0;
@@ -1101,18 +1174,15 @@ end;
 
 function TLayerStackInterface.GetBackColor(ASelected: boolean): TColor;
 begin
-  if DarkTheme and not (ASelected and FSysColorSelection) then
-  begin
-    if ASelected then
-      result := clLightText
-    else
-      result := MergeBGRAWithGammaCorrection(ColorToBGRA(clDarkBtnFace), 1, ColorToBGRA(clDarkEditableFace), 1);
-  end else
+  if ASelected then
+    result := DarkThemeInstance.GetColorHighlightBack(DarkTheme) else
   begin
-    if ASelected then
-      result := ColorToBGRA(clHighlight)
+    if DarkTheme then
+      result := MergeBGRAWithGammaCorrection(
+                  DarkThemeInstance.GetColorButtonFace(true), 1,
+                  DarkThemeInstance.GetColorEditableFace(true), 1)
     else
-      result := ColorToBGRA(clWindow);
+      result := DarkThemeInstance.GetColorEditableFace(DarkTheme);
   end;
 end;
 

+ 27 - 1
lazpaint/dialog/unewimage.pas

@@ -63,17 +63,21 @@ type
     procedure FormShow(Sender: TObject);
     procedure SpinEdit_WidthChange(Sender: TObject);
   private
+    FLazPaintInstance: TLazPaintCustomInstance;
     FLastEnteredValue: TLastEnteredValue;
     FRatio: double;
     FRatioWasChanged: boolean;
     FRecomputing: boolean;
     FBackColor: TBGRAPixel;
+    procedure SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+    procedure ThemeChanged(Sender: TObject);
     procedure UpdatePreview;
     function GetBitDepth: integer;
   public
-    LazPaintInstance: TLazPaintCustomInstance;
     ForIcon: boolean;
     newImageResult: TBGRABitmap;
+    destructor Destroy; override;
+    property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
   end; 
 
 function ShowNewImageDlg(AInstance: TLazPaintCustomInstance; AForIcon: boolean; out tx,ty,bpp: integer; out back: TBGRAPixel):boolean;
@@ -357,11 +361,33 @@ begin
     else ToolBar_Rotate.Color := ColorToBGRA(FBackColor);
 end;
 
+procedure TFNewImage.SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+begin
+  if FLazPaintInstance=AValue then Exit;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  FLazPaintInstance:=AValue;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
+end;
+
+procedure TFNewImage.ThemeChanged(Sender: TObject);
+begin
+  vsPreview.DiscardBitmap;
+end;
+
 function TFNewImage.GetBitDepth: integer;
 begin
   result := StrToInt(ComboBox_BitDepth.Text);
 end;
 
+destructor TFNewImage.Destroy;
+begin
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  inherited Destroy;
+end;
+
 {$R *.lfm}
 
 end.

+ 1 - 1
lazpaint/dialog/uobject3d.lfm

@@ -240,7 +240,7 @@ object FObject3D: TFObject3D
           Top = 28
           Width = 20
           Enabled = False
-          OnMouseDown = Shape_MaterialColorMouseDown
+          OnMouseUp = Shape_MaterialColorMouseUp
         end
         object SpinEdit_SpecularIndex: TSpinEdit
           Left = 90

+ 2 - 2
lazpaint/dialog/uobject3d.pas

@@ -116,7 +116,7 @@ type
     procedure PaintBox_LightPosPaint(Sender: TObject);
     procedure Shape_LightColorMouseUp(Sender: TObject; {%H-}Button: TMouseButton;
       {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
-    procedure Shape_MaterialColorMouseDown(Sender: TObject;
+    procedure Shape_MaterialColorMouseUp(Sender: TObject;
       {%H-}Button: TMouseButton; {%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
     procedure SpinEdit_ColorOpacityChange(Sender: TObject);
     procedure SpinEdit_ColorOpacityKeyPress(Sender: TObject; var Key: char);
@@ -638,7 +638,7 @@ begin
   end;
 end;
 
-procedure TFObject3D.Shape_MaterialColorMouseDown(Sender: TObject;
+procedure TFObject3D.Shape_MaterialColorMouseUp(Sender: TObject;
   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
 begin
   if materialIndex <> -1 then

+ 28 - 2
lazpaint/dialog/uresample.pas

@@ -38,17 +38,21 @@ type
     procedure ToolButton23Click(Sender: TObject);
     procedure vsPreviewRedraw(Sender: TObject; Bitmap: TBGRABitmap);
   private
+    FLazPaintInstance: TLazPaintCustomInstance;
     FIgnoreInput: boolean;
     FLockedAspectRatio: single;
     FParameters: TVariableSet;
     FMUnit: integer;
+    procedure SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+    procedure ThemeChanged(Sender: TObject);
     procedure UpdatePreview;
     procedure ComputeAspectRatio;
     function NewHeight: integer;
     function NewWidth: integer;
   public
-    LazPaintInstance: TLazPaintCustomInstance;
-  end; 
+    destructor Destroy; override;
+    property LazPaintInstance: TLazPaintCustomInstance read FLazPaintInstance write SetLazPaintInstance;
+  end;
 
 function ShowResampleDialog(Instance: TLazPaintCustomInstance; AParameters: TVariableSet):boolean;
 
@@ -187,6 +191,13 @@ begin
   if result <= 1 then result := 1;
 end;
 
+destructor TFResample.Destroy;
+begin
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  inherited Destroy;
+end;
+
 function TFResample.NewHeight: integer;
 begin
   case FMUnit of
@@ -254,6 +265,21 @@ begin
   vsPreview.RedrawBitmap;
 end;
 
+procedure TFResample.SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+begin
+  if FLazPaintInstance=AValue then Exit;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+  FLazPaintInstance:=AValue;
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
+end;
+
+procedure TFResample.ThemeChanged(Sender: TObject);
+begin
+  vsPreview.DiscardBitmap;
+end;
+
 procedure TFResample.ComputeAspectRatio;
 begin
   if (NewWidth >= 1) and (NewHeight >= 1) then

+ 40 - 3
lazpaint/image/uimage.pas

@@ -44,6 +44,7 @@ type
     FOnSelectedLayerIndexChanging: TOnCurrentLayerIndexChanged;
     FOnSelectionMaskChanged: TOnSelectionMaskChanged;
     FOnSelectedLayerIndexChanged: TOnCurrentLayerIndexChanged;
+    FOnSizeChanged: TNotifyEvent;
     FOnStackChanged: TOnStackChanged;
     FOnQueryExitToolHandler: TOnQueryExitToolHandler;
     FCurrentState: TImageState;
@@ -81,6 +82,7 @@ type
     function GetSelectionTransform: TAffineMatrix;
     procedure LayeredActionDone(Sender: TObject);
     procedure LayeredActionProgress({%H-}ASender: TObject; AProgressPercent: integer);
+    procedure LayeredSizeChanged(Sender: TObject);
     procedure NeedSelectionLayerAfterMask;
     function GetBlendOperation(AIndex: integer): TBlendOperation;
     function GetCurrentFilenameUTF8: string;
@@ -122,6 +124,7 @@ type
     procedure CompressUndoIfNecessary;
     procedure NotifyException(AFunctionName: string; AException: Exception);
     procedure SetOnActionProgress(AValue: TLayeredActionProgressEvent);
+    procedure SetOnSizeChanged(AValue: TNotifyEvent);
     procedure SetSelectionTransform(ATransform: TAffineMatrix);
     procedure UpdateIconFileUTF8(AFilename: string; AOutputFilename: string = ''; AExport: boolean = false);
     procedure UpdateTiffFileUTF8(AFilename: string; AOutputFilename: string = ''; AExport: boolean = false);
@@ -222,6 +225,7 @@ type
     procedure VerticalFlip; overload;
     procedure RotateCW;
     procedure RotateCCW;
+    procedure Rotate180;
     procedure Resample(AWidth, AHeight: integer; filter: TResampleFilter);
     function ApplySmartZoom3: boolean;
 
@@ -266,6 +270,7 @@ type
     property OnImageRenderChanged: TNotifyEvent read FOnImageRenderChanged write FOnImageRenderChanged;
     property OnImageSaving: TLazPaintImageObservable read FOnImageSaving;
     property OnImageExport: TLazPaintImageObservable read FOnImageExport;
+    property OnSizeChanged: TNotifyEvent read FOnSizeChanged write SetOnSizeChanged;
     property OnActionProgress: TLayeredActionProgressEvent read FOnActionProgress write SetOnActionProgress;
     property NbLayers: integer read GetNbLayers;
     property Empty: boolean read GetEmpty;
@@ -314,7 +319,7 @@ uses UGraph, UResourceStrings, Dialogs,
     BGRAPalette, BGRAColorQuantization, UFileSystem,
     BGRAThumbnail, BGRAIconCursor, UTiff, LazPaintType,
     BGRALazPaint, BGRAAnimatedGif,
-    BGRAGradientScanner;
+    BGRAGradientScanner, BGRASVGOriginal, Forms;
 
 function ComputeAcceptableImageSize(AWidth, AHeight: integer): TSize;
 var ratio,newRatio: single;
@@ -463,7 +468,8 @@ function TLazPaintImage.AbleToSaveAsUTF8(AFilename: string): boolean;
 var format: TBGRAImageFormat;
 begin
   format := SuggestImageFormat(AFilename);
-  result := (DefaultBGRAImageWriter[format] <> nil) or (format in [ifIco,ifCur]);
+  result := (DefaultBGRAImageWriter[format] <> nil) or
+    (format in [ifIco,ifCur,ifSvg]);
   if result and (format = ifXPixMap) then
   begin
     if (Width > 256) or (Height > 256) then
@@ -490,7 +496,7 @@ var s: TStream;
   format: TBGRAImageFormat;
 begin
   format := SuggestImageFormat(AFilename);
-  if format in[ifOpenRaster,ifPhoxo,ifLazPaint] then
+  if format in[ifOpenRaster,ifPhoxo,ifLazPaint,ifSvg] then
   begin
     s := FileManager.CreateFileStream(AFilename, fmCreate);
     try
@@ -707,6 +713,13 @@ begin
     layeredBmp := TryCreateLayeredBitmapReader(ext);
     if Assigned(layeredBmp) then
     begin
+      if layeredBmp is TBGRALayeredSVG then
+      with TBGRALayeredSVG(layeredBmp) do
+      begin
+        ContainerWidth := Screen.Width;
+        ContainerHeight := Screen.Height;
+        DefaultLayerName:= rsLayer;
+      end;
       layeredBmp.LoadFromStream(s);
       with ComputeAcceptableImageSize(layeredBmp.Width,layeredBmp.Height) do
         if (cx < layeredBmp.Width) or (cy < layeredBmp.Height) then
@@ -916,6 +929,12 @@ begin
   FOnActionProgress:=AValue;
 end;
 
+procedure TLazPaintImage.SetOnSizeChanged(AValue: TNotifyEvent);
+begin
+  if FOnSizeChanged=AValue then Exit;
+  FOnSizeChanged:=AValue;
+end;
+
 procedure TLazPaintImage.SetSelectionTransform(ATransform: TAffineMatrix);
 
   procedure InvalidateTransformedSelection;
@@ -1505,6 +1524,12 @@ begin
     OnActionProgress(self, AProgressPercent);
 end;
 
+procedure TLazPaintImage.LayeredSizeChanged(Sender: TObject);
+begin
+  if Assigned(FOnSizeChanged) then
+    FOnSizeChanged(self);
+end;
+
 procedure TLazPaintImage.NeedSelectionLayerAfterMask;
 var
   bounds,
@@ -2212,6 +2237,17 @@ begin
   SelectionMaskMayChangeCompletely;
 end;
 
+procedure TLazPaintImage.Rotate180;
+begin
+  if not CheckNoAction then exit;
+  try
+    AddUndo(FCurrentState.Rotate180);
+  except on ex: exception do NotifyException('Rotate180',ex);
+  end;
+  ImageMayChangeCompletely;
+  SelectionMaskMayChangeCompletely;
+end;
+
 function TLazPaintImage.CheckCurrentLayerVisible: boolean;
 begin
   result := CurrentLayerVisible;
@@ -2368,6 +2404,7 @@ begin
   FCurrentState.OnOriginalLoadError:=@OriginalLoadError;
   FCurrentState.OnActionProgress:= @LayeredActionProgress;
   FCurrentState.OnActionDone:=@LayeredActionDone;
+  FCurrentState.OnSizeChanged:=@LayeredSizeChanged;
   FRenderUpdateRectInPicCoord := rect(0,0,0,0);
   FRenderUpdateRectInVSCoord := rect(0,0,0,0);
   FOnSelectionMaskChanged := nil;

+ 140 - 75
lazpaint/image/uimageaction.pas

@@ -66,6 +66,7 @@ type
     procedure VerticalFlip(AOption: TFlipOption);
     procedure RotateCW;
     procedure RotateCCW;
+    procedure Rotate180;
     procedure LinearNegativeAll;
     procedure NegativeAll;
     procedure SwapRedBlueAll;
@@ -108,7 +109,7 @@ implementation
 uses Controls, Dialogs, UResourceStrings, UObject3D,
      ULoadImage, UGraph, UClipboard, Types, BGRAGradientOriginal,
      BGRATransform, ULoading, math, LCVectorClipboard, LCVectorOriginal, LCVectorRectShapes,
-     BGRALayers, BGRAUTF8, UFileSystem;
+     BGRALayers, BGRAUTF8, UFileSystem, Forms, UTranslation;
 
 { TImageActions }
 
@@ -151,6 +152,7 @@ begin
   Scripting.RegisterScriptFunction('SelectionVerticalFlip',@GenericScriptFunction,ARegister);
   Scripting.RegisterScriptFunction('ImageRotateCW',@GenericScriptFunction,ARegister);
   Scripting.RegisterScriptFunction('ImageRotateCCW',@GenericScriptFunction,ARegister);
+  Scripting.RegisterScriptFunction('ImageRotate180',@GenericScriptFunction,ARegister);
   Scripting.RegisterScriptFunction('ImageLinearNegative',@GenericScriptFunction,ARegister);
   Scripting.RegisterScriptFunction('ImageNegative',@GenericScriptFunction,ARegister);
   Scripting.RegisterScriptFunction('ImageSwapRedBlue',@GenericScriptFunction,ARegister);
@@ -242,6 +244,7 @@ begin
   if f = 'ImageFlatten' then Flatten else
   if f = 'ImageRotateCW' then RotateCW else
   if f = 'ImageRotateCCW' then RotateCCW else
+  if f = 'ImageRotate180' then Rotate180 else
   if f = 'ImageLinearNegative' then LinearNegativeAll else
   if f = 'ImageNegative' then NegativeAll else
   if f = 'ImageSwapRedBlue' then SwapRedBlueAll else
@@ -377,39 +380,73 @@ function TImageActions.ScriptLayerSaveAs(AVars: TVariableSet): TScriptResult;
 var
   name, ext: String;
   layerCopy: TBGRABitmap;
-  layerIdx: Integer;
+  layerIdx, origIdx: Integer;
   writer: TFPCustomImageWriter;
-  imgFormat: TBGRAImageFormat;
+  imgFormat, imgFormatFromName: TBGRAImageFormat;
+  streamOut: TStream;
+  layeredCopy: TBGRALayeredBitmap;
 begin
   name := AVars.Strings['FileName'];
+  imgFormatFromName := SuggestImageFormat(name);
   if AVars.Strings['Format'] = '' then
-    imgFormat := SuggestImageFormat(name)
+    imgFormat := imgFormatFromName
   else
     imgFormat := SuggestImageFormat(AVars.Strings['Format']);
-  if imgFormat = ifUnknown then imgFormat := ifPng;
   ext := UTF8LowerCase(ExtractFileExt(name));
-  if ext = '.tmp' then
+  if imgFormat = ifUnknown then
   begin
-    layerCopy := TBGRABitmap.Create(Image.Width, Image.Height);
-    writer := CreateBGRAImageWriter(imgFormat, true);
-    try
-      layerIdx := Image.CurrentLayerIndex;
-      layerCopy.PutImage(Image.LayerOffset[layerIdx].x, Image.LayerOffset[layerIdx].y,
-        Image.LayerBitmap[layerIdx], dmSet);
-      layerCopy.SaveToFileUTF8(name, writer);
-      result := srOk;
-      AVars.Strings['Result'] := name;
-    except
-      on ex: Exception do
-      begin
-        FInstance.ShowError(rsSave, ex.Message);
-        result := srException;
+    if ext = '.tmp' then
+      imgFormat := ifPng
+    else
+      exit(srInvalidParameters);
+  end;
+  //wont overwrite a file that is probably not an image
+  if FileManager.FileExists(name) and (imgFormatFromName = ifUnknown) then
+    exit(srInvalidParameters);
+  streamOut := FileManager.CreateFileStream(name, fmCreate);
+  try
+    layerIdx := Image.CurrentLayerIndex;
+    if imgFormatFromName in[ifLazPaint, ifPhoxo, ifSvg, ifOpenRaster] then
+    begin
+      layeredCopy := TBGRALayeredBitmap.Create(Image.Width,Image.Height);
+      try
+        if Image.LayerOriginalDefined[layerIdx] and Image.LayerOriginalKnown[layerIdx] then
+        begin
+          origIdx := layeredCopy.AddOriginal(Image.LayerOriginal[layerIdx], false);
+          layeredCopy.AddLayerFromOriginal(layeredCopy.Original[origIdx].Guid,
+            Image.LayerOriginalMatrix[layerIdx], Image.BlendOperation[layerIdx],
+            Image.LayerOpacity[layerIdx]);
+          layeredCopy.LayerName[0] := Image.LayerName[layerIdx];
+        end;
+        layeredCopy.RenderOriginalsIfNecessary;
+        layeredCopy.SaveToStreamAs(streamOut, SuggestImageExtension(imgFormat));
+      finally
+        layeredCopy.Free;
+      end;
+    end else
+    begin
+      layerCopy := TBGRABitmap.Create(Image.Width, Image.Height);
+      layerCopy.FillTransparent;
+      writer := CreateBGRAImageWriter(imgFormat, true);
+      try
+        layerCopy.PutImage(Image.LayerOffset[layerIdx].x, Image.LayerOffset[layerIdx].y,
+          Image.LayerBitmap[layerIdx], dmSet);
+        layerCopy.SaveToStream(streamOut, writer);
+        result := srOk;
+        AVars.Strings['Result'] := name;
+      except
+        on ex: Exception do
+        begin
+          FInstance.ShowError(rsSave, ex.Message);
+          result := srException;
+        end;
       end;
+      layerCopy.Free;
+      writer.Free;
     end;
-    layerCopy.Free;
-    writer.Free;
-  end else
-    exit(srInvalidParameters);
+  finally
+    streamOut.Free;
+  end;
 end;
 
 function TImageActions.ScriptLayerSelectId(AVars: TVariableSet): TScriptResult;
@@ -1087,16 +1124,58 @@ function TImageActions.TryAddLayerFromFile(AFilenameUTF8: string; ALoadedImage:
   end;
 
 var
-  newPicture: TBGRABitmap;
-  svgOrig: TBGRALayerSVGOriginal;
-  m: TAffineMatrix;
-  ofsF: TPointF;
-  ext: String;
   layeredBmp: TBGRACustomLayeredBitmap;
-  bmpOrig: TBGRALayerImageOriginal;
+
+  procedure ImportLayeredBmp;
+  var
+    m: TAffineMatrix;
+    i: Integer;
+    ofsF: TPointF;
+    bmpOrig: TBGRALayerImageOriginal;
+    doFound, somethingDone: boolean;
+  begin
+    m := ComputeStretchMatrix(layeredBmp.Width, layeredBmp.Height);
+    try
+      Image.DoBegin;
+      for i := 0 to layeredBmp.NbLayers-1 do
+      begin
+        if (layeredBmp.LayerOriginalGuid[i] <> GUID_NULL) and
+           layeredBmp.LayerOriginalKnown[i] then
+        begin
+          if not AddLayerFromOriginal(layeredBmp.LayerOriginal[i].Duplicate,
+            layeredBmp.LayerName[i], m*layeredBmp.LayerOriginalMatrix[i],
+            layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
+        end else
+        begin
+          if IsAffineMatrixTranslation(m) then
+          begin
+            ofsF := m*PointF(layeredBmp.LayerOffset[i].x, layeredBmp.LayerOffset[i].y);
+            if not NewLayer(layeredBmp.GetLayerBitmapCopy(i), layeredBmp.LayerName[i],
+                     Point(round(ofsF.X), round(ofsF.Y)),
+                     layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
+          end else
+          begin
+            bmpOrig := TBGRALayerImageOriginal.Create;
+            bmpOrig.AssignImage(layeredBmp.GetLayerBitmapDirectly(i));
+            if not AddLayerFromOriginal(bmpOrig, layeredBmp.LayerName[i],
+              m * AffineMatrixTranslation(layeredBmp.LayerOffset[i].x, layeredBmp.LayerOffset[i].y),
+              layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
+          end;
+        end;
+        setlength(result, length(result)+1);
+        result[high(result)] := Image.LayerId[image.CurrentLayerIndex];
+      end;
+    finally
+      image.DoEnd(doFound, somethingDone);
+    end;
+  end;
+
+var
+  imgFormat: TBGRAImageFormat;
   s: TStream;
-  i: Integer;
-  doFound, somethingDone: boolean;
+  newPicture: TBGRABitmap;
+  flattened: TBGRABitmap;
+  ext: String;
 
 begin
   result := nil;
@@ -1107,20 +1186,20 @@ begin
     exit;
   end;
   try
-    case Image.DetectImageFormat(AFilenameUTF8) of
-    ifSvg:
-    begin
-      svgOrig := LoadSVGOriginalUTF8(AFilenameUTF8);
-      m := ComputeStretchMatrix(svgOrig.Width, svgOrig.Height);
-      AddLayerFromOriginal(svgOrig, ExtractFileName(AFilenameUTF8), m);
-      setlength(result, 1);
-      result[0] := Image.LayerId[image.CurrentLayerIndex];
-      FreeAndNil(ALoadedImage);
-    end;
-    ifLazPaint, ifOpenRaster, ifPaintDotNet, ifPhoxo:
+    imgFormat := Image.DetectImageFormat(AFilenameUTF8);
+    case imgFormat of
+    ifLazPaint, ifOpenRaster, ifSvg, ifPaintDotNet, ifPhoxo:
     begin
       ext := UTF8LowerCase(ExtractFileExt(AFilenameUTF8));
       layeredBmp := TryCreateLayeredBitmapReader(ext);
+      if layeredBmp is TBGRALayeredSVG then
+      with TBGRALayeredSVG(layeredBmp) do
+      begin
+        ContainerWidth := Image.Width;
+        ContainerHeight := Image.Height;
+        DPI:= Screen.PixelsPerInch;
+        DefaultLayerName:= rsLayer;
+      end;
       try
         s := FileManager.CreateFileStream(AFilenameUTF8, fmOpenRead or fmShareDenyWrite);
         try
@@ -1130,40 +1209,21 @@ begin
           finally
             if Assigned(FInstance) then FInstance.EndLoadingImage;
           end;
-          m := ComputeStretchMatrix(layeredBmp.Width, layeredBmp.Height);
-          try
-            Image.DoBegin;
-            for i := 0 to layeredBmp.NbLayers-1 do
-            begin
-              if (layeredBmp.LayerOriginalGuid[i] <> GUID_NULL) and
-                 layeredBmp.LayerOriginalKnown[i] then
-              begin
-                if not AddLayerFromOriginal(layeredBmp.LayerOriginal[i].Duplicate,
-                  layeredBmp.LayerName[i], m*layeredBmp.LayerOriginalMatrix[i],
-                  layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
-              end else
-              begin
-                if IsAffineMatrixTranslation(m) then
-                begin
-                  ofsF := m*PointF(layeredBmp.LayerOffset[i].x, layeredBmp.LayerOffset[i].y);
-                  if not NewLayer(layeredBmp.GetLayerBitmapCopy(i), layeredBmp.LayerName[i],
-                           Point(round(ofsF.X), round(ofsF.Y)),
-                           layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
-                end else
-                begin
-                  bmpOrig := TBGRALayerImageOriginal.Create;
-                  bmpOrig.AssignImage(layeredBmp.GetLayerBitmapDirectly(i));
-                  if not AddLayerFromOriginal(bmpOrig, layeredBmp.LayerName[i],
-                    m * AffineMatrixTranslation(layeredBmp.LayerOffset[i].x, layeredBmp.LayerOffset[i].y),
-                    layeredBmp.BlendOperation[i], layeredBmp.LayerOpacity[i]) then break;
-                end;
+          if layeredBmp.NbLayers > 1 then
+          begin
+            case QuestionDlg(rsOpen, AppendQuestionMark(rsFlattenImage), mtInformation,
+              [mrYes, rsYes, mrNo, rsNo, mrCancel, rsCancel], 0) of
+            mrYes: begin
+                flattened := layeredBmp.ComputeFlatImage;
+                FreeAndNil(layeredBmp);
+                layeredBmp:= TBGRALayeredBitmap.Create(flattened.Width, flattened.Height);
+                TBGRALayeredBitmap(layeredBmp).AddOwnedLayer(flattened);
+                ImportLayeredBmp;
               end;
-              setlength(result, length(result)+1);
-              result[high(result)] := Image.LayerId[image.CurrentLayerIndex];
+            mrNo: ImportLayeredBmp;
             end;
-          finally
-            image.DoEnd(doFound, somethingDone);
-          end;
+          end else
+            ImportLayeredBmp;
         finally
           s.Free;
         end;
@@ -1340,6 +1400,11 @@ begin
   Image.RotateCCW;
 end;
 
+procedure TImageActions.Rotate180;
+begin
+  Image.Rotate180;
+end;
+
 procedure TImageActions.LinearNegativeAll;
 begin
   Image.LinearNegativeAll;

+ 2 - 0
lazpaint/image/uimagediff.pas

@@ -2272,12 +2272,14 @@ begin
       if imgState.SelectionMask <> nil then newSelectionMask := imgState.SelectionMask.RotateCW as TBGRABitmap else newSelectionMask := nil;
       if imgState.SelectionLayer <> nil then newSelectionLayer := imgState.SelectionLayer.RotateCW as TBGRABitmap else newSelectionLayer := nil;
       imgState.ReplaceSelection(newSelectionMask, newSelectionLayer);
+      if (imgState.Width <> imgState.Height) then imgState.NotifySizeChanged;
     end;
   iaRotateCCW: begin
       imgState.LayeredBitmap.RotateCCW;
       if imgState.SelectionMask <> nil then newSelectionMask := imgState.SelectionMask.RotateCCW as TBGRABitmap else newSelectionMask := nil;
       if imgState.SelectionLayer <> nil then newSelectionLayer := imgState.SelectionLayer.RotateCCW as TBGRABitmap else newSelectionLayer := nil;
       imgState.ReplaceSelection(newSelectionMask, newSelectionLayer);
+      if (imgState.Width <> imgState.Height) then imgState.NotifySizeChanged;
     end;
   end;
 end;

+ 53 - 0
lazpaint/image/uimagestate.pas

@@ -22,6 +22,7 @@ type
     FOnOriginalChange: TEmbeddedOriginalChangeEvent;
     FOnOriginalEditingChange: TEmbeddedOriginalEditingChangeEvent;
     FOnOriginalLoadError: TEmbeddedOriginalLoadErrorEvent;
+    FOnSizeChanged: TNotifyEvent;
     FSelectionMask: TBGRABitmap;
     FLastSelectionMaskBoundsIsDefined,
     FLastSelectionLayerBoundsIsDefined: TBoundsState;
@@ -62,8 +63,11 @@ type
     procedure SetLinearBlend(AValue: boolean);
     procedure SetOnActionDone(AValue: TNotifyEvent);
     procedure SetOnActionProgress(AValue: TLayeredActionProgressEvent);
+    procedure SetOnSizeChanged(AValue: TNotifyEvent);
     procedure SetSelectionMask(AValue: TBGRABitmap);
     function MakeLayerName: string;
+    procedure CheckSizeChanged(APrevSize: TSize);
+    function GetSize: TSize;
   public
     SelectionLayer: TBGRABitmap;
     selectedLayerId: integer;
@@ -80,12 +84,14 @@ type
 
     // whole image
     procedure SetSize(AWidth,AHeight: integer);
+    procedure NotifySizeChanged;
     procedure Assign(AValue: TBGRABitmap; AOwned: boolean);
     procedure Assign(AValue: TBGRACustomLayeredBitmap; AOwned: boolean);
     procedure Assign(AValue: TImageState; AOwned: boolean);
 
     function RotateCW: TCustomImageDifference;
     function RotateCCW: TCustomImageDifference;
+    function Rotate180: TCustomImageDifference;
     function HorizontalFlip: TCustomImageDifference; overload;
     function VerticalFlip: TCustomImageDifference; overload;
     procedure Resample(AWidth,AHeight: integer; AQuality: TResampleMode; AFilter: TResampleFilter);
@@ -186,6 +192,7 @@ type
     property OnOriginalLoadError: TEmbeddedOriginalLoadErrorEvent read FOnOriginalLoadError write FOnOriginalLoadError;
     property OnActionProgress: TLayeredActionProgressEvent read FOnActionProgress write SetOnActionProgress;
     property OnActionDone: TNotifyEvent read FOnActionDone write SetOnActionDone;
+    property OnSizeChanged: TNotifyEvent read FOnSizeChanged write SetOnSizeChanged;
   end;
 
 implementation
@@ -549,6 +556,12 @@ begin
   FOnActionProgress:=AValue;
 end;
 
+procedure TImageState.SetOnSizeChanged(AValue: TNotifyEvent);
+begin
+  if FOnSizeChanged=AValue then Exit;
+  FOnSizeChanged:=AValue;
+end;
+
 procedure TImageState.SetSelectionMask(AValue: TBGRABitmap);
 begin
   If AValue = FSelectionMask then exit;
@@ -580,6 +593,18 @@ begin
   end;
 end;
 
+procedure TImageState.CheckSizeChanged(APrevSize: TSize);
+begin
+  if GetSize <> APrevSize then NotifySizeChanged;
+end;
+
+function TImageState.GetSize: TSize;
+begin
+  if Assigned(FLayeredBitmap) then
+    result := Size(FLayeredBitmap.Width, FLayeredBitmap.Height)
+    else result := Size(0,0);
+end;
+
 procedure TImageState.SetLayerBitmap(layer: integer; ABitmap: TBGRABitmap;
   AOwned: boolean);
 begin
@@ -683,9 +708,20 @@ begin
 end;
 
 procedure TImageState.SetSize(AWidth, AHeight: integer);
+var
+  prevSize: TSize;
 begin
   if LayeredBitmap <> nil then
+  begin
+    prevSize := GetSize;
     LayeredBitmap.SetSize(AWidth,AHeight);
+    CheckSizeChanged(prevSize);
+  end;
+end;
+
+procedure TImageState.NotifySizeChanged;
+begin
+  if Assigned(OnSizeChanged) then OnSizeChanged(self);
 end;
 
 procedure TImageState.PrepareForRendering;
@@ -706,7 +742,10 @@ procedure TImageState.Assign(AValue: TBGRABitmap; AOwned: boolean);
 var
   xorMask: TBGRABitmap;
   idx: Integer;
+  prevSize: TSize;
 begin
+  prevSize := GetSize;
+
   if LayeredBitmap = nil then
     SetLayeredBitmap(TBGRALayeredBitmap.Create);
 
@@ -738,14 +777,20 @@ begin
     end;
   end;
   SelectedImageLayerIndex := 0;
+
+  CheckSizeChanged(prevSize);
 end;
 
 procedure TImageState.Assign(AValue: TBGRACustomLayeredBitmap; AOwned: boolean);
+var
+  prevSize: TSize;
 begin
   if AOwned and (AValue is TBGRALayeredBitmap) then
   begin
+    prevSize := GetSize;
     FreeAndNil(FLayeredBitmap);
     SetLayeredBitmap(TBGRALayeredBitmap(AValue));
+    CheckSizeChanged(prevSize);
   end else
   begin
     LayeredBitmap.Assign(AValue, true, true);
@@ -1182,6 +1227,14 @@ begin
   result := TInversibleStateDifference.Create(self, iaRotateCCW);
 end;
 
+function TImageState.Rotate180: TCustomImageDifference;
+begin
+  if LayeredBitmap = nil then
+    result := nil
+  else
+  result := TInversibleStateDifference.Create(self, iaRotate180);
+end;
+
 function TImageState.ComputeLayerOffsetDifference(AOffsetX, AOffsetY: integer): TCustomImageDifference;
 begin
   result := TApplyLayerOffsetStateDifference.Create(self, LayeredBitmap.LayerUniqueId[SelectedImageLayerIndex], AOffsetX,AOffsetY, false);

+ 119 - 43
lazpaint/lazpaint.lpi

@@ -24,11 +24,11 @@
       <UseVersionInfo Value="True"/>
       <MajorVersionNr Value="7"/>
       <MinorVersionNr Value="1"/>
-      <RevisionNr Value="5"/>
+      <RevisionNr Value="6"/>
       <CharSet Value="04B0"/>
       <StringTable CompanyName="http://sourceforge.net/projects/lazpaint/" FileDescription="LazPaint" InternalName="lazpaint" OriginalFilename="lazpaint.exe" ProductName="LazPaint"/>
     </VersionInfo>
-    <BuildModes Count="8">
+    <BuildModes Count="10">
       <Item1 Name="Debug" Default="True"/>
       <Item2 Name="Release">
         <CompilerOptions>
@@ -40,7 +40,7 @@
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -78,7 +78,7 @@
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -113,12 +113,12 @@
           <Version Value="11"/>
           <PathDelim Value="\"/>
           <Target>
-            <Filename Value="release\bin\lazpaint_x64"/>
+            <Filename Value="release\bin\lazpaint64"/>
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -148,7 +148,48 @@
           </Linking>
         </CompilerOptions>
       </Item4>
-      <Item5 Name="Release macOS">
+      <Item5 Name="Debug macOS">
+        <MacroValues Count="1">
+          <Macro1 Name="LCLWidgetType" Value="cocoa"/>
+        </MacroValues>
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
+            <UnitOutputDirectory Value="debug\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
+          </SearchPaths>
+          <CodeGeneration>
+            <Checks>
+              <RangeChecks Value="True"/>
+              <OverflowChecks Value="True"/>
+              <StackChecks Value="True"/>
+            </Checks>
+            <VerifyObjMethodCallValidity Value="True"/>
+            <TargetCPU Value="x86_64"/>
+            <TargetOS Value="darwin"/>
+            <Optimizations>
+              <OptimizationLevel Value="0"/>
+            </Optimizations>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <DebugInfoType Value="dsDwarf2Set"/>
+              <UseHeaptrc Value="True"/>
+            </Debugging>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+          <Other>
+            <CustomOptions Value="-dDEBUG"/>
+          </Other>
+        </CompilerOptions>
+      </Item5>
+      <Item6 Name="Release macOS">
         <MacroValues Count="1">
           <Macro1 Name="LCLWidgetType" Value="cocoa"/>
         </MacroValues>
@@ -161,7 +202,7 @@
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -179,6 +220,7 @@
           <Linking>
             <Debugging>
               <GenerateDebugInfo Value="False"/>
+              <DebugInfoType Value="dsDwarf2Set"/>
               <UseLineInfoUnit Value="False"/>
               <StripSymbols Value="True"/>
             </Debugging>
@@ -190,58 +232,58 @@
             </Options>
           </Linking>
         </CompilerOptions>
-      </Item5>
-      <Item6 Name="Debug macOS">
-        <MacroValues Count="1">
-          <Macro1 Name="LCLWidgetType" Value="cocoa"/>
-        </MacroValues>
+      </Item6>
+      <Item7 Name="Release Linux32">
         <CompilerOptions>
           <Version Value="11"/>
           <PathDelim Value="\"/>
+          <Target>
+            <Filename Value="release\bin\lazpaint32"/>
+          </Target>
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="debug\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
+          <Parsing>
+            <SyntaxOptions>
+              <UseAnsiStrings Value="False"/>
+            </SyntaxOptions>
+          </Parsing>
           <CodeGeneration>
-            <Checks>
-              <RangeChecks Value="True"/>
-              <OverflowChecks Value="True"/>
-              <StackChecks Value="True"/>
-            </Checks>
-            <VerifyObjMethodCallValidity Value="True"/>
-            <TargetCPU Value="x86_64"/>
-            <TargetOS Value="darwin"/>
+            <TargetCPU Value="i386"/>
+            <TargetOS Value="linux"/>
             <Optimizations>
-              <OptimizationLevel Value="0"/>
+              <OptimizationLevel Value="3"/>
+              <VariablesInRegisters Value="True"/>
             </Optimizations>
           </CodeGeneration>
           <Linking>
             <Debugging>
-              <UseHeaptrc Value="True"/>
+              <GenerateDebugInfo Value="False"/>
+              <UseLineInfoUnit Value="False"/>
+              <StripSymbols Value="True"/>
             </Debugging>
+            <LinkSmart Value="True"/>
             <Options>
               <Win32>
                 <GraphicApplication Value="True"/>
               </Win32>
             </Options>
           </Linking>
-          <Other>
-            <CustomOptions Value="-dDEBUG"/>
-          </Other>
         </CompilerOptions>
-      </Item6>
-      <Item7 Name="Release Linux32">
+      </Item7>
+      <Item8 Name="Release Linux64">
         <CompilerOptions>
           <Version Value="11"/>
           <PathDelim Value="\"/>
           <Target>
-            <Filename Value="release\bin\lazpaint"/>
+            <Filename Value="release\bin\lazpaint64"/>
           </Target>
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -249,7 +291,7 @@
             </SyntaxOptions>
           </Parsing>
           <CodeGeneration>
-            <TargetCPU Value="i386"/>
+            <TargetCPU Value="x86_64"/>
             <TargetOS Value="linux"/>
             <Optimizations>
               <OptimizationLevel Value="3"/>
@@ -270,8 +312,43 @@
             </Options>
           </Linking>
         </CompilerOptions>
-      </Item7>
-      <Item8 Name="Release Linux64">
+      </Item8>
+      <Item9 Name="DebugQt5">
+        <MacroValues Count="1">
+          <Macro2 Name="LCLWidgetType" Value="qt5"/>
+        </MacroValues>
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
+            <UnitOutputDirectory Value="debug\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
+          </SearchPaths>
+          <CodeGeneration>
+            <Optimizations>
+              <OptimizationLevel Value="0"/>
+            </Optimizations>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <UseHeaptrc Value="True"/>
+            </Debugging>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+          <Other>
+            <CustomOptions Value="-dDEBUG"/>
+          </Other>
+        </CompilerOptions>
+      </Item9>
+      <Item10 Name="ReleaseQt5">
+        <MacroValues Count="1">
+          <Macro2 Name="LCLWidgetType" Value="qt5"/>
+        </MacroValues>
         <CompilerOptions>
           <Version Value="11"/>
           <PathDelim Value="\"/>
@@ -281,7 +358,7 @@
           <SearchPaths>
             <IncludeFiles Value="$(ProjOutDir)"/>
             <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)"/>
+            <UnitOutputDirectory Value="release\lib\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
           </SearchPaths>
           <Parsing>
             <SyntaxOptions>
@@ -289,8 +366,6 @@
             </SyntaxOptions>
           </Parsing>
           <CodeGeneration>
-            <TargetCPU Value="x86_64"/>
-            <TargetOS Value="linux"/>
             <Optimizations>
               <OptimizationLevel Value="3"/>
               <VariablesInRegisters Value="True"/>
@@ -310,9 +385,10 @@
             </Options>
           </Linking>
         </CompilerOptions>
-      </Item8>
-      <SharedMatrixOptions Count="1">
-        <Item1 ID="061641364023" Modes="Debug macOS,Release macOS" Type="IDEMacro" MacroName="LCLWidgetType" Value="cocoa"/>
+      </Item10>
+      <SharedMatrixOptions Count="2">
+        <Item1 ID="061641364023" Modes="Release macOS,Debug macOS" Type="IDEMacro" MacroName="LCLWidgetType" Value="cocoa"/>
+        <Item2 ID="477649945430" Modes="ReleaseQt5,DebugQt5" Type="IDEMacro" MacroName="LCLWidgetType" Value="qt5"/>
       </SharedMatrixOptions>
     </BuildModes>
     <PublishOptions>
@@ -334,11 +410,11 @@
     <RequiredPackages Count="5">
       <Item1>
         <PackageName Value="BGRABitmapPack"/>
-        <MinVersion Major="11" Minor="2" Release="5" Valid="True"/>
+        <MinVersion Major="11" Minor="3" Release="1" Valid="True"/>
       </Item1>
       <Item2>
         <PackageName Value="bgracontrols"/>
-        <MinVersion Major="7" Minor="0" Valid="True"/>
+        <MinVersion Major="7" Minor="1" Valid="True"/>
       </Item2>
       <Item3>
         <PackageName Value="lazpaintcontrols"/>
@@ -981,7 +1057,7 @@
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir)"/>
       <OtherUnitFiles Value="tablet;tools;dialog;dialog\color;dialog\filter;image"/>
-      <UnitOutputDirectory Value="debug\$(TargetCPU)-$(TargetOS)"/>
+      <UnitOutputDirectory Value="debug\$(TargetCPU)-$(TargetOS)-$(LCLWidgetType)-$(FPCVer).nosync"/>
     </SearchPaths>
     <CodeGeneration>
       <Optimizations>

+ 9 - 2
lazpaint/lazpaintdialogs.inc

@@ -54,7 +54,8 @@ var
   vW,vH,vBack: TScriptVariableReference;
   w,h: NativeInt;
   back: TBGRAPixel;
-  whDefined: boolean;
+  whDefined, dlgSuccess: boolean;
+  topMostInfo: TTopMostInfo;
 begin
   if ToolManager.ToolSleeping then
   begin
@@ -104,7 +105,13 @@ begin
     bitmapRepl := MakeNewBitmapReplacement(w,h,back)
   else
   begin
-    if not ShowNewImageDlg(bitmapRepl) then
+    topMostInfo := HideTopmost;
+    try
+      dlgSuccess := ShowNewImageDlg(bitmapRepl);
+    finally
+      ShowTopmost(topMostInfo);
+    end;
+    if not dlgSuccess then
     begin
       result := srCancelledByUser;
       exit;

+ 1 - 1
lazpaint/lazpaintembeddedpack.lpk

@@ -26,7 +26,7 @@
         </Debugging>
       </Linking>
     </CompilerOptions>
-    <Version Major="7" Minor="1" Release="5"/>
+    <Version Major="7" Minor="1" Release="6"/>
     <Files Count="94">
       <Item1>
         <Filename Value="lazpaintinstance.pas"/>

+ 132 - 25
lazpaint/lazpaintinstance.pas

@@ -6,8 +6,8 @@ unit LazpaintInstance;
 interface
 
 uses
-  Classes, SysUtils, LazPaintType, BGRABitmap, BGRABitmapTypes, BGRALayers,
-  Menus, Controls, fgl,
+  Classes, SysUtils, LazPaintType, BGRABitmap, BGRABitmapTypes, BGRALayers, LCVectorialFill,
+  Menus, Forms, Controls, fgl,
 
   LazPaintMainForm, UMainFormLayout,
 
@@ -24,12 +24,16 @@ const
 type
   TImageListList = specialize TFPGObjectList<TImageList>;
 
+  TListeners = specialize TFPGList<TNotifyEvent>;
+
   { TLazPaintInstance }
 
   TLazPaintInstance = class(TLazPaintCustomInstance)
   private
     FScriptName: String;
+    FThemeListeners: TListeners;
 
+    procedure ChooseColorHide(Sender: TObject);
     function GetFormAdjustCurves: TFAdjustCurves;
     function GetFormCanvasSize: TFCanvasSize;
     function GetFormColorIntensity: TFColorIntensity;
@@ -38,6 +42,7 @@ type
     function GetFormShiftColors: TFShiftColors;
     function GetInitialized: boolean;
     function GetMainFormVisible: boolean;
+    procedure LayerStackHide(Sender: TObject);
     procedure OnImageActionProgress({%H-}ASender: TObject; AProgressPercent: integer);
     procedure OnLayeredBitmapLoadStartHandler(AFilenameUTF8: string);
     procedure OnLayeredBitmapLoadProgressHandler(APercentage: integer);
@@ -45,6 +50,7 @@ type
     procedure OnLayeredBitmapSavedHandler();
     procedure OnLayeredBitmapSaveProgressHandler(APercentage: integer);
     procedure OnLayeredBitmapSaveStartHandler(AFilenameUTF8: string);
+    procedure OnSizeChanged(Sender: TObject);
     procedure RegisterScripts(ARegister: Boolean);
     function ScriptColorColorize(AVars: TVariableSet): TScriptResult;
     function ScriptColorCurves(AVars: TVariableSet): TScriptResult;
@@ -69,6 +75,7 @@ type
     procedure PythonBusy({%H-}Sender: TObject);
     function ScriptShowMessage(AVars: TVariableSet): TScriptResult;
     function ScriptInputBox(AVars: TVariableSet): TScriptResult;
+    procedure ToolQueryColorTarget(sender: TToolManager; ATarget: TVectorialFill);
 
   protected
     InColorFromFChooseColor: boolean;
@@ -118,6 +125,7 @@ type
     procedure SetToolBoxWindowPopup(AValue: TPopupMenu); override;
     function GetFullscreen: boolean; override;
     procedure SetFullscreen(AValue: boolean); override;
+    function GetToolWindowVisible(AWindow: TForm; ADockedVisible: boolean = false): boolean;
     function GetDockLayersAndColors: boolean; override;
     procedure SetDockLayersAndColors(AValue: boolean); override;
     function GetScriptContext: TScriptContext; override;
@@ -172,7 +180,6 @@ type
     function GetMainFormBounds: TRect; override;
     procedure EditSelectionHandler(var AImage: TBGRABitmap);
     function GetZoomFactor: single; override;
-    procedure ApplyTheme(ADarkTheme: boolean); override;
     procedure UpdateLayerControlVisibility;
     procedure UpdateChooseColorControlVisibility;
     property FormCanvasSize: TFCanvasSize read GetFormCanvasSize;
@@ -185,6 +192,8 @@ type
   public
     constructor Create; override;
     constructor Create(AEmbedded: boolean); override;
+    procedure RegisterThemeListener(AHandler: TNotifyEvent; ARegister: boolean); override;
+    procedure NotifyThemeChanged; override;
     procedure StartLoadingImage(AFilename: string); override;
     procedure EndLoadingImage; override;
     procedure StartSavingImage(AFilename: string); override;
@@ -202,7 +211,7 @@ type
     function ProcessCommands(commands: TStringList): boolean; override;
     procedure ChangeIconSize(size: integer); override;
     procedure Show; override;
-    procedure Hide; override;
+    function Hide: boolean; override;
     procedure Run; override;
     procedure Restart; override;
     procedure CancelRestart; override;
@@ -217,6 +226,7 @@ type
     procedure ColorFromFChooseColor; override;
     procedure ColorToFChooseColor; override;
     procedure ExitColorEditor; override;
+    function ColorEditorActive: boolean; override;
     function ShowSaveOptionDlg({%H-}AParameters: TVariableSet; AOutputFilenameUTF8: string;
       ASkipOptions: boolean; AExport: boolean): boolean; override;
     function ShowColorIntensityDlg(AParameters: TVariableSet): TScriptResult; override;
@@ -270,7 +280,7 @@ type
 
 implementation
 
-uses LCLType, Types, Forms, Dialogs, FileUtil, StdCtrls, LCLIntf, BGRAUTF8, UTranslation,
+uses LCLType, Types, Dialogs, FileUtil, StdCtrls, LCLIntf, BGRAUTF8, UTranslation,
 
      URadialBlur, UMotionBlur, UEmboss, UTwirl, UWaveDisplacement,
      unewimage, uresample, UPixelate, unoisefilter, ufilters,
@@ -293,6 +303,27 @@ begin
   Init(AEmbedded);
 end;
 
+procedure TLazPaintInstance.RegisterThemeListener(AHandler: TNotifyEvent;
+  ARegister: boolean);
+begin
+  if ARegister then
+  begin
+    if FThemeListeners.IndexOf(AHandler) = -1 then
+      FThemeListeners.Add(AHandler);
+  end else
+  begin
+    FThemeListeners.Remove(AHandler);
+  end;
+end;
+
+procedure TLazPaintInstance.NotifyThemeChanged;
+var
+  i: Integer;
+begin
+  for i := 0 to FThemeListeners.Count-1 do
+    FThemeListeners[i](self);
+end;
+
 procedure TLazPaintInstance.StartLoadingImage(AFilename: string);
 begin
   FLoadingFilename:= AFilename;
@@ -431,6 +462,7 @@ end;
 procedure TLazPaintInstance.Init(AEmbedded: boolean);
 begin
   Title := 'LazPaint ' + LazPaintCurrentVersion;
+  FThemeListeners := TListeners.Create;
   FCustomImageList := TImageListList.Create;
   FTopMostInfo.choosecolorHidden := 0;
   FTopMostInfo.layerstackHidden := 0;
@@ -449,10 +481,12 @@ begin
   FImage.OnStackChanged:= @OnStackChanged;
   FImage.OnException := @OnFunctionException;
   FImage.OnActionProgress:=@OnImageActionProgress;
+  FImage.OnSizeChanged:=@OnSizeChanged;
   FToolManager := TToolManager.Create(FImage, self, nil, BlackAndWhite, FScriptContext);
   UseConfig(TIniFile.Create(''));
   FToolManager.OnPopup := @OnToolPopup;
   FToolManager.OnFillChanged:= @ToolFillChanged;
+  FToolManager.OnQueryColorTarget:=@ToolQueryColorTarget;
   FSelectionEditConfig := nil;
   FTextureEditConfig := nil;
   FImageAction := TImageActions.Create(self);
@@ -475,6 +509,7 @@ begin
   Application.CreateForm(TFChooseColor, FChooseColor);
   FChooseColor.LazPaintInstance := self;
   FChooseColor.DarkTheme:= Config.GetDarkTheme;
+  FChooseColor.OnHide:=@ChooseColorHide;
 
   FInFormsNeeded := false;
 end;
@@ -525,6 +560,7 @@ begin
   if Assigned(FLayerStack) then exit;
   TFLayerStack_CustomDPI := (Config.DefaultIconSize(DoScaleX(16,OriginalDPI))*96+8) div 16;
   Application.CreateForm(TFLayerStack,FLayerStack);
+  FLayerStack.OnHide:=@LayerStackHide;
   FLayerStack.LazPaintInstance := self;
   FLayerStack.DarkTheme:= Config.GetDarkTheme;
   defaultZoom := Config.DefaultLayerStackZoom;
@@ -543,6 +579,11 @@ begin
   FLayerStack.AddButton(FMain.LayerHorizontalFlip);
   FLayerStack.AddButton(FMain.LayerVerticalFlip);
   FLayerStack.AddButton(FMain.ToolLayerMapping);
+
+  FLayerStack.AddLayerMenu(FMain.LayerDuplicate);
+  FLayerStack.AddLayerMenu(FMain.LayerRemoveCurrent);
+  FLayerStack.AddLayerMenu(FMain.LayerRasterize);
+  FLayerStack.AddLayerMenu(FMain.LayerExport);
 end;
 
 procedure TLazPaintInstance.CreateToolBox;
@@ -699,6 +740,12 @@ begin
     result := false;
 end;
 
+procedure TLazPaintInstance.LayerStackHide(Sender: TObject);
+begin
+  if not DockLayersAndColors then
+    FLayerControlVisible:= false;
+end;
+
 procedure TLazPaintInstance.OnImageActionProgress(ASender: TObject;
   AProgressPercent: integer);
 begin
@@ -727,6 +774,12 @@ begin
   result := FFormAdjustCurves;
 end;
 
+procedure TLazPaintInstance.ChooseColorHide(Sender: TObject);
+begin
+  if not DockLayersAndColors then
+    FChooseColorControlVisible:= false;
+end;
+
 function TLazPaintInstance.GetFormColorIntensity: TFColorIntensity;
 begin
   if FFormColorIntensity = nil then
@@ -836,6 +889,29 @@ begin
     result := srCancelledByUser;
 end;
 
+procedure TLazPaintInstance.ToolQueryColorTarget(sender: TToolManager;
+  ATarget: TVectorialFill);
+begin
+  if ATarget = ToolManager.ForeFill then
+  begin
+    if ToolManager.ForeFill.FillType = vftGradient then
+      ChooseColorTarget := ctForeColorStartGrad
+      else ChooseColorTarget := ctForeColorSolid;
+  end else
+  if ATarget = ToolManager.BackFill then
+  begin
+    if ToolManager.BackFill.FillType = vftGradient then
+      ChooseColorTarget := ctBackColorStartGrad
+      else ChooseColorTarget := ctBackColorSolid;
+  end else
+  if ATarget = ToolManager.OutlineFill then
+  begin
+    if ToolManager.OutlineFill.FillType = vftGradient then
+      ChooseColorTarget := ctOutlineColorStartGrad
+      else ChooseColorTarget := ctOutlineColorSolid;
+  end;
+end;
+
 procedure TLazPaintInstance.OnLayeredBitmapLoadStartHandler(AFilenameUTF8: string);
 begin
   if FLoadingLayers = nil then FLoadingLayers := TFLoading.Create(nil);
@@ -921,6 +997,11 @@ begin
   end;
 end;
 
+procedure TLazPaintInstance.OnSizeChanged(Sender: TObject);
+begin
+  if FMain <> nil then FMain.Layout.InvalidatePicture(true);
+end;
+
 procedure TLazPaintInstance.PythonBusy(Sender: TObject);
 begin
   Application.ProcessMessages;
@@ -944,7 +1025,7 @@ end;
 
 function TLazPaintInstance.GetLayerWindowVisible: boolean;
 begin
-  result := FLayerControlVisible;
+  result := GetToolWindowVisible(FLayerStack, FLayerControlVisible);
 end;
 
 procedure TLazPaintInstance.SetLayerWindowVisible(AValue: boolean);
@@ -994,14 +1075,6 @@ begin
       result := inherited GetZoomFactor;
 end;
 
-procedure TLazPaintInstance.ApplyTheme(ADarkTheme: boolean);
-begin
-  if Assigned(FChooseColor) then FChooseColor.DarkTheme := ADarkTheme;
-  if Assigned(FLayerStack) then FLayerStack.DarkTheme := ADarkTheme;
-  if Assigned(FMain) then FMain.DarkTheme := ADarkTheme;
-  if Assigned(FFormToolbox) then FFormToolbox.DarkTheme:= ADarkTheme;
-end;
-
 procedure TLazPaintInstance.UpdateLayerControlVisibility;
 begin
   if FLayerStack <> nil then
@@ -1009,7 +1082,11 @@ begin
     if DockLayersAndColors then
       FLayerStack.Visible := false
     else
-      FLayerStack.Visible := FLayerControlVisible;
+    begin
+      if FLayerStack.Visible and FLayerControlVisible then
+        FLayerStack.BringToFront
+        else FLayerStack.Visible := FLayerControlVisible;
+    end;
   end;
   if FMain <> nil then
   begin
@@ -1037,7 +1114,11 @@ begin
     if DockLayersAndColors then
       FChooseColor.Visible := false
     else
-      FChooseColor.Visible := FChooseColorControlVisible;
+    begin
+      if FChooseColor.Visible and FChooseColorControlVisible then
+        FChooseColor.BringToFront
+        else FChooseColor.Visible := FChooseColorControlVisible;
+    end;
   end;
   if FMain <> nil then
   begin
@@ -1071,21 +1152,18 @@ end;
 
 function TLazPaintInstance.GetChooseColorVisible: boolean;
 begin
-  result := FChooseColorControlVisible;
+  result := GetToolWindowVisible(FChooseColor, FChooseColorControlVisible);
 end;
 
 function TLazPaintInstance.GetToolboxVisible: boolean;
 begin
-  Result:= ((FFormToolbox <> nil) and FFormToolbox.Visible) or
+  Result:= GetToolWindowVisible(FFormToolbox) or
            ((FMain <> nil) and not (FMain.Layout.ToolBoxDocking in [twNone,twWindow]));
 end;
 
 function TLazPaintInstance.GetImageListWindowVisible: boolean;
 begin
-  if FImageList <> nil then
-    Result:= FImageList.Visible
-  else
-    Result := false;
+  result := GetToolWindowVisible(FImageList);
 end;
 
 procedure TLazPaintInstance.SetChooseColorVisible(const AValue: boolean);
@@ -1373,6 +1451,17 @@ begin
   end;
 end;
 
+function TLazPaintInstance.GetToolWindowVisible(AWindow: TForm; ADockedVisible: boolean = false): boolean;
+begin
+  if Assigned(AWindow) and AWindow.Visible then
+  begin
+    result := not ((AWindow.FormStyle <> fsStayOnTop) and (AWindow.BorderStyle <> bsDialog) and
+                   Assigned(FMain) and FMain.Active and
+                   FMain.BoundsRect.Contains(AWindow.BoundsRect));
+  end else
+    result := ADockedVisible;
+end;
+
 function TLazPaintInstance.GetDockLayersAndColors: boolean;
 begin
   result := FDockLayersAndColors;
@@ -1446,9 +1535,14 @@ begin
   FMain.Show;
 end;
 
-procedure TLazPaintInstance.Hide;
+function TLazPaintInstance.Hide: boolean;
 begin
-  if MainFormVisible then FMain.Hide;
+  if MainFormVisible then
+  begin
+    FMain.Hide;
+    result := true;
+  end
+  else result := false;
 end;
 
 procedure TLazPaintInstance.Run;
@@ -1529,6 +1623,7 @@ begin
   FreeAndNil(FScriptContext);
   FreeAndNil(FImageList);
   FreeAndNil(FCustomImageList);
+  FreeAndNil(FThemeListeners);
   inherited Destroy;
 end;
 
@@ -1536,6 +1631,7 @@ function TLazPaintInstance.HideTopmost: TTopMostInfo;
 begin
   result.defined:= false;
   if FDestroying then exit;
+  ExitColorEditor;
 
   if (FFormToolbox <> nil) and FFormToolbox.Visible then
   begin
@@ -1788,6 +1884,13 @@ begin
   if Assigned(FChooseColor) then FChooseColor.HideEditor;
 end;
 
+function TLazPaintInstance.ColorEditorActive: boolean;
+begin
+  if Assigned(FChooseColor) then
+    result := FChooseColor.EditorVisible
+    else result := false;
+end;
+
 function TLazPaintInstance.ShowSaveOptionDlg(AParameters: TVariableSet;
   AOutputFilenameUTF8: string; ASkipOptions: boolean; AExport: boolean): boolean;
 begin
@@ -1923,6 +2026,8 @@ begin
     result := true;
   if (FLayerStack <> nil) and FLayerStack.Visible and FLayerStack.Active then
     result := true;
+  if (FImageList <> nil) and FImageList.Visible and FImageList.Active then
+    result := true;
 end;
 
 function TLazPaintInstance.GetTopMostVisible: boolean;
@@ -1934,7 +2039,9 @@ begin
   end;
   FormsNeeded;
   result := (Assigned(FFormToolbox) and FFormToolbox.Visible) or
-            FChooseColor.Visible or FLayerStack.Visible;
+            (Assigned(FChooseColor) and FChooseColor.Visible) or
+            (Assigned(FLayerStack) and FLayerStack.Visible) or
+            (Assigned(FImageList) and FImageList.Visible);
 end;
 
 function TLazPaintInstance.GetTopMostOkToUnfocus: boolean;

Різницю між файлами не показано, бо вона завелика
+ 432 - 620
lazpaint/lazpaintmainform.lfm


+ 177 - 57
lazpaint/lazpaintmainform.pas

@@ -23,8 +23,10 @@ type
   { TFMain }
 
   TFMain = class(TForm)
+    LayerExport: TAction;
     FileExport: TAction;
     ExportPictureDialog: TSaveDialog;
+    Label_Donate: TLabel;
     MenuScript: TMenuItem;
     Panel_OutlineFill: TPanel;
     Panel_Donate: TPanel;
@@ -246,6 +248,7 @@ type
     RenderClouds: TAction;
     ImageRotateCCW: TAction;
     ImageRotateCW: TAction;
+    ImageRotate180: TAction;
     ImageChangeCanvasSize: TAction;
     ImageFillBackground: TAction;
     ImageClearAlpha: TAction;
@@ -479,6 +482,7 @@ type
     procedure ItemDockLayersAndColorsClick(Sender: TObject);
     procedure ItemFullscreenClick(Sender: TObject);
     procedure ItemViewDockToolboxClick(Sender: TObject);
+    procedure LayerExportExecute(Sender: TObject);
     procedure LayerRasterizeUpdate(Sender: TObject);
     procedure LayerZoomExecute(Sender: TObject);
     procedure LayerZoomUpdate(Sender: TObject);
@@ -668,6 +672,7 @@ type
     procedure PictureOnPaint(Sender: TObject);
     procedure PictureToolbarUpdate(Sender: TObject);
     function ScriptShowColorDialog(AVars: TVariableSet): TScriptResult;
+    procedure ThemeChanged(Sender: TObject);
     procedure VectorialFill_Change(Sender: TObject);
     procedure vectorialFill_ClickLabel(Sender: TObject);
     procedure VectorialFill_TypeChange(Sender: TObject);
@@ -714,6 +719,8 @@ type
     FCoordinatesCaptionCount: NativeInt;
     FToolbarElementsInitDone: boolean;
     FPenPlusMinus: integer;
+    FLastDonateClick: TDateTime;
+    FInHideFill: boolean;
 
     function GetDarkTheme: boolean;
     function GetImageAction: TImageActions;
@@ -780,7 +787,7 @@ type
     procedure HideFill(ATimeMs: Integer = 300; AClearTime: boolean = false);
     procedure OnImageChangedHandler({%H-}AEvent: TLazPaintImageObservationEvent);
     procedure OnImageRenderChanged({%H-}Sender: TObject);
-    procedure LabelAutosize(ALabel: TLabel);
+    procedure LabelAutosize(ALabel: TLabel; ATargetDPI: integer);
     procedure AskMergeSelection(ACaption: string);
     procedure UpdateSpecialKeys({%H-}Shift: TShiftState);
     procedure UpdateCurveModeToolbar;
@@ -880,8 +887,9 @@ begin
   FLayout.OnToolbarUpdate:=@PictureToolbarUpdate;
   FLayout.OnPictureMouseMove:=@PictureMouseMove;
   FLayout.OnPictureMouseBefore:=@PictureMouseBefore;
+  FInHideFill := false;
 
-  ScaleControl(Self,OriginalDPI);
+  //ScaleControl(Self,OriginalDPI);
   self.Color := clBtnFace; //toolbar color inherited on mac
 
   //mac interface
@@ -938,6 +946,9 @@ end;
 
 procedure TFMain.FormDestroy(Sender: TObject);
 begin
+  if Assigned(FLazPaintInstance) then
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
+
   if Assigned(Image) then
   begin
     Image.OnSelectionChanged := nil;
@@ -999,6 +1010,7 @@ begin
     FLazPaintInstance := AValue;
     FLayout.LazPaintInstance := AValue;
     Init;
+    FLazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
   end;
 end;
 
@@ -1110,6 +1122,8 @@ procedure TFMain.FormShow(Sender: TObject);
 var
   m: TMainFormMenu;
   startFillControlWidth: LongInt;
+  iconSize: Integer;
+  toolbarDPI: integer;
 begin
   if FLayout.Menu = nil then
   begin
@@ -1123,7 +1137,30 @@ begin
       Panel_CloseShape,Panel_LineCap,Panel_Aliasing,
       Panel_SplineStyle,Panel_Eraser,Panel_Tolerance,Panel_Text,Panel_Altitude,Panel_TextShadow,Panel_TextOutline,
       Panel_OutlineFill,Panel_PhongShape,Panel_PerspectiveOption,Panel_Brush,Panel_Ratio,Panel_Donate],Panel_ToolbarBackground);
-    m.ImageList := LazPaintInstance.Icons[ScaleY(16, 96)];
+    iconSize := round(Config.DefaultIconSize(ScaleY(16, 96)) * 16 / 20);
+    if iconSize < 16 then iconSize := 16;
+    toolbarDPI := round(96*iconSize/16);
+    m.ScaleToolbars(toolbarDPI);
+    ScaleControl(Panel_PenWidthPreview, OriginalDPI, toolbarDPI, toolbarDPI);
+    LabelAutosize(Label_Pen, toolbarDPI);
+    LabelAutosize(Label_Back, toolbarDPI);
+    LabelAutosize(Label_PenWidth, toolbarDPI);
+    LabelAutosize(Label_Eraser, toolbarDPI);
+    LabelAutosize(Label_Tolerance, toolbarDPI);
+    LabelAutosize(Label_Grid, toolbarDPI);
+    LabelAutosize(Label_Curve, toolbarDPI);
+    LabelAutosize(Label_Text, toolbarDPI);
+    LabelAutosize(Label_TextBlur, toolbarDPI);
+    LabelAutosize(Label_ShadowOffset, toolbarDPI);
+    LabelAutosize(Label_Shape, toolbarDPI);
+    LabelAutosize(Label_PhongBorder, toolbarDPI);
+    LabelAutosize(Label_Altitude, toolbarDPI);
+    LabelAutosize(Label_OutlineWidth, toolbarDPI);
+    LabelAutosize(Label_Brush, toolbarDPI);
+    LabelAutosize(Label_Spacing, toolbarDPI);
+    LabelAutosize(Label_Ratio, toolbarDPI);
+    LabelAutosize(Label_Donate, toolbarDPI);
+    m.ImageList := LazPaintInstance.Icons[iconSize];
     m.Apply;
     FLayout.Menu := m;
 
@@ -1357,6 +1394,7 @@ var
       LazPaintInstance.ShowError(dialogTitle, rsFileExtensionNotSupported);
       result := srException;
     end else
+    if not Image.CheckNoAction then result := srException else
     begin
       try
         saved := false;
@@ -1529,6 +1567,7 @@ begin
     begin
       AskMergeSelection(rsSave);
       try
+        if not Image.CheckNoAction then result := srException else
         if SuggestImageFormat(Image.currentFilenameUTF8) in [ifIco,ifCur,ifTiff,ifGif] then
         begin
            LazPaintInstance.StartSavingImage(Image.currentFilenameUTF8);
@@ -1670,6 +1709,7 @@ procedure TFMain.FilterAnyExecute(Sender: TObject);
 var filterName: string;
     params: TVariableSet;
 begin
+  if Assigned(LazPaintInstance) then LazPaintInstance.ExitColorEditor;
   if Sender is TAction then
   begin
     filterName := (Sender as TAction).Name;
@@ -1740,6 +1780,7 @@ procedure TFMain.RenderAnyExecute(Sender: TObject);
 var filterName: string;
     params: TVariableSet;
 begin
+  if Assigned(LazPaintInstance) then LazPaintInstance.ExitColorEditor;
   if Sender is TAction then
   begin
     filterName := (Sender as TAction).Name;
@@ -1877,24 +1918,19 @@ begin
         FBrowseSelections.AllowMultiSelect := false;
         FBrowseSelections.Caption := LoadSelectionDialog.Title;
       end;
-      self.Hide;
-      try
-        FBrowseSelections.FilterIndex:= LoadSelectionDialog.FilterIndex;
-        if FBrowseSelections.ShowModal = mrOK then
-        begin
-          LoadSelectionDialog.FilterIndex := FBrowseSelections.FilterIndex;
-          LazPaintInstance.ShowTopmost(topmost);
-          selectionFileName := FBrowseSelections.Filename;
-          loadedImage := FBrowseSelections.GetChosenImage;
-          Config.AddRecentDirectory(ExtractFilePath(selectionFileName));
-        end else
-        begin
-          result := srCancelledByUser;
-          LazPaintInstance.ShowTopmost(topmost);
-          exit;
-        end;
-      finally
-        self.Show;
+      FBrowseSelections.FilterIndex:= LoadSelectionDialog.FilterIndex;
+      if FBrowseSelections.ShowModal = mrOK then
+      begin
+        LoadSelectionDialog.FilterIndex := FBrowseSelections.FilterIndex;
+        LazPaintInstance.ShowTopmost(topmost);
+        selectionFileName := FBrowseSelections.Filename;
+        loadedImage := FBrowseSelections.GetChosenImage;
+        Config.AddRecentDirectory(ExtractFilePath(selectionFileName));
+      end else
+      begin
+        result := srCancelledByUser;
+        LazPaintInstance.ShowTopmost(topmost);
+        exit;
       end;
     end else
     begin
@@ -2116,10 +2152,11 @@ begin
                   case DetectFileFormat(Filenames[i]) of
                    ifSvg:
                      begin
-                       svgOrig := LoadSVGOriginalUTF8(Filenames[i]);
+                       svgOrig := LoadSVGOriginalUTF8(Filenames[i], Screen.Width, Screen.Height,
+                         Screen.PixelsPerInch / 96 * CanvasScale);
                        loadedLayers[i].orig := svgOrig;
-                       if ceil(svgOrig.Width) > tx then tx := ceil(svgOrig.Width);
-                       if ceil(svgOrig.Height) > ty then ty := ceil(svgOrig.Height);
+                       tx := max(tx, floor(svgOrig.Width + 0.95));
+                       ty := max(ty, floor(svgOrig.Height + 0.95));
                      end
                    else
                      begin
@@ -2166,7 +2203,7 @@ begin
               if Length(Errors)>0 then
               begin
                 topmost := LazPaintInstance.HideTopmost;
-                QuestionDlg (rsError,rsFollowingErrorsOccured+ LineEnding+ Errors, mtError,[11,rsOkay],'');
+                QuestionDlg (rsError,rsFollowingErrorsOccurred+ LineEnding+ Errors, mtError,[11,rsOkay],'');
                 LazPaintInstance.ShowTopmost(topmost);
               end;
               for i := 0 to high(loadedLayers) do
@@ -2597,6 +2634,15 @@ begin
     FCoordinatesCaptionCount := 0;
   end;
   FLayout.CheckDelayedUpdate;
+  if Assigned(LazPaintInstance) then
+  begin
+    if DarkThemeInstance.HasSystemDarkThemeChanged then
+    begin
+      if (Config.GetDarkThemePreference = dtpAuto) and (LazPaintInstance.DarkTheme <> DarkThemeInstance.IsSystemDarkTheme) then
+        LazPaintInstance.DarkTheme := DarkThemeInstance.IsSystemDarkTheme
+        else LazPaintInstance.NotifyThemeChanged;
+    end;
+  end;
   TimerUpdate.Enabled := true;
 end;
 
@@ -2621,8 +2667,18 @@ begin
 end;
 
 procedure TFMain.ViewDarkThemeExecute(Sender: TObject);
+var
+  newDarkTheme: Boolean;
 begin
-  LazPaintInstance.DarkTheme := not LazPaintInstance.DarkTheme;
+  newDarkTheme := not LazPaintInstance.DarkTheme;
+  if newDarkTheme = DarkThemeInstance.IsSystemDarkTheme then
+    Config.SetDarkThemePreference(dtpAuto) else
+    begin
+      if newDarkTheme then
+        Config.SetDarkThemePreference(dtpDark)
+        else Config.SetDarkThemePreference(dtpAuto);
+    end;
+  LazPaintInstance.DarkTheme := newDarkTheme;
 end;
 
 procedure TFMain.ViewDarkThemeUpdate(Sender: TObject);
@@ -2796,6 +2852,7 @@ var toolName: string;
   texMapBounds: TRect;
 begin
   if ToolManager.ToolSleeping then exit;
+  LazPaintInstance.ExitColorEditor;
   texMapBounds := EmptyRect;
   toolName := AVars.Strings['Name'];
   Tool := StrToPaintToolType(toolName);
@@ -3240,6 +3297,11 @@ begin
   result := srOk;
 end;
 
+procedure TFMain.ThemeChanged(Sender: TObject);
+begin
+  DarkTheme := LazPaintInstance.DarkTheme;
+end;
+
 procedure TFMain.BrushCreateGeometricExecute(Sender: TObject);
 var b: TLazPaintBrush;
 begin
@@ -3548,6 +3610,76 @@ begin
     Layout.ToolBoxDocking := twWindow;
 end;
 
+procedure TFMain.LayerExportExecute(Sender: TObject);
+var
+  topMost: TTopMostInfo;
+  saveDlg: TSaveDialog;
+  layerIdx, mr: Integer;
+  defaultExt, filename: String;
+
+  procedure DoExportLayer(AFilename: string);
+  var
+    vars: TVariableSet;
+  begin
+    FExportInitialDir := extractFilePath(AFilename);
+    if Config.DefaultRememberStartupExportDirectory then
+      Config.SetStartupExportDirectory(FExportInitialDir);
+
+    vars := TVariableSet.Create('LayerSaveAs');
+    vars.Strings['FileName'] := AFilename;
+    CallScriptFunction(vars);
+    vars.Free;
+  end;
+
+begin
+  layerIdx := Image.CurrentLayerIndex;
+  if not Image.LayerOriginalDefined[layerIdx] then
+    defaultExt := '.png' else
+  if Image.LayerOriginalClass[layerIdx] = TBGRALayerSVGOriginal then
+    defaultExt := '.svg'
+  else
+    defaultExt := '.lzp';
+  filename := FileManager.GetValidFilename(Image.LayerName[layerIdx]) + defaultExt;
+  topMost := LazPaintInstance.HideTopmost;
+  saveDlg := ExportPictureDialog;
+  if UseImageBrowser then
+  begin
+    if not assigned(FSaveImage) then
+    begin
+      FSaveImage := TFBrowseImages.Create(self);
+      FSaveImage.LazPaintInstance := LazPaintInstance;
+      FSaveImage.IsSaveDialog := true;
+      FSaveImage.ShowRememberStartupDirectory:= true;
+      if Config.DefaultRememberSaveFormat then
+        FSaveImage.DefaultExtensions:= Config.DefaultSaveExtensions;
+    end;
+    FSaveImage.Filter := saveDlg.Filter;
+    FSaveImage.Caption := saveDlg.Title;
+    FSaveImage.InitialFilename := filename;
+    FSaveImage.DefaultExtension := defaultExt;
+    FSaveImage.InitialDirectory:= FExportInitialDir;
+    FSaveImage.RememberStartDirectory:= FLazPaintInstance.Config.DefaultRememberStartupExportDirectory;
+    FSaveImage.FilterIndex := saveDlg.FilterIndex;
+    mr := FSaveImage.ShowModal;
+    LazPaintInstance.Config.SetRememberStartupExportDirectory(FSaveImage.RememberStartDirectory);
+    if mr = mrOK then
+    begin
+      saveDlg.FilterIndex := FSaveImage.FilterIndex;
+      DoExportLayer(FSaveImage.FileName);
+    end;
+  end else
+  begin
+    saveDlg.FileName := filename;
+    saveDlg.DefaultExt := defaultExt;
+    saveDlg.InitialDir:= FExportInitialDir;
+    if saveDlg.Execute then
+    begin
+      DoExportLayer(saveDlg.FileName);
+    end;
+  end;
+  LazPaintInstance.ShowTopmost(topMost);
+end;
+
 procedure TFMain.LayerRasterizeUpdate(Sender: TObject);
 begin
   LayerRasterize.Enabled := Image.LayerOriginalDefined[Image.CurrentLayerIndex];
@@ -3630,7 +3762,9 @@ end;
 
 procedure TFMain.EditPasteUpdate(Sender: TObject);
 begin
-  EditPaste.Enabled := ToolManager.ToolProvideCommand(tcPaste) or Image.CurrentLayerVisible;
+  if Assigned(LazPaintInstance) and LazPaintInstance.ColorEditorActive then
+    EditPaste.Enabled := false
+    else EditPaste.Enabled := ToolManager.ToolProvideCommand(tcPaste) or Image.CurrentLayerVisible;
 end;
 
 procedure TFMain.EditDeselectUpdate(Sender: TObject);
@@ -3652,6 +3786,8 @@ end;
 procedure TFMain.ScriptExecute(Sender: TObject);
 var actionName: string;
 begin
+  if Assigned(LazPaintInstance) then
+    LazPaintInstance.ExitColorEditor;
   if Sender is TAction then
   begin
     actionName := (Sender as TAction).Name;
@@ -3786,18 +3922,13 @@ begin
         FBrowseBrushes.AllowMultiSelect := false;
         FBrowseBrushes.Caption := OpenBrushDialog.Title;
       end;
-      self.Hide;
-      try
-        FBrowseBrushes.InitialDirectory := Config.DefaultBrushDirectory;
-        FBrowseBrushes.FilterIndex:= OpenBrushDialog.FilterIndex;
-        if FBrowseBrushes.ShowModal = mrOK then
-        begin
-          OpenBrushDialog.FilterIndex := FBrowseBrushes.FilterIndex;
-          brushFilename := FBrowseBrushes.Filename;
-          newBrushBmp := FBrowseBrushes.GetChosenImage.bmp;
-        end;
-      finally
-        self.Show;
+      FBrowseBrushes.InitialDirectory := Config.DefaultBrushDirectory;
+      FBrowseBrushes.FilterIndex:= OpenBrushDialog.FilterIndex;
+      if FBrowseBrushes.ShowModal = mrOK then
+      begin
+        OpenBrushDialog.FilterIndex := FBrowseBrushes.FilterIndex;
+        brushFilename := FBrowseBrushes.Filename;
+        newBrushBmp := FBrowseBrushes.GetChosenImage.bmp;
       end;
     end else
     begin
@@ -3979,16 +4110,6 @@ var
     end else FreeAndNil(picture.bmp);
   end;
 
-  procedure ImportSvg;
-  var
-    layered: TBGRALayeredBitmap;
-  begin
-    StartImport(filenameUTF8);
-    layered := LoadSVGImageUTF8(filenameUTF8);
-    Image.Assign(layered,true, false);
-    EndImport;
-  end;
-
 begin
   result := false;
   if filenameUTF8 = '' then exit;
@@ -4001,11 +4122,7 @@ begin
   picture := TImageEntry.Empty;
   try
     format := Image.DetectImageFormat(filenameUTF8);
-    if format = ifSvg then
-    begin
-      ImportSvg;
-    end else
-    if Assigned(ALoadedImage) and Assigned(ALoadedImage^.bmp) then
+    if (format <> ifSvg) and Assigned(ALoadedImage) and Assigned(ALoadedImage^.bmp) then
     begin
       picture := ALoadedImage^;
       ALoadedImage^.bmp := nil;
@@ -4145,11 +4262,14 @@ begin
   if LazPaintInstance.TopMostHasFocus then
   begin
     if LazPaintInstance.TopMostOkToUnfocus then
-      SafeSetFocus(self)
+    begin
+      if ToolWindowStyle = fsStayOnTop then
+        SafeSetFocus(self);
+    end
     else
       exit;
   end;
-  if (CurrentTool in[ptText,ptEditShape]) and TextSpinEditFocused then VectorialFill_Pen.SetFocus;
+  if (CurrentTool in[ptText,ptEditShape]) and TextSpinEditFocused then Layout.FocusImage;
 end;
 
 procedure TFMain.PictureOnPaint(Sender: TObject);
@@ -4337,7 +4457,7 @@ end;
 
 procedure TFMain.SetDarkTheme(AValue: boolean);
 begin
-  if LAyout.DarkTheme<>AValue then
+  if Layout.DarkTheme<>AValue then
   begin
     Layout.DarkTheme := AValue;
     DarkThemeInstance.Apply(Panel_PenWidthPreview, AValue);

+ 9 - 4
lazpaint/lazpainttype.pas

@@ -11,7 +11,7 @@ uses
   {$IFDEF LINUX}, InterfaceBase{$ENDIF};
 
 const
-  LazPaintVersion = 7010500;
+  LazPaintVersion = 7010600;
 
   function LazPaintVersionStr: string;
 
@@ -60,6 +60,9 @@ const
 
 const
   OriginalDPI = 96;
+  ToolWindowFixedSize = {$IFDEF LINUX}bsDialog{$ELSE}bsToolWindow{$ENDIF};
+  ToolWindowSizeable = {$IFDEF LINUX}bsSizeable{$ELSE}bsSizeToolWin{$ENDIF};
+  ToolWindowStyle = {$IF defined(LINUX) and defined(LCLqt5)}fsNormal{$ELSE}fsStayOnTop{$ENDIF};
 
   function LazPaintCurrentVersion : String;
 
@@ -213,7 +216,6 @@ type
     procedure SetLayerWindowWidth(AValue: integer); virtual; abstract;
 
     function GetMainFormBounds: TRect; virtual; abstract;
-    procedure ApplyTheme(ADarkTheme: boolean); virtual; abstract;
   public
     Title,AboutText: string;
     EmbeddedResult: TModalResult;
@@ -221,6 +223,8 @@ type
 
     constructor Create; virtual; abstract;
     constructor Create(AEmbedded: boolean); virtual; abstract;
+    procedure RegisterThemeListener(AHandler: TNotifyEvent; ARegister: boolean); virtual; abstract;
+    procedure NotifyThemeChanged; virtual; abstract;
     procedure StartLoadingImage(AFilename: string); virtual; abstract;
     procedure EndLoadingImage; virtual; abstract;
     procedure StartSavingImage(AFilename: string); virtual; abstract;
@@ -238,7 +242,7 @@ type
     function ProcessCommands(commands: TStringList): boolean; virtual; abstract;
     procedure ChangeIconSize(size: integer); virtual; abstract;
     procedure Show; virtual; abstract;
-    procedure Hide; virtual; abstract;
+    function Hide: boolean; virtual; abstract;
     procedure Run; virtual; abstract;
     procedure Restart; virtual; abstract;
     procedure CancelRestart; virtual; abstract;
@@ -253,6 +257,7 @@ type
     procedure ColorFromFChooseColor; virtual; abstract;
     procedure ColorToFChooseColor; virtual; abstract;
     procedure ExitColorEditor; virtual; abstract;
+    function ColorEditorActive: boolean; virtual; abstract;
     function GetColor(ATarget: TColorTarget): TBGRAPixel;
     procedure SetColor(ATarget: TColorTarget; AColor: TBGRAPixel);
     function ShowSaveOptionDlg(AParameters: TVariableSet; AOutputFilenameUTF8: string;
@@ -613,7 +618,7 @@ begin
     if AValue <> Config.GetDarkTheme then
     begin
       Config.SetDarkTheme(AValue);
-      ApplyTheme(AValue);
+      NotifyThemeChanged;
     end;
   end;
 end;

+ 72 - 29
lazpaint/maintoolbar.inc

@@ -225,23 +225,6 @@ begin
   Label_Coordinates.Caption := '';
   FCoordinatesCaption:= '';
   FCoordinatesCaptionCount := 0;
-  LabelAutosize(Label_Pen);
-  LabelAutosize(Label_Back);
-  LabelAutosize(Label_PenWidth);
-  LabelAutosize(Label_Eraser);
-  LabelAutosize(Label_Tolerance);
-  LabelAutosize(Label_Grid);
-  LabelAutosize(Label_Curve);
-  LabelAutosize(Label_Text);
-  LabelAutosize(Label_TextBlur);
-  LabelAutosize(Label_ShadowOffset);
-  LabelAutosize(Label_Shape);
-  LabelAutosize(Label_PhongBorder);
-  LabelAutosize(Label_Altitude);
-  LabelAutosize(Label_OutlineWidth);
-  LabelAutosize(Label_Brush);
-  LabelAutosize(Label_Spacing);
-  LabelAutosize(Label_Ratio);
   Image_SwapColors.Hint := Image_SwapColors.Hint + ' (X)';
 
   Tool_CurveModeAuto.Hint := Tool_CurveModeAuto.Hint + ' (A)';
@@ -272,18 +255,18 @@ begin
   end;
 end;
 
-procedure TFMain.LabelAutosize(ALabel: TLabel);
+procedure TFMain.LabelAutosize(ALabel: TLabel; ATargetDPI: integer);
 var
   delta, nextPos: integer;
   container: TWinControl;
   nextControl: TControl;
   I, prefWidth, prefHeight: Integer;
 begin
-  ALabel.Font.Height := -DoScaleY(12, OriginalDPI);
+  ALabel.Font.Height := -DoScaleY(12, OriginalDPI, ATargetDPI);
   prefWidth := ALabel.Width;
   prefHeight := ALabel.Width;
   ALabel.GetPreferredSize(prefWidth, prefHeight);
-  ALabel.Width := prefWidth+DoScaleX(5, OriginalDPI);
+  ALabel.Width := prefWidth+DoScaleX(5, OriginalDPI, ATargetDPI);
   nextPos := MaxLongInt;
   container := ALabel.Parent;
   for i := 0 to container.ControlCount-1 do
@@ -584,7 +567,8 @@ end;
 
 procedure TFMain.QueryArrange;
 begin
-  if FShouldArrange then
+  if FShouldArrange and not (Assigned(FLayout) and FLayout.Arranging)
+     and not FInHideFill then
     TimerArrange.Enabled := true;
 end;
 
@@ -755,11 +739,52 @@ begin
 end;
 
 procedure TFMain.TimerArrangeTimer(Sender: TObject);
+  procedure SetTarget(AFillControl: TLCVectorialFillControl);
+  begin
+    if (AFillControl.FillType = vftGradient) then
+    begin
+      if AFillControl = VectorialFill_Pen then
+        LazPaintInstance.ChooseColorTarget:= ctForeColorStartGrad else
+      if AFillControl = VectorialFill_Back then
+        LazPaintInstance.ChooseColorTarget:= ctBackColorStartGrad else
+      if AFillControl = VectorialFill_Outline then
+        LazPaintInstance.ChooseColorTarget:= ctOutlineColorStartGrad;
+    end else
+    begin
+      if AFillControl = VectorialFill_Pen then
+        LazPaintInstance.ChooseColorTarget:= ctForeColorSolid else
+      if AFillControl = VectorialFill_Back then
+        LazPaintInstance.ChooseColorTarget:= ctBackColorSolid else
+      if AFillControl = VectorialFill_Outline then
+        LazPaintInstance.ChooseColorTarget:= ctOutlineColorSolid;
+    end;
+  end;
+var
+  ct: TContextualToolbars;
 begin
   if Assigned(FLayout) then
   begin
     UpdateAllowedFillTypes;
     FLayout.Arrange;
+    ct := ToolManager.GetContextualToolbars;
+    if (LazPaintInstance.ChooseColorTarget in [ctForeColorSolid, ctForeColorStartGrad,
+      ctForeColorEndGrad]) and not (ctPenFill in ct) then
+    begin
+      if ctBackFill in ct then SetTarget(VectorialFill_Back)
+      else if ctOutlineFill in ct then SetTarget(VectorialFill_Outline);
+    end else
+    if (LazPaintInstance.ChooseColorTarget in [ctBackColorSolid, ctBackColorStartGrad,
+      ctBackColorEndGrad]) and not (ctBackFill in ct) then
+    begin
+      if ctOutlineFill in ct then SetTarget(VectorialFill_Outline)
+      else if ctPenFill in ct then SetTarget(VectorialFill_Pen);
+    end else
+    if (LazPaintInstance.ChooseColorTarget in [ctOutlineColorSolid, ctOutlineColorStartGrad,
+      ctOutlineColorEndGrad]) and not (ctOutlineFill in ct) then
+    begin
+      if ctBackFill in ct then SetTarget(VectorialFill_Back)
+      else if ctPenFill in ct then SetTarget(VectorialFill_Pen);
+    end;
   end;
   TimerArrange.Enabled:= false;
 end;
@@ -767,17 +792,30 @@ end;
 procedure TFMain.TimerHideFillTimer(Sender: TObject);
 begin
   TimerHideFill.Enabled := false;
-  VectorialFill_Pen.Height := VectorialFill_Pen.ToolIconSize + VectorialFill_Pen.VerticalPadding;
-  VectorialFill_Back.Height := VectorialFill_Back.ToolIconSize + VectorialFill_Back.VerticalPadding;
-  VectorialFill_Outline.Height := VectorialFill_Outline.ToolIconSize + VectorialFill_Outline.VerticalPadding;
+  FInHideFill := true;
+  VectorialFill_Pen.Height := min(VectorialFill_Pen.ToolIconSize + VectorialFill_Pen.VerticalPadding,
+                               Panel_SwapColor.ClientHeight - VectorialFill_Pen.Top - 1);
+  VectorialFill_Pen.Tag := 0;
+  VectorialFill_Back.Height := min(VectorialFill_Back.ToolIconSize + VectorialFill_Back.VerticalPadding,
+                               Panel_SwapColor.ClientHeight - VectorialFill_Back.Top - 1);
+  VectorialFill_Back.Tag := 0;
+  VectorialFill_Outline.Height := min(VectorialFill_Outline.ToolIconSize + VectorialFill_Outline.VerticalPadding,
+                                  Panel_SwapColor.ClientHeight - VectorialFill_Outline.Top - 1);
+  VectorialFill_Outline.Tag := 0;
   Panel_PenFill.Height := Panel_SwapColor.Height;
   Panel_BackFill.Height := Panel_SwapColor.Height;
   Panel_OutlineFill.Height := Panel_SwapColor.Height;
+  FInHideFill := false
 end;
 
 procedure TFMain.ToolButton_DonateClick(Sender: TObject);
 begin
-  LazPaintInstance.Donate;
+  if Now > FLastDonateClick + (10 / (24*60*60) ) then
+  begin
+    MessagePopup(rsDonate, 3000);
+    FLastDonateClick := Now;
+    LazPaintInstance.Donate;
+  end;
 end;
 
 procedure TFMain.SpinEdit_GridNbExit(Sender: TObject);
@@ -1517,14 +1555,19 @@ begin
   AFillControl.BringToFront;
   AFillControl.Height := AFillControl.PreferredSize.cy;
   APanel.Height := AFillControl.Top + AFillControl.Height + DoScaleY(3, OriginalDPI);
+  AFillControl.Tag := 1;
   HideFill(3000, true);
 end;
 
 procedure TFMain.HideFill(ATimeMs: Integer; AClearTime: boolean);
 begin
-  if AClearTime then TimerHideFill.Enabled := false;
-  TimerHideFill.Interval := ATimeMs;
-  TimerHideFill.Enabled := true;
+  if (VectorialFill_Pen.Tag = 1) or (VectorialFill_Back.Tag = 1) or
+     (VectorialFill_Outline.Tag = 1) then
+  begin
+    if AClearTime then TimerHideFill.Enabled := false;
+    TimerHideFill.Interval := ATimeMs;
+    TimerHideFill.Enabled := true;
+  end;
 end;
 
 procedure TFMain.Panel_ToolbarBackgroundMouseMove(Sender: TObject;
@@ -1619,7 +1662,7 @@ begin
   bmp := TBGRABitmap.Create(round(PaintBox_PenPreview.Width*scaling),
     round(PaintBox_PenPreview.Height*scaling), Panel_PenWidthPreview.Color);
   bmp.ClipRect := rect(1,1,bmp.Width-1,bmp.Height-1);
-  if DarkTheme then c := clLightText else c := clBtnText;
+  c := DarkThemeInstance.GetColorButtonText(DarkTheme);
   x := round(bmp.Width/2);
   y := round(bmp.Height/2);
   if Assigned(Zoom) then visualSize := ToolManager.PenWidth * Zoom.Factor else visualSize := ToolManager.PenWidth;

+ 213 - 0
lazpaint/ns_url_request.pas

@@ -0,0 +1,213 @@
+unit ns_url_request;
+
+{
+  TNSHTTPSendAndReceive class for use by itself as an HTTP client or with
+   Web Service Toolkit (http://wiki.freepascal.org/Web_Service_Toolkit).
+
+  Author:    Phil Hess.
+  Copyright: Copyright 2011 Phil Hess.
+  License:   Modified LGPL (see Free Pascal's rtl/COPYING.FPC).
+             This means you can link your code to this compiled unit (statically
+             in a standalone executable or dynamically in a library) without
+             releasing your code. Only changes to this unit need to be made
+             publicly available.
+}
+
+{$modeswitch ObjectiveC1}
+
+interface
+
+uses
+  SysUtils,
+  Classes,
+  CocoaUtils,
+{$IF DEFINED(IPHONESIM) OR DEFINED(CPUARM) OR DEFINED(CPUAARCH64)}  //iOS
+ {$IFDEF NoiPhoneAll}
+  Foundation
+ {$ELSE}
+  iPhoneAll
+ {$ENDIF}
+{$ELSE}  //macOS
+ {$IFDEF NoCocoaAll}
+  Foundation
+ {$ELSE}
+  CocoaAll
+ {$ENDIF}
+{$ENDIF};
+
+type
+
+  { TNSHTTPSendAndReceive }
+
+  TNSHTTPSendAndReceive = class(TObject)
+  private
+    FAddress : string;
+    FMethod : string;
+    FTimeOut : Integer;
+    FLastErrMsg : string;
+  public
+    property Address : string read FAddress write FAddress;
+    property Method : string read FMethod write FMethod;
+    property TimeOut : Integer read FTimeOut write FTimeOut;
+    property LastErrMsg : string read FLastErrMsg;
+    constructor Create;
+    class procedure SimpleGet(AUrl: string; AStream: TStream);
+    function SendAndReceive(ARequest  : TStream;
+                            AResponse : TStream;
+                            Headers   : TStringList) : Boolean; overload;
+    function SendAndReceive(out AResponse : string) : Boolean; overload;
+    function PostForm(const FormFields : string;
+                        out AResponse  : string) : Boolean; overload;
+  end;
+
+
+implementation
+
+constructor TNSHTTPSendAndReceive.Create;
+begin
+  inherited Create;
+  FMethod := 'GET';
+  FTimeOut := 30;
+end;
+
+class procedure TNSHTTPSendAndReceive.SimpleGet(AUrl: string; AStream: TStream);
+begin
+  With Self.Create do
+    try
+      Address:= AUrl;
+      if not SendAndReceive(nil,AStream,nil) then
+        raise exception.Create('SimpleGet failed');
+    finally
+      Free;
+    end;
+end;
+
+function TNSHTTPSendAndReceive.SendAndReceive(ARequest  : TStream;
+                                              AResponse : TStream;
+                                              Headers   : TStringList) : Boolean;
+ {Send HTTP request to current Address URL, returning downloaded data
+   in AResponse stream and True as function result. If error occurs,
+   return False and set LastErrMsg.
+  Optional ARequest stream can be used to set the HTTP request body.
+  Optional Headers list of name-value pairs can be used to set
+   HTTP headers.}
+var
+  urlRequest  : NSMutableURLRequest;
+  requestData : NSMutableData;
+  HdrNum      : Integer;
+  urlResponse : NSURLResponse;
+  error       : NSError;
+  urlData     : NSData;
+begin
+  Result := False;
+  try
+    urlRequest := NSMutableURLRequest.requestWithURL_cachePolicy_timeoutInterval(
+                   NSURL.URLWithString(NSStringUtf8(Address)),
+                   NSURLRequestUseProtocolCachePolicy, Timeout);
+
+    if Method <> '' then
+      urlRequest.setHTTPMethod(NSStringUtf8(Method));
+
+    if Assigned(ARequest) and (ARequest.Size > 0) then
+      begin
+      try
+        requestData := NSMutableData.alloc.initWithLength(ARequest.Size);
+        ARequest.Position := 0;
+        ARequest.ReadBuffer(requestData.mutableBytes^, ARequest.Size);
+        urlRequest.setHTTPBody(requestData);
+      finally
+        requestData.release;
+        end;
+      end;
+
+    if Assigned(Headers) then
+      begin
+      for HdrNum := 0 to Headers.Count-1 do
+        begin
+        urlRequest.addValue_forHTTPHeaderField(NSStringUtf8(Headers.ValueFromIndex[HdrNum]),
+                                               NSStringUtf8(Headers.Names[HdrNum]));
+        end;
+      end;
+
+    urlData := NSURLConnection.sendSynchronousRequest_returningResponse_error(
+                urlRequest, @urlResponse, @error);
+    if not Assigned(urlData) then
+      begin
+      FLastErrMsg := NSStringToString(error.localizedDescription);
+      Exit;
+      end;
+
+    AResponse.Position := 0;
+    AResponse.WriteBuffer(urlData.bytes^, urlData.length);
+    AResponse.Position := 0;
+    Result := True;
+
+  except
+    on E : Exception do
+      begin
+      FLastErrMsg := E.Message;
+      end;
+  end;
+end;
+
+
+function TNSHTTPSendAndReceive.SendAndReceive(out AResponse : string) : Boolean;
+ {Send HTTP request to current Address URL, returning downloaded data
+   in AResponse string and True as function result. If error occurs,
+   return False and set LastErrMsg.}
+var
+  Data : TMemoryStream;
+begin
+  Data := TMemoryStream.Create;
+  try
+    Result := SendAndReceive(nil, Data, nil);
+    if Result then
+      begin
+      SetLength(AResponse, Data.Size);
+      if Data.Size > 0 then
+        Data.Read(AResponse[1], Data.Size);
+      end;
+  finally
+    Data.Free;
+  end;
+end;
+
+
+function TNSHTTPSendAndReceive.PostForm(const FormFields : string;
+                                          out AResponse  : string) : Boolean;
+ {Post FormFields to current Address URL, returning downloaded data
+   in AResponse string and True as function result. If error occurs,
+   return False and set LastErrMsg.
+  Note FormFields must be in URL query string form (for example,
+   'name1=value1&name2=value2') and URL encoded.}
+var
+  Request : TMemoryStream;
+  Headers : TStringList;
+  Data    : TMemoryStream;
+begin
+  Request := TMemoryStream.Create;
+  Headers := TStringList.Create;
+  Data := TMemoryStream.Create;
+  try
+    FMethod := 'POST';
+    if FormFields <> '' then
+      Request.Write(FormFields[1], Length(FormFields));
+    Headers.Add('Content-Type=application/x-www-form-urlencoded');
+    Headers.Add('Content-Length=' + IntToStr(Request.Size));
+    Result := SendAndReceive(Request, Data, Headers);
+    if Result then
+      begin
+      SetLength(AResponse, Data.Size);
+      if Data.Size > 0 then
+        Data.Read(AResponse[1], Data.Size);
+      end;
+  finally
+    Request.Free;
+    Headers.Free;
+    Data.Free;
+  end;
+end;
+
+
+end.
+

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.ar.po

@@ -239,11 +239,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "عرض"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr ""
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr ""
 
@@ -1098,6 +1098,10 @@ msgstr "تدوير 90° CCW"
 msgid "Rotate 90° CW"
 msgstr "تدوير 90° CW"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "تدوير 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "التكبير الذكي x3"
@@ -3022,8 +3026,8 @@ msgstr "مجلد"
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.bg.po

@@ -239,11 +239,11 @@ msgctxt "TFCANVASSIZE.LABEL_WIDTH.CAPTION"
 msgid "Width :"
 msgstr "Ширина:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Добавяне на цвета в палитрата"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Премахване на цвета от палитрата"
 
@@ -1095,6 +1095,10 @@ msgstr "Завъртане на 270°"
 msgid "Rotate 90° CW"
 msgstr "Завъртане на 90°"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Завъртане на 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Умно увеличаване х 3"
@@ -3007,8 +3011,8 @@ msgstr "Папка"
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.cs.po

@@ -245,11 +245,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Šířka :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Přidat barvu do palety"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Odebrat barvu z palety"
 
@@ -1107,6 +1107,10 @@ msgstr "Otočit 90° CCW"
 msgid "Rotate 90° CW"
 msgstr "Otočit 90° CW"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Otočit 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Chytré zvětšení x3"
@@ -3038,8 +3042,8 @@ msgstr "Složka"
 msgid "Folder or container already exists."
 msgstr "Složka nebo zásobník již existují."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Nastaly následující chyby:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.de.po

@@ -250,11 +250,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Breite:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Farbe der Palette hinzufügen"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Farbe von Palette entfernen"
 
@@ -1110,6 +1110,10 @@ msgstr "Drehung 90° gegen den UZS"
 msgid "Rotate 90° CW"
 msgstr "Drehung 90° im Uhrzeigersinn (UZS)"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Drehung 90°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Smart Zoom x3"
@@ -3036,8 +3040,8 @@ msgstr "Ordner"
 msgid "Folder or container already exists."
 msgstr "Ordner oder Container existiert schon."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Folgende Fehler traten auf:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.es.po

@@ -241,11 +241,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Ancho:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Agregar color a la paleta"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Quitar color de la paleta"
 
@@ -1099,6 +1099,10 @@ msgstr "Rotar 90º CCR"
 msgid "Rotate 90° CR"
 msgstr "Rotar 90º CR"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Rotar 180º"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Zoom inteligente x3"
@@ -3029,8 +3033,8 @@ msgstr "Carpeta"
 msgid "Folder or container already exists."
 msgstr "La carpeta o el contenedor ya existe."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Estos errores han ocurrido:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.fi.po

@@ -231,11 +231,11 @@ msgctxt "TFCANVASSIZE.LABEL_WIDTH.CAPTION"
 msgid "Width :"
 msgstr "Leveys :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Lisää väri väripalettiin"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Poista väri väripaletista"
 
@@ -1092,6 +1092,10 @@ msgstr "Kierrä 90° vastapäivään"
 msgid "Rotate 90° CW"
 msgstr "Kierrä 90° myötäpäivään"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Kierrä 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr ""
@@ -3019,8 +3023,8 @@ msgstr "Kansio"
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.fr.po

@@ -239,11 +239,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Largeur :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Ajouter à la palette des couleurs"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Retirer de la palette des couleurs"
 
@@ -1098,6 +1098,10 @@ msgstr "Rotation 90° (horloge à rebours)"
 msgid "Rotate 90° CW"
 msgstr "Rotation 90° (horloge)"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Rotation 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Zoom intelligent x3"
@@ -3031,8 +3035,8 @@ msgstr "Dossier"
 msgid "Folder or container already exists."
 msgstr "Le dossier ou conteneur existe déjà"
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Les erreurs suivantes sont survenues :"
 
 #: uresourcestrings.rsframes

+ 10 - 6
lazpaint/release/bin/i18n/lazpaint.ja.po

@@ -239,11 +239,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "幅:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr ""
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr ""
 
@@ -1092,11 +1092,15 @@ msgstr "Resample image"
 
 #: tfmain.imagerotateccw.caption
 msgid "Rotate 90° CCW"
-msgstr "Rotate 90° CCW"
+msgstr "反時計回りに90°回転"
 
 #: tfmain.imagerotatecw.caption
 msgid "Rotate 90° CW"
-msgstr "Rotate 90° CW"
+msgstr "時計回りに90°回転"
+
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "180°回転"
 
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
@@ -3021,8 +3025,8 @@ msgstr ""
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.kab.po

@@ -242,11 +242,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Tehri :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Rnu ini ɣer tpaliḍt"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Kkes ini si tpaliḍt"
 
@@ -1100,6 +1100,10 @@ msgstr "Tuzzya 90° (mgal tanila n temrilt)"
 msgid "Rotate 90° CW"
 msgstr "Tuzzya 90° (di tnila n temrilt)"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Tuzzya 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Asemɣer amegzu x3"
@@ -3029,8 +3033,8 @@ msgstr "Akaram"
 msgid "Folder or container already exists."
 msgstr "Akaram neɣ anagbar yella yakan."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Ḍrant-d tuccḍiwin-agi:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.lv.po

@@ -249,11 +249,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Platums:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Pievienot krāsu paletei"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Izņemt krāsu no paletes"
 
@@ -1111,6 +1111,10 @@ msgstr "Pagriezt pa 90° pretēji pulkstenim"
 msgid "Rotate 90° CW"
 msgstr "Pagriezt pa 90°"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Pagriezt pa 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Palielināt attēlu trīskārtīgi"
@@ -3041,8 +3045,8 @@ msgstr "Mape"
 msgid "Folder or container already exists."
 msgstr "Mape vai resursu datne jau ir."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Kļūda:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.nl.po

@@ -266,11 +266,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Breedte :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Kleur toevoegen aan palet"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Verwijder kleur van palet"
 
@@ -1124,6 +1124,10 @@ msgstr "90° naar links draaien"
 msgid "Rotate 90° CW"
 msgstr "90° naar rechts draaien"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "180° draaien"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Slimme zoom x3"
@@ -3047,8 +3051,8 @@ msgstr "Folder"
 msgid "Folder or container already exists."
 msgstr "Map of container bestaat al."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "De volgende fouten zijn opgetreden:"
 
 #: uresourcestrings.rsframes

+ 3595 - 0
lazpaint/release/bin/i18n/lazpaint.pl.po

@@ -0,0 +1,3595 @@
+msgid ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: de\n"
+"X-Generator: Poedit 1.6.7\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: tablet.getprocfailed
+msgid "Procedure %s failed to load properly."
+msgstr "Procedura %s nie została prawidłowo zainicjonowana."
+
+#: tablet.openfailed
+msgid "Tablet context failed to open."
+msgstr "Nie udało się otworzyć kontekstu tabletu."
+
+#: tfabout.button_donate.caption
+msgctxt "tfabout.button_donate.caption"
+msgid "Donate..."
+msgstr "Dotacja..."
+
+#: tfabout.caption
+msgctxt "tfabout.caption"
+msgid "About"
+msgstr "O programie"
+
+#: tfabout.labelurl.caption
+msgid "http://sourceforge.net/projects/lazpaint/"
+msgstr "http://sourceforge.net/projects/lazpaint/"
+
+#: tfabout.label_authors.caption
+msgctxt "tfabout.label_authors.caption"
+msgid "Authors:"
+msgstr "Autorzy:"
+
+#: tfabout.label_authorsvalue.caption
+#| msgid "Circular help by FabienWang and Lainz"
+msgctxt "tfabout.label_authorsvalue.caption"
+msgid "Circular helped by FabienWang, Lainz and others"
+msgstr "Okólnik wspomagany przez FabienWanga, Lainza i innych"
+
+#: tfabout.label_homepage.caption
+msgctxt "tfabout.label_homepage.caption"
+msgid "Homepage:"
+msgstr "Strona domowa:"
+
+#: tfabout.label_libraries.caption
+msgctxt "tfabout.label_libraries.caption"
+msgid "Libraries used:"
+msgstr "Użyte biblioteki:"
+
+#: tfabout.label_licence.caption
+msgctxt "tfabout.label_licence.caption"
+msgid "Licence:"
+msgstr "Licencja:"
+
+#: tfabout.label_opensource.caption
+msgctxt "tfabout.label_opensource.caption"
+msgid "Open source (GPLv3)"
+msgstr "Otwarte źródło (GPLv3)"
+
+#: tfadjustcurves.button_cancel.caption
+msgctxt "tfadjustcurves.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfadjustcurves.button_ok.caption
+msgctxt "tfadjustcurves.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfadjustcurves.caption
+msgid "Adjust curves"
+msgstr "Dostosuj krzywe kolorów"
+
+#: tfadjustcurves.toolbutton_newcurve.hint
+msgid "Discard current curve and start a new one"
+msgstr "Odrzuć bieżącą krzywą kolorów i rozpocznij nową"
+
+#: tfadjustcurves.toolbutton_posterize.hint
+msgctxt "tfadjustcurves.toolbutton_posterize.hint"
+msgid "Posterize"
+msgstr "Posteryzuj"
+
+#: tfadjustcurves.toolbutton_removepoint.hint
+msgid "Remove selected point (Del)"
+msgstr "Usuń wybrany punkt (Del)"
+
+#: tfblendop.button_cancel.caption
+msgctxt "tfblendop.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfblendop.button_ok.caption
+msgctxt "tfblendop.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfblendop.caption
+msgid "Blend operation"
+msgstr "Operacja mieszania"
+
+#: tfblendop.label_blendopcategory.caption
+msgctxt "tfblendop.label_blendopcategory.caption"
+msgid "Category of blend operation"
+msgstr "Kategoria operacji mieszanian"
+
+#: tfblendop.label_blendopvalue.caption
+msgctxt "tfblendop.label_blendopvalue.caption"
+msgid "."
+msgstr "."
+
+#: tfblendop.label_kritaover.caption
+msgctxt "tfblendop.label_kritaover.caption"
+msgid "Krita"
+msgstr "Krita"
+
+#: tfblendop.label_kritaover.hint
+msgid "Blend operations that are available in Krita"
+msgstr "Operacje mieszania, które są dostępne w Krita"
+
+#: tfblendop.label_otherover.caption
+msgctxt "tfblendop.label_otherover.caption"
+msgid "Other"
+msgstr "Inne"
+
+#: tfblendop.label_otherover.hint
+msgid "Blend operations of LazPaint and Paint.NET"
+msgstr "Operacje mieszania LazPaint i Paint.NET"
+
+#: tfblendop.label_patternover.caption
+msgctxt "tfblendop.label_patternover.caption"
+msgid "Pattern over"
+msgstr "Wzór górny"
+
+#: tfblendop.label_patternover.hint
+msgid "Preview blend operation with the specified image on top"
+msgstr "Podgląd operacji mieszania z określonym obrazem na wierzchu"
+
+#: tfblendop.label_patternunder.caption
+msgctxt "tfblendop.label_patternunder.caption"
+msgid "Pattern under"
+msgstr "Wzór dolny"
+
+#: tfblendop.label_patternunder.hint
+msgid "Preview blend operation with the specified image underneath"
+msgstr "Podgląd operacji mieszania z określonym obrazem poniżej"
+
+#: tfblendop.label_previewwith.caption
+msgctxt "tfblendop.label_previewwith.caption"
+msgid "Preview with"
+msgstr "Podgląd za pomocą"
+
+#: tfblendop.label_selectedblendop.caption
+msgid "Selected blend operation :"
+msgstr "Wybrana operacja mieszania:"
+
+#: tfblendop.label_svgover.caption
+msgctxt "tfblendop.label_svgover.caption"
+msgid "Basic SVG"
+msgstr "Podstawowa SVG"
+
+#: tfblendop.label_svgover.hint
+msgid "Basic blend operations that are available in virtually all image editors"
+msgstr "Podstawowe operacje mieszania są dostępne we wszystkich edytorach obrazów"
+
+#: tfbrowseimages.caption
+msgid "Browse images"
+msgstr "Przeglądaj obrazy"
+
+#: tfbrowseimages.checkbox_usedirectoryonstartup.caption
+msgid "Use this directory on startup"
+msgstr "Użyj tego katalogu podczas uruchamiania"
+
+#: tfbrowseimages.label_status.caption
+msgctxt "tfbrowseimages.label_status.caption"
+msgid "."
+msgstr "."
+
+#: tfbrowseimages.toolbutton_createfolderorcontainer.hint
+msgid "Create folder or container"
+msgstr "Utwórz folder lub kontener"
+
+#: tfbrowseimages.toolbutton_goup.hint
+msgid "Go one directory up"
+msgstr "Przejdź o jeden katalog wyżej"
+
+#: tfbrowseimages.toolbutton_openselectedfiles.hint
+msgid "Open selected files"
+msgstr "Otwórz wybrane pliki"
+
+#: tfbrowseimages.toolbutton_viewbigicon.hint
+msgctxt "tfbrowseimages.toolbutton_viewbigicon.hint"
+msgid "Show big icons"
+msgstr "Pokaż duże ikony"
+
+#: tfbrowseimages.toolbutton_viewdetails.hint
+msgctxt "tfbrowseimages.toolbutton_viewdetails.hint"
+msgid "Show details and preview"
+msgstr "Pokaż szczegóły i podgląd"
+
+#: tfbrowseimages.tool_selectdrive.hint
+msgid "Select drive"
+msgstr "Wybierz dysk"
+
+#: tfcanvassize.button_cancel.caption
+msgctxt "TFCANVASSIZE.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfcanvassize.button_ok.caption
+msgctxt "TFCANVASSIZE.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfcanvassize.caption
+msgctxt "tfcanvassize.caption"
+msgid "Canvas size"
+msgstr "Rozmiar obszaru roboczego"
+
+#: tfcanvassize.checkbox_flipmode.caption
+msgid "Flip mode"
+msgstr "Tryb odbicia"
+
+#: tfcanvassize.label_anchor.caption
+msgctxt "tfcanvassize.label_anchor.caption"
+msgid "Anchor :"
+msgstr "Kotwica:"
+
+#: tfcanvassize.label_height.caption
+msgctxt "tfcanvassize.label_height.caption"
+msgid "Height :"
+msgstr "Wysokość:"
+
+#: tfcanvassize.label_width.caption
+msgctxt "tfcanvassize.label_width.caption"
+msgid "Width :"
+msgstr "Szerokość:"
+
+#: tfchoosecolor.bcbutton_addtopalette.hint
+msgid "Add color to palette"
+msgstr "Dodaj kolor do pelety"
+
+#: tfchoosecolor.bcbutton_removefrompalette.hint
+msgid "Remove color from palette"
+msgstr "Usuń kolor z pelety"
+
+#: tfchoosecolor.caption
+msgctxt "tfchoosecolor.caption"
+msgid "Color"
+msgstr "Kolory"
+
+#: tfchoosecolor.lcolor.hint
+msgid "Color description: click to type in a color with the keyboard using color names or CSS notation."
+msgstr "Opis koloru: kliknij, aby wpisać kolor za pomocą klawiatury, używając nazw kolorów lub notacji CSS"
+
+#: tfcolorintensity.button_cancel.caption
+msgctxt "TFCOLORINTENSITY.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfcolorintensity.button_ok.caption
+msgctxt "TFCOLORINTENSITY.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfcolorintensity.caption
+msgctxt "tfcolorintensity.caption"
+msgid "Intensity"
+msgstr "Intensywność"
+
+#: tfcolorintensity.label_multiply.caption
+msgctxt "tfcolorintensity.label_multiply.caption"
+msgid "Multiply"
+msgstr "Zwielokrotnienie"
+
+#: tfcolorintensity.label_shift.caption
+msgctxt "tfcolorintensity.label_shift.caption"
+msgid "Shift"
+msgstr "Zmień"
+
+#: tfcolorize.button_cancel.caption
+msgctxt "TFCOLORIZE.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfcolorize.button_ok.caption
+msgctxt "TFCOLORIZE.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfcolorize.caption
+msgctxt "tfcolorize.caption"
+msgid "Colorize"
+msgstr "Koloruj"
+
+#: tfcolorize.checkbox_gsba.caption
+msgctxt "tfcolorize.checkbox_gsba.caption"
+msgid "Corrected hue and lightness"
+msgstr "Poprawiony odcień i jasność"
+
+#: tfcolorize.label_colorness.caption
+msgctxt "tfcolorize.label_colorness.caption"
+msgid "Colorness"
+msgstr "Kolorystyka"
+
+#: tfcolorize.label_hue.caption
+msgctxt "tfcolorize.label_hue.caption"
+msgid "Hue"
+msgstr "Odcień"
+
+#: tfcolorize.label_preset.caption
+msgid "Preset"
+msgstr "Zalecany"
+
+#: tfcustomblur.button_cancel.caption
+msgctxt "TFCUSTOMBLUR.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfcustomblur.button_editmask.caption
+msgid "Edit mask..."
+msgstr "Edytuj maskę..."
+
+#: tfcustomblur.button_loadmask.caption
+msgid "Load mask..."
+msgstr "Ładuj maskę..."
+
+#: tfcustomblur.button_ok.caption
+msgctxt "TFCUSTOMBLUR.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfcustomblur.caption
+msgctxt "tfcustomblur.caption"
+msgid "Custom blur"
+msgstr "Rozmycie niestandardowe"
+
+#: tfcustomblur.openpicturedialog1.title
+msgid "Open grayscale file"
+msgstr "Otwórz plik w skali szarości"
+
+#: tfemboss.button_cancel.caption
+msgctxt "TFEMBOSS.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfemboss.button_ok.caption
+msgctxt "TFEMBOSS.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfemboss.caption
+msgctxt "tfemboss.caption"
+msgid "Emboss"
+msgstr "Tłoczenie"
+
+#: tfemboss.checkbox_preservecolors.caption
+msgid "Preserve colors"
+msgstr "Zachowaj kolory"
+
+#: tfemboss.checkbox_transparent.caption
+msgid "Transparent"
+msgstr "Przezroczystość"
+
+#: tfemboss.label_direction.caption
+msgctxt "tfemboss.label_direction.caption"
+msgid "Direction :"
+msgstr "Kierunek:"
+
+#: tffilterfunction.button_cancel.caption
+msgctxt "tffilterfunction.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tffilterfunction.button_ok.caption
+msgctxt "tffilterfunction.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tffilterfunction.caption
+msgid "Apply function"
+msgstr "Zastosuj funkcję"
+
+#: tffilterfunction.checkbox_gamma.caption
+msgid "Gamma correction"
+msgstr "Korekcja gamma"
+
+#: tffilterfunction.checkbox_gsba.caption
+msgctxt "tffilterfunction.checkbox_gsba.caption"
+msgid "Corrected hue and lightness"
+msgstr "Poprawiony odcień i jasność"
+
+#: tffilterfunction.label_alphaequals.caption
+msgctxt "tffilterfunction.label_alphaequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_blueequals.caption
+msgctxt "tffilterfunction.label_blueequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_greenequals.caption
+msgctxt "tffilterfunction.label_greenequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_hueequals.caption
+msgctxt "tffilterfunction.label_hueequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_lightnessequals.caption
+msgctxt "tffilterfunction.label_lightnessequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_redequals.caption
+msgctxt "tffilterfunction.label_redequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_saturationequals.caption
+msgctxt "tffilterfunction.label_saturationequals.caption"
+msgid "."
+msgstr "."
+
+#: tffilterfunction.label_variables.caption
+msgid "Variables :"
+msgstr "Zmienne:"
+
+#: tffilterfunction.tabsheet_hsl.caption
+msgid "HSL"
+msgstr "HSL"
+
+#: tffilterfunction.tabsheet_rgb.caption
+msgctxt "tffilterfunction.tabsheet_rgb.caption"
+msgid "RGB"
+msgstr "RGB"
+
+#: tfgeometricbrush.button_cancel.caption
+msgctxt "tfgeometricbrush.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfgeometricbrush.button_ok.caption
+msgctxt "tfgeometricbrush.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfgeometricbrush.caption
+msgid "Geometric brush"
+msgstr "Pędzel geometryczny"
+
+#: tfgeometricbrush.checkbox_isgradient.caption
+msgid "Opacity gradient"
+msgstr "Gradient krycia"
+
+#: tfgeometricbrush.label1.caption
+msgid "Number of sides:"
+msgstr "Liczba stron:"
+
+#: tfimagelist.caption
+msgid "Image List"
+msgstr "Lista obrazów"
+
+#: tfimagelist.pmautouncheckonopen.caption
+msgid "Autouncheck files after being open"
+msgstr "Automatycznie sprawdzaj pliki po otwarciu"
+
+#: tfimagelist.pmautouncheckonsave.caption
+msgid "Autouncheck files after being edited and saved"
+msgstr "Automatycznie sprawdzaj pliki po edycji i zapisie"
+
+#: tfimagelist.pmremoveall.caption
+msgid "Empty image list"
+msgstr "Pusta lista obrazów"
+
+#: tfimagelist.pmremovenonexistent.caption
+msgid "Remove nonexistent images"
+msgstr "Usuń nieistniejące obrazy"
+
+#: tfimagelist.pmremoveunchecked.caption
+msgid "Remove unchecked images"
+msgstr "Usuń niezaznaczone obrazy"
+
+#: tfimagelist.pmunchecknonexistent.caption
+msgid "Uncheck nonexistent files"
+msgstr "Odznacz nieistniejące pliki"
+
+#: tfimagelist.stringgrid1.columns[0].title.caption
+msgctxt "tfimagelist.stringgrid1.columns[0].title.caption"
+msgid "-"
+msgstr "-"
+
+#: tfimagelist.stringgrid1.columns[1].title.caption
+msgctxt "tfimagelist.stringgrid1.columns[1].title.caption"
+msgid "-"
+msgstr "-"
+
+#: tfimagelist.stringgrid1.columns[2].title.caption
+msgctxt "tfimagelist.stringgrid1.columns[2].title.caption"
+msgid "-"
+msgstr "-"
+
+#: tfimagelist.stringgrid1.columns[3].title.caption
+msgctxt "tfimagelist.stringgrid1.columns[3].title.caption"
+msgid "-"
+msgstr "-"
+
+#: tfimagelist.tbaddfiles.hint
+msgid "Add images to list"
+msgstr "Dodaj obrazy do listy"
+
+#: tfimagelist.tbautouncheck.hint
+msgid "Enable/disable autounchecking for processed files"
+msgstr "Włącz / wyłącz automatyczne sprawdzanie przetworzonych plików"
+
+#: tfimagelist.tbautozoomfit.hint
+msgid "Enable/disable autofitting images in the LazPaint window"
+msgstr "Włącz / wyłącz automatyczne dopasowywanie obrazów w oknie LazPaint"
+
+#: tfimagelist.tbcheckall.hint
+msgid "Check all files for processing"
+msgstr "Sprawdź wszystkie pliki do przetworzenia"
+
+#: tfimagelist.tbminiwindow.hint
+msgid "Switch to miniwindow"
+msgstr "Przełącz na miniokno"
+
+#: tfimagelist.tbmovedown.hint
+msgid "Move selected items down"
+msgstr "Przesuń wybrane elementy w dół"
+
+#: tfimagelist.tbmoveup.hint
+msgid "Move selected items up"
+msgstr "Przesuń wybrane elementy w górę"
+
+#: tfimagelist.tbnormalwindows.hint
+msgid "Switch to normal window"
+msgstr "Przełącz na normalne okno"
+
+#: tfimagelist.tbopenimage.hint
+msgid "Open current image"
+msgstr "Otwórz bieżący obraz"
+
+#: tfimagelist.tbopennext.hint
+msgctxt "tfimagelist.tbopennext.hint"
+msgid "Open next image (Alt-Right)"
+msgstr "Otwórz następny obraz (Alt-Prawy)"
+
+#: tfimagelist.tbopennextsw.hint
+msgctxt "tfimagelist.tbopennextsw.hint"
+msgid "Open next image"
+msgstr "Otwórz następny obraz "
+
+#: tfimagelist.tbopenprev.hint
+msgctxt "tfimagelist.tbopenprev.hint"
+msgid "Open previous image (Alt-Left)"
+msgstr "Otwórz poprzedni obraz (Alt-Lewy)"
+
+#: tfimagelist.tbopenprevsw.hint
+msgctxt "tfimagelist.tbopenprevsw.hint"
+msgid "Open previous image"
+msgstr "Otwórz poprzedni obraz"
+
+#: tfimagelist.tbremoveitem.hint
+msgid "Remove selected images from list"
+msgstr "Usuń wybrane obrazy z listy"
+
+#: tfimagelist.tbuncheckall.hint
+msgid "Uncheck all files for processing"
+msgstr "Odznacz wszystkie pliki do przetwarzania"
+
+#: tflayerstack.caption
+msgctxt "tflayerstack.caption"
+msgid "Layers"
+msgstr "Warstwy"
+
+#: tflayerstack.toolblendop.hint
+msgctxt "tflayerstack.toolblendop.hint"
+msgid "Select blend operation"
+msgstr "Wybierz operację mieszania"
+
+#: tflayerstack.toolzoomlayerstackin.hint
+msgctxt "tflayerstack.toolzoomlayerstackin.hint"
+msgid "Zoom layer stack in"
+msgstr "Powiększ okno warstwy"
+
+#: tflayerstack.toolzoomlayerstackout.hint
+msgctxt "tflayerstack.toolzoomlayerstackout.hint"
+msgid "Zoom layer stack out"
+msgstr "Pomniejsz okno warstwy"
+
+#: tfloading.caption
+msgctxt "tfloading.caption"
+msgid "Loading..."
+msgstr "Ładowanie..."
+
+#: tfmain.brushcreategeometric.hint
+msgctxt "tfmain.brushcreategeometric.hint"
+msgid "Create geometric brush"
+msgstr "Utwórz pędzel geometryczny"
+
+#: tfmain.brushloadfromfile.hint
+msgctxt "tfmain.brushloadfromfile.hint"
+msgid "Load brush from file..."
+msgstr "Załaduj pędzel z pliku..."
+
+#: tfmain.brushremovecurrent.hint
+msgid "Remove current brush"
+msgstr "Usuń bieżący pędzel"
+
+#: tfmain.caption
+msgctxt "tfmain.caption"
+msgid "LazPaint"
+msgstr "LazPaint"
+
+#: tfmain.colorcolorize.caption
+msgid "Colorize..."
+msgstr "Koloruj..."
+
+#: tfmain.colorcurves.caption
+msgid "Curves..."
+msgstr "Krzywe..."
+
+#: tfmain.colordialog1.title
+msgid "Choose color"
+msgstr "Wybierz kolor"
+
+#: tfmain.colorintensity.caption
+msgid "Intensity..."
+msgstr "Intensywność..."
+
+#: tfmain.colorlightness.caption
+#| msgid "Lightness..."
+msgid "Brightness / Contrast..."
+msgstr "Jasność / kontrast..."
+
+#: tfmain.colorposterize.caption
+msgid "Posterize..."
+msgstr "Posteryzuj..."
+
+#: tfmain.colorshiftcolors.caption
+msgctxt "tfmain.colorshiftcolors.caption"
+msgid "Shift colors..."
+msgstr "Zmień kolory..."
+
+#: tfmain.combobox_penstyle.hint
+msgid "Pen style"
+msgstr "Styl pióra"
+
+#: tfmain.editcopy.caption
+msgid "Copy"
+msgstr "Kopiuj"
+
+#: tfmain.editcopy.hint
+msgid "Copy selection"
+msgstr "Kopiuj zaznaczenie"
+
+#: tfmain.editcut.caption
+msgid "Cut"
+msgstr "Wytnij"
+
+#: tfmain.editcut.hint
+msgid "Cut selection"
+msgstr "Wytnij zaznaczenie"
+
+#: tfmain.editdeleteselection.caption
+msgctxt "tfmain.editdeleteselection.caption"
+msgid "Delete"
+msgstr "Usuń"
+
+#: tfmain.editdeleteselection.hint
+msgid "Delete selection"
+msgstr "Usuń zaznaczenie"
+
+#: tfmain.editdeselect.hint
+msgctxt "TFMAIN.EDITDESELECT.HINT"
+msgid "Deselect"
+msgstr "Odznacz"
+
+#: tfmain.editinvertselection.hint
+msgctxt "TFMAIN.EDITINVERTSELECTION.HINT"
+msgid "Invert selection"
+msgstr "Odwróć zaznaczenie"
+
+#: tfmain.editmovedown.hint
+msgid "Move down"
+msgstr "Przesuń w dół"
+
+#: tfmain.editmovetoback.hint
+msgid "Send to back"
+msgstr "Przesuń wstecz"
+
+#: tfmain.editmovetofront.hint
+msgid "Bring to front"
+msgstr "Przesuń na wierzch"
+
+#: tfmain.editmoveup.hint
+msgid "Move up"
+msgstr "Przesuń w górę"
+
+#: tfmain.editpaste.hint
+msgctxt "TFMAIN.EDITPASTE.HINT"
+msgid "Paste"
+msgstr "Wklej"
+
+#: tfmain.editpasteasnew.caption
+msgid "Paste as new image"
+msgstr "Wklej jako nowy obraz"
+
+#: tfmain.editpasteasnewlayer.caption
+msgid "Paste as new layer"
+msgstr "Wklej jako nową warstwę"
+
+#: tfmain.editredo.hint
+msgctxt "TFMAIN.EDITREDO.HINT"
+msgid "Redo"
+msgstr "Ponów"
+
+#: tfmain.editselectall.caption
+msgctxt "tfmain.editselectall.caption"
+msgid "Select all"
+msgstr "Zaznacz wszystko"
+
+#: tfmain.editselectall.hint
+#, fuzzy
+msgctxt "tfmain.editselectall.hint"
+msgid "Select all"
+msgstr "Zaznacz wszystko"
+
+#: tfmain.editselection.caption
+msgid "Edit selection..."
+msgstr "Edytuj zaznaczenie..."
+
+#: tfmain.editselectionfit.caption
+msgid "Selection fit"
+msgstr "Dostosuj"
+
+#: tfmain.editshapealignbottom.hint
+msgid "Align shape to the bottom"
+msgstr "Dopasuj kształt do dołu"
+
+#: tfmain.editshapealignleft.hint
+msgid "Align shape left"
+msgstr "Dopasuj kształt do lewej"
+
+#: tfmain.editshapealignright.hint
+msgid "Align shape right"
+msgstr "Dopasuj kształt do prawej"
+
+#: tfmain.editshapealigntop.hint
+msgid "Align shape to the top"
+msgstr "Dopasuj kształt do góry"
+
+#: tfmain.editshapecenterhorizontally.hint
+msgid "Center shape horizontally"
+msgstr "Wyśrodkuj kształt w poziomie"
+
+#: tfmain.editshapecentervertically.hint
+msgid "Center shape vertically"
+msgstr "Wyśrodkuj kształt w pionie"
+
+#: tfmain.editshapetocurve.hint
+msgid "Convert shape to curve"
+msgstr "Przekształć kształt w krzywą"
+
+#: tfmain.editundo.caption
+msgid "Undo"
+msgstr "Cofnij"
+
+#: tfmain.editundo.hint
+msgid "Undo last modification"
+msgstr "Cofnij ostatnią modyfikację"
+
+#: tfmain.embeddedcancel.caption
+msgctxt "TFMAIN.EMBEDDEDCANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfmain.embeddedcancel.hint
+msgid "Cancel modifications"
+msgstr "Anuluj modyfikacje"
+
+#: tfmain.embeddedvalidate.caption
+msgid "Validate"
+msgstr "Zatwierdź"
+
+#: tfmain.embeddedvalidate.hint
+msgid "Validate modifications"
+msgstr "Zatwierdź modyfikacje"
+
+#: tfmain.exportpicturedialog.title
+msgid "Export as..."
+msgstr "Eksportuj jako..."
+
+#: tfmain.filechooseentry.caption
+msgid "Choose entry..."
+msgstr "Wybierz wpis"
+
+#: tfmain.filechooseentry.hint
+msgid "Choose entry within file"
+msgstr "Wybierz wpis w pliku"
+
+#: tfmain.fileexport.caption
+msgid "Export..."
+msgstr "Eksportuj..."
+
+#: tfmain.fileimport3d.caption
+msgid "Import 3D object..."
+msgstr "Importuj obiekt 3D..."
+
+#: tfmain.fileloadselection.caption
+msgid "Load selection..."
+msgstr "Ładuj zaznaczenie..."
+
+#: tfmain.filenew.caption
+msgid "New..."
+msgstr "Nowy..."
+
+#: tfmain.filenew.hint
+msgid "Create a new file"
+msgstr "Utwórz nowy plik"
+
+#: tfmain.fileopen.caption
+msgid "Open..."
+msgstr "Otwórz..."
+
+#: tfmain.fileopen.hint
+msgctxt "TFMAIN.FILEOPEN.HINT"
+msgid "Open existing file"
+msgstr "Otwórz istniejący plik"
+
+#: tfmain.fileprint.caption
+msgid "Print..."
+msgstr "Drukuj..."
+
+#: tfmain.filequit.hint
+msgctxt "TFMAIN.FILEQUIT.HINT"
+msgid "Quit"
+msgstr "Wyjdź"
+
+#: tfmain.filereload.caption
+msgctxt "tfmain.filereload.caption"
+msgid "Reload"
+msgstr "Przeładuj"
+
+#: tfmain.fileremembersaveformat.hint
+msgid "Remember save format"
+msgstr "Pamiętaj format zapisu"
+
+#: tfmain.filerunscript.caption
+msgid "Run script..."
+msgstr "Uruchom skrypt..."
+
+#: tfmain.filesave.caption
+msgctxt "TFMAIN.FILESAVE.CAPTION"
+msgid "Save"
+msgstr "Zapisz"
+
+#: tfmain.filesave.hint
+msgid "Save current file"
+msgstr "Aktuelle Datei speichern"
+
+#: tfmain.filesaveas.caption
+msgid "Save as..."
+msgstr "Zapisz jako..."
+
+#: tfmain.filesaveas.hint
+msgid "Save file as"
+msgstr "Zapisz plik jako..."
+
+#: tfmain.filesaveasinsamefolder.caption
+msgid "Save in same folder..."
+msgstr "Zapisz w tym samym folderze..."
+
+#: tfmain.filesaveselectionas.caption
+msgctxt "TFMAIN.FILESAVESELECTIONAS.CAPTION"
+msgid "Save selection as..."
+msgstr "Zapisz zaznaczone jako..."
+
+#: tfmain.fileuseimagebrowser.caption
+msgctxt "tfmain.fileuseimagebrowser.caption"
+msgid "Use image browser"
+msgstr "Użyj przeglądarki obrazów"
+
+#: tfmain.filterblurbox.caption
+msgid "Box blur..."
+msgstr "Rozmycie pudełkowe..."
+
+#: tfmain.filterblurcorona.caption
+msgctxt "tfmain.filterblurcorona.caption"
+msgid "Corona blur..."
+msgstr "Rozmycie koronowe..."
+
+#: tfmain.filterblurcustom.caption
+msgctxt "tfmain.filterblurcustom.caption"
+msgid "Custom blur..."
+msgstr "Rozmycie niestandardowe..."
+
+#: tfmain.filterblurdisk.caption
+msgctxt "tfmain.filterblurdisk.caption"
+msgid "Disk blur..."
+msgstr "Rozmycie dyskowe..."
+
+#: tfmain.filterblurfast.caption
+msgctxt "tfmain.filterblurfast.caption"
+msgid "Fast blur..."
+msgstr "Rozmycie szybkie..."
+
+#: tfmain.filterblurmotion.caption
+msgctxt "tfmain.filterblurmotion.caption"
+msgid "Motion blur..."
+msgstr "Rozmycie w ruchu..."
+
+#: tfmain.filterblurprecise.caption
+msgctxt "tfmain.filterblurprecise.caption"
+msgid "Precise blur..."
+msgstr "Rozmycie dokładne..."
+
+#: tfmain.filterblurradial.caption
+msgctxt "tfmain.filterblurradial.caption"
+msgid "Gaussian blur..."
+msgstr "Rozmycie Gaussiana..."
+
+#: tfmain.filtercleartype.caption
+msgid "ClearType"
+msgstr "ClearType"
+
+#: tfmain.filtercleartypeinverse.caption
+msgid "Inverse ClearType"
+msgstr "Odwrotny ClearType"
+
+#: tfmain.filtercomplementarycolor.caption
+msgid "Complementary colors"
+msgstr "Kolory przeciwne"
+
+#: tfmain.filtercontour.caption
+msgid "Contour"
+msgstr "Kontur"
+
+#: tfmain.filtercylinder.caption
+msgid "Cylinder"
+msgstr "Cylinder"
+
+#: tfmain.filteremboss.caption
+msgid "Emboss..."
+msgstr "Tłoczenie..."
+
+#: tfmain.filterfunction.caption
+msgid "Apply function..."
+msgstr "Funkcje..."
+
+#: tfmain.filtergrayscale.caption
+msgid "Grayscale"
+msgstr "Skala szarości"
+
+#: tfmain.filterlinearnegative.caption
+msgctxt "tfmain.filterlinearnegative.caption"
+msgid "Linear negative"
+msgstr "Negatyw liniowy"
+
+#: tfmain.filtermedian.caption
+msgid "Median"
+msgstr "Mediana"
+
+#: tfmain.filternegative.caption
+msgctxt "tfmain.filternegative.caption"
+msgid "Negative"
+msgstr "Negatyw"
+
+#: tfmain.filternoise.caption
+msgid "Noise filter..."
+msgstr "Filtr szumu..."
+
+#: tfmain.filternormalize.caption
+msgid "Normalize"
+msgstr "Normalizuj"
+
+#: tfmain.filterphong.caption
+msgctxt "tfmain.filterphong.caption"
+msgid "Shaded map..."
+msgstr "Mapa cieniowana..."
+
+#: tfmain.filterpixelate.caption
+msgid "Pixelate..."
+msgstr "Pikselizacja..."
+
+#: tfmain.filterplane.caption
+msgid "Plane (slow)"
+msgstr "Poziom (wolno)"
+
+#: tfmain.filterrain.caption
+msgid "Rain..."
+msgstr "Deszcz..."
+
+#: tfmain.filtersharpen.caption
+msgid "Sharpen..."
+msgstr "Wyostrzenie..."
+
+#: tfmain.filtersmooth.caption
+msgid "Smooth"
+msgstr "Wygładzenie"
+
+#: tfmain.filtersphere.caption
+msgctxt "TFMAIN.FILTERSPHERE.CAPTION"
+msgid "Sphere"
+msgstr "Sfera"
+
+#: tfmain.filtertwirl.caption
+msgid "Twirl..."
+msgstr "Wir..."
+
+#: tfmain.filterwavedisplacement.caption
+msgid "Wave displacement..."
+msgstr "Fala zmienna..."
+
+#: tfmain.forgetdialoganswers.caption
+msgid "Forget dialog box answers"
+msgstr "Zapomnij wpisy w oknie dialogowym"
+
+#: tfmain.forgetdialoganswers.hint
+msgid "Forget answers given to dialog boxes"
+msgstr "Zapomnij odpowiedzi w oknie dialogowym"
+
+#: tfmain.helpabout.caption
+msgid "About..."
+msgstr "O programie..."
+
+#: tfmain.helpindex.caption
+msgid "Index..."
+msgstr "Indeks..."
+
+#: tfmain.imagechangecanvassize.caption
+msgid "Canvas size..."
+msgstr "Rozmiar obszaru roboczego..."
+
+#: tfmain.imageclearalpha.caption
+msgid "Clear alpha channel and set background"
+msgstr "Wyczyść kanał alfa i ustaw tło"
+
+#: tfmain.imagecrop.caption
+msgid "Crop to selection"
+msgstr "Przytnij do zaznaczenia"
+
+#: tfmain.imagecroplayer.caption
+msgid "Crop to selection and current layer"
+msgstr "Przytnij do zaznaczenia i bieżącej warstwy"
+
+#: tfmain.imagefillbackground.caption
+msgid "Fill background with antialiasing"
+msgstr "Wypełnij tło z wygładzaniem krawędzi"
+
+#: tfmain.imageflatten.caption
+msgid "Flatten image"
+msgstr "Spłaszcz obraz"
+
+#: tfmain.imagehorizontalflip.caption
+msgctxt "tfmain.imagehorizontalflip.caption"
+msgid "Horizontal flip"
+msgstr "Odbij poziomo"
+
+#: tfmain.imagehorizontalflip.hint
+msgctxt "tfmain.imagehorizontalflip.hint"
+msgid "Flip image horizontally"
+msgstr "Odbij obraz poziomo"
+
+#: tfmain.imagelinearnegative.caption
+msgctxt "tfmain.imagelinearnegative.caption"
+msgid "Linear negative"
+msgstr "Negatyw liniowy"
+
+#: tfmain.imagenegative.caption
+msgctxt "tfmain.imagenegative.caption"
+msgid "Negative"
+msgstr "Negatyw"
+
+#: tfmain.imagerepeat.caption
+msgid "Repeat..."
+msgstr "Powtórz..."
+
+#: tfmain.imageresample.caption
+msgid "Resample..."
+msgstr "Próbkuj ponownie..."
+
+#: tfmain.imageresample.hint
+msgid "Resample image"
+msgstr "Ponownie próbkuj obraz"
+
+#: tfmain.imagerotateccw.caption
+msgid "Rotate 90° CCW"
+msgstr "Obróć o 90° w lewo"
+
+#: tfmain.imagerotatecw.caption
+msgid "Rotate 90° CW"
+msgstr "Obróć o 90° w prawo"
+
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Obróć o 180°"
+
+#: tfmain.imagesmartzoom3.caption
+msgid "Smart zoom x3"
+msgstr "Inteligentny zoom x3"
+
+#: tfmain.imageswapredblue.caption
+msgid "Swap red and blue channels"
+msgstr "Zamień kanały czerwony i niebieski"
+
+#: tfmain.imageverticalflip.caption
+msgctxt "tfmain.imageverticalflip.caption"
+msgid "Vertical flip"
+msgstr "Odbij pionowo"
+
+#: tfmain.imageverticalflip.hint
+msgid "Flip image vertically"
+msgstr "Odbij obraz pionowo"
+
+#: tfmain.image_currenttool.hint
+msgctxt "TFMAIN.IMAGE_CURRENTTOOL.HINT"
+msgid "Selected tool"
+msgstr "Narzędzia zaznaczania"
+
+#: tfmain.image_swapcolors.hint
+msgctxt "tfmain.image_swapcolors.hint"
+msgid "Switch color"
+msgstr "Przełącz kolor"
+
+#: tfmain.itemdocklayersandcolors.caption
+msgid "Dock layers and colors"
+msgstr "Zadokuj warstwy i kolory"
+
+#: tfmain.itemdonate.caption
+msgctxt "tfmain.itemdonate.caption"
+msgid "Donate..."
+msgstr "Wesprzyj..."
+
+#: tfmain.itemfullscreen.caption
+msgid "Fullscreen"
+msgstr "Pełny ekran"
+
+#: tfmain.itemuseimagebrowser.caption
+msgctxt "tfmain.itemuseimagebrowser.caption"
+msgid "Use image browser"
+msgstr "Użyj przeglądarki obrazów"
+
+#: tfmain.itemviewdocktoolbox.caption
+msgid "Dock toolbox"
+msgstr "Zadokuj przybornik"
+
+#: tfmain.label_altitude.caption
+msgid "Altitude"
+msgstr "Wysokość"
+
+#: tfmain.label_back.caption
+msgid "Back"
+msgstr "Wstecz"
+
+#: tfmain.label_brush.caption
+msgctxt "tfmain.label_brush.caption"
+msgid "Brush"
+msgstr "Pędzel"
+
+#: tfmain.label_coordinates.caption
+#, fuzzy
+#| msgid "99999x99999"
+msgid "9999x9999"
+msgstr "99999x99999"
+
+#: tfmain.label_coordinates.hint
+msgid "Coordinates"
+msgstr "Współrzędne"
+
+#: tfmain.label_currentdiff.caption
+msgctxt "TFMAIN.LABEL_CURRENTDIFF.CAPTION"
+msgid "100%"
+msgstr "100%"
+
+#: tfmain.label_currentdiff.hint
+msgid "Color difference"
+msgstr "Różnica kolorów"
+
+#: tfmain.label_currentzoom.caption
+msgctxt "TFMAIN.LABEL_CURRENTZOOM.CAPTION"
+msgid "%"
+msgstr "%"
+
+#: tfmain.label_currentzoom.hint
+msgid "Current zoom"
+msgstr "Bieżące powiększenie"
+
+#: tfmain.label_curve.caption
+msgctxt "TFMAIN.LABEL_CURVE.CAPTION"
+msgid "Curve"
+msgstr "Krzywe"
+
+#: tfmain.label_eraser.caption
+msgctxt "tfmain.label_eraser.caption"
+msgid "Erase"
+msgstr "Gumka"
+
+#: tfmain.label_grid.caption
+msgctxt "TFMAIN.LABEL_GRID.CAPTION"
+msgid "Grid"
+msgstr "Siatka"
+
+#: tfmain.label_gridx.caption
+msgctxt "tfmain.label_gridx.caption"
+msgid "x"
+msgstr "x"
+
+#: tfmain.label_outlinewidth.caption
+msgctxt "tfmain.label_outlinewidth.caption"
+msgid "Width"
+msgstr "Szerokość"
+
+#: tfmain.label_pen.caption
+msgctxt "TFMAIN.LABEL_PEN.CAPTION"
+msgid "Pen"
+msgstr "Próbnik"
+
+#: tfmain.label_penwidth.caption
+msgctxt "tfmain.label_penwidth.caption"
+msgid "Width"
+msgstr "Szerokość"
+
+#: tfmain.label_phongborder.caption
+msgctxt "tfmain.label_phongborder.caption"
+msgid "Border"
+msgstr "Krawędź"
+
+#: tfmain.label_ratio.caption
+msgid "Ratio"
+msgstr "Proporcje"
+
+#: tfmain.label_shadowoffset.caption
+msgctxt "TFMAIN.LABEL_SHADOWOFFSET.CAPTION"
+msgid "Offset"
+msgstr "Offsetowy"
+
+#: tfmain.label_shape.caption
+msgctxt "TFMAIN.LABEL_SHAPE.CAPTION"
+msgid "Shape"
+msgstr "Kształt"
+
+#: tfmain.label_spacing.caption
+msgid "Spacing"
+msgstr "Rozstaw"
+
+#: tfmain.label_text.caption
+msgctxt "TFMAIN.LABEL_TEXT.CAPTION"
+msgid "Text"
+msgstr "Tekst"
+
+#: tfmain.label_textblur.caption
+msgctxt "TFMAIN.LABEL_TEXTBLUR.CAPTION"
+msgid "Blur"
+msgstr "Rozmycie"
+
+#: tfmain.label_tolerance.caption
+msgctxt "tfmain.label_tolerance.caption"
+msgid "Tolerance"
+msgstr "Tolerancja"
+
+#: tfmain.layeraddnew.hint
+msgctxt "tfmain.layeraddnew.hint"
+msgid "Add new layer"
+msgstr "Dodaj nową warstwę"
+
+#: tfmain.layerduplicate.hint
+msgctxt "tfmain.layerduplicate.hint"
+msgid "Duplicate selected layer"
+msgstr "Duplikuj wybraną warstwę"
+
+#: tfmain.layerfromfile.hint
+msgctxt "tfmain.layerfromfile.hint"
+msgid "Import layer from file..."
+msgstr "Importuj warstwę z pliku..."
+
+#: tfmain.layerhorizontalflip.hint
+msgid "Flip layer horizontally"
+msgstr "Odbij warstwę poziomo"
+
+#: tfmain.layermergeover.hint
+msgctxt "tfmain.layermergeover.hint"
+msgid "Merge layer over"
+msgstr "Scal z warstwą poniżej"
+
+#: tfmain.layermove.hint
+msgctxt "tfmain.layermove.hint"
+msgid "Move layer"
+msgstr "Przesuń warstwę"
+
+#: tfmain.layerrasterize.hint
+msgid "Rasterize layer"
+msgstr "Rasteryzuj warstwę"
+
+#: tfmain.layerremovecurrent.hint
+msgctxt "tfmain.layerremovecurrent.hint"
+msgid "Remove layer"
+msgstr "Usuń warstwę"
+
+#: tfmain.layerrotate.hint
+msgctxt "tfmain.layerrotate.hint"
+msgid "Rotate layer"
+msgstr "Obróć warstwę"
+
+#: tfmain.layerverticalflip.hint
+msgctxt "tfmain.layerverticalflip.hint"
+msgid "Flip layer vertically"
+msgstr "Obdij warstwę pionowo"
+
+#: tfmain.layerzoom.hint
+msgid "Zoom layer"
+msgstr "Powiększ warstwę"
+
+#: tfmain.loadselectiondialog.title
+msgid "Load selection"
+msgstr "Ładuj zaznaczone"
+
+#: tfmain.menucolors.caption
+msgctxt "tfmain.menucolors.caption"
+msgid "Colors"
+msgstr "Kolory"
+
+#: tfmain.menucoordinatestoolbar.caption
+msgid "Show coordinates"
+msgstr "Pokaż współrzędne"
+
+#: tfmain.menucopypastetoolbar.caption
+msgid "Show copy/paste toolbar"
+msgstr "Pokaż pasek narzędzi kopiuj/wklej"
+
+#: tfmain.menudocktoolboxleft.caption
+msgid "Dock left"
+msgstr "Dokuj w lewo"
+
+#: tfmain.menudocktoolboxright.caption
+msgid "Dock right"
+msgstr "Dokuj w prawo"
+
+#: tfmain.menuedit.caption
+msgctxt "tfmain.menuedit.caption"
+msgid "Edit"
+msgstr "Edycja"
+
+#: tfmain.menufile.caption
+msgid "File"
+msgstr "Plik"
+
+#: tfmain.menufiletoolbar.caption
+msgid "Show file toolbar"
+msgstr "Pokaż pasek narzędziowy pliku"
+
+#: tfmain.menufilter.caption
+msgctxt "tfmain.menufilter.caption"
+msgid "Filter"
+msgstr "Efekty"
+
+#: tfmain.menuhelp.caption
+msgctxt "tfmain.menuhelp.caption"
+msgid "Help"
+msgstr "Pomoc"
+
+#: tfmain.menuimage.caption
+msgctxt "tfmain.menuimage.caption"
+msgid "Image"
+msgstr "Obraz"
+
+#: tfmain.menulanguage.caption
+msgctxt "tfmain.menulanguage.caption"
+msgid "Language"
+msgstr "Język"
+
+#: tfmain.menuradialblur.caption
+msgctxt "tfmain.menuradialblur.caption"
+msgid "Radial blur"
+msgstr "Rozmycie promieniowe"
+
+#: tfmain.menurecentfiles.caption
+msgctxt "tfmain.menurecentfiles.caption"
+msgid "Recent files"
+msgstr "Ostatnie pliki"
+
+#: tfmain.menuremovetransparency.caption
+msgctxt "tfmain.menuremovetransparency.caption"
+msgid "Remove transparency"
+msgstr "Usuń przezroczystość"
+
+#: tfmain.menurender.caption
+msgctxt "tfmain.menurender.caption"
+msgid "Render"
+msgstr "Renderowanie"
+
+#: tfmain.menuscript.caption
+#, fuzzy
+msgctxt "tfmain.menuscript.caption"
+msgid "Script"
+msgstr "Skrypt"
+
+#: tfmain.menuselect.caption
+msgctxt "tfmain.menuselect.caption"
+msgid "Select"
+msgstr "Zaznaczenie"
+
+#: tfmain.menushowpalette.caption
+msgctxt "tfmain.menushowpalette.caption"
+msgid "Show palette"
+msgstr "Pokaż paletę"
+
+#: tfmain.menutool.caption
+#| msgid "Tool"
+msgctxt "tfmain.menutool.caption"
+msgid "Tools"
+msgstr "Narzędzia"
+
+#: tfmain.menuundocktoolbox.caption
+msgid "Undock"
+msgstr "Oddokuj"
+
+#: tfmain.menuundoredotoolbar.caption
+msgid "Show undo/redo toolbar"
+msgstr "Pokaż pasek narzędzi cofania/ponawiania"
+
+#: tfmain.menuview.caption
+msgctxt "tfmain.menuview.caption"
+msgid "View"
+msgstr "Widok"
+
+#: tfmain.menuzoomtoolbar.caption
+msgid "Show zoom toolbar"
+msgstr "Pokaż pasek narzędzi powiększania"
+
+#: tfmain.open3dobjectdialog.title
+msgctxt "tfmain.open3dobjectdialog.title"
+msgid "Import 3D object"
+msgstr "Importuj obiekt 3D"
+
+#: tfmain.openbrushdialog.title
+msgid "Open brush"
+msgstr "Otwórz pędzel"
+
+#: tfmain.openpicturedialog1.title
+msgid "Open existing image"
+msgstr "Otwórz istniejący obraz"
+
+#: tfmain.opentexturedialog.title
+msgctxt "tfmain.opentexturedialog.title"
+msgid "Open texture"
+msgstr "Otwórz teksturę"
+
+#: tfmain.perspective_repeat.hint
+msgctxt "tfmain.perspective_repeat.hint"
+msgid "Repeat image"
+msgstr "Powtórz obraz"
+
+#: tfmain.perspective_twoplanes.hint
+msgctxt "tfmain.perspective_twoplanes.hint"
+msgid "Draw opposite plane too"
+msgstr "Narysuj również przeciwległą powierzchnię"
+
+#: tfmain.rendercamouflage.caption
+msgid "Camouflage"
+msgstr "Kamuflaż"
+
+#: tfmain.renderclouds.caption
+msgid "Clouds"
+msgstr "Chmury"
+
+#: tfmain.rendercustomwater.caption
+msgid "Water with custom colors"
+msgstr "Woda niestandardowa"
+
+#: tfmain.rendercyclicperlinnoise.caption
+msgctxt "tfmain.rendercyclicperlinnoise.caption"
+msgid "Cyclic Perlin noise"
+msgstr "Szum Perlina (cykliczny)"
+
+#: tfmain.rendermarble.caption
+msgid "Marble"
+msgstr "Marmur"
+
+#: tfmain.rendermetalfloor.caption
+msgid "Metal floor"
+msgstr "Metalowa posadzka"
+
+#: tfmain.renderperlinnoise.caption
+msgid "Perlin noise"
+msgstr "Szum Perlina"
+
+#: tfmain.renderplastik.caption
+msgid "Plastik"
+msgstr "Plastik"
+
+#: tfmain.renderroundstone.caption
+msgid "Round stone"
+msgstr "Wygładzony kamień"
+
+#: tfmain.rendersnowprint.caption
+msgid "Snow print"
+msgstr "Ślady na śniegu"
+
+#: tfmain.renderstone.caption
+msgid "Stone"
+msgstr "Skała"
+
+#: tfmain.renderwater.caption
+msgctxt "tfmain.renderwater.caption"
+msgid "Water"
+msgstr "Woda"
+
+#: tfmain.renderwood.caption
+msgid "Wood"
+msgstr "Drewno"
+
+#: tfmain.renderwoodvertical.caption
+msgid "Vertical wood"
+msgstr "Deska"
+
+#: tfmain.savepicturedialog1.title
+msgid "Save file as..."
+msgstr "Zapisz plik jako..."
+
+#: tfmain.saveselectiondialog.title
+msgctxt "TFMAIN.SAVESELECTIONDIALOG.TITLE"
+msgid "Save selection as..."
+msgstr "Zapisz zaznaczenie jako..."
+
+#: tfmain.selectionhorizontalflip.hint
+msgid "Flip selection horizontally"
+msgstr "Odbij poziomo"
+
+#: tfmain.selectionverticalflip.hint
+msgid "Flip selection vertically"
+msgstr "Odbij pionowo"
+
+#: tfmain.spinedit_arrowsizex.hint
+msgctxt "tfmain.spinedit_arrowsizex.hint"
+msgid "Horizontal size of the arrow"
+msgstr "Poziomy rozmiar strzałki"
+
+#: tfmain.spinedit_arrowsizey.hint
+msgctxt "tfmain.spinedit_arrowsizey.hint"
+msgid "Vertical size of the arrow"
+msgstr "Pionowy rozmiar strzałki"
+
+#: tfmain.spinedit_brushspacing.hint
+msgctxt "tfmain.spinedit_brushspacing.hint"
+msgid "Spacing between patterns"
+msgstr "Odstępy między wzorami"
+
+#: tfmain.spinedit_eraser.hint
+msgctxt "tfmain.spinedit_eraser.hint"
+msgid "Eraser opacity"
+msgstr "Krycie gumki"
+
+#: tfmain.spinedit_penwidth.hint
+msgctxt "tfmain.spinedit_penwidth.hint"
+msgid "Pen width"
+msgstr "Szerokość pióra"
+
+#: tfmain.spinedit_phongbordersize.hint
+msgctxt "tfmain.spinedit_phongbordersize.hint"
+msgid "Border size"
+msgstr "Rozmiar krawędzi"
+
+#: tfmain.spinedit_shapealtitude.hint
+msgctxt "tfmain.spinedit_shapealtitude.hint"
+msgid "Shape altitude"
+msgstr "Głębia cienia"
+
+#: tfmain.spinedit_textblur.hint
+msgctxt "tfmain.spinedit_textblur.hint"
+msgid "Shadow blur"
+msgstr "Rozmycie cienia"
+
+#: tfmain.spinedit_textoutlinewidth.hint
+msgctxt "tfmain.spinedit_textoutlinewidth.hint"
+msgid "Text outline width"
+msgstr "Szerokość konturu tekstu"
+
+#: tfmain.spinedit_textshadowx.hint
+msgctxt "tfmain.spinedit_textshadowx.hint"
+msgid "Horizontal shadow offset"
+msgstr "Poziome przesunięcie cienia"
+
+#: tfmain.spinedit_textshadowy.hint
+msgctxt "tfmain.spinedit_textshadowy.hint"
+msgid "Vertical shadow offset"
+msgstr "Pionowe przesunięcie cienia"
+
+#: tfmain.spinedit_textsize.hint
+msgctxt "tfmain.spinedit_textsize.hint"
+msgid "Text size"
+msgstr "Rozmiar tekstu"
+
+#: tfmain.toolbrush.hint
+msgctxt "tfmain.toolbrush.hint"
+msgid "Brush"
+msgstr "Pędzel"
+
+#: tfmain.toolchangedocking.hint
+msgctxt "tfmain.toolchangedocking.hint"
+msgid "Change docking"
+msgstr "Dokowanie (lewa/prawa)"
+
+#: tfmain.toolclone.hint
+msgid "Clone tool"
+msgstr "Klonowanie"
+
+#: tfmain.toolcolorpicker.hint
+msgctxt "TFMAIN.TOOLCOLORPICKER.HINT"
+msgid "Color picker"
+msgstr "Próbnik koloru"
+
+#: tfmain.tooldeformation.caption
+msgid "Deformation"
+msgstr "Deformacja"
+
+#: tfmain.tooldeformation.hint
+msgid "Deformation grid"
+msgstr "Siatka deformacji"
+
+#: tfmain.tooleditshape.hint
+msgid "Edit shape"
+msgstr "Kształt"
+
+#: tfmain.toolellipse.hint
+msgctxt "TFMAIN.TOOLELLIPSE.HINT"
+msgid "Ellipse"
+msgstr "Elipsa"
+
+#: tfmain.tooleraser.hint
+msgctxt "TFMAIN.TOOLERASER.HINT"
+msgid "Eraser"
+msgstr "Gumka"
+
+#: tfmain.toolfloodfill.hint
+msgid "Floodfill"
+msgstr "Wypełnienie"
+
+#: tfmain.toolgradient.caption
+msgid "Gradient"
+msgstr "Gadient"
+
+#: tfmain.toolgradient.hint
+msgid "Render gradient"
+msgstr "Gradient"
+
+#: tfmain.toolhand.caption
+msgid "Hand"
+msgstr "Rączka"
+
+#: tfmain.toolhand.hint
+msgid "Move and scroll picture"
+msgstr "Rączka"
+
+#: tfmain.toolhotspot.caption
+msgctxt "tfmain.toolhotspot.caption"
+msgid "Hot spot"
+msgstr "Aktywny punkt"
+
+#: tfmain.toolhotspot.hint
+msgid "Choose hot spot of a cursor"
+msgstr "Wybierz aktywny punkt kursora"
+
+#: tfmain.toollayermapping.hint
+msgctxt "tfmain.toollayermapping.hint"
+msgid "Layer perspective"
+msgstr "Perspektywa warstwy"
+
+#: tfmain.toolmagicwand.caption
+msgid "Magic wand"
+msgstr "Magiczna różdżka"
+
+#: tfmain.toolmagicwand.hint
+msgid "Magic wand select"
+msgstr "Magiczna rożdżka"
+
+#: tfmain.toolmoveselection.hint
+msgctxt "TFMAIN.TOOLMOVESELECTION.HINT"
+msgid "Move selection"
+msgstr "Przesuń"
+
+#: tfmain.toolopenedcurve.hint
+msgid "Opened curve"
+msgstr "Krzywa otwarta"
+
+#: tfmain.toolpen.caption
+msgctxt "TFMAIN.TOOLPEN.CAPTION"
+msgid "Pen"
+msgstr "Pióro"
+
+#: tfmain.toolpen.hint
+msgid "Simple pen"
+msgstr "Proste pióro"
+
+#: tfmain.toolphong.hint
+msgctxt "TFMAIN.TOOLPHONG.HINT"
+msgid "Shaded shape"
+msgstr "Cieniowany kształt"
+
+#: tfmain.toolpolygon.caption
+msgid "Polygon"
+msgstr "Wielokąt"
+
+#: tfmain.toolpolygon.hint
+msgid "Polygon or polyline"
+msgstr "Wielokąt lub polilinia"
+
+#: tfmain.toolpolyline.hint
+msgid "Polyline"
+msgstr "Polilinia"
+
+#: tfmain.toolrect.hint
+msgctxt "TFMAIN.TOOLRECT.HINT"
+msgid "Rectangle"
+msgstr "Prostokąt"
+
+#: tfmain.toolrotateselection.hint
+msgctxt "TFMAIN.TOOLROTATESELECTION.HINT"
+msgid "Rotate selection"
+msgstr "Obróć"
+
+#: tfmain.toolselectellipse.hint
+msgctxt "TFMAIN.TOOLSELECTELLIPSE.HINT"
+msgid "Select ellipse"
+msgstr "Elipsa"
+
+#: tfmain.toolselectpen.caption
+msgctxt "tfmain.toolselectpen.caption"
+msgid "Selection pen"
+msgstr "Pióro"
+
+#: tfmain.toolselectpen.hint
+msgctxt "tfmain.toolselectpen.hint"
+msgid "Draw selection with pen"
+msgstr "Pióro"
+
+#: tfmain.toolselectpoly.hint
+msgctxt "TFMAIN.TOOLSELECTPOLY.HINT"
+msgid "Select polygon"
+msgstr "Wielokąt"
+
+#: tfmain.toolselectrect.hint
+msgctxt "TFMAIN.TOOLSELECTRECT.HINT"
+msgid "Select rectangle"
+msgstr "Prostokąt"
+
+#: tfmain.toolselectspline.hint
+msgctxt "tfmain.toolselectspline.hint"
+msgid "Select curve"
+msgstr "Krzywa"
+
+#: tfmain.toolspline.caption
+msgctxt "TFMAIN.TOOLSPLINE.CAPTION"
+msgid "Curve"
+msgstr "Krzywa zamknięta"
+
+#: tfmain.toolspline.hint
+#, fuzzy
+msgctxt "tfmain.toolspline.hint"
+msgid "Curve"
+msgstr "Krzywa zamknięta"
+
+#: tfmain.tooltext.hint
+msgctxt "TFMAIN.TOOLTEXT.HINT"
+msgid "Text"
+msgstr "Tekst"
+
+#: tfmain.tooltexturemapping.hint
+msgctxt "tfmain.tooltexturemapping.hint"
+msgid "Texture mapping"
+msgstr "Mapowanie tekstur"
+
+#: tfmain.tool_aliasing.hint
+msgid "Disable antialiasing"
+msgstr "Wyłącz wygładzanie krawędzi"
+
+#: tfmain.tool_capflat.hint
+msgctxt "TFMAIN.TOOL_CAPFLAT.HINT"
+msgid "Flat cap"
+msgstr "Płaska nasadka"
+
+#: tfmain.tool_capround.hint
+msgctxt "TFMAIN.TOOL_CAPROUND.HINT"
+msgid "Round cap"
+msgstr "Okrągła nasadka"
+
+#: tfmain.tool_capsquare.hint
+msgctxt "TFMAIN.TOOL_CAPSQUARE.HINT"
+msgid "Square cap"
+msgstr "Kwadratowa nasadka"
+
+#: tfmain.tool_closeshape.hint
+msgctxt "tfmain.tool_closeshape.hint"
+msgid "Close shape"
+msgstr "Zamknij kształt"
+
+#: tfmain.tool_curvemodeangle.hint
+msgid "Draw an angle"
+msgstr "Narysuj kąt"
+
+#: tfmain.tool_curvemodeauto.hint
+msgctxt "tfmain.tool_curvemodeauto.hint"
+msgid "Autodetect angles"
+msgstr "Automatyczne wykrywanie kątów"
+
+#: tfmain.tool_curvemodecurve.hint
+msgid "Draw a curve"
+msgstr "Narysuj krzywą"
+
+#: tfmain.tool_curvemovepoint.hint
+msgid "Move point"
+msgstr "Przesuń punkt"
+
+#: tfmain.tool_drawshapeborder.hint
+msgctxt "tfmain.tool_drawshapeborder.hint"
+msgid "Draw border"
+msgstr "Narysuj krawędź"
+
+#: tfmain.tool_erasealpha.hint
+msgctxt "tfmain.tool_erasealpha.hint"
+msgid "Make transparent"
+msgstr "Uczyń przezroczystym"
+
+#: tfmain.tool_eraseblur.hint
+msgctxt "tfmain.tool_eraseblur.hint"
+msgid "Soften"
+msgstr "Zmiękczenie"
+
+#: tfmain.tool_erasedarken.hint
+msgid "Darken"
+msgstr "Ściemnienie"
+
+#: tfmain.tool_eraselighten.hint
+msgid "Lighten"
+msgstr "Rozjaśnienie"
+
+#: tfmain.tool_erasesharpen.hint
+msgid "Sharpen"
+msgstr "Wyostrzenie"
+
+#: tfmain.tool_fillshape.hint
+msgctxt "tfmain.tool_fillshape.hint"
+msgid "Fill shape"
+msgstr "Wypełnij kształt"
+
+#: tfmain.tool_gridmovewithoutdeformation.hint
+msgctxt "tfmain.tool_gridmovewithoutdeformation.hint"
+msgid "Move grid without deformation"
+msgstr "Przesuń siatkę bez deformacji"
+
+#: tfmain.tool_joinbevel.hint
+msgctxt "TFMAIN.TOOL_JOINBEVEL.HINT"
+msgid "Bevel join"
+msgstr "Połączenie fazowane"
+
+#: tfmain.tool_joinmiter.hint
+msgctxt "TFMAIN.TOOL_JOINMITER.HINT"
+msgid "Miter join"
+msgstr "Połączenie ukośne"
+
+#: tfmain.tool_joinround.hint
+msgctxt "TFMAIN.TOOL_JOINROUND.HINT"
+msgid "Round join"
+msgstr "Połączenie okrągłe"
+
+#: tfmain.tool_phongshapecone.hint
+msgctxt "tfmain.tool_phongshapecone.hint"
+msgid "Cone"
+msgstr "Stożek"
+
+#: tfmain.tool_phongshapehorizontalcylinder.hint
+msgctxt "tfmain.tool_phongshapehorizontalcylinder.hint"
+msgid "Horizontal cylinder"
+msgstr "Cylinder poziomy"
+
+#: tfmain.tool_phongshaperectangle.hint
+msgctxt "tfmain.tool_phongshaperectangle.hint"
+msgid "Rectangle"
+msgstr "Prostokąt"
+
+#: tfmain.tool_phongshaperoundrect.hint
+msgctxt "tfmain.tool_phongshaperoundrect.hint"
+msgid "Rounded rectangle"
+msgstr "Prostokąt zaokrąglony"
+
+#: tfmain.tool_phongshapesphere.hint
+msgctxt "tfmain.tool_phongshapesphere.hint"
+msgid "Sphere"
+msgstr "Sfera"
+
+#: tfmain.tool_phongshapeverticalcone.hint
+msgctxt "tfmain.tool_phongshapeverticalcone.hint"
+msgid "Vertical cone"
+msgstr "Stożek pionowy"
+
+#: tfmain.tool_phongshapeverticalcylinder.hint
+msgctxt "tfmain.tool_phongshapeverticalcylinder.hint"
+msgid "Vertical cylinder"
+msgstr "Cylinder pionowy"
+
+#: tfmain.tool_progressivefloodfill.caption
+msgctxt "tfmain.tool_progressivefloodfill.caption"
+msgid "Progressive floodfill"
+msgstr "Wypełnienie progresywne"
+
+#: tfmain.tool_progressivefloodfill.hint
+msgctxt "tfmain.tool_progressivefloodfill.hint"
+msgid "Progressive floodfill"
+msgstr "Wypełnienie progresywne"
+
+#: tfmain.tool_textaligncenter.hint
+msgid "Center"
+msgstr "Wyśrodkuj"
+
+#: tfmain.tool_textalignleft.hint
+msgid "Align left"
+msgstr "Wyrównaj do lewej"
+
+#: tfmain.tool_textalignright.hint
+msgid "Align right"
+msgstr "Wyrównaj do prawej"
+
+#: tfmain.tool_textfont.hint
+msgctxt "TFMAIN.TOOL_TEXTFONT.HINT"
+msgid "Choose font..."
+msgstr "Wybierz czcionkę..."
+
+#: tfmain.tool_textoutline.hint
+#| msgid "Progressive floodfill"
+msgctxt "TFMAIN.TOOL_TEXTOUTLINE.HINT"
+msgid "Text outline"
+msgstr "Zarys tekstu"
+
+#: tfmain.tool_textphong.hint
+msgctxt "TFMAIN.TOOL_TEXTPHONG.HINT"
+msgid "Text phong shading"
+msgstr "Cień tekstu phong"
+
+#: tfmain.tool_textshadow.hint
+msgctxt "TFMAIN.TOOL_TEXTSHADOW.HINT"
+msgid "Text shadow"
+msgstr "Cień tekstu"
+
+#: tfmain.viewcolors.caption
+msgctxt "TFMAIN.VIEWCOLORS.CAPTION"
+msgid "Colors"
+msgstr "Kolory"
+
+#: tfmain.viewdarktheme.caption
+msgid "Dark theme"
+msgstr "Ciemny motyw"
+
+#: tfmain.viewgrid.caption
+msgctxt "TFMAIN.VIEWGRID.CAPTION"
+msgid "Grid"
+msgstr "Siatka"
+
+#: tfmain.viewimagelist.caption
+msgid "Image list"
+msgstr "Lista obrazów"
+
+#: tfmain.viewlayerstack.caption
+msgctxt "tfmain.viewlayerstack.caption"
+msgid "Layers"
+msgstr "Warstwy"
+
+#: tfmain.viewlayerstackbutton.caption
+msgctxt "tfmain.viewlayerstackbutton.caption"
+msgid "Show layers"
+msgstr "Pokaż warstwy"
+
+#: tfmain.viewlayerstackbutton.hint
+msgctxt "tfmain.viewlayerstackbutton.hint"
+msgid "Show or hide layer stack window"
+msgstr "Pokaż lub ukryj okno stosu warstw"
+
+#: tfmain.viewpalette.caption
+msgctxt "tfmain.viewpalette.caption"
+msgid "Palette"
+msgstr "Paleta"
+
+#: tfmain.viewstatusbar.caption
+msgid "Status bar"
+msgstr "Pasek stanu"
+
+#: tfmain.viewtoolbox.caption
+msgid "Toolbox"
+msgstr "Przybornik"
+
+#: tfmain.viewworkspacecolor.caption
+msgid "Set workspace color..."
+msgstr "Kolor obszaru roboczego..."
+
+#: tfmain.viewzoomfit.caption
+msgctxt "tfmain.viewzoomfit.caption"
+msgid "Zoom fit"
+msgstr "Dopasuj powiększenie"
+
+#: tfmain.viewzoomfit.hint
+msgctxt "TFMAIN.VIEWZOOMFIT.HINT"
+msgid "Zoom to fit in the window"
+msgstr "Dopasuj powiększenie do okna"
+
+#: tfmain.viewzoomin.hint
+msgctxt "TFMAIN.VIEWZOOMIN.HINT"
+msgid "Zoom in"
+msgstr "Powiększ"
+
+#: tfmain.viewzoomoriginal.caption
+msgctxt "TFMAIN.VIEWZOOMORIGINAL.CAPTION"
+msgid "Original size"
+msgstr "Oryginalny rozmiar"
+
+#: tfmain.viewzoomoriginal.hint
+msgid "Zoom to original pixel size"
+msgstr "Powiększ do oryginalnego rozmiaru w pikselach"
+
+#: tfmain.viewzoomout.hint
+msgctxt "TFMAIN.VIEWZOOMOUT.HINT"
+msgid "Zoom out"
+msgstr "Zmniejsz"
+
+#: tfmotionblur.button_cancel.caption
+msgctxt "TFMOTIONBLUR.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfmotionblur.button_ok.caption
+msgctxt "TFMOTIONBLUR.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfmotionblur.caption
+msgctxt "tfmotionblur.caption"
+msgid "Motion blur"
+msgstr "Rozmycie w ruchu"
+
+#: tfmotionblur.checkbox_oriented.caption
+msgid "Oriented"
+msgstr "Zorientowane"
+
+#: tfmotionblur.label_distance.caption
+msgctxt "tfmotionblur.label_distance.caption"
+msgid "Distance :"
+msgstr "Dystans:"
+
+#: tfmultiimage.button_cancel.caption
+msgctxt "tfmultiimage.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfmultiimage.button_ok.caption
+msgctxt "tfmultiimage.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfmultiimage.caption
+msgid "Choose image"
+msgstr "Wybierz obraz"
+
+#: tfnewimage.button_cancel.caption
+msgctxt "TFNEWIMAGE.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfnewimage.button_ok.caption
+msgctxt "TFNEWIMAGE.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfnewimage.caption
+msgctxt "tfnewimage.caption"
+msgid "New image"
+msgstr "Nowy obraz"
+
+#: tfnewimage.combobox_bitdepth.text
+msgid "32"
+msgstr ""
+
+#: tfnewimage.label_bitdepth.caption
+msgid "Bit depth :"
+msgstr "Głębia bitowa:"
+
+#: tfnewimage.label_height.caption
+msgctxt "tfnewimage.label_height.caption"
+msgid "Height :"
+msgstr "Wysokość:"
+
+#: tfnewimage.label_height1.caption
+msgid "Ratio :"
+msgstr "Proporcje:"
+
+#: tfnewimage.label_memoryrequired.caption
+msgid "Memory required :"
+msgstr "Wymagana pamięć:"
+
+#: tfnewimage.label_width.caption
+msgctxt "tfnewimage.label_width.caption"
+msgid "Width :"
+msgstr "Szerokość:"
+
+#: tfnoisefilter.button_cancel.caption
+msgctxt "tfnoisefilter.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfnoisefilter.button_ok.caption
+msgctxt "tfnoisefilter.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfnoisefilter.caption
+msgid "Noise filter"
+msgstr "Filtr szumu"
+
+#: tfnoisefilter.label_opacity.caption
+msgid "Opacity:"
+msgstr "Krycie:"
+
+#: tfnoisefilter.radio_grayscalenoise.caption
+msgid "Grayscale noise"
+msgstr "Szum w skali szarości"
+
+#: tfnoisefilter.radio_rgbnoise.caption
+msgid "RGB noise"
+msgstr "Szum RGB"
+
+#: tfobject3d.button_cancel.caption
+msgctxt "tfobject3d.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfobject3d.button_loadtex.caption
+msgid "Texture..."
+msgstr "Tekstura..."
+
+#: tfobject3d.button_notex.caption
+msgid "No tex."
+msgstr "Bez tekst."
+
+#: tfobject3d.button_ok.caption
+msgctxt "tfobject3d.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfobject3d.caption
+msgid "3D object"
+msgstr "Obiekt 3D"
+
+#: tfobject3d.checkbox_antialiasing.caption
+msgid "Antialiasing"
+msgstr "Wygładzanie krawędzi"
+
+#: tfobject3d.checkbox_biface.caption
+msgid "2-sided faces"
+msgstr "Powierzchnia dwustronna"
+
+#: tfobject3d.checkbox_textureinterp.caption
+msgid "Texture interpolation"
+msgstr "Interpolacja tekstur"
+
+#: tfobject3d.groupbox_selectedlight.caption
+msgid "Selected light"
+msgstr "Wybrane źródło światła"
+
+#: tfobject3d.groupbox_selectedmaterial.caption
+msgctxt "tfobject3d.groupbox_selectedmaterial.caption"
+msgid "Selected material"
+msgstr "Wybrany materiał"
+
+#: tfobject3d.label_color.caption
+msgctxt "tfobject3d.label_color.caption"
+msgid "Color :"
+msgstr "Kolor:"
+
+#: tfobject3d.label_color1.caption
+msgctxt "tfobject3d.label_color1.caption"
+msgid "Color :"
+msgstr "Kolor:"
+
+#: tfobject3d.label_height.caption
+msgctxt "tfobject3d.label_height.caption"
+msgid "Height :"
+msgstr "Wysokość:"
+
+#: tfobject3d.label_lightingnormals.caption
+msgctxt "tfobject3d.label_lightingnormals.caption"
+msgid "Lighting normals :"
+msgstr "Normalne oświetlenie:"
+
+#: tfobject3d.label_lights.caption
+msgid "Lights :"
+msgstr "Światła:"
+
+#: tfobject3d.label_materials.caption
+msgctxt "tfobject3d.label_materials.caption"
+msgid "Materials :"
+msgstr "Materiały:"
+
+#: tfobject3d.label_opacity.caption
+msgctxt "tfobject3d.label_opacity.caption"
+msgid "Opacity :"
+msgstr "Krycie:"
+
+#: tfobject3d.label_specularindex.caption
+msgctxt "tfobject3d.label_specularindex.caption"
+msgid "Spec. index :"
+msgstr "Współczynnik załamania światła:"
+
+#: tfobject3d.label_width.caption
+msgctxt "tfobject3d.label_width.caption"
+msgid "Width :"
+msgstr "Szerokość:"
+
+#: tfobject3d.label_zoom.caption
+msgctxt "tfobject3d.label_zoom.caption"
+msgid "Zoom"
+msgstr "Powiększenie"
+
+#: tfobject3d.lights.caption
+msgid "Lights"
+msgstr "Światła"
+
+#: tfobject3d.materials.caption
+msgid "Materials"
+msgstr "Materiały"
+
+#: tfobject3d.opentexturedialog.title
+msgctxt "tfobject3d.opentexturedialog.title"
+msgid "Open texture"
+msgstr "Twórz teksturę"
+
+#: tfobject3d.rendering.caption
+msgid "Rendering"
+msgstr "Renderowanie"
+
+#: tfobject3d.tooladddirectional.hint
+msgid "Add a directional light"
+msgstr "Dodaj światło kierunkowe"
+
+#: tfobject3d.toolpointlight.hint
+msgid "Add a point light"
+msgstr "Dodaj światło punktowe"
+
+#: tfobject3d.toolremoveselectedlight.hint
+msgid "Remove selected light"
+msgstr "Usuń wybrane światło"
+
+#: tfphongfilter.button_cancel.caption
+msgctxt "tfphongfilter.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfphongfilter.button_ok.caption
+msgctxt "tfphongfilter.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfphongfilter.caption
+msgctxt "tfphongfilter.caption"
+msgid "Shaded map"
+msgstr "Mapa cieniowana"
+
+#: tfphongfilter.groupbox_color.caption
+msgctxt "tfphongfilter.groupbox_color.caption"
+msgid "Color"
+msgstr "Kolor"
+
+#: tfphongfilter.groupbox_color1.caption
+msgid "Altitude map"
+msgstr "Mapa wysokości"
+
+#: tfphongfilter.label_altitude.caption
+msgid "Global altitude :"
+msgstr "Globalna wysokość:"
+
+#: tfphongfilter.label_lightposition.caption
+msgid "Light position :"
+msgstr "Pozycja światła:"
+
+#: tfphongfilter.radio_mapalpha.caption
+msgid "Alpha"
+msgstr "Alfa"
+
+#: tfphongfilter.radio_mapblue.caption
+msgid "B"
+msgstr "B"
+
+#: tfphongfilter.radio_mapgreen.caption
+msgid "G"
+msgstr "G"
+
+#: tfphongfilter.radio_maplightness.caption
+msgctxt "tfphongfilter.radio_maplightness.caption"
+msgid "Lightness"
+msgstr "Jasność"
+
+#: tfphongfilter.radio_maplinearlightness.caption
+msgid "Linear lightness"
+msgstr "Jasność liniowa"
+
+#: tfphongfilter.radio_mapred.caption
+msgid "R"
+msgstr "R"
+
+#: tfphongfilter.radio_mapsaturation.caption
+msgctxt "tfphongfilter.radio_mapsaturation.caption"
+msgid "Saturation"
+msgstr "Nasycenie"
+
+#: tfphongfilter.radio_usebackcolor.caption
+msgid "Back color"
+msgstr "Kolor tła"
+
+#: tfphongfilter.radio_usekeep.caption
+msgid "Keep"
+msgstr "Trzymaj"
+
+#: tfphongfilter.radio_usepencolor.caption
+msgid "Pen color"
+msgstr "Kolor pióra"
+
+#: tfphongfilter.radio_usetexture.caption
+msgctxt "tfphongfilter.radio_usetexture.caption"
+msgid "Current texture"
+msgstr "Bieżąca tekstura"
+
+#: tfpixelate.button_cancel.caption
+msgctxt "TFPIXELATE.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfpixelate.button_ok.caption
+msgctxt "TFPIXELATE.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfpixelate.caption
+msgctxt "tfpixelate.caption"
+msgid "Pixelate"
+msgstr "Pikselizacja"
+
+#: tfpixelate.label_pixelsize.caption
+msgctxt "tfpixelate.label_pixelsize.caption"
+msgid "Pixel size :"
+msgstr "Rozmiar piksela:"
+
+#: tfpixelate.label_quality.caption
+msgctxt "tfpixelate.label_quality.caption"
+msgid "Quality :"
+msgstr "Metoda:"
+
+#: tfposterize.button_cancel.caption
+msgctxt "tfposterize.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfposterize.button_ok.caption
+msgctxt "tfposterize.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfposterize.caption
+msgctxt "tfposterize.caption"
+msgid "Posterize"
+msgstr "Posteryzuj"
+
+#: tfposterize.checkbox_bylightness.caption
+msgid "By lightness"
+msgstr "jasnością"
+
+#: tfposterize.label_levels.caption
+msgid "Levels :"
+msgstr "Poziomy:"
+
+#: tfpreviewdialog.caption
+msgid "Preview"
+msgstr "Podgląd"
+
+#: tfpreviewdialog.lstatus.caption
+msgctxt "tfpreviewdialog.lstatus.caption"
+msgid "."
+msgstr "."
+
+#: tfprint.button_configureprinter.caption
+msgid "Configure..."
+msgstr "Konfiguracja..."
+
+#: tfprint.button_print.caption
+msgid "Print!"
+msgstr "Drukuj!"
+
+#: tfprint.button_zoomfit.caption
+msgctxt "tfprint.button_zoomfit.caption"
+msgid "Zoom fit"
+msgstr "Dopasuj powiększenie"
+
+#: tfprint.caption
+msgid "Print"
+msgstr "Drukuj"
+
+#: tfprint.checkbox_ratio.caption
+msgctxt "tfprint.checkbox_ratio.caption"
+msgid "Keep aspect ratio"
+msgstr "Zachowaj proporcje"
+
+#: tfprint.groupbox_imagesize.caption
+msgid "Image size"
+msgstr "Rozmiar obrazu"
+
+#: tfprint.groupbox_margins.caption
+msgid "Margins"
+msgstr "Marginesy"
+
+#: tfprint.label_bottom.caption
+msgid "Bottom:"
+msgstr "Dolny:"
+
+#: tfprint.label_dpix.caption
+msgctxt "tfprint.label_dpix.caption"
+msgid "."
+msgstr "."
+
+#: tfprint.label_dpiy.caption
+msgctxt "tfprint.label_dpiy.caption"
+msgid "."
+msgstr "."
+
+#: tfprint.label_height.caption
+msgid "Height:"
+msgstr "Górny:"
+
+#: tfprint.label_left.caption
+msgid "Left:"
+msgstr "Lewy:"
+
+#: tfprint.label_orientation.caption
+msgid "Orientation:"
+msgstr "Oientacja:"
+
+#: tfprint.label_printerandpaper.caption
+msgid "Printer and paper:"
+msgstr "Drukarka i papier:"
+
+#: tfprint.label_right.caption
+msgid "Right:"
+msgstr "Prawy:"
+
+#: tfprint.label_top.caption
+msgid "Top:"
+msgstr "Góra:"
+
+#: tfprint.label_width.caption
+msgid "Width:"
+msgstr "Szerokość:"
+
+#: tfquestion.caption
+msgid "Question"
+msgstr "Pytanie"
+
+#: tfquestion.checkbox_rememberchoice.caption
+msgid "Remember this choice"
+msgstr "Zapamiętaj ten wybór"
+
+#: tfquestion.label_message.caption
+msgctxt "tfquestion.label_message.caption"
+msgid "."
+msgstr "."
+
+#: tfradialblur.button_cancel.caption
+msgctxt "TFRADIALBLUR.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfradialblur.button_ok.caption
+msgctxt "TFRADIALBLUR.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfradialblur.caption
+msgctxt "tfradialblur.caption"
+msgid "Radial blur"
+msgstr "Rozmycie promieniowe"
+
+#: tfradialblur.label_radius.caption
+msgctxt "tfradialblur.label_radius.caption"
+msgid "Radius :"
+msgstr "Promień:"
+
+#: tfrain.button_cancel.caption
+msgctxt "tfrain.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfrain.button_ok.caption
+msgctxt "tfrain.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfrain.caption
+msgid "Rain"
+msgstr "Deszcz"
+
+#: tfrain.label_quantity.caption
+msgid "Quantity:"
+msgstr "Siła:"
+
+#: tfrain.label_wind.caption
+msgid "Wind :"
+msgstr "Wiatr:"
+
+#: tfresample.button_cancel.caption
+msgctxt "TFRESAMPLE.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfresample.button_ok.caption
+msgctxt "TFRESAMPLE.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfresample.caption
+msgctxt "tfresample.caption"
+msgid "Resample"
+msgstr "Próbkuj ponownie"
+
+#: tfresample.checkbox_ratio.caption
+msgctxt "tfresample.checkbox_ratio.caption"
+msgid "Keep aspect ratio"
+msgstr "Zachowaj proporcje"
+
+#: tfresample.label_height.caption
+msgctxt "tfresample.label_height.caption"
+msgid "Height :"
+msgstr "Wysokość:"
+
+#: tfresample.label_quality.caption
+msgctxt "tfresample.label_quality.caption"
+msgid "Quality :"
+msgstr "Jakość:"
+
+#: tfresample.label_width.caption
+msgctxt "tfresample.label_width.caption"
+msgid "Width :"
+msgstr "Szerokość:"
+
+#: tfsaveoption.button_cancel.caption
+msgctxt "tfsaveoption.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfsaveoption.button_ok.caption
+msgctxt "tfsaveoption.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfsaveoption.caption
+msgctxt "tfsaveoption.caption"
+msgid "Save"
+msgstr "Zapisz"
+
+#: tfsaveoption.checkbox_dithering.caption
+msgid "Dithering"
+msgstr "Ditering"
+
+#: tfsaveoption.label1.caption
+msgid "Quality:"
+msgstr "Jakość:"
+
+#: tfsaveoption.label_0.caption
+msgid "0"
+msgstr "0"
+
+#: tfsaveoption.label_1.caption
+msgid "100"
+msgstr "100"
+
+#: tfsaveoption.label_50.caption
+msgid "50"
+msgstr "50"
+
+#: tfsaveoption.label_colordepth.caption
+msgid "Color depth:"
+msgstr "Głębia koloru:"
+
+#: tfsaveoption.label_size.caption
+msgid "Size:"
+msgstr "Rozmiar:"
+
+#: tfsaveoption.radiobutton_16colors.caption
+msgid "16 colors"
+msgstr "16 kolorów"
+
+#: tfsaveoption.radiobutton_24bitsperpixel.caption
+msgid "24 bits"
+msgstr "24 kolory"
+
+#: tfsaveoption.radiobutton_256colors.caption
+msgid "256 colors"
+msgstr "256 kolorów"
+
+#: tfsaveoption.radiobutton_2colors.caption
+msgid "2 colors"
+msgstr "2 kolory"
+
+#: tfsaveoption.radiobutton_32bitsperpixel.caption
+msgid "32 bits"
+msgstr "32 bity"
+
+#: tfsaveoption.radiobutton_miomap.caption
+msgid "MioMap"
+msgstr "Nawigacja"
+
+#: tfsharpen.button_cancel.caption
+msgctxt "tfsharpen.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfsharpen.button_ok.caption
+msgctxt "tfsharpen.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfsharpen.caption
+msgid "Sharpen/Smooth"
+msgstr "Wyostrz / Wygładź"
+
+#: tfsharpen.label_amount.caption
+msgctxt "tfsharpen.label_amount.caption"
+msgid "Amount :"
+msgstr "Siła:"
+
+#: tfshiftcolors.button_cancel.caption
+msgctxt "TFSHIFTCOLORS.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfshiftcolors.button_ok.caption
+msgctxt "TFSHIFTCOLORS.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tfshiftcolors.caption
+msgctxt "tfshiftcolors.caption"
+msgid "Shift colors"
+msgstr "Przełącz kolory"
+
+#: tfshiftcolors.checkbox_gsba.caption
+msgctxt "tfshiftcolors.checkbox_gsba.caption"
+msgid "Corrected hue and lightness"
+msgstr "Popraw odcień i jasność"
+
+#: tfshiftcolors.label1.caption
+msgctxt "TFSHIFTCOLORS.LABEL1.CAPTION"
+msgid "Hue"
+msgstr "Odcień"
+
+#: tfshiftcolors.label2.caption
+msgctxt "TFSHIFTCOLORS.LABEL2.CAPTION"
+msgid "Saturation"
+msgstr "Jasność"
+
+#: tftoolbox.caption
+msgctxt "tftoolbox.caption"
+msgid "Tools"
+msgstr "Narzędzia"
+
+#: tftwirl.button_cancel.caption
+msgctxt "TFTWIRL.BUTTON_CANCEL.CAPTION"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tftwirl.button_ok.caption
+msgctxt "TFTWIRL.BUTTON_OK.CAPTION"
+msgid "OK"
+msgstr "OK"
+
+#: tftwirl.caption
+msgctxt "tftwirl.caption"
+msgid "Twirl"
+msgstr "Wir"
+
+#: tftwirl.label_angle.caption
+msgctxt "tftwirl.label_angle.caption"
+msgid "Angle :"
+msgstr "Kąt:"
+
+#: tftwirl.label_radius.caption
+msgctxt "tftwirl.label_radius.caption"
+msgid "Radius :"
+msgstr "Promień:"
+
+#: tfwavedisplacement.button_cancel.caption
+msgctxt "tfwavedisplacement.button_cancel.caption"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: tfwavedisplacement.button_ok.caption
+msgctxt "tfwavedisplacement.button_ok.caption"
+msgid "OK"
+msgstr "OK"
+
+#: tfwavedisplacement.caption
+msgid "Wave displacement"
+msgstr "Przesunięcie fali"
+
+#: tfwavedisplacement.label_displacement.caption
+msgid "Displacement :"
+msgstr "Przesunięcie:"
+
+#: tfwavedisplacement.label_phase.caption
+msgid "Phase :"
+msgstr "Faza:"
+
+#: tfwavedisplacement.label_wavelength.caption
+msgid "Wavelength :"
+msgstr "Długość fali:"
+
+#: uresourcestrings.rsactioninprogress
+msgid "Action in progress"
+msgstr "Wykonywanie akcji..."
+
+#: uresourcestrings.rsaddtoimagelist
+msgid "Add files to the image processing list"
+msgstr "Dodaj pliki do listy przetwarzania obrazów"
+
+#: uresourcestrings.rsalignshape
+msgid "Align shape"
+msgstr "Dopasuj kształt"
+
+#: uresourcestrings.rsallapplications
+msgid "all"
+msgstr "wszystkie"
+
+#: uresourcestrings.rsallsupportedfiletypes
+msgid "All supported filetypes"
+msgstr "Wszystkie obsługiwane typy plików"
+
+#: uresourcestrings.rsalt
+msgid "ALT"
+msgstr "ALT"
+
+#: uresourcestrings.rsanimatedgif
+msgid "Animated GIF"
+msgstr "Animowane GIF"
+
+#: uresourcestrings.rsautodetect
+msgid "Autodetect"
+msgstr "Automatycznie"
+
+#: uresourcestrings.rsbackspaceremovelastpoint
+msgid "Press BACKSPACE to remove last point"
+msgstr "Naciśnij BACKSPACE, aby usunąć ostatni punkt"
+
+#: uresourcestrings.rsbestquality
+msgid "Best quality"
+msgstr "Najlepsza jakość"
+
+#: uresourcestrings.rsbitmap
+msgid "Bitmap"
+msgstr "Bitmap"
+
+#: uresourcestrings.rsblendopnotusedforbackground
+msgid "The blend operation is applied only if there is a layer underneath"
+msgstr "Operacja mieszania jest stosowana tylko wtedy, gdy poniżej znajduje się warstwa"
+
+#: uresourcestrings.rsblue
+msgid "Blue"
+msgstr "Niebieski"
+
+#: uresourcestrings.rsbrightness
+msgid "Brightness"
+msgstr "Jasność"
+
+#: uresourcestrings.rsbytes
+msgid "Bytes"
+msgstr "Bajtów"
+
+#: uresourcestrings.rscancel
+msgctxt "uresourcestrings.rscancel"
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: uresourcestrings.rscancelledbyuser
+msgid "Cancelled by user"
+msgstr "Anulowane przez użytkownika"
+
+#: uresourcestrings.rscannotdrawshapeonsvglayer
+msgid "Cannot draw shape on SVG layer"
+msgstr "Nie można narysować kształtu na warstwie SVG"
+
+#: uresourcestrings.rscannotopenfile
+msgid "Cannot open file"
+msgstr "Nie można otworzyć pliku"
+
+#: uresourcestrings.rscanvassize
+msgctxt "uresourcestrings.rscanvassize"
+msgid "Canvas size"
+msgstr "Rozmiar obszaru roboczego"
+
+#: uresourcestrings.rscdrom
+msgid "CD"
+msgstr "CD"
+
+#: uresourcestrings.rsclearpalette
+msgid "Clear palette"
+msgstr "Wyczyść paletę"
+
+#: uresourcestrings.rscloserequest
+msgid "Close request"
+msgstr "Zamknij polecenie"
+
+#: uresourcestrings.rscmd
+msgid "CMD"
+msgstr "CMD"
+
+#: uresourcestrings.rscolors
+msgctxt "uresourcestrings.rscolors"
+msgid "Colors"
+msgstr "Kolory"
+
+#: uresourcestrings.rsconfirmdeletefromcontainer
+msgid "Are you sure you want to delete this file from the container?"
+msgstr "Na pewno chcesz usunąć ten plik z kontenera?"
+
+#: uresourcestrings.rsconfirmdeletemultiplefromcontainer
+msgid "Are you sure you want to delete these %1 files from the container?"
+msgstr "Na pewno chcesz usunąć plik %1 z kontenera?"
+
+#: uresourcestrings.rsconfirmmovemultipletotrash
+msgid "Are you sure you want to move these %1 files to the trash?"
+msgstr "Na pewno chcesz przenieść %1 plików do kosza?"
+
+#: uresourcestrings.rsconfirmmovetotrash
+msgid "Are you sure you want to move this file to the trash?"
+msgstr "Czy na pewno chcesz przenieść ten plik do kosza?"
+
+#: uresourcestrings.rsconflictingactions
+msgid "Conflicting actions"
+msgstr "Sprzeczne akcje"
+
+#: uresourcestrings.rscontrast
+msgid "Contrast"
+msgstr "Kontrast"
+
+#: uresourcestrings.rscorrectedhueccw
+msgctxt "uresourcestrings.rscorrectedhueccw"
+msgid "Corr. Hue CCW"
+msgstr "Kor. odc. CCW"
+
+#: uresourcestrings.rscorrectedhuecw
+msgctxt "uresourcestrings.rscorrectedhuecw"
+msgid "Corr. Hue CW"
+msgstr "Kor. odc. CW"
+
+#: uresourcestrings.rscosine
+msgid "Cosine"
+msgstr "Cosinus"
+
+#: uresourcestrings.rscrop
+msgid "Crop"
+msgstr "Przytnij"
+
+#: uresourcestrings.rsctrl
+msgid "CTRL"
+msgstr "CTRL"
+
+#: uresourcestrings.rscurvemodehint
+msgid "Press S or X to set the curve mode of the last point"
+msgstr "Naciśnij S lub X, aby ustawić tryb krzywej ostatniego punktu"
+
+#: uresourcestrings.rsdefaultpalette
+msgid "Default palette"
+msgstr "Paleta domyślna"
+
+#: uresourcestrings.rsdeletefile
+msgctxt "uresourcestrings.rsdeletefile"
+msgid "Delete"
+msgstr "Usuń"
+
+#: uresourcestrings.rsdeleteimageentry
+msgid "Delete selected image entry?"
+msgstr "Usunąć wybrany zapis obrazu?"
+
+#: uresourcestrings.rsdirectorynotempty
+msgid "Directory is not empty"
+msgstr "Katalog nie jest pusty"
+
+#: uresourcestrings.rsditherlayerusingpalette
+msgid "Dither layer using palette"
+msgstr "Diteruj warstwę za pomocą palety"
+
+#: uresourcestrings.rsduplicateimage
+msgid "Duplicate image"
+msgstr "Duplikuj obraz"
+
+#: uresourcestrings.rseditmask
+msgid "Edit mask"
+msgstr "Edytuj maskę"
+
+#: uresourcestrings.rseditselection
+msgid "Edit selection"
+msgstr "Edytuj zaznaczenie"
+
+#: uresourcestrings.rsedittexture
+msgid "Edit texture"
+msgstr "Edytuj teksturę"
+
+#: uresourcestrings.rsemptylayer
+msgid "Layer is empty"
+msgstr "Warstwa jest pusta"
+
+#: uresourcestrings.rsemptyselection
+msgid "Selection is empty"
+msgstr "Zaznaczenie jest puste"
+
+#: uresourcestrings.rsendwithoutmatchingbegin
+msgid "End without matching begin"
+msgstr "Koniec bez początku"
+
+#: uresourcestrings.rsenterfolderorcontainername
+msgid "Enter name for new folder or container (using RES or LRS extension):"
+msgstr "Wpisz nazwę nowego folderu lub kontenera (używając rozszerzenia RES lub LRS):"
+
+#: uresourcestrings.rsenterlayername
+msgid "Enter layer name:"
+msgstr "Wpisz nazwę warstwy:"
+
+#: uresourcestrings.rsentries
+msgid "Entries"
+msgstr "Wpisy"
+
+#: uresourcestrings.rserror
+msgid "Error"
+msgstr "Błąd"
+
+#: uresourcestrings.rserrordecodingraw
+msgid "Error decoding raw image."
+msgstr "Błąd podczas dekodowania RAW obrazu."
+
+#: uresourcestrings.rserrorloadingoriginal
+msgid "Error while loading original however layer can be rasterized."
+msgstr "Błąd podczas ładowania oryginału, jednak warstwa może zostać rasteryzowana"
+
+#: uresourcestrings.rserroronopeningfile
+msgid "Error on opening file \"%1\""
+msgstr "Błąd otwarcia pliku \"%1\""
+
+#: uresourcestrings.rsexception
+msgid "An exception was encountered"
+msgstr "Napotkano wyjątek"
+
+#: uresourcestrings.rsexitrequest
+msgid "Exit request"
+msgstr "Polecenie zamknięcia"
+
+#: uresourcestrings.rsexpect1parameter
+msgid "expects one parameter : "
+msgstr "oczekuje jednego parametru: "
+
+#: uresourcestrings.rsexpect2parameters
+msgid "expects two parameters : "
+msgstr "oczekuje dwóch parametrów: "
+
+#: uresourcestrings.rsexpectnparameters
+msgid "expects N parameters : "
+msgstr "oczekuje N parametrów: "
+
+#: uresourcestrings.rsfast
+msgid "Fast"
+msgstr "Szybka"
+
+#: uresourcestrings.rsfilecannotbeempty
+msgid "File cannot be empty"
+msgstr "Plik nie może być pusty"
+
+#: uresourcestrings.rsfiledate
+msgid "Date"
+msgstr "Datam"
+
+#: uresourcestrings.rsfileextensionnotsupported
+msgid "This file extension is not supported."
+msgstr "To rozszerzenie pliku nie jest obsługiwane."
+
+#: uresourcestrings.rsfileformatnotrecognized
+msgid "The file format has not been recognized."
+msgstr "Ten format pliku nie został rozpoznany."
+
+#: uresourcestrings.rsfilename
+msgid "Filename"
+msgstr "Nazwa pliku"
+
+#: uresourcestrings.rsfilenotfound
+msgid "File not found!"
+msgstr "Pliku nie znaleziono!"
+
+#: uresourcestrings.rsfilenotsaved
+msgid "File not saved"
+msgstr "Plik nie został zapisany"
+
+#: uresourcestrings.rsfilesize
+msgid "Size"
+msgstr "Rozmiar"
+
+#: uresourcestrings.rsfilesystem
+msgid "File system"
+msgstr "System pliku"
+
+#: uresourcestrings.rsfiletype
+msgid "Type"
+msgstr "Typ"
+
+#: uresourcestrings.rsfixeddrive
+msgid "Fixed"
+msgstr "Naprawiony"
+
+#: uresourcestrings.rsfolder
+msgid "Folder"
+msgstr "Folder"
+
+#: uresourcestrings.rsfolderorcontaineralreadyexists
+msgid "Folder or container already exists."
+msgstr "Folder lub kontener już istnieje."
+
+#: uresourcestrings.rsfollowingerrorsoccured
+msgid "Following errors occured:"
+msgstr "Wystąpiły następujące błędy:"
+
+#: uresourcestrings.rsframes
+msgid "Frames"
+msgstr "Ramki"
+
+#: uresourcestrings.rsfunctionnotdefined
+msgid "The function %1 is not defined."
+msgstr "Funkcja %1 nie została zdefiniowana."
+
+#: uresourcestrings.rsgreen
+msgid "Green"
+msgstr "Zielony"
+
+#: uresourcestrings.rshalfcosine
+msgid "Half-cosine"
+msgstr "Pół-cosinus"
+
+#: uresourcestrings.rsholdkeyforsquare
+msgid "Hold %1 to draw a square or a circle"
+msgstr "Przytrzymaj %1 aby narysować kwadrat lub okrąg"
+
+#: uresourcestrings.rsholdkeyrestrictrotation
+msgid "Hold %1 to restrict rotation angle"
+msgstr "Przytrzymaj %1 aby ograniczyć kąt obrotu"
+
+#: uresourcestrings.rsholdkeysnaptopixel
+msgid "Hold %1 to snap to pixels"
+msgstr "Przytrzymaj %1 aby przyciągnąć do pikseli"
+
+#: uresourcestrings.rsholdkeysscalemode
+msgid "Hold %1 or %2 to scale"
+msgstr "Przytrzymaj %1 lub %2 aby skalować"
+
+#: uresourcestrings.rshotspot
+msgctxt "uresourcestrings.rshotspot"
+msgid "Hot spot"
+msgstr "Gorący punkt"
+
+#: uresourcestrings.rshue
+msgctxt "uresourcestrings.rshue"
+msgid "Hue"
+msgstr "Odcień"
+
+#: uresourcestrings.rshueccw
+msgctxt "uresourcestrings.rshueccw"
+msgid "Hue CCW"
+msgstr "Odcień CWW"
+
+#: uresourcestrings.rshuecw
+msgctxt "uresourcestrings.rshuecw"
+msgid "Hue CW"
+msgstr "Odcień CW"
+
+#: uresourcestrings.rsiconimagealreadyexists
+msgid "There is already an image with this size and depth."
+msgstr "Istnieje już obraz o takim rozmiarze i głębi."
+
+#: uresourcestrings.rsiconorcursor
+msgid "Icon/cursor"
+msgstr "Ikona/Kursor"
+
+#: uresourcestrings.rsiconsize
+msgctxt "uresourcestrings.rsiconsize"
+msgid "Icon size"
+msgstr "Rozmiar ikon"
+
+#: uresourcestrings.rsimagetoobig
+msgid "Image is too big"
+msgstr "Obraz jest za duży"
+
+#: uresourcestrings.rsinfinity
+msgctxt "uresourcestrings.rsinfinity"
+msgid "Infinity"
+msgstr "Nieskończoność"
+
+#: uresourcestrings.rsinformation
+msgid "Information"
+msgstr "Informacje"
+
+#: uresourcestrings.rsdownload
+msgid "Download"
+msgstr "Pobieranie"
+
+#: uresourcestrings.rsintensity
+msgctxt "uresourcestrings.rsintensity"
+msgid "Intensity"
+msgstr "Intensywność"
+
+#: uresourcestrings.rsinternalerror
+msgid "Internal error"
+msgstr "Błąd wewnętrzny"
+
+#: uresourcestrings.rsinvalidname
+msgid "Invalid name"
+msgstr "Błędna nazwa"
+
+#: uresourcestrings.rsinvalidopacity
+msgid "Invalid opacity : "
+msgstr "Nieprawidłowe krycie:"
+
+#: uresourcestrings.rsinvalidparameters
+msgid "Invalid parameters"
+msgstr "Niepoprawne parametry"
+
+#: uresourcestrings.rsinvalidresamplesize
+msgid "Invalid resample size : "
+msgstr "Nieprawidłowy rozmiar ponownego próbkowania:"
+
+#: uresourcestrings.rsinvalidsizefornew
+msgid "Invalid size for new : "
+msgstr "Nieprawidłowy rozmiar dla nowego:"
+
+#: uresourcestrings.rskeepchanges
+msgid "Do you want to keep changes?"
+msgstr "Chcesz zachować zmiany?"
+
+#: uresourcestrings.rskeepemptyspace
+msgid "Keep empty space around opaque pixels?"
+msgstr "Zachować puste miejsce wokół nieprzezroczystych pikseli?"
+
+#: uresourcestrings.rslanczos
+msgid "Lanczos %1"
+msgstr "Lanczos %1"
+
+#: uresourcestrings.rslandscape
+msgid "Landscape"
+msgstr "Krajobraz"
+
+#: uresourcestrings.rslatestversion
+msgid "The latest version of LazPaint available online is"
+msgstr "Najnowsza wersja LazPaint dostępna online "
+
+#: uresourcestrings.rslayeredimage
+msgid "Layered image"
+msgstr "Obraz warstwowy"
+
+#: uresourcestrings.rslayers
+msgctxt "uresourcestrings.rslayers"
+msgid "Layers"
+msgstr "Warstwy"
+
+#: uresourcestrings.rslayer
+msgctxt "uresourcestrings.rslayer"
+msgid "Layer"
+msgstr "Warstwa"
+
+#: uresourcestrings.rslazpaint
+msgctxt "uresourcestrings.rslazpaint"
+msgid "LazPaint"
+msgstr "LazPaint"
+
+#: uresourcestrings.rslazpaintonly
+msgid "LazPaint only"
+msgstr "Tylko LazPaint"
+
+#: uresourcestrings.rslight
+msgid "Light"
+msgstr "Światło"
+
+#: uresourcestrings.rslightness
+msgctxt "uresourcestrings.rslightness"
+msgid "Lightness"
+msgstr "Jasność"
+
+#: uresourcestrings.rslightposition
+msgid "Light position"
+msgstr "Pozycja światła"
+
+#: uresourcestrings.rslinear
+msgid "Linear"
+msgstr "Liniowa"
+
+#: uresourcestrings.rslinearrgb
+msgid "Linear RGB"
+msgstr "Linearny RGB"
+
+#: uresourcestrings.rsloadandmergepalette
+msgid "Load and merge palette..."
+msgstr "Załąduj i scal paletę..."
+
+#: uresourcestrings.rsloading
+msgid "Loading"
+msgstr "Ładowanie..."
+
+#: uresourcestrings.rsloadpalette
+msgid "Load palette..."
+msgstr "Ładuj paletę..."
+
+#: uresourcestrings.rsloopcount
+msgid "Loop count"
+msgstr "Liczba pętli"
+
+#: uresourcestrings.rsmakencolorspalettefrombitmap
+msgid "Make %1-colors palette from image"
+msgstr "Utwórz paletę %1-kolorową z obrazu"
+
+#: uresourcestrings.rsmergeselection
+msgid "Do you want to merge selection?"
+msgstr "Chcesz scalić zaznaczenie?"
+
+#: uresourcestrings.rsmitchell
+msgid "Mitchella"
+msgstr "Mitchella"
+
+#: uresourcestrings.rsmorethanonefile
+msgid "You are trying to open more than one file. How would you like these files to be opened?"
+msgstr "Próbujesz otworzyć więcej niż jeden plik. Jak chciałbyś, aby były otwierane?"
+
+#: uresourcestrings.rsmovingorrotatingselection
+msgid "Moving or rotating selection"
+msgstr "Przenoszenie lub obracanie zaznaczeniat"
+
+#: uresourcestrings.rsmustreleaseselection
+msgid "You must first release the selection"
+msgstr "Najpierw musisz zwolnić zaznaczenie"
+
+#: uresourcestrings.rsmustshowlayer
+msgid "You must first make the layer visible"
+msgstr "Najpierw musisz uwidocznić warstwę"
+
+#: uresourcestrings.rsnetworkdrive
+msgid "Network"
+msgstr "Sieć"
+
+#: uresourcestrings.rsnewimage
+msgctxt "uresourcestrings.rsnewimage"
+msgid "New image"
+msgstr "Nowy obraz"
+
+#: uresourcestrings.rsno
+msgid "No"
+msgstr "Nie"
+
+#: uresourcestrings.rsnoactivelayer
+msgid "No active layer"
+msgstr "Warstwa nieaktywna"
+
+#: uresourcestrings.rsnoactiveselection
+msgid "There is no active selection"
+msgstr "Brak aktywnego zaznaczenia"
+
+#: uresourcestrings.rsnoandproceedtonext
+msgid "Do not save and open another file"
+msgstr "Nie zapisuj i nie otwieraj innego pliku"
+
+#: uresourcestrings.rsnoname
+msgid "noname"
+msgstr "bez nazwy"
+
+#: uresourcestrings.rsnormalblendop
+msgid "Normal"
+msgstr "Normalny"
+
+#: uresourcestrings.rsnothingtobedeformed
+msgid "There is nothing to be deformed"
+msgstr "Nie ma nic do zdeformowania"
+
+#: uresourcestrings.rsnothingtoberetrieved
+msgid "There is nothing to be retrieved"
+msgstr "Nie ma nic do odzyskania"
+
+#: uresourcestrings.rsnotreasonableformat
+msgid "It is not reasonable to save such a big image in this file format."
+msgstr "Nie zaleca się zapisywania tak dużego obrazu w tym formacie pliku."
+
+#: uresourcestrings.rsnumber
+msgid "№"
+msgstr "Nr."
+
+#: uresourcestrings.rsokay
+msgid "Okay"
+msgstr "OK"
+
+#: uresourcestrings.rsopacity
+msgid "Opacity"
+msgstr "Krycie"
+
+#: uresourcestrings.rsopen
+msgid "Open"
+msgstr "Otwórz"
+
+#: uresourcestrings.rsopenfilesaslayers
+msgid "Open files as layers in a single image"
+msgstr "Otwórz pliki jako warstwy na jednym obrazie"
+
+#: uresourcestrings.rsopenfirstfileonly
+msgid "Open the first file only"
+msgstr "Otwórz tylko pierwszy plik"
+
+#: uresourcestrings.rsopening
+msgid "Opening"
+msgstr "Otwieranie..."
+
+#: uresourcestrings.rsopenmultipleimagefiles
+msgid "Open multiple image files"
+msgstr "Otwórz wiele plików graficznych"
+
+#: uresourcestrings.rsotherblendop
+msgid "Other..."
+msgstr "Inne..."
+
+#: uresourcestrings.rsoverwritefile
+msgid "File already exists. Do you want to overwrite it?"
+msgstr "Plik już istnieje. Chcesz go nadpisać?"
+
+#: uresourcestrings.rspaletteincludesalphachannel
+msgid "Palette includes alpha channel"
+msgstr "Paleta zawiera kanał alfa"
+
+#: uresourcestrings.rspaletteoptions
+msgid "Palette options"
+msgstr "Opcje palety"
+
+#: uresourcestrings.rspercent
+msgctxt "uresourcestrings.rspercent"
+msgid "%"
+msgstr "%"
+
+#: uresourcestrings.rsportait
+msgid "Portrait"
+msgstr "Portret"
+
+#: uresourcestrings.rsposterizelayerusingpalette
+msgid "Posterize layer using palette"
+msgstr "Posteryzuj warstwę za pomocą palety"
+
+#: uresourcestrings.rspresetname
+msgid "Preset name"
+msgstr "Wstępna nazwa"
+
+#: uresourcestrings.rspx
+msgid "px"
+msgstr "px"
+
+#: uresourcestrings.rspythonunexpectedversion
+msgid "Expected Python version %1 but %2 found."
+msgstr "Oczekiwano wersji %1 Pythona, ale znaleziono %2 ."
+
+#: uresourcestrings.rsramdisk
+msgid "RAM disk"
+msgstr "Dysk RAM"
+
+#: uresourcestrings.rsrasterlayer
+msgid "Raster layer"
+msgstr "Warstwa rastrowa"
+
+#: uresourcestrings.rsrecentdirectories
+msgid "Recent directories:"
+msgstr "Ostanie katalogi:"
+
+#: uresourcestrings.rsred
+msgid "Red"
+msgstr "Czerwony"
+
+#: uresourcestrings.rsreload
+msgctxt "uresourcestrings.rsreload"
+msgid "Reload"
+msgstr "Przeładuj"
+
+#: uresourcestrings.rsreloadchanged
+msgid "Bitmap has been modified. Do you really want to reload?"
+msgstr "Mapa bitowa została zmodyfikowana. Chcesz załadować ją ponownie?"
+
+#: uresourcestrings.rsremovabledrive
+msgid "Removable"
+msgstr "Usuwalny"
+
+#: uresourcestrings.rsrepeatimage
+msgctxt "uresourcestrings.rsrepeatimage"
+msgid "Repeat image"
+msgstr "Potwórz obraz"
+
+#: uresourcestrings.rsresamplingimage
+msgid "Resampling image..."
+msgstr "Ponowne próbkowanie obrazu..."
+
+#: uresourcestrings.rsretrieveselectedarea
+msgid "Do you want to retrieve selected area?"
+msgstr "Chcesz pobrać zaznaczony obszar?"
+
+#: uresourcestrings.rsreturnvalides
+msgid "Press ENTER to validate"
+msgstr "Naciśnij klawisz ENTER, aby potwierdzić"
+
+#: uresourcestrings.rsrgb
+msgctxt "uresourcestrings.rsrgb"
+msgid "RGB"
+msgstr "RGB"
+
+#: uresourcestrings.rsrightclickforsource
+msgid "Use RIGHT click to define source"
+msgstr "Użyj prawokliku, aby zdefiniować źródło"
+
+#: uresourcestrings.rssaturation
+msgctxt "uresourcestrings.rssaturation"
+msgid "Saturation"
+msgstr "Nasycenie"
+
+#: uresourcestrings.rssave
+msgctxt "uresourcestrings.rssave"
+msgid "Save"
+msgstr "Zapisz"
+
+#: uresourcestrings.rssaveasbuttonhint
+msgctxt "uresourcestrings.rssaveasbuttonhint"
+msgid "Save with specified filename"
+msgstr "Zapisz z określoną nazwą pliku"
+
+#: uresourcestrings.rssavechanges
+msgid "Current bitmap has been modified. Do you want to save changes?"
+msgstr "Bieżąca mapa bitowa została zmodyfikowana. Zachować zmiany?"
+
+#: uresourcestrings.rssavepaletteas
+msgid "Save palette as..."
+msgstr "Zapisz paletę jako..."
+
+#: uresourcestrings.rsscript
+msgctxt "uresourcestrings.rsscript"
+msgid "Script"
+msgstr "Skrypt"
+
+#: uresourcestrings.rsselectblendoperation
+#, fuzzy
+msgctxt "uresourcestrings.rsselectblendoperation"
+msgid "Select blend operation"
+msgstr "Wybierz operację mieszania"
+
+#: uresourcestrings.rsshift
+msgid "SHIFT"
+msgstr "SHIFT"
+
+#: uresourcestrings.rsshowpalette
+msgctxt "uresourcestrings.rsshowpalette"
+msgid "Show palette"
+msgstr "Pokaż paletę"
+
+#: uresourcestrings.rssourceposition
+msgid "Source position"
+msgstr "Pozycja źródłowa"
+
+#: uresourcestrings.rsspline
+msgctxt "uresourcestrings.rsspline"
+msgid "Spline"
+msgstr "Klinowa"
+
+#: uresourcestrings.rsstoragedevice
+msgid "Device"
+msgstr "Urządzenie"
+
+#: uresourcestrings.rstexturemapping
+msgctxt "uresourcestrings.rstexturemapping"
+msgid "Texture mapping"
+msgstr "Mapowanie tekstur"
+
+#: uresourcestrings.rstherearenocheckeditems
+msgid "There are no checked items. Check some items or add some new ones."
+msgstr "Brak zaznaczonych pozycji. Sprawdź elementy lub dodaj nowe."
+
+#: uresourcestrings.rsthereisnofilenamegivenforthisfileusesaveas
+msgid "There is no file name given for this file. Use \"Save as...\" from the main menu."
+msgstr "Nie podano nazwy dla tego pliku. Użyj \"Zapisz jako ...\" z menu głównego."
+
+#: uresourcestrings.rstodo
+msgid "To do"
+msgstr "Do pracy"
+
+#: uresourcestrings.rstodoimages
+msgid "Images left: %1"
+msgstr "Pozostałe obrazy: %1"
+
+#: uresourcestrings.rstooloninvisiblelayer
+msgid "Tool cannot be used on an invisible layer"
+msgstr "Nie można użyć narzędzia na niewidocznej warstwie"
+
+#: uresourcestrings.rstoomanyactions
+msgid "Too many actions"
+msgstr "Za dużo akcji"
+
+#: uresourcestrings.rstoomanylayers
+msgid "Too many layers"
+msgstr "Za dużo warstw"
+
+#: uresourcestrings.rstoomanyshapesinlayer
+msgid "Too many shapes in layer"
+msgstr "Za dużo kształtów w warstwie"
+
+#: uresourcestrings.rstotalimages
+msgid "Total images: %1"
+msgstr "Całkowita liczba obrazów: %1"
+
+#: uresourcestrings.rstransferselectiontootherlayer
+msgid "Transfer selection to other layer?"
+msgstr "Przenieść zaznaczenie na inną warstwę?"
+
+#: uresourcestrings.rstransformedrasterlayer
+msgid "Transformed raster layer"
+msgstr "Przekształcona warstwa rastrowa"
+
+#: uresourcestrings.rstransformselectioncontent
+msgid "Do you want to transform content of the selection?"
+msgstr "Chcesz zmienić zawartość zaznaczenia?"
+
+#: uresourcestrings.rsunabletoapplyfilter
+msgid "Unable to apply filter : "
+msgstr "Kann Filter nicht anwenden: "
+
+#: uresourcestrings.rsunabletoloadfile
+msgid "Unable to load file : "
+msgstr "Nie można załadować pliku: "
+
+#: uresourcestrings.rsunabletosavefile
+msgid "Unable to save file : "
+msgstr "Nie można zapisać pliku: "
+
+#: uresourcestrings.rsunknowncommand
+msgid "Unknown command : "
+msgstr "Nieznane polecenie: "
+
+#: uresourcestrings.rsunknownoriginal
+msgid "Unknown original"
+msgstr "Nieznany oryginał"
+
+#: uresourcestrings.rsvectoriallayer
+msgid "Vectorial layer"
+msgstr "Warstwa wektorowa"
+
+#: uresourcestrings.rsyes
+msgid "Yes"
+msgstr "Tak"
+
+#: uresourcestrings.rszoomlayerstackin
+#, fuzzy
+msgctxt "uresourcestrings.rszoomlayerstackin"
+msgid "Zoom layer stack in"
+msgstr "Powiększ stos warstw"
+
+#: uresourcestrings.rszoomlayerstackout
+#, fuzzy
+msgctxt "uresourcestrings.rszoomlayerstackout"
+msgid "Zoom layer stack out"
+msgstr "Pomniejsz stos warstw"
+

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.po

@@ -231,11 +231,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr ""
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr ""
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr ""
 
@@ -1089,6 +1089,10 @@ msgstr ""
 msgid "Rotate 90° CW"
 msgstr ""
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr ""
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr ""
@@ -3018,8 +3022,8 @@ msgstr ""
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.pt_BR.po

@@ -241,11 +241,11 @@ msgctxt "TFCANVASSIZE.LABEL_WIDTH.CAPTION"
 msgid "Width :"
 msgstr "Largura :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Adicionar cor à paleta"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Remover a cor da paleta"
 
@@ -1100,6 +1100,10 @@ msgstr "Girar 90° CCW"
 msgid "Rotate 90° CW"
 msgstr "Girar 90° CW"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Girar 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Zoom inteligente x3"
@@ -3035,8 +3039,8 @@ msgstr "Pasta"
 msgid "Folder or container already exists."
 msgstr "Pasta ou contêiner já existe."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Ocorreram os seguintes erros:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.ru.po

@@ -234,11 +234,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Ширина:"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr ""
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr ""
 
@@ -1093,6 +1093,10 @@ msgstr "Поворот на 90° против часовой стрелки"
 msgid "Rotate 90° CW"
 msgstr "Поворот на 90° по часовой стрелке"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Поворот на 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Интеллектуальное увеличение x3"
@@ -3014,8 +3018,8 @@ msgstr ""
 msgid "Folder or container already exists."
 msgstr ""
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr ""
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.sv.po

@@ -231,11 +231,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "Bredd :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "Lägg till färg till palett"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "Ta bort färg från palett"
 
@@ -1090,6 +1090,10 @@ msgstr "Rotera 90° moturs"
 msgid "Rotate 90° CW"
 msgstr "Rotera 90° medurs"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "Rotera 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "Smart zoom x3"
@@ -3013,8 +3017,8 @@ msgstr "Mapp"
 msgid "Folder or container already exists."
 msgstr "Mappen eller behållaren finns redan."
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "Följande fel har inträffat:"
 
 #: uresourcestrings.rsframes

+ 8 - 4
lazpaint/release/bin/i18n/lazpaint.zh_CN.po

@@ -241,11 +241,11 @@ msgctxt "tfcanvassize.label_width.caption"
 msgid "Width :"
 msgstr "宽度 :"
 
-#: tfchoosecolor.bcbutton_addtopalette.hint
+#: uresourcestrings.rsaddtopalette
 msgid "Add color to palette"
 msgstr "向调色板添加颜色"
 
-#: tfchoosecolor.bcbutton_removefrompalette.hint
+#: uresourcestrings.rsremovefrompalette
 msgid "Remove color from palette"
 msgstr "从调色板中删除颜色"
 
@@ -1099,6 +1099,10 @@ msgstr "逆时针旋转 90°"
 msgid "Rotate 90° CW"
 msgstr "顺时针旋转 90°"
 
+#: tfmain.imagerotate180.caption
+msgid "Rotate 180°"
+msgstr "旋转 180°"
+
 #: tfmain.imagesmartzoom3.caption
 msgid "Smart zoom x3"
 msgstr "智能变焦 x3"
@@ -3028,8 +3032,8 @@ msgstr "文件夹"
 msgid "Folder or container already exists."
 msgstr "文件夹或容器已存在。"
 
-#: uresourcestrings.rsfollowingerrorsoccured
-msgid "Following errors occured:"
+#: uresourcestrings.rsfollowingerrorsoccurred
+msgid "Following errors occurred:"
 msgstr "发生以下错误:"
 
 #: uresourcestrings.rsframes

+ 1 - 1
lazpaint/release/debian/applications/lazpaint.desktop

@@ -1,5 +1,4 @@
 [Desktop Entry]
-Encoding=UTF-8
 Name=LazPaint
 Name[fr]=LazPaint
 Comment=LazPaint
@@ -10,3 +9,4 @@ Terminal=false
 Type=Application
 Categories=Graphics
 GenericName=LazPaint
+Keywords=image; editor; raster; vectorial; paint; layer; photo

+ 27 - 0
lazpaint/release/debian/debian/changelog

@@ -1,3 +1,30 @@
+lazpaint (7.1.6) stable; urgency=low
+
+  * Debian: various icon sizes for Linux application menu
+  * Debian: compatibility with debuild (to release in Debian distributions)
+  * MacOS: retina scaling of button glyphs
+  * MacOS: fix online requests (version check)
+  * clipboard: supports paste from redirected URL and HTML inline data
+  * color chooser: window switches to available fill options
+  * color chooser: copy/paste color definition
+  * language: add Polish translation
+  * interface: add support for Qt5
+  * interface: repaint on theme change
+  * interface: detect system dark theme
+  * interface: scale top toolbar, more icon sizes
+  * interface: larger textboxes in image browser, Escape to close
+  * interface: vertical splitter to resize docked controls / image view
+  * layers: add HSL and corrected HSL blend modes
+  * layers: add context menu for layer
+  * layers: export layer (in context menu)
+  * image: add 180-degree rotation
+  * SVG: read/write layered SVG (interoperates with Inkscape)
+  * SVG: exports vectorial layers to SVG
+  * SVG: fix scaling, better support for text
+  * OpenRaster: support for SVG layers (interoperates with MyPaint)
+
+ -- circular <[email protected]>  Wed, 2 Dec 2020 10:25:00 +0100
+  
 lazpaint (7.1.5) stable; urgency=low
 
   * image browser: can move to trash on MacOS

+ 8 - 7
lazpaint/release/debian/debian/control

@@ -2,14 +2,15 @@ Source: lazpaint
 Section: graphics
 Priority: optional
 Maintainer: circular <[email protected]>
-Build-Depends: lazarus-project (>= 2.0.2), dpkg-dev (>= 7)
 Homepage: https://wiki.freepascal.org/LazPaint
 Package: lazpaint
 Architecture: any
-Version: 7.1.5
+Version: 7.1.6
 Depends: ${shlibs:Depends}
-Description: Graphics viewer and editor. 
- Can read layered files (lzp, ora, pdn, oXo), multi-images (gif, ico, tiff), 
- flat files (bmp, jpeg, pcx, png, tga, xpm, xwd), vectorial (svg), 3D (obj).
- Has drawing tools, phong shading, curve adjustments,
- filters and render some textures.
+Conflicts: lazpaint-gtk2, lazpaint-gtk3, lazpaint-qt4, lazpaint-qt5
+Description: Image editor with raster and vector layers
+ Can read layered files (lzp, ora, pdn, oXo, flat psd), multi-images (gif,
+ ico, tiff), flat files (bmp, jpeg, pcx, png, tga, webp, xpm, xwd),
+ raw images (dng, cr2, nef, arw...), vectorial (svg), 3D (obj). Has drawing
+ tools, vector shapes, phong shading, curve adjustments, filters, render
+ some textures, Python scripting.

+ 25 - 9
lazpaint/release/debian/makedeb.sh

@@ -9,7 +9,7 @@ SHARE_DIR="${USER_DIR}/share"
 RESOURCE_DIR="${SHARE_DIR}/lazpaint"
 DOC_PARENT_DIR="${SHARE_DIR}/doc"
 DOC_DIR="${DOC_PARENT_DIR}/lazpaint"
-SOURCE_BIN="../bin"
+SOURCE_BIN=$(readlink --canonicalize "../bin")
 TARGET_ARCHITECTURE="$(dpkg --print-architecture)"
 VERSION="$(sed -n 's/^Version: //p' debian/control)"
 
@@ -25,23 +25,39 @@ PACKAGE_NAME="lazpaint${VERSION}_${OS_NAME}"
 echo "Version is $VERSION"
 echo "Target OS is ${OS_NAME}"
 
+rm -rf "${STAGING_DIR}"
+mkdir "${STAGING_DIR}"
+pushd ../../..
+
 if [ ! -f "${SOURCE_BIN}/lazpaint" ]; then
-  echo "Cannot find binary file."  
-  exit 1
+    if [ -z "$1" ]; then
+        echo "Usage: ./makedeb [TARGET]"
+        echo "where TARGET can be Gtk2, Win32 or Qt5"
+        exit 1
+    fi
+    echo "Compiling..."
+    make distclean
+    ./configure --prefix=/usr
+    make TARGET=$1
+else
+    echo "Using already compiled binary."
 fi
 
 echo "Creating package..."
 
-rm -rf "${STAGING_DIR}"
-mkdir "${STAGING_DIR}"
-pushd ../../..
-make install prefix=/usr "DESTDIR=$STAGING_DIR"
+make install "DESTDIR=$STAGING_DIR"
 popd
 
 mkdir "${STAGING_DIR}/DEBIAN"
 cp "debian/control" "${STAGING_DIR}/DEBIAN"
 sed -i -e "s/Architecture: any/Architecture: ${TARGET_ARCHITECTURE}/" "${STAGING_DIR}/DEBIAN/control"
 
+mkdir "${DOC_PARENT_DIR}"
+mkdir "${DOC_DIR}"
+cp "debian/changelog" "${DOC_DIR}"
+cp "debian/copyright" "${DOC_DIR}"
+gzip -9 -n "${DOC_DIR}/changelog"
+
 echo "Determining dependencies..."
 dpkg-shlibdeps "${BIN_DIR}/lazpaint"
 DEPENDENCIES="$(sed -n 's/^shlibs:Depends=//p' debian/substvars)"
@@ -61,8 +77,8 @@ NO_INSTALL_ARCHIVE="${PACKAGE_NAME}_no_install.tar.gz"
 
 echo "Making ${NO_INSTALL_ARCHIVE}..."
 mv "${BIN_DIR}/lazpaint" "${RESOURCE_DIR}/lazpaint"
-mv "${DOC_DIR}/copyright" "${RESOURCE_DIR}/copyright"
-mv "${DOC_DIR}/README" "${RESOURCE_DIR}/README"
+cp "debian/copyright" "${RESOURCE_DIR}/copyright"
+cp "../bin/readme.txt" "${RESOURCE_DIR}/README"
 pushd ${SHARE_DIR}
 tar -czf "../../../${NO_INSTALL_ARCHIVE}" "lazpaint"
 popd

+ 8 - 4
lazpaint/release/debian/man/man1/lazpaint.1

@@ -19,14 +19,19 @@ If supplied, the INPUT FILE is loaded. If the OUTPUT FILE is supplied, the image
 DIRECTORY
 .RS
 set the directory where Python scripts for LazPaint are located.
-
 .RE
+
 .B -script
 FILENAME
 .RS
 runs the specified Python script. It must have a ".py" extension.
 .RE
 
+.B -quit
+.RS
+quits the program even if no output file was provided. Can be useful when only running scripts.
+.RE
+
 .B -new
 WIDTH,HEIGHT
 .RS
@@ -81,8 +86,7 @@ rotates the image clockwise.
 rotates the image counter-clockwise.
 .RE
 
-.B -quit
+.B -rotate180
 .RS
-quits the program even if no output file was provided. Can be useful when only running scripts.
+rotates the image 180 degrees.
 .RE
-

BIN
lazpaint/release/debian/pixmaps/lazpaint.png


+ 2 - 2
lazpaint/release/macOS/LazPaint.app/Contents/Info.plist

@@ -19,9 +19,9 @@
     <key>CFBundleSignature</key>
     <string>lazp</string>
     <key>CFBundleShortVersionString</key>
-    <string>7.1.5</string>
+    <string>7.1.6</string>
     <key>CFBundleVersion</key>
-    <string>7.1.5</string>
+    <string>7.1.6</string>
     <key>CSResourcesFileMapped</key>
     <true/>
     <key>CFBundleDocumentTypes</key>

+ 1 - 1
lazpaint/release/macOS/makedmg.sh

@@ -8,7 +8,7 @@ if ! [ ${OSTYPE:0:6} = "darwin" ]; then
 fi
 
 appname=LazPaint
-appversion=7.1.5
+appversion=7.1.6
 pkgversion=0
 appnamenospaces=lazpaint
 appbundle="$appname.app"

+ 1 - 1
lazpaint/release/stable/pad_file.xml

@@ -126,4 +126,4 @@
 		<Distribution_Permissions>You can distribute this software freely as long as it remains opensource.</Distribution_Permissions>
 		<EULA>Opensource</EULA>
 	</Permissions>
-</XML_DIZ_INFO>
+</XML_DIZ_INFO>

+ 0 - 0
lazpaint/release/windows/dcraw/dcraw_x64.exe → lazpaint/release/windows/dcraw/dcraw64.exe


+ 4 - 4
lazpaint/release/windows/lazpaint.iss

@@ -1,7 +1,7 @@
 #define MyAppName "LazPaint"
 #define MyAppOutputName "lazpaint"
 #define MyInstallerSuffix "_setup_win32_win64"
-#define MyAppVersion "7.1.5"
+#define MyAppVersion "7.1.6"
 #define MyAppPublisher "Circular, Fabien Wang, Lainz and others"
 #define MyAppURL "http://sourceforge.net/projects/lazpaint/"
 #define MyAppExeName "lazpaint.exe"
@@ -102,12 +102,12 @@ Name: "assoc_xpm"; Description: "{cm:AssocFileExtension,{#MyAppName},.xpm}"; Fla
 
 [Files]
 Source: "{#ReleaseDir}lazpaint32.exe"; DestDir: "{app}"; DestName: "{#MyAppExeName}"; Flags: ignoreversion; Check: not Is64BitInstallMode
-Source: "{#ReleaseDir}lazpaint_x64.exe"; DestDir: "{app}"; DestName: "{#MyAppExeName}"; Flags: ignoreversion; Check: Is64BitInstallMode
+Source: "{#ReleaseDir}lazpaint64.exe"; DestDir: "{app}"; DestName: "{#MyAppExeName}"; Flags: ignoreversion; Check: Is64BitInstallMode
 Source: "dcraw\dcraw32.exe"; DestDir: "{app}"; DestName: "{#DCRawExeName}"; Flags: ignoreversion; Check: not Is64BitInstallMode
-Source: "dcraw\dcraw_x64.exe"; DestDir: "{app}"; DestName: "{#DCRawExeName}"; Flags: ignoreversion; Check: Is64BitInstallMode
+Source: "dcraw\dcraw64.exe"; DestDir: "{app}"; DestName: "{#DCRawExeName}"; Flags: ignoreversion; Check: Is64BitInstallMode
 Source: "libwebp\libwebp32.dll"; DestDir: "{app}"; DestName: "{#LibWebPDllName}"; Flags: ignoreversion; Check: not Is64BitInstallMode
 Source: "libwebp\libwebp64.dll"; DestDir: "{app}"; DestName: "{#LibWebPDllName}"; Flags: ignoreversion; Check: Is64BitInstallMode
-Source: "{#ReleaseDir}i18n\*.po"; DestDir: "{app}\i18n"; Excludes: "i18n\lazpaint_x64.po"; Flags: ignoreversion
+Source: "{#ReleaseDir}i18n\*.po"; DestDir: "{app}\i18n"; Flags: ignoreversion
 Source: "{#ReleaseDir}models\*.*"; DestDir: "{app}\models"; Flags: ignoreversion
 Source: "{#ReleaseDir}readme.txt"; DestDir: "{app}"; Flags: ignoreversion
 Source: "{#ScriptsDir}*"; DestDir: "{app}\scripts"; Flags: ignoreversion; Excludes: "\__pycache__\*";  

+ 3 - 3
lazpaint/release/windows/stage.bat

@@ -41,11 +41,11 @@ goto donebin32
 echo Error: 32-bit binary not found
 :donebin32
 
-if not exist ..\bin\lazpaint_x64.exe goto :missingbin64
+if not exist ..\bin\lazpaint64.exe goto :missingbin64
 echo Staging 64-bit version...
 if not exist lazpaint64 mkdir lazpaint64
-copy ..\bin\lazpaint_x64.exe lazpaint64\lazpaint.exe >nul
-copy dcraw\dcraw_x64.exe lazpaint64\dcraw.exe >nul
+copy ..\bin\lazpaint64.exe lazpaint64\lazpaint.exe >nul
+copy dcraw\dcraw64.exe lazpaint64\dcraw.exe >nul
 copy libwebp\libwebp64.dll lazpaint64 >nul
 copy ..\bin\readme.txt lazpaint64 >nul
 copy ..\bin\*.ini lazpaint64 >nul

+ 32 - 17
lazpaint/tools/utool.pas

@@ -171,6 +171,7 @@ type
 
   TOnToolChangedHandler = procedure(sender: TToolManager; ANewToolType: TPaintToolType) of object;
   TOnPopupToolHandler = procedure(sender: TToolManager; APopupMessage: TToolPopupMessage; AKey: Word; AAlways: boolean) of object;
+  TOnQueryColorTargetHandler = procedure(sender: TToolManager; ATarget: TVectorialFill) of object;
 
   TShapeOption = (toAliasing, toDrawShape, toFillShape, toCloseShape);
   TShapeOptions = set of TShapeOption;
@@ -186,6 +187,7 @@ type
   TToolManager = class
   private
     FConfigProvider: IConfigProvider;
+    FOnQueryColorTarget: TOnQueryColorTargetHandler;
     FShouldExitTool: boolean;
     FImage: TLazPaintImage;
     FBlackAndWhite: boolean;
@@ -414,6 +416,7 @@ type
     procedure SetLightAltitude(AValue: integer);
     procedure SetLightPosition(AValue: TPointF);
     procedure SetLineCap(AValue: TPenEndCap);
+    procedure SetOnQueryColorTarget(AValue: TOnQueryColorTargetHandler);
     procedure SetOutlineColor(AValue: TBGRAPixel);
     procedure SetPerspectiveOptions(AValue: TPerspectiveOptions);
     procedure SetPhongShapeAltitude(AValue: integer);
@@ -466,6 +469,7 @@ type
     function GetCurrentToolType: TPaintToolType;
     function SetCurrentToolType(tool: TPaintToolType): boolean;
     function UpdateContextualToolbars: boolean;
+    function GetContextualToolbars: TContextualToolbars;
     function ToolCanBeUsed: boolean;
     function ToolHasLineCap: boolean;
     procedure ToolWakeUp;
@@ -494,6 +498,7 @@ type
     function IsBackEditGradTexPoints: boolean;
     function IsOutlineEditGradTexPoints: boolean;
     procedure QueryExitTool;
+    procedure QueryColorTarget(ATarget: TVectorialFill);
 
     function RenderTool(formBitmap: TBGRABitmap): TRect;
     function GetRenderBounds(VirtualScreenWidth, VirtualScreenHeight: integer): TRect;
@@ -579,6 +584,7 @@ type
     property OnPopup: TOnPopupToolHandler read FOnPopupToolHandler write FOnPopupToolHandler;
     property OnEraserChanged: TNotifyEvent read FOnEraserChanged write FOnEraserChanged;
     property OnFillChanged: TNotifyEvent read FOnFillChanged write FOnFillChanged;
+    property OnQueryColorTarget: TOnQueryColorTargetHandler read FOnQueryColorTarget write SetOnQueryColorTarget;
     property OnPenWidthChanged: TNotifyEvent read FOnPenWidthChanged write FOnPenWidthChanged;
     property OnBrushChanged: TNotifyEvent read FOnBrushChanged write FOnBrushChanged;
     property OnBrushListChanged: TNotifyEvent read FOnBrushListChanged write FOnBrushListChanged;
@@ -1391,6 +1397,12 @@ begin
   if Assigned(FOnLineCapChanged) then FOnLineCapChanged(self);
 end;
 
+procedure TToolManager.SetOnQueryColorTarget(AValue: TOnQueryColorTargetHandler);
+begin
+  if FOnQueryColorTarget=AValue then Exit;
+  FOnQueryColorTarget:=AValue;
+end;
+
 procedure TToolManager.SetOutlineColor(AValue: TBGRAPixel);
 begin
   FOutlineFill.SolidColor := AValue;
@@ -1576,14 +1588,9 @@ function TToolManager.ToolHasLineCap: boolean;
 var
   contextualToolbars: TContextualToolbars;
 begin
-  if CurrentTool = nil then
-    result := false
-  else
-  begin
-    contextualToolbars := CurrentTool.GetContextualToolbars;
-    result := (ctLineCap in contextualToolbars) and CurrentTool.HasPen and
-              (not (toCloseShape in ShapeOptions) or not (ctCloseShape in contextualToolbars));
-  end;
+  contextualToolbars := GetContextualToolbars;
+  result := (ctLineCap in contextualToolbars) and CurrentTool.HasPen and
+            (not (toCloseShape in ShapeOptions) or not (ctCloseShape in contextualToolbars));
 end;
 
 function TToolManager.GetBackColor: TBGRAPixel;
@@ -3177,16 +3184,10 @@ var
 
 begin
   result := false;
+  contextualToolbars := GetContextualToolbars;
   if Assigned(FCurrentTool) then
-  begin
-    contextualToolbars := FCurrentTool.GetContextualToolbars;
-    hasPen := FCurrentTool.HasPen;
-  end
-  else
-  begin
-    contextualToolbars := [ctPenFill, ctBackFill];
-    hasPen := false;
-  end;
+    hasPen := FCurrentTool.HasPen
+    else hasPen := false;
 
   if (ctBackFill in contextualToolbars) and not (ctPenFill in contextualToolbars) then
     OrResult(SetControlsVisible(FillControls, True, 'Panel_BackFill')) else
@@ -3224,6 +3225,14 @@ begin
   if result and Assigned(FOnToolbarChanged) then FOnToolbarChanged(self);
 end;
 
+function TToolManager.GetContextualToolbars: TContextualToolbars;
+begin
+  if Assigned(FCurrentTool) then
+    result := FCurrentTool.GetContextualToolbars
+  else
+    result := [ctPenFill, ctBackFill];
+end;
+
 function TToolManager.InternalBitmapToVirtualScreen(PtF: TPointF): TPointF;
 begin
   if Assigned(FCurrentTool) then
@@ -3793,6 +3802,12 @@ begin
   FShouldExitTool:= true;
 end;
 
+procedure TToolManager.QueryColorTarget(ATarget: TVectorialFill);
+begin
+  if Assigned(OnQueryColorTarget) then
+    OnQueryColorTarget(self, ATarget);
+end;
+
 function TToolManager.RenderTool(formBitmap: TBGRABitmap): TRect;
 begin
   if ToolCanBeUsed and Assigned(CurrentTool) and not FInTool then

+ 9 - 2
lazpaint/tools/utoolbasic.pas

@@ -451,8 +451,15 @@ begin
       if ssShift in ShiftState then
         c := Manager.Image.RenderedImage.GetPixel(pt.X,pt.Y)
         else c := toolDest.GetPixel(pt.X,pt.Y);
-      if colorpickingRight then Manager.BackColor := c
-        else Manager.ForeColor := c;
+      if colorpickingRight then
+      begin
+        Manager.BackColor := c;
+        Manager.QueryColorTarget(Manager.BackFill);
+      end else
+      begin
+        Manager.ForeColor := c;
+        Manager.QueryColorTarget(Manager.ForeFill);
+      end;
     end;
   end;
 end;

+ 3 - 2
lazpaint/tools/utooltext.pas

@@ -163,8 +163,9 @@ begin
     PenPhong := Manager.TextPhong;
   end;
   if (Manager.TextShadow <> FPrevShadow) or
-     (Manager.TextShadowBlurRadius <> FPrevShadowRadius) or
-     (Manager.TextShadowOffset <> FPrevShadowOffset) then
+     (FPrevShadow and
+     ((Manager.TextShadowBlurRadius <> FPrevShadowRadius) or
+     (Manager.TextShadowOffset <> FPrevShadowOffset))) then
   begin
     toolDest := GetToolDrawingLayer;
     r:= UpdateShape(toolDest);

+ 15 - 0
lazpaint/uchoosecolor.pas

@@ -28,6 +28,7 @@ type
     procedure SetColorTarget(AValue: TColorTarget);
     procedure SetDarkTheme(AValue: boolean);
     procedure SetLazPaintInstance(AValue: TLazPaintCustomInstance);
+    procedure ThemeChanged(Sender: TObject);
   protected
     FInterface: TChooseColorInterface;
   public
@@ -51,6 +52,8 @@ implementation
 procedure TFChooseColor.FormCreate(Sender: TObject);
 begin
   FInterface := TChooseColorInterface.Create(ChooseColorControl, TFChooseColor_CustomDPI);
+  BorderStyle := ToolWindowSizeable;
+  FormStyle := ToolWindowStyle;
 end;
 
 procedure TFChooseColor.FormDeactivate(Sender: TObject);
@@ -60,6 +63,8 @@ end;
 
 procedure TFChooseColor.FormDestroy(Sender: TObject);
 begin
+  if Assigned(LazPaintInstance) then
+    LazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
   FreeAndNil(FInterface);
 end;
 
@@ -108,7 +113,11 @@ procedure TFChooseColor.SetLazPaintInstance(AValue: TLazPaintCustomInstance);
 begin
   if Assigned(FInterface) then
   begin
+    if Assigned(FInterface.LazPaintInstance) then
+      FInterface.LazPaintInstance.RegisterThemeListener(@ThemeChanged, false);
     FInterface.LazPaintInstance:= AValue;
+    if Assigned(FInterface.LazPaintInstance) then
+      FInterface.LazPaintInstance.RegisterThemeListener(@ThemeChanged, true);
 
     with FInterface.GetPreferredSize do
     begin
@@ -122,6 +131,12 @@ begin
   end;
 end;
 
+procedure TFChooseColor.ThemeChanged(Sender: TObject);
+begin
+  if Assigned(FInterface) and Assigned(LazPaintInstance) then
+    FInterface.DarkTheme := LazPaintInstance.DarkTheme;
+end;
+
 function TFChooseColor.GetDarkTheme: boolean;
 begin
   if Assigned(FInterface) then

+ 8 - 3
lazpaint/uclipboard.pas

@@ -31,7 +31,7 @@ implementation
 uses Dialogs, BGRABitmapTypes, Clipbrd, Graphics, LCLIntf, LCLType, GraphType
     {$IFDEF PDN_CLIPBOARD_FORMAT}, math, BGRADNetDeserial{$ENDIF}
     {$IFDEF BMP_CLIPBOARD_FORMAT}, FPWriteBMP{$ENDIF}
-    {$IFDEF HTML_CLIPBOARD_FORMAT}, fphttpclient{$ENDIF};
+    {$IFDEF HTML_CLIPBOARD_FORMAT}, UOnline{$ENDIF};
 
 {$IFDEF DEBUG_CLIPBOARD}
 const
@@ -216,6 +216,7 @@ var
   stream: TMemoryStream;
   url: string;
 begin
+  result := nil;
   if tokens.Count > 0 then
   begin
     if UpperCase(tokens[0]) = 'IMG' then
@@ -229,7 +230,7 @@ begin
           delete(url,5,1);
         stream := TMemoryStream.Create;
         try
-          TFPHttpClient.SimpleGet(url,stream);
+          MyHttpGet(url,stream);
           stream.Position:= 0;
           result := TBGRABitmap.Create(stream);
         except on ex: exception do begin
@@ -341,7 +342,11 @@ begin
           inTag := false;
           result := GetBitmapFromTag(tagTokens);
           tagTokens.clear;
-          if result <> nil then exit;
+          if result <> nil then
+          begin
+            tagTokens.Free;
+            exit;
+          end;
         end else
           if data[p]>#32 then
             tagTokens.Add(data[p]);

+ 6 - 2
lazpaint/ucommandline.pas

@@ -11,7 +11,7 @@ uses classes, LazpaintType, uresourcestrings;
   {$DEFINE SHOW_MANUAL_IN_WINDOW }
 {$ENDIF}
 
-const Manual: array[0..61] of string = (
+const Manual: array[0..64] of string = (
 'NAME',
 '       LazPaint - Image editor',
 '',
@@ -73,7 +73,10 @@ const Manual: array[0..61] of string = (
 '              rotates the image clockwise.',
 '',
 '       -rotateccw',
-'              rotates the image counter-clockwise.');
+'              rotates the image counter-clockwise.',
+'',
+'       -rotate180',
+'              rotates the image 180 degrees.');
 
 procedure ProcessCommands(instance: TLazPaintCustomInstance; commandsUTF8: TStringList; out errorEncountered, fileSaved, quitQuery: boolean);
 function ParamStrUTF8(AIndex: integer): string;
@@ -317,6 +320,7 @@ begin
         if LowerCmd='smartzoom3' then AImageActions.SmartZoom3 else
         if LowerCmd='rotatecw' then AImageActions.RotateCW else
         if LowerCmd='rotateccw' then AImageActions.RotateCCW else
+        if LowerCmd='rotate180' then AImageActions.Rotate180 else
         if copy(lowerCmd,1,9)='gradient(' then begin if not DoGradient then exit end else
         if lowerCmd = 'gradient' then begin if not NextAsFuncParam or not DoGradient then exit end else
         if copy(lowerCmd,1,8)='opacity(' then begin if not DoOpacity then exit end else

+ 57 - 4
lazpaint/uconfig.pas

@@ -16,6 +16,8 @@ type
     function GetConfig: TLazPaintConfig;
   end;
 
+  TDarkThemePreference = (dtpAuto, dtpDark, dtpLight);
+
   { TLazPaintConfig }
 
   TLazPaintConfig = class
@@ -26,6 +28,8 @@ type
     colorizePresets: TList;
     FVersion: string;
     FDarkTheme,FDarkThemeEvaluated: boolean;
+    FDarkThemePreference: TDarkThemePreference;
+    FDarkThemePreferenceEvaluated: boolean;
     FWorkspaceColor: TColor;
     FWorkspaceColorEvaluated: boolean;
     function GetBrushCount: integer;
@@ -108,6 +112,8 @@ type
     procedure SetDefaultIconSize(value: integer);
     function GetDarkTheme: boolean;
     procedure SetDarkTheme(AValue: boolean);
+    function GetDarkThemePreference: TDarkThemePreference;
+    procedure SetDarkThemePreference(AValue: TDarkThemePreference);
 
     //new image config
     function DefaultImageWidth: integer;
@@ -137,6 +143,8 @@ type
     function DefaultScreenSize: TRect;
     function DefaultDockLayersAndColors: boolean;
     procedure SetDefaultDockLayersAndColors(value: boolean);
+    function DefaultDockLayersAndColorsWidth: integer;
+    procedure SetDefaultDockLayersAndColorsWidth(AValue: integer);
     function ScreenSizeChanged: boolean;
     procedure SetDefaultScreenSize(value: TRect);
     function DefaultMainWindowMaximized: boolean;
@@ -350,7 +358,7 @@ var
 
 implementation
 
-uses uparse, LCLProc, BGRAUTF8, LazFileUtils, UFileSystem;
+uses uparse, LCLProc, BGRAUTF8, LazFileUtils, UFileSystem, UDarkTheme;
 
 const maxRecentFiles = 10;
       maxRecentDirectories = 10;
@@ -507,7 +515,7 @@ end;
 
 function TLazPaintConfig.DefaultDockLayersAndColors: boolean;
 begin
-  result := iniOptions.ReadBool('Window','DockLayersAndColors',false);
+  result := iniOptions.ReadBool('Window','DockLayersAndColors',true);
 end;
 
 procedure TLazPaintConfig.SetDefaultDockLayersAndColors(value: boolean);
@@ -515,9 +523,19 @@ begin
   iniOptions.WriteBool('Window','DockLayersAndColors',value);
 end;
 
+function TLazPaintConfig.DefaultDockLayersAndColorsWidth: integer;
+begin
+  result := iniOptions.ReadInteger('Window','DockLayersAndColorsWidth',0);
+end;
+
+procedure TLazPaintConfig.SetDefaultDockLayersAndColorsWidth(AValue: integer);
+begin
+  iniOptions.WriteInteger('Window','DockLayersAndColorsWidth',AValue);
+end;
+
 procedure TLazPaintConfig.SetDefaultScreenSize(value: TRect);
 begin
- iniOptions.WriteString('Window','ScreenSize',RectToStr(value));
+  iniOptions.WriteString('Window','ScreenSize',RectToStr(value));
 end;
 
 function TLazPaintConfig.DefaultMainWindowMaximized: boolean;
@@ -1711,7 +1729,12 @@ function TLazPaintConfig.GetDarkTheme: boolean;
 begin
   if not FDarkThemeEvaluated then
   begin
-    FDarkTheme := iniOptions.ReadBool('General','DarkTheme', false);
+    if GetDarkThemePreference = dtpAuto then
+    begin
+      FDarkTheme := DarkThemeInstance.IsSystemDarkTheme;
+      DarkThemeInstance.HasSystemDarkThemeChanged;
+    end else
+      FDarkTheme := iniOptions.ReadBool('General','DarkTheme', false);
     FDarkThemeEvaluated:= true;
   end;
   result := FDarkTheme;
@@ -1726,6 +1749,36 @@ begin
   FWorkspaceColorEvaluated:= false;
 end;
 
+function TLazPaintConfig.GetDarkThemePreference: TDarkThemePreference;
+var
+  s: String;
+begin
+  if not FDarkThemePreferenceEvaluated then
+  begin
+    s := iniOptions.ReadString('General','DarkThemePreference', 'auto');
+    if CompareText(s,'dark')=0 then FDarkThemePreference:= dtpDark
+    else if CompareText(s,'light')=0 then FDarkThemePreference:= dtpLight
+    else FDarkThemePreference:= dtpAuto;
+    FDarkThemePreferenceEvaluated:= true;
+  end;
+  result := FDarkThemePreference;
+end;
+
+procedure TLazPaintConfig.SetDarkThemePreference(AValue: TDarkThemePreference);
+var
+  s: String;
+begin
+  if FDarkThemeEvaluated and (AValue = FDarkThemePreference) then exit;
+  case AValue of
+  dtpDark: s := 'Dark';
+  dtpLight: s := 'Light';
+  else s := 'Auto';
+  end;
+  iniOptions.WriteString('General','DarkThemePreference', s);
+  FDarkThemePreference:= AValue;
+  FDarkThemePreferenceEvaluated:= true;
+end;
+
 function TLazPaintConfig.ScreenSizeChanged: boolean;
 var currentScreenSize,previousScreenSize: TRect;
 begin

+ 311 - 82
lazpaint/udarktheme.pas

@@ -2,29 +2,32 @@
 unit UDarkTheme;
 
 {$mode objfpc}{$H+}
+{$IFDEF DARWIN}{$modeswitch objectivec1}{$ENDIF}
 
 interface
 
 uses
-  Classes, SysUtils, Forms, ComCtrls, StdCtrls, Controls, ExtCtrls,
+  Classes, SysUtils, Forms, ComCtrls, StdCtrls, Controls, ExtCtrls, Graphics,
   LazPaintType, BCButton, BCComboBox, BCTrackbarUpdown, LCVectorialFillControl;
 
-const
-  clDarkBtnHighlight = $e0e0e0;
-  clDarkBtnFace = $606060;
-  clDarkEditableFace = $808080;
-  clLightText = $f0f0f0;
-  clDarkPanelHighlight = $909090;
-  clDarkPanelShadow = $404040;
-
 type
 
   { TDarkTheme }
 
   TDarkTheme = class
-    procedure PanelPaint(Sender: TObject);
-    procedure ToolBarPaint(Sender: TObject);
-    procedure ToolBarPaintButton(Sender: TToolButton; State: integer);
+  private
+    FLastSystemDarkTheme: boolean;
+  public
+    constructor Create;
+    procedure PanelPaint(Sender: TObject; ADarkTheme: boolean);
+    procedure PanelPaintDark(Sender: TObject);
+    procedure PanelPaintLight(Sender: TObject);
+    procedure ToolBarPaint(Sender: TObject; ADarkTheme: boolean);
+    procedure ToolBarPaintLight(Sender: TObject);
+    procedure ToolBarPaintDark(Sender: TObject);
+    procedure ToolBarPaintButton(Sender: TToolButton; State: integer; ADarkTheme: boolean);
+    procedure ToolBarPaintButtonLight(Sender: TToolButton; State: integer);
+    procedure ToolBarPaintButtonDark(Sender: TToolButton; State: integer);
     procedure Apply(AForm: TForm; AThemeEnabled: boolean; ARecursive: boolean = true); overload;
     procedure Apply(APanel: TPanel; AThemeEnabled: boolean; ARecursive: boolean = true); overload;
     procedure Apply(AVectorialFill: TLCVectorialFillControl; AThemeEnabled: boolean); overload;
@@ -33,16 +36,100 @@ type
     procedure Apply(ACombo: TBCComboBox; ADarkTheme: boolean; AFontHeightRatio: single = 0.5); overload;
     procedure Apply(AUpDown: TBCTrackbarUpdown; ADarkTheme: boolean); overload;
     procedure Apply(ALabel: TLabel; ADarkTheme: boolean); overload;
+    function IsSystemDarkTheme: boolean;
+    function IsLclDarkTheme: boolean;
+    function IsLclLightThemeSafe: boolean;
+    function HasSystemDarkThemeChanged: boolean;
+    function GetColorButtonHighlight(ADarkTheme: boolean): TColor;
+    function GetColorButtonFace(ADarkTheme: boolean): TColor;
+    function GetColorButtonText(ADarkTheme: boolean): TColor;
+    function GetColorForm(ADarkTheme: boolean): TColor;
+    function GetColorEditableFace(ADarkTheme: boolean): TColor;
+    function GetColorEditableText(ADarkTheme: boolean): TColor;
+    function GetColorPanelHighlight(ADarkTheme: boolean): TColor;
+    function GetColorPanelShadow(ADarkTheme: boolean): TColor;
+    function GetColorHighlightBack(ADarkTheme: boolean): TColor;
+    function GetColorHighlightText(ADarkTheme: boolean): TColor;
   end;
 
 var
   DarkThemeInstance: TDarkTheme;
 
-
 implementation
 
 uses
-  BCTypes, BGRABitmap, BGRABitmapTypes, GraphType, Graphics, BGRACustomDrawn, LCScaleDPI;
+  BCTypes, BGRABitmap, BGRABitmapTypes, GraphType, BGRACustomDrawn, LCScaleDPI
+  {$IFDEF DARWIN}, CocoaAll, CocoaUtils{$ENDIF}
+  {$IFDEF WINDOWS}, Windows, Win32Proc, Registry{$ENDIF};
+
+const
+  clDarkBtnHighlight = $e0e0e0;
+  clDarkBtnFace = $606060;
+  clDarkEditableFace = $808080;
+  clLightText = $f0f0f0;
+  clDarkPanelHighlight = $909090;
+  clDarkPanelShadow = $404040;
+
+{$IFDEF DARWIN}
+{ returns true, if this app runs on macOS 10.14 Mojave or newer }
+function IsMojaveOrNewer: boolean;
+var
+  minOsVer: NSOperatingSystemVersion;
+begin
+  // Setup minimum version (Mojave)
+  minOsVer.majorVersion:= 10;
+  minOsVer.minorVersion:= 14;
+  minOsVer.patchVersion:= 0;
+
+  // Check minimum version
+  if NSProcessInfo.ProcessInfo.isOperatingSystemAtLeastVersion(minOSVer) then
+    Result := True
+  else
+    Result := False;
+end;
+
+function GetPrefString(const KeyName : string) : string;
+begin
+  Result := NSStringToString(NSUserDefaults.standardUserDefaults.stringForKey(NSStr(@KeyName[1])));
+end;
+
+function IsMojaveDarkTheme: boolean;
+begin
+  Result := pos('DARK',UpperCase(GetPrefString('AppleInterfaceStyle'))) > 0;
+end;
+{$ENDIF}
+
+{$IFDEF WINDOWS}
+type
+  TWinDarkThemeMode = (dtmLight, dtmDark, dtmUnknown);
+
+// by "jwdietrich" from Lazarus forum
+// IsDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
+function GetWinDarkTheme: TWinDarkThemeMode;
+const
+  KEYPATH = '\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize';
+  KEYNAME = 'AppsUseLightTheme';
+var
+  Registry: TRegistry;
+begin
+  Result := dtmUnknown;
+  Registry := TRegistry.Create;
+  try
+    Registry.RootKey := HKEY_CURRENT_USER;
+    if Registry.OpenKeyReadOnly(KEYPATH) then
+      begin
+        if Registry.ValueExists(KEYNAME) then
+        begin
+          if Registry.ReadBool(KEYNAME) then
+            result := dtmLight
+            else result := dtmDark;
+        end;
+      end;
+  finally
+    Registry.Free;
+  end;
+end;
+{$ENDIF}
 
 procedure BCAssignSystemState(AState: TBCButtonState; AFontColor, ATopColor, AMiddleTopColor, AMiddleBottomColor, ABottomColor, ABorderColor: TColor);
 begin
@@ -50,7 +137,7 @@ begin
   begin
     Border.Style := bboSolid;
     Border.Color := ABorderColor;
-    Border.ColorOpacity := 255;
+    Border.ColorOpacity := 192;
     FontEx.Color := AFontColor;
     FontEx.Style := [];
     FontEx.Shadow := True;
@@ -88,23 +175,38 @@ end;
 
 { TDarkTheme }
 
-procedure TDarkTheme.PanelPaint(Sender: TObject);
+constructor TDarkTheme.Create;
+begin
+  FLastSystemDarkTheme := IsSystemDarkTheme;
+end;
+
+procedure TDarkTheme.PanelPaint(Sender: TObject; ADarkTheme: boolean);
 var
   c: TCanvas;
 begin
   if Sender is TCustomControl then
   begin
     c := TCustomControl(Sender).Canvas;
-    c.Pen.Color := clDarkPanelHighlight;
+    c.Pen.Color := GetColorPanelHighlight(ADarkTheme);
     c.Line(0, 0, c.Width, 0);
     c.Line(0, 0, 0, c.Height);
-    c.Pen.Color := clDarkPanelShadow;
+    c.Pen.Color := GetColorPanelShadow(ADarkTheme);
     c.Line(0, c.Height-1, c.Width, c.Height-1);
     c.Line(c.Width-1, 0, c.Width-1, c.Height);
   end;
 end;
 
-procedure TDarkTheme.ToolBarPaint(Sender: TObject);
+procedure TDarkTheme.PanelPaintDark(Sender: TObject);
+begin
+  PanelPaint(Sender, true);
+end;
+
+procedure TDarkTheme.PanelPaintLight(Sender: TObject);
+begin
+  PanelPaint(Sender, false);
+end;
+
+procedure TDarkTheme.ToolBarPaint(Sender: TObject; ADarkTheme: boolean);
 var
   T: TToolBar;
 begin
@@ -113,23 +215,34 @@ begin
     T := TToolBar(Sender);
     if T.Align = alLeft then
     begin
-      T.Canvas.Pen.Color := clDarkPanelShadow;
+      T.Canvas.Pen.Color := GetColorPanelShadow(ADarkTheme);
       T.Canvas.Line(T.Width-1, 0, T.Width-1, T.Height)
     end
     else if T.Align = alRight then
     begin
-      T.Canvas.Pen.Color := clDarkPanelHighlight;
+      T.Canvas.Pen.Color := GetColorPanelHighlight(ADarkTheme);
       T.Canvas.Line(0, 0, 0, T.Height)
     end
     else
     begin
-      T.Canvas.Pen.Color := clDarkPanelShadow;
+      T.Canvas.Pen.Color := GetColorPanelShadow(ADarkTheme);
       T.Canvas.Line(0, 0, T.Width, 0);
     end;
   end;
 end;
 
-procedure TDarkTheme.ToolBarPaintButton(Sender: TToolButton; State: integer);
+procedure TDarkTheme.ToolBarPaintLight(Sender: TObject);
+begin
+  ToolbarPaint(Sender, false);
+end;
+
+procedure TDarkTheme.ToolBarPaintDark(Sender: TObject);
+begin
+  ToolbarPaint(Sender, true);
+end;
+
+procedure TDarkTheme.ToolBarPaintButton(Sender: TToolButton; State: integer;
+  ADarkTheme: boolean);
 var
   Bitmap: TBGRABitmap;
   //ts: TSize;
@@ -226,14 +339,21 @@ begin
   end;
 end;
 
+procedure TDarkTheme.ToolBarPaintButtonLight(Sender: TToolButton; State: integer);
+begin
+  ToolBarPaintButton(Sender, State, false);
+end;
+
+procedure TDarkTheme.ToolBarPaintButtonDark(Sender: TToolButton; State: integer);
+begin
+  ToolBarPaintButton(Sender, State, false);
+end;
+
 procedure TDarkTheme.Apply(AForm: TForm; AThemeEnabled: boolean; ARecursive: boolean);
 var
   i: Integer;
 begin
-  if AThemeEnabled then
-    AForm.Color := clDarkBtnFace
-  else
-    AForm.Color := clBtnFace;
+  AForm.Color := GetColorButtonFace(AThemeEnabled);
   if ARecursive then
   for i := 0 to AForm.ControlCount-1 do
   begin
@@ -255,14 +375,21 @@ begin
   if AThemeEnabled then
   begin
     APanel.BevelOuter:= bvNone;
-    if APanel.OnPaint = nil then APanel.OnPaint := @PanelPaint;
-    APanel.Color := clDarkBtnFace;
+    if (APanel.OnPaint = nil) or (APanel.OnPaint = @PanelPaintLight) then
+      APanel.OnPaint := @PanelPaintDark;
   end else
   begin
-    APanel.BevelOuter:= bvRaised;
-    if APanel.OnPaint = @PanelPaint then APanel.OnPaint := nil;
-    APanel.Color := clBtnFace;
+    if not IsLclLightThemeSafe then
+    begin
+      APanel.BevelOuter:= bvNone;
+      APanel.OnPaint := @PanelPaintLight;
+    end else
+    begin
+      APanel.BevelOuter:= bvRaised;
+      if APanel.OnPaint = @PanelPaintDark then APanel.OnPaint := nil;
+    end;
   end;
+  APanel.Color := GetColorButtonFace(AThemeEnabled);
   if ARecursive then
   for i := 0 to APanel.ControlCount-1 do
   begin
@@ -286,10 +413,7 @@ procedure TDarkTheme.Apply(AVectorialFill: TLCVectorialFillControl;
 var
   i: Integer;
 begin
-  if AThemeEnabled then
-    AVectorialFill.Color := clDarkBtnFace
-  else
-    AVectorialFill.Color := clBtnFace;
+  AVectorialFill.Color := GetColorButtonFace(AThemeEnabled);
 
   for i := 0 to AVectorialFill.ControlCount-1 do
   begin
@@ -310,13 +434,14 @@ var
 begin
   if AThemeEnabled then
   begin
-    if AToolbar.OnPaintButton = nil then AToolbar.OnPaintButton := @ToolBarPaintButton;
-    AToolbar.Color := clDarkBtnFace;
+    if (AToolbar.OnPaintButton = nil) or (AToolbar.OnPaintButton = @ToolBarPaintButtonLight) then
+      AToolbar.OnPaintButton := @ToolBarPaintButtonDark;
   end else
   begin
-    if AToolbar.OnPaintButton = @ToolBarPaintButton then AToolbar.OnPaintButton := nil;
-    AToolbar.Color := clBtnFace;
+    if not IsLclLightThemeSafe then  AToolbar.OnPaintButton := @ToolBarPaintButtonLight else
+    if AToolbar.OnPaintButton = @ToolBarPaintButtonDark then AToolbar.OnPaintButton := nil;
   end;
+  AToolbar.Color := GetColorButtonFace(AThemeEnabled);
   for i := 0 to AToolbar.ControlCount-1 do
   begin
     if AToolbar.Controls[i] is TBCButton then
@@ -346,33 +471,34 @@ procedure TDarkTheme.Apply(AButton: TBCButton; ADarkTheme: boolean; AFontHeightR
     result := BGRAToColor(HSLAToBGRA(hsla1));
   end;
 
-var highlight, btnFace, btnShadow, btnText: TColor;
+var highlight, btnFace, btnShadow, btnText, gradMiddle: TColor;
   fh: Int64;
 begin
   if ADarkTheme then
   begin
     highlight := $a0a0a0;
-    btnFace := clDarkEditableFace;
-    btnText := clLightText;
-    btnShadow:= clDarkPanelShadow;
   end else
   begin
     {$IFDEF DARWIN}
-    highlight := MergeColor(clBtnFace,clWhite);
+    highlight := MergeColor(GetColorButtonFace(false),clWhite);
     {$ELSE}
-    highlight := clBtnHighlight;
+    highlight := GetColorButtonHighlight(false);
     {$ENDIF}
-    btnFace := clBtnFace;
-    btnText := clBtnText;
-    btnShadow := clBtnShadow;
   end;
+  btnFace := GetColorButtonFace(ADarkTheme);
+  btnText := GetColorButtonText(ADarkTheme);
+  btnShadow := GetColorPanelShadow(ADarkTheme);
+  gradMiddle := MergeColor(btnFace,highlight);
   with AButton do
   begin
     Rounding.RoundX := DoScaleX(3, OriginalDPI);
     Rounding.RoundY := DoScaleX(3, OriginalDPI);
-    BCAssignSystemState(StateNormal, btnText, btnFace, highlight, btnFace, btnShadow, btnShadow);
-    BCAssignSystemState(StateHover, HoverColor(btnText), HoverColor(btnFace), HoverColor(highlight), HoverColor(btnFace), HoverColor(btnShadow), HoverColor(btnShadow));
-    BCAssignSystemState(StateClicked, HoverColor(btnText), HoverColor(MergeColor(btnFace,btnShadow)), HoverColor(btnFace), HoverColor(MergeColor(btnFace,btnShadow)), HoverColor(btnShadow), HoverColor(btnShadow));
+    BCAssignSystemState(StateNormal, btnText, btnFace, highlight,
+      gradMiddle, btnShadow, btnShadow);
+    BCAssignSystemState(StateHover, HoverColor(btnText), HoverColor(btnFace), HoverColor(highlight),
+      HoverColor(gradMiddle), HoverColor(btnShadow), HoverColor(btnShadow));
+    BCAssignSystemState(StateClicked, HoverColor(btnText), HoverColor(MergeColor(btnFace,btnShadow)),
+      HoverColor(btnFace), HoverColor(MergeColor(btnFace,btnShadow)), HoverColor(btnShadow), HoverColor(btnShadow));
     fh := round((AButton.Height+4)*AFontHeightRatio);
     StateNormal.Border.LightWidth := 0;
     StateNormal.FontEx.Height := fh;
@@ -408,49 +534,152 @@ begin
     Button.StateClicked.FontEx.ShadowColorOpacity:= 96;
     Button.StateHover.FontEx.Height := fh;
     Button.StateHover.FontEx.ShadowColorOpacity:= 96;
-    if ADarkTheme then
-    begin
-      DropDownBorderColor:= clBlack;
-      DropDownFontColor:= clLightText;
-      DropDownColor:= clDarkBtnFace;
-      FocusBorderColor:= clLightText;
-    end else
-    begin
-      DropDownBorderColor := MergeBGRA(ColorToBGRA(clWindowText),ColorToBGRA(clWindow));
-      DropDownFontColor:= clWindowText;
-      DropDownColor:= clWindow;
-      FocusBorderColor:= clWindowText;
-    end;
-    DropDownFontHighlight:= clHighlightText;
-    DropDownHighlight:= clHighlight;
+    DropDownFontColor:= GetColorEditableText(ADarkTheme);
+    DropDownColor:= GetColorEditableFace(ADarkTheme);
+    FocusBorderColor:= GetColorEditableText(ADarkTheme);
+    DropDownBorderColor:= MergeBGRA(ColorToBGRA(DropDownFontColor), ColorToBGRA(DropDownColor));
+    DropDownFontHighlight:= GetColorHighlightText(ADarkTheme);
+    DropDownHighlight:= GetColorHighlightBack(ADarkTheme);
   end;
 end;
 
 procedure TDarkTheme.Apply(AUpDown: TBCTrackbarUpdown; ADarkTheme: boolean);
 begin
   if ADarkTheme then
+    AUpDown.ButtonBackground.Color:= $a0a0a0
+  else
+    AUpDown.ButtonBackground.Color:= GetColorButtonFace(ADarkTheme);
+
+  AUpDown.Border.Color := GetColorPanelShadow(ADarkTheme);
+  AUpDown.Background.Color := GetColorEditableFace(ADarkTheme);
+  AUpDown.ButtonBackground.Style:= bbsColor;
+  AUpDown.Font.Color := GetColorEditableText(ADarkTheme);
+end;
+
+procedure TDarkTheme.Apply(ALabel: TLabel; ADarkTheme: boolean);
+begin
+  ALabel.Font.Color := GetColorEditableText(ADarkTheme);
+end;
+
+function TDarkTheme.IsSystemDarkTheme: boolean;
+begin
+  {$IFDEF DARWIN}
+  if IsMojaveOrNewer then
+    exit(IsMojaveDarkTheme);
+  {$ENDIF}
+  {$IFDEF WINDOWS}
+  case GetWinDarkTheme of
+    dtmLight: exit(false);
+    dtmDark: exit(true);
+  end;
+  {$ENDIF}
+  result := IsLclDarkTheme;
+end;
+
+function TDarkTheme.IsLclDarkTheme: boolean;
+const
+  cMax = $A0;
+var
+  N: TColor;
+begin
+  N:= ColorToRGB(clWindow);
+  Result:= (Red(N)<cMax) and (Green(N)<cMax) and (Blue(N)<cMax);
+end;
+
+function TDarkTheme.IsLclLightThemeSafe: boolean;
+begin
+  result := not IsLclDarkTheme and not IsSystemDarkTheme;
+end;
+
+function TDarkTheme.HasSystemDarkThemeChanged: boolean;
+var
+  newState: Boolean;
+begin
+  newState := IsSystemDarkTheme;
+  if newState <> FLastSystemDarkTheme then
   begin
-    AUpDown.Border.Color := clDarkPanelShadow;
-    AUpDown.Background.Color := clDarkEditableFace;
-    AUpDown.ButtonBackground.Style:= bbsColor;
-    AUpDown.ButtonBackground.Color:= $a0a0a0;
-    AUpDown.Font.Color := clLightText;
+    result := true;
+    FLastSystemDarkTheme:= newState;
   end else
+    result := false;
+end;
+
+function TDarkTheme.GetColorButtonHighlight(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkBtnHighlight
+  else if not IsLclLightThemeSafe then result := $f0f0f0
+  else result := clBtnHighlight;
+end;
+
+function TDarkTheme.GetColorButtonFace(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkBtnFace
+  else if not IsLclLightThemeSafe then result := $d8d8d8
+  else result := clBtnFace;
+end;
+
+function TDarkTheme.GetColorForm(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkBtnFace
+  else if not IsLclLightThemeSafe then result := $d8d8d8
+  else result := clForm;
+end;
+
+function TDarkTheme.GetColorEditableFace(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkEditableFace
+  else if not IsLclLightThemeSafe then result := $ffffff
+  else result := clWindow;
+end;
+
+function TDarkTheme.GetColorEditableText(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clLightText
+  else if not IsLclLightThemeSafe then result := $303030
+  else result := clWindowText;
+end;
+
+function TDarkTheme.GetColorButtonText(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clLightText
+  else if not IsLclLightThemeSafe then result := clBlack
+  else result := clBtnText;
+end;
+
+function TDarkTheme.GetColorPanelHighlight(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkPanelHighlight
+  else if not IsLclLightThemeSafe then result := $f0f0f0
+  else result := clBtnHighlight;
+end;
+
+function TDarkTheme.GetColorPanelShadow(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then result := clDarkPanelShadow
+  else if not IsLclLightThemeSafe then result := $808080
+  else result := clBtnShadow;
+end;
+
+function TDarkTheme.GetColorHighlightBack(ADarkTheme: boolean): TColor;
+begin
+  if ADarkTheme then
   begin
-    AUpDown.Border.Color := MergeBGRA(ColorToBGRA(clWindowText),ColorToBGRA(clBtnFace));
-    AUpDown.Background.Color := clWindow;
-    AUpDown.ButtonBackground.Style:= bbsColor;
-    AUpDown.ButtonBackground.Color:= clBtnFace;
-    AUpDown.Font.Color := clWindowText;
-  end;
+    if BGRADiff(ColorToBGRA(clHighlight), clDarkBtnFace)>=64 then
+      result := clHighlight
+      else result := MergeBGRA(ColorToBGRA(clLightText), ColorToBGRA(clHighlight));
+  end
+  else result := clHighlight;
 end;
 
-procedure TDarkTheme.Apply(ALabel: TLabel; ADarkTheme: boolean);
+function TDarkTheme.GetColorHighlightText(ADarkTheme: boolean): TColor;
 begin
   if ADarkTheme then
-    ALabel.Font.Color := clLightText
-  else
-    ALabel.Font.Color := clWindowText;
+  begin
+    if BGRADiff(ColorToBGRA(clHighlight), clDarkBtnFace)>=64 then
+      result := clHighlightText
+      else result := clBlack;
+  end
+  else result := clHighlightText;
 end;
 
 initialization

+ 1 - 1
lazpaint/ufileextensions.pas

@@ -323,7 +323,7 @@ initialization
   RegisterPicExt('Portable Network Graphic','png', [eoReadable,eoWritable]);
   RegisterPicExt(rsPhotoshop,'psd', [eoReadable]);
   BGRASVG.RegisterSvgFormat;
-  RegisterPicExt('Scalable Vector Graphic','svg', [eoReadable]);
+  RegisterPicExt('Scalable Vector Graphic','svg', [eoReadable, eoWritable]);
   RegisterPicExt('Targa','tga', [eoReadable,eoWritable]);
   RegisterPicExt('Tiff','tif;tiff', [eoReadable,eoWritable]);
   RegisterPicExt('WebP','webp', [eoReadable,eoWritable]);

Деякі файли не було показано, через те що забагато файлів було змінено