diff --git a/Builds/MSVC/Installer/FractoriumInstaller.wixproj b/Builds/MSVC/Installer/FractoriumInstaller.wixproj
index bceea02..67ea487 100644
--- a/Builds/MSVC/Installer/FractoriumInstaller.wixproj
+++ b/Builds/MSVC/Installer/FractoriumInstaller.wixproj
@@ -6,7 +6,7 @@
3.7
{c8096c47-e358-438c-a520-146d46b0637d}
2.0
- Fractorium_Beta_0.9.9.1
+ Fractorium_Beta_0.9.9.2
Package
$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets
$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
diff --git a/Builds/MSVC/Installer/Product.wxs b/Builds/MSVC/Installer/Product.wxs
index 82c3de7..a5d6735 100644
--- a/Builds/MSVC/Installer/Product.wxs
+++ b/Builds/MSVC/Installer/Product.wxs
@@ -1,6 +1,6 @@
-
+
@@ -13,7 +13,7 @@
-
+
+
+
+
diff --git a/Builds/MSVC/VS2013/Ember.rc b/Builds/MSVC/VS2013/Ember.rc
index 26ccb12..bd0ecb5 100644
Binary files a/Builds/MSVC/VS2013/Ember.rc and b/Builds/MSVC/VS2013/Ember.rc differ
diff --git a/Builds/MSVC/VS2013/EmberCL.rc b/Builds/MSVC/VS2013/EmberCL.rc
index a12a70f..85e7567 100644
Binary files a/Builds/MSVC/VS2013/EmberCL.rc and b/Builds/MSVC/VS2013/EmberCL.rc differ
diff --git a/Builds/MSVC/VS2013/Fractorium.vcxproj b/Builds/MSVC/VS2013/Fractorium.vcxproj
index 1656e9b..021dbd0 100644
--- a/Builds/MSVC/VS2013/Fractorium.vcxproj
+++ b/Builds/MSVC/VS2013/Fractorium.vcxproj
@@ -304,6 +304,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
Use
Use
+
@@ -335,6 +336,11 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
+
+
+
+
+
Create
@@ -351,6 +357,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -399,6 +411,18 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
@@ -449,6 +473,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -497,6 +527,18 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
@@ -533,6 +575,12 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -581,6 +629,18 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
@@ -639,6 +699,87 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/VariationsDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssDialog.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssDialog.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
+
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing csshighlighter.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/csshighlighter.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
+
+
+
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+ $(QTDIR)\bin\moc.exe;%(FullPath)
+ Moc%27ing QssTextEdit.h...
+ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp
+ "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fFractoriumPch.h" "-f../../../../../Source/Fractorium/QssTextEdit.h" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_MULTIMEDIA_LIB -DQT_HELP_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_XML_LIB -D_MBCS "-I." "-I$(QTDIR)\include" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles" "-I$(ProjectDir)..\..\..\Fractorium\GeneratedFiles\ConfigurationName" "-I$(QTDIR)\..\qtmultimedia\include\QtMultimedia" "-I$(QTDIR)\..\qtmultimedia\include" "-I$(QTDIR)\..\qttools\include" "-I$(QTDIR)\..\qttools\include\QtHelp" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtXml" "-I.\GeneratedFiles" "-I$(ProjectDir)..\..\..\Source\Ember" "-I$(ProjectDir)..\..\..\Source\EmberCL" "-I$(ProjectDir)..\..\..\Source\EmberCommon" "-I$(ProjectDir)..\..\..\..\glm" "-I$(ProjectDir)..\..\..\..\tbb\include" "-I$(ProjectDir)..\..\..\..\libjpeg" "-I$(ProjectDir)..\..\..\..\libpng" "-I$(ProjectDir)..\..\..\..\libxml2\include" "-I$(ProjectDir)..\..\..\..\glew\include" "-I$(AMDAPPSDKROOT)\include" "-I$(CUDA_PATH)include" "-I.\GeneratedFiles\$(ConfigurationName)\."
+
+
$(QTDIR)\bin\moc.exe;%(FullPath);%(AdditionalInputs)
@@ -1280,6 +1421,32 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"
.\GeneratedFiles\ui_%(Filename).h;%(Outputs)
"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+ $(QTDIR)\bin\uic.exe;%(AdditionalInputs)
+ Uic%27ing %(Identity)...
+ .\GeneratedFiles\ui_%(Filename).h;%(Outputs)
+ "$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"
+
diff --git a/Builds/MSVC/VS2013/Fractorium.vcxproj.filters b/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
index acef896..ab5eb74 100644
--- a/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
+++ b/Builds/MSVC/VS2013/Fractorium.vcxproj.filters
@@ -54,7 +54,7 @@
False
- {95078dd1-1c6e-476d-b565-cc844cef63d2}
+ {5ba9fccd-8922-4037-956f-d57177a43700}
@@ -271,6 +271,51 @@
Generated Files\ReleaseNvidia
+
+ Generated Files\Debug
+
+
+ Generated Files\Release
+
+
+ Generated Files\ReleaseNvidia
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
+
+ Generated Files\Debug
+
+
+ Generated Files\Release
+
+
+ Generated Files\ReleaseNvidia
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
+
+ Generated Files\Debug
+
+
+ Generated Files\Release
+
+
+ Generated Files\ReleaseNvidia
+
@@ -318,6 +363,15 @@
Generated Files
+
+ Generated Files
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
@@ -386,6 +440,18 @@
Dialogs
+
+ Form Files
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
+
+ Dialogs\Qss
+
diff --git a/Builds/QtCreator/Fractorium/Fractorium.pro b/Builds/QtCreator/Fractorium/Fractorium.pro
index 54737fd..26c61d9 100644
--- a/Builds/QtCreator/Fractorium/Fractorium.pro
+++ b/Builds/QtCreator/Fractorium/Fractorium.pro
@@ -50,7 +50,12 @@ SOURCES += \
../../../Source/Fractorium/Main.cpp \
../../../Source/Fractorium/OptionsDialog.cpp \
../../../Source/Fractorium/VariationsDialog.cpp \
- ../../../Source/Fractorium/SpinBox.cpp
+ ../../../Source/Fractorium/SpinBox.cpp \
+ ../../../Source/Fractorium/csshighlighter.cpp \
+ ../../../Source/Fractorium/qcssparser.cpp \
+ ../../../Source/Fractorium/qcssscanner.cpp \
+ ../../../Source/Fractorium/QssDialog.cpp \
+ ../../../Source/Fractorium/QssTextEdit.cpp
HEADERS += \
../../../Source/Fractorium/AboutDialog.h \
@@ -79,14 +84,21 @@ HEADERS += \
../../../Source/Fractorium/FractoriumCommon.h \
../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h \
../../../Source/Fractorium/PaletteTableWidgetItem.h \
- ../../../Source/Fractorium/VariationsDialog.h
+ ../../../Source/Fractorium/VariationsDialog.h \
+ ../../../Source/Fractorium/csshighlighter.h \
+ ../../../Source/Fractorium/qcssparser.h \
+ ../../../Source/Fractorium/qcssscanner.h \
+ ../../../Source/Fractorium/qfunctions.h \
+ ../../../Source/Fractorium/QssDialog.h \
+ ../../../Source/Fractorium/QssTextEdit.h
FORMS += \
../../../Source/Fractorium/AboutDialog.ui \
../../../Source/Fractorium/FinalRenderDialog.ui \
../../../Source/Fractorium/Fractorium.ui \
../../../Source/Fractorium/VariationsDialog.ui \
- ../../../Source/Fractorium/OptionsDialog.ui
+ ../../../Source/Fractorium/OptionsDialog.ui \
+ ../../../Source/Fractorium/QssDialog.ui
OTHER_FILES += \
../../../Source/Fractorium/Fractorium.aps \
diff --git a/Data/dark.qss b/Data/dark.qss
new file mode 100644
index 0000000..22fc301
--- /dev/null
+++ b/Data/dark.qss
@@ -0,0 +1,611 @@
+/*---Base Style---
+ This is needed to deal with the large tabs in the fusion theme which is the default on Linux, and optional on Windows.
+ It's not needed for other themes.
+ You should keep this at the top of whatever custom style you make to ensure the tabs aren't unusually large.*/
+QTabBar::tab { height: 5ex; }/*Do this for windows*/
+/*QTabBar::tab { height: 3ex; }*//*Do this for linux*/
+
+/*This is needed to give the labels on the status bar some padding.*/
+QStatusBar QLabel { padding-left: 2px; padding-right: 2px; }
+
+/*Specific styles below this line*/
+
+QObject
+{
+ background-color : rgb(53, 53, 53);
+ color: darkgray;
+ alternate-background-color: rgb(53, 53, 53);
+ selection-color: black;
+ selection-background-color: rgb(42, 130, 218);
+}
+
+QObject:disabled
+{
+ color: rgb(35, 35, 35);
+ background-color: rgb(53, 53, 53);
+ border-color: rgb(35, 35, 35);
+}
+
+QDockWidget::float-button
+{
+ background-color: gray;
+}
+
+QDockWidget::title
+{
+ margin: 1px;
+ padding: 2px;
+ background-color: gray;
+}
+
+QTabWidget::pane
+{
+ border: 1px solid gray;
+}
+
+QPushButton
+{
+ margin: 1px;
+ padding: 4px;
+ border: 1px solid gray;
+}
+
+QPushButton:pressed
+{
+ background-color: gray;
+}
+
+QPushButton:focus
+{
+ outline: none;
+}
+
+QTableView QPushButton
+{
+ border: 1px solid gray;
+ margin: 1px;
+ padding: 0px;
+}
+
+QLineEdit, QTextEdit
+{
+ border: 1px solid gray;
+ color: darkgray;
+ background-color: rgb(40, 40, 50);
+ selection-background-color: darkgray;
+}
+
+QToolTip
+{
+ background-color: darkgray;
+ border: 1px solid darkgray;
+}
+
+QSpinBox,
+QDoubleSpinBox
+{
+ padding-right: 0px;
+ color: darkgray;
+ selection-background-color: darkgray;
+ font: 9pt "Segoe UI";/*For some reason the font changes if you set any style. Set this to whatever font is the default on your system*/
+}
+
+QCheckBox
+{
+ spacing: 5px;
+}
+
+QCheckBox::indicator,
+QTableView::indicator
+{
+ border: none;
+ border-radius: 2px;
+ background-color: lightgray;
+}
+
+QCheckBox::indicator:enabled:unchecked,
+QTableView::indicator:enabled:unchecked
+{
+ background-color: lightgray;
+ image: url(:/Fractorium/Icons/checkbox_unchecked.png);
+}
+
+QCheckBox::indicator:enabled:checked,
+QTableView::indicator:enabled:checked
+{
+ background-color: lightgray;
+ image: url(:/Fractorium/Icons/checkbox_checked.png);
+}
+
+QCheckBox::indicator:disabled:unchecked,
+QTableView::indicator:disabled:unchecked
+{
+ background-color: gray;
+ image: none;
+}
+
+QCheckBox::indicator:disabled:checked,
+QTableView::indicator:disabled:checked
+{
+ background-color: gray;
+ image: none;
+}
+
+QRadioButton::indicator:checked
+{
+ background-color: black;
+ border: 2px solid gray;
+ border-radius: 7px;
+ width: 8px;
+ height: 8px;
+ margin: 3px;
+ padding: 1px;
+}
+
+QRadioButton::indicator:checked:disabled
+{
+ background-color: rgb(35, 35, 35);
+}
+
+QRadioButton::indicator:unchecked
+{
+ border: 2px solid gray;
+ border-radius: 7px;
+ width: 8px;
+ height: 8px;
+ margin: 3px;
+ padding: 1px;
+}
+
+QComboBox
+{
+ margin: 0px;
+ padding-left: 4px;
+ border: 1px solid gray;
+}
+
+QComboBox::down-arrow:enabled
+{
+ border: 1px solid gray;
+ margin-right: 2px;
+ margin-top: 0px;
+ margin-bottom: 1px;
+}
+
+
+QComboBox::down-arrow:disabled
+{
+ border: 1px solid rgb(35, 35, 35);
+ margin-right: 2px;
+ margin-top: 0px;
+ margin-bottom: 1px;
+}
+
+QComboBox::drop-down
+{
+ border: none;
+}
+
+/*For some reason this is needed with Fusion, but not with Windows*/
+QComboBox::item:selected
+{
+ selection-background-color: darkgray;
+}
+
+QComboBox QAbstractItemView
+{
+ border: 1px solid gray;
+ outline: none;
+ selection-background-color: darkgray;
+}
+
+QTableView QComboBox
+{
+ margin: 1px;
+ padding: 0px;
+ padding-left: 3px;
+}
+
+QGroupBox QComboBox
+{
+ margin: 1px;
+ margin-bottom: 0px;
+}
+
+QTableView QComboBox::down-arrow
+{
+ margin-top: 0px;
+ margin-right: 1px;
+ margin-bottom: 0px;
+}
+
+QProgressBar
+{
+ color: black;
+ background-color: gray;
+ border: 0px none gray;
+ border-radius: 3px;
+ text-align: center;
+}
+
+QProgressBar::chunk
+{
+ border-radius: 3px;
+ background-color: lightgray;
+}
+
+QStatusBar QProgressBar
+{
+ min-width: 300px;
+ max-width: 300px;
+ margin-right: 4px;
+}
+
+QMenuBar
+{
+ border-bottom: 1px solid gray;
+}
+
+QMenuBar::item
+{
+ background-color: rgb(53, 53, 53);
+}
+
+QMenu::item:disabled
+{
+ color: rgb(35, 35, 35);
+
+}
+
+QMenu::item:enabled:selected
+{
+ background-color: gray;
+}
+
+QMenu::item:disabled:selected
+{
+ background-color: rgb(53, 53, 53);
+}
+
+QToolBar
+{
+ border: 0px none gray;
+}
+
+QGroupBox
+{
+ padding-top: 3px;
+ border: 2px solid gray;
+ border-radius: 4px;
+ margin-top: 3ex;
+}
+
+QGroupBox::title
+{
+ subcontrol-origin: border;
+ subcontrol-position: top left;
+ margin-top: -1ex;
+ margin-left: 0px;
+ padding-right: 1px;
+ padding-left: 2px;
+ top: -2ex;
+ left: 8px;
+}
+
+QListView
+{
+ selection-color: black;
+ selection-background-color: darkgray;
+}
+
+QListView::item:selected
+{
+ background-color: darkgray;
+}
+
+QTreeView
+{
+ border: 1px solid gray;
+ background-color: rgb(53, 53, 53);
+}
+
+/*Setting this gives a more consistent look, but removes the ability to gray variations that are included in the xform*/
+QTreeView::item
+{
+ background-color: rgb(53, 53, 53);
+ color: darkgray;
+ outline: none;
+}
+
+QTreeView::item:selected
+{
+ border: 0px none black;
+ background-color: gray;
+ outline: none;
+}
+
+QTreeView::branch:!has-children
+{
+ background: rgb(53, 53, 53);
+}
+
+QTreeView::branch:has-children:closed
+{
+ border: 1px solid darkgray;
+ background: gray;
+ margin: 2px;
+}
+
+QTreeView::branch:has-children:!closed
+{
+ border: 1px solid lightgray;
+ background: gray;
+ margin-left: 1px;
+ margin-right: 0px;
+ margin-top: 3px;
+ margin-bottom: 3px;
+}
+
+QTableView
+{
+ border-left: 0px none gray;
+ border-top: 0px none gray;
+ border-right: 0px none gray;
+ border-bottom: 0px none gray;
+ gridline-color: gray;
+ color: darkgray;
+ selection-color: darkgray;
+ selection-background-color: rgb(53, 53, 53);
+}
+
+QTableView QTableCornerButton::section:enabled
+{
+ background-color: darkgray;
+}
+
+QTableView QTableCornerButton::section:disabled
+{
+ background-color: rgb(53, 53, 53);
+}
+
+QTableView::indicator:disabled
+{
+ background-color: rgb(35, 35, 35);
+}
+
+QTableView:disabled
+{
+ color: rgb(35, 35, 35);
+ border: none;
+ gridline-color: rgb(35, 35, 35);
+}
+
+QHeaderView::section::vertical:enabled
+{
+ color: black;
+ background-color: gray;
+ border: none;
+ border-bottom: 1px solid gray;
+ padding: 4px;
+}
+
+QHeaderView::section::horizontal:enabled
+{
+ color: black;
+ background-color: darkgray;
+ border: 0px solid darkgray;
+ border-right: 1px solid gray;
+ padding: 4px;
+}
+
+QHeaderView::section::vertical:disabled
+{
+ color: rgb(35, 35, 35);
+ background-color: rgb(53, 53, 53);
+ border: 0px none darkgray;
+ border-bottom: 1px solid rgb(53, 53, 53);
+ padding: 4px;
+}
+
+QHeaderView::section::horizontal:disabled
+{
+ color:rgb(35, 35, 35);
+ background-color: rgb(53, 53, 53);
+ border: 0px none darkgray;
+ border-right: 1px solid rgb(53, 53, 53);
+ padding: 4px;
+}
+
+QScrollBar::vertical
+{
+ background-color: darkgray;
+ border: 0px solid darkgray;
+ width: 15px;
+ margin: 22px 0 22px 0;
+}
+
+QScrollBar::handle::vertical
+{
+ background-color: gray;
+ border-top: 1px solid darkgray;
+ border-bottom: 1px solid darkgray;
+ min-height: 20px;
+}
+
+QScrollBar::add-line::vertical
+{
+ border: 0px solid darkgray;
+ background-color: gray;
+ height: 22px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line::vertical
+{
+ border: 0px solid darkgray;
+ background-color: gray;
+ height: 22px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow::vertical, QScrollBar::down-arrow::vertical
+{
+ border: 2px solid darkgray;
+ width: 5px;
+ height: 12px;
+ background-color: gray;
+}
+
+QScrollBar::add-page::vertical, QScrollBar::sub-page::vertical, QScrollBar::add-page::horizontal, QScrollBar::sub-page::horizontal
+{
+ background-color: darkgray;
+}
+
+QScrollBar::horizontal
+{
+ background-color: darkgray;
+ border: 0px solid darkgray;
+ height: 15px;
+ margin: 0px 20px 0 20px;
+}
+
+QScrollBar::handle::horizontal
+{
+ background-color: gray;
+ border-left: 1px solid darkgray;
+ border-right: 1px solid darkgray;
+ min-width: 20px;
+}
+
+QScrollBar::add-line::horizontal
+{
+ border: 0px solid darkgray;
+ background-color: gray;
+ width: 20px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line::horizontal
+{
+ border: 0px solid darkgray;
+ background-color: gray;
+ width: 20px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::left-arrow::horizontal, QScrollBar::right-arrow::horizontal
+{
+ border: 2px solid darkgray;
+ width: 12px;
+ height: 5px;
+ background-color: gray;
+}
+
+QMenu::separator
+{
+ height: 1px;
+ background-color: gray;
+}
+
+QToolBar::separator
+{
+ width: 1px;
+ margin-top: 3px;
+ margin-bottom: 2px;
+ background-color: gray;
+}
+
+QStatusBar::item
+{
+ border: none;
+}
+
+/*Specific controls*/
+QTableWidget#ColorTableHeader QHeaderView::section::horizontal,
+QTableWidget#GeometryTableHeader QHeaderView::section::horizontal,
+QTableWidget#FilterTableHeader QHeaderView::section::horizontal,
+QTableWidget#IterationTableHeader QHeaderView::section::horizontal,
+QTreeWidget#LibraryTree QHeaderView::section::horizontal
+{
+ border-right: none;
+}
+
+QTableWidget#ColorTable,
+QTableWidget#GeometryTable,
+QTableWidget#FilterTable,
+QTableWidget#IterationTable,
+QTableWidget#XformWeightNameTable
+{
+ border-left: 1px solid gray;
+}
+
+QTableWidget#SummaryTable,
+QTableWidget#PaletteListTable
+{
+ border-left: 1px solid gray;
+}
+
+QTableWidget#SummaryTable QHeaderView::section::vertical
+{
+ background-color: darkgray;
+}
+
+QTableWidget#PaletteAdjustTable,
+QTableWidget#PalettePreviewTable,
+QTableWidget#XformColorIndexTable,
+QTableWidget#XformColorValuesTable,
+QTableWidget#InfoBoundsTable,
+QTableWidget#OptionsXmlSavingTable,
+QTableWidget#OptionsIdentityTable,
+QTableWidget#FinalRenderSizeTable,
+QTableWidget#FinalRenderParamsTable
+{
+ border-left: 1px solid gray;
+ border-top: 1px solid gray;
+}
+
+QLineEdit#PaletteFilterLineEdit,
+QLineEdit#VariationsFilterLineEdit
+{
+ height: 20px;
+ min-height: 20px;
+ max-height: 20px;
+}
+
+QSpinBox#ThreadCountSpin,
+QSpinBox#RandomCountSpin,
+QSpinBox#CpuSubBatchSpin,
+QSpinBox#OpenCLSubBatchSpin,
+QSpinBox#FinalRenderCurrentSpin,
+QSpinBox#FinalRenderThreadCountSpin
+{
+ padding: 2px;
+ border: 1px solid gray;
+}
+
+QSpinBox#ThreadCountSpin:disabled,
+QSpinBox#CpuSubBatchSpin:disabled,
+QSpinBox#OpenCLSubBatchSpin:disabled,
+QSpinBox#FinalRenderCurrentSpin:disabled,
+QSpinBox#FinalRenderThreadCountSpin:disabled
+{
+ padding: 2px;
+ border: 1px solid rgb(35, 35, 35);
+}
+
+QTableView#FinalRenderParamsTable QComboBox
+{
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+QTableView#FinalRenderParamsTable QPushButton
+{
+ margin-top: 1px;
+ margin-bottom: 2px;
+ padding: 0px;
+}
diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h
index 6374ca5..e01f97e 100644
--- a/Source/Ember/Ember.h
+++ b/Source/Ember/Ember.h
@@ -180,7 +180,7 @@ public:
SetProjFunc();
ClearEdit();
- if (ember.m_Edits != nullptr)
+ if (ember.m_Edits)
m_Edits = xmlCopyDoc(ember.m_Edits, 1);
CopyVec(m_EmberMotionElements, ember.m_EmberMotionElements);
@@ -858,7 +858,7 @@ public:
var->m_Weight = 0;
- if (parVar != nullptr)
+ if (parVar)
parVar->Clear();
for (size_t k = 0; k < size; k++)//For each ember in the list.
@@ -869,17 +869,17 @@ public:
{
Variation* tempVar = tempXform->GetVariationById(var->VariationId());//See if the variation at this xform index exists in that ember at this xform index.
- if (tempVar != nullptr)
+ if (tempVar)
{
//Interp weight.
var->m_Weight += tempVar->m_Weight * coefs[k];
//If it was a parametric variation, interp params.
- if (parVar != nullptr)
+ if (parVar)
{
ParametricVariation* tempParVar = dynamic_cast*>(tempVar);
- if (tempParVar != nullptr && (parVar->ParamCount() == tempParVar->ParamCount()))//This check will should always be true, but just check to be absolutely sure to avoid clobbering memory.
+ if (tempParVar && (parVar->ParamCount() == tempParVar->ParamCount()))//This check will should always be true, but just check to be absolutely sure to avoid clobbering memory.
{
auto params = parVar->Params();
auto tempParams = tempParVar->Params();
@@ -1461,7 +1461,7 @@ public:
///
void ClearEdit()
{
- if (m_Edits != nullptr)
+ if (m_Edits)
xmlFreeDoc(m_Edits);
m_Edits = nullptr;
diff --git a/Source/Ember/EmberDefines.h b/Source/Ember/EmberDefines.h
index 8b16751..e937571 100644
--- a/Source/Ember/EmberDefines.h
+++ b/Source/Ember/EmberDefines.h
@@ -42,7 +42,7 @@
namespace EmberNs
{
-#define EMBER_VERSION "0.9.9.1"
+#define EMBER_VERSION "0.9.9.2"
#define EPS6 T(1e-6)
#define EPS std::numeric_limits::epsilon()//Apoplugin.h uses -20, but it's more mathematically correct to do it this way.
#define ISAAC_SIZE 4
diff --git a/Source/Ember/EmberToXml.h b/Source/Ember/EmberToXml.h
index b288126..97c7611 100644
--- a/Source/Ember/EmberToXml.h
+++ b/Source/Ember/EmberToXml.h
@@ -296,7 +296,7 @@ public:
}
}
- if (doEdits && ember.m_Edits != nullptr)
+ if (doEdits && ember.m_Edits)
os << ToString(xmlDocGetRootElement(ember.m_Edits), 1, true, printEditDepth);
os << "\n";
@@ -448,7 +448,7 @@ public:
os.str("");
//Check for errors.
- if (commentDoc != nullptr)
+ if (commentDoc)
{
//Loop through the children of the new document and copy them into the rootNode.
diff --git a/Source/Ember/Interpolate.h b/Source/Ember/Interpolate.h
index 950ca86..98b0df3 100644
--- a/Source/Ember/Interpolate.h
+++ b/Source/Ember/Interpolate.h
@@ -544,7 +544,7 @@ public:
static void InterpParametricVar(vector*>& first, ParametricVariation* second, vector& c)
{
//First, make sure the variation vector is the same size as the coefficient vector.
- if (second != nullptr && first.size() == c.size())
+ if (second && first.size() == c.size())
{
second->Clear();
auto secondParams = second->Params();
diff --git a/Source/Ember/PaletteList.h b/Source/Ember/PaletteList.h
index 8a8d7a5..95ea736 100644
--- a/Source/Ember/PaletteList.h
+++ b/Source/Ember/PaletteList.h
@@ -49,7 +49,7 @@ public:
{
xmlDocPtr doc = xmlReadMemory(static_cast(buf.data()), int(buf.size()), filename.c_str(), nullptr, XML_PARSE_NONET);
- if (doc != nullptr)
+ if (doc)
{
auto rootNode = xmlDocGetRootElement(doc);
auto pfilename = shared_ptr(new string(filename));
diff --git a/Source/Ember/Renderer.cpp b/Source/Ember/Renderer.cpp
index 50ba671..47e6fd9 100644
--- a/Source/Ember/Renderer.cpp
+++ b/Source/Ember/Renderer.cpp
@@ -1410,8 +1410,8 @@ template size_t Renderer::FuseCount()
/// Non-virtual iterator wrappers.
///
-template const byte* Renderer::XformDistributions() const { return m_Iterator != nullptr ? m_Iterator->XformDistributions() : nullptr; }
-template size_t Renderer::XformDistributionsSize() const { return m_Iterator != nullptr ? m_Iterator->XformDistributionsSize() : 0; }
+template const byte* Renderer::XformDistributions() const { return m_Iterator ? m_Iterator->XformDistributions() : nullptr; }
+template size_t Renderer::XformDistributionsSize() const { return m_Iterator ? m_Iterator->XformDistributionsSize() : 0; }
template Point* Renderer::Samples(size_t threadIndex) const { return threadIndex < m_Samples.size() ? const_cast*>(m_Samples[threadIndex].data()) : nullptr; }
///
diff --git a/Source/Ember/Timing.h b/Source/Ember/Timing.h
index bdd5fdf..f5c1c07 100644
--- a/Source/Ember/Timing.h
+++ b/Source/Ember/Timing.h
@@ -50,7 +50,7 @@ public:
m_EndTime = Clock::now();
double ms = ElapsedTime();
- if (str != nullptr)
+ if (str)
{
cout << string(str) << (fullString ? "" : " processing time: ") << Format(ms) << endl;
}
diff --git a/Source/Ember/Utils.h b/Source/Ember/Utils.h
index 2e021b8..8634d8f 100644
--- a/Source/Ember/Utils.h
+++ b/Source/Ember/Utils.h
@@ -182,7 +182,7 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru
{
fopen_s(&f, filename, "rb");//Open in binary mode.
- if (f != nullptr)
+ if (f)
{
struct _stat statBuf;
@@ -225,7 +225,7 @@ static bool ReadFile(const char* filename, string& buf, bool nullTerminate = tru
b = false;
}
- if (f != nullptr)
+ if (f)
fclose(f);
return b;
@@ -279,7 +279,7 @@ static void ClearVec(vector& vec, bool arrayDelete = false)
{
for (size_t i = 0; i < vec.size(); i++)
{
- if (vec[i] != nullptr)
+ if (vec[i])
{
if (arrayDelete)
delete [] vec[i];
diff --git a/Source/Ember/Variation.h b/Source/Ember/Variation.h
index 4bc6aed..8886324 100644
--- a/Source/Ember/Variation.h
+++ b/Source/Ember/Variation.h
@@ -1874,7 +1874,7 @@ protected:
#define VARCOPYDOUBLE(name) \
virtual void Copy(Variation*& var) const override \
{ \
- if (var != nullptr) \
+ if (var) \
delete var; \
\
var = new name(*this); \
@@ -1905,7 +1905,7 @@ protected:
\
virtual void Copy(Variation*& var) const override \
{ \
- if (var != nullptr) \
+ if (var) \
delete var; \
\
var = new name(*this); \
@@ -1932,7 +1932,7 @@ protected:
\
virtual void Copy(Variation*& var) const override \
{ \
- if (var != nullptr) \
+ if (var) \
delete var; \
\
var = new name(*this); \
@@ -2018,7 +2018,7 @@ protected:
\
virtual void Copy(Variation*& var) const override \
{ \
- if (var != nullptr) \
+ if (var) \
delete var; \
\
var = new name(*this); \
@@ -2049,7 +2049,7 @@ protected:
\
virtual void Copy(Variation*& var) const override \
{ \
- if (var != nullptr) \
+ if (var) \
delete var; \
\
var = new name(*this); \
diff --git a/Source/Ember/VariationList.h b/Source/Ember/VariationList.h
index 24c8727..6abd57c 100644
--- a/Source/Ember/VariationList.h
+++ b/Source/Ember/VariationList.h
@@ -412,7 +412,7 @@ public:
/// A pointer to the variation if found, else nullptr.
const Variation* GetVariation(eVariationId id) const
{
- for (size_t i = 0; i < m_Variations.size() && m_Variations[i] != nullptr; i++)
+ for (size_t i = 0; i < m_Variations.size() && m_Variations[i]; i++)
if (id == m_Variations[i]->VariationId())
return m_Variations[i];
@@ -435,7 +435,7 @@ public:
/// A pointer to the variation if found, else nullptr.
const Variation* GetVariation(const string& name) const
{
- for (size_t i = 0; i < m_Variations.size() && m_Variations[i] != nullptr; i++)
+ for (size_t i = 0; i < m_Variations.size() && m_Variations[i]; i++)
if (!_stricmp(name.c_str(), m_Variations[i]->Name().c_str()))
return m_Variations[i];
@@ -466,7 +466,7 @@ public:
/// The parametric variation with a matching name, else nullptr.
const ParametricVariation* GetParametricVariation(const string& name) const
{
- for (size_t i = 0; i < m_ParametricVariations.size() && m_ParametricVariations[i] != nullptr; i++)
+ for (size_t i = 0; i < m_ParametricVariations.size() && m_ParametricVariations[i]; i++)
if (!_stricmp(name.c_str(), m_ParametricVariations[i]->Name().c_str()))
return m_ParametricVariations[i];
@@ -480,7 +480,7 @@ public:
/// The index of the variation with the matching name, else -1
int GetVariationIndex(const string& name)
{
- for (size_t i = 0; i < m_Variations.size() && m_Variations[i] != nullptr; i++)
+ for (size_t i = 0; i < m_Variations.size() && m_Variations[i]; i++)
if (!_stricmp(name.c_str(), m_Variations[i]->Name().c_str()))
return int(i);
diff --git a/Source/Ember/Xform.h b/Source/Ember/Xform.h
index f36edec..fca3203 100644
--- a/Source/Ember/Xform.h
+++ b/Source/Ember/Xform.h
@@ -370,7 +370,7 @@ public:
{
for (auto v : variations)
{
- if (v != nullptr && v->VariationId() == id)
+ if (v && v->VariationId() == id)
{
var = v;
keepGoing = false;
@@ -395,7 +395,7 @@ public:
{
for (auto v : variations)
{
- if (v != nullptr && v->Name() == name)
+ if (v && v->Name() == name)
{
var = v;
keepGoing = false;
@@ -447,7 +447,7 @@ public:
{
for (size_t i = 0; i < variations.size(); i++)
{
- if (variations[i] != nullptr && variations[i]->VariationId() == id)
+ if (variations[i] && variations[i]->VariationId() == id)
{
delete variations[i];
variations.erase(variations.begin() + i);
@@ -768,7 +768,7 @@ public:
//At this point, we've added if needed, or just applied the motion func to the weight.
//Now apply the motion func to the params if needed.
- if (motParVar != nullptr)
+ if (motParVar)
{
auto parVar = dynamic_cast*>(var);
auto params = parVar->Params();
diff --git a/Source/EmberAnimate/EmberAnimate.rc b/Source/EmberAnimate/EmberAnimate.rc
index 2b37b96..ff4f154 100644
--- a/Source/EmberAnimate/EmberAnimate.rc
+++ b/Source/EmberAnimate/EmberAnimate.rc
@@ -49,8 +49,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,9,1
- PRODUCTVERSION 0,9,9,1
+ FILEVERSION 0,9,9,2
+ PRODUCTVERSION 0,9,9,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -67,12 +67,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as animations with motion blur"
- VALUE "FileVersion", "0.9.9.1"
+ VALUE "FileVersion", "0.9.9.2"
VALUE "InternalName", "EmberAnimate.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2015, GPL v3"
VALUE "OriginalFilename", "EmberAnimate.exe"
VALUE "ProductName", "Ember Animate"
- VALUE "ProductVersion", "0.9.9.1"
+ VALUE "ProductVersion", "0.9.9.2"
END
END
BLOCK "VarFileInfo"
diff --git a/Source/EmberCL/RendererCL.cpp b/Source/EmberCL/RendererCL.cpp
index b9d0df5..6005364 100644
--- a/Source/EmberCL/RendererCL.cpp
+++ b/Source/EmberCL/RendererCL.cpp
@@ -759,7 +759,7 @@ eRenderStatus RendererCL::AccumulatorToFinalImage(byte* pixels, size
{
eRenderStatus status = RunFinalAccum();
- if (status == RENDER_OK && pixels != nullptr && !m_Devices.empty() && !m_Devices[0]->m_Wrapper.Shared())
+ if (status == RENDER_OK && pixels && !m_Devices.empty() && !m_Devices[0]->m_Wrapper.Shared())
{
pixels += finalOffset;
diff --git a/Source/EmberGenome/EmberGenome.rc b/Source/EmberGenome/EmberGenome.rc
index b067a10..0cb0868 100644
--- a/Source/EmberGenome/EmberGenome.rc
+++ b/Source/EmberGenome/EmberGenome.rc
@@ -49,8 +49,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,9,1
- PRODUCTVERSION 0,9,9,1
+ FILEVERSION 0,9,9,2
+ PRODUCTVERSION 0,9,9,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -67,12 +67,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Manipulates fractal flames parameter files"
- VALUE "FileVersion", "0.9.9.1"
+ VALUE "FileVersion", "0.9.9.2"
VALUE "InternalName", "EmberGenome.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2015, GPL v3"
VALUE "OriginalFilename", "EmberGenome.exe"
VALUE "ProductName", "Ember Genome"
- VALUE "ProductVersion", "0.9.9.1"
+ VALUE "ProductVersion", "0.9.9.2"
END
END
BLOCK "VarFileInfo"
diff --git a/Source/EmberRender/EmberRender.rc b/Source/EmberRender/EmberRender.rc
index b5087c3..8196e23 100644
--- a/Source/EmberRender/EmberRender.rc
+++ b/Source/EmberRender/EmberRender.rc
@@ -49,8 +49,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,9,9,1
- PRODUCTVERSION 0,9,9,1
+ FILEVERSION 0,9,9,2
+ PRODUCTVERSION 0,9,9,2
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -67,12 +67,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Open Source"
VALUE "FileDescription", "Renders fractal flames as single images"
- VALUE "FileVersion", "0.9.9.1"
+ VALUE "FileVersion", "0.9.9.2"
VALUE "InternalName", "EmberRender.exe"
VALUE "LegalCopyright", "Copyright (C) Matt Feemster 2015, GPL v3"
VALUE "OriginalFilename", "EmberRender.exe"
VALUE "ProductName", "Ember Render"
- VALUE "ProductVersion", "0.9.9.1"
+ VALUE "ProductVersion", "0.9.9.2"
END
END
BLOCK "VarFileInfo"
diff --git a/Source/Fractorium/AboutDialog.ui b/Source/Fractorium/AboutDialog.ui
index 3782146..cc16621 100644
--- a/Source/Fractorium/AboutDialog.ui
+++ b/Source/Fractorium/AboutDialog.ui
@@ -58,7 +58,7 @@
QFrame::NoFrame
- <html><head/><body><p align="center"><br/>Fractorium 0.9.9.1 Beta</p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Lead: Matt Feemster<br/>Contributors: Simon Detheridge</span></p></body></html>
+ <html><head/><body><p align="center"><br/>Fractorium 0.9.9.2 Beta</p><p align="center"><span style=" font-size:10pt;">A Qt-based fractal flame editor which uses a C++ re-write of the flam3 algorithm named Ember and a GPU capable version named EmberCL which implements a portion of the cuburn algorithm in OpenCL.</span></p><p align="center"><span style=" font-size:10pt;">Lead: Matt Feemster<br/>Contributors: Simon Detheridge</span></p></body></html>
Qt::RichText
@@ -85,7 +85,7 @@
483
-
+
-
@@ -246,12 +246,12 @@
-
-
+
6
-
-
+
100
@@ -277,7 +277,7 @@
- okButton
+ OkButton
clicked()
AboutDialog
accept()
diff --git a/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h b/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
index 5830b6c..9fd382c 100644
--- a/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
+++ b/Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
@@ -34,7 +34,7 @@ public:
/// Unused
/// unused
/// The DoubleSpinBox member
- QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
+ virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
m_SpinBox->setParent(parent);
@@ -46,7 +46,7 @@ public:
///
/// Unused
/// Unused
- void destroyEditor(QWidget* editor, const QModelIndex& index) const override
+ virtual void destroyEditor(QWidget* editor, const QModelIndex& index) const override
{
}
@@ -55,7 +55,7 @@ public:
///
/// Unused
/// Unused
- void setEditorData(QWidget* editor, const QModelIndex& index) const override
+ virtual void setEditorData(QWidget* editor, const QModelIndex& index) const override
{
QPoint p(index.row(), index.column());
auto value = index.model()->data(index, Qt::EditRole).toDouble();
@@ -70,7 +70,7 @@ public:
/// Unused
/// The model whose value will be set
/// The cell index of the model
- void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
+ virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
{
model->setData(index, m_SpinBox->value(), Qt::EditRole);
}
@@ -81,7 +81,7 @@ public:
/// The DoubleSpinBox member
/// Contains the rectangle to be used for the geometry of the DoubleSpinBox
/// Unused
- void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
+ virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
{
editor->setGeometry(option.rect);
}
diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp
index 7b6bd16..1181424 100644
--- a/Source/Fractorium/FinalRenderDialog.cpp
+++ b/Source/Fractorium/FinalRenderDialog.cpp
@@ -38,7 +38,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
connect(ui.FinalRenderScaleNoneRadioButton, SIGNAL(toggled(bool)), this, SLOT(OnScaleRadioButtonChanged(bool)), Qt::QueuedConnection);
connect(ui.FinalRenderScaleWidthRadioButton, SIGNAL(toggled(bool)), this, SLOT(OnScaleRadioButtonChanged(bool)), Qt::QueuedConnection);
connect(ui.FinalRenderScaleHeightRadioButton, SIGNAL(toggled(bool)), this, SLOT(OnScaleRadioButtonChanged(bool)), Qt::QueuedConnection);
- connect(ui.DeviceTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnDeviceTableCellChanged(int, int)), Qt::QueuedConnection);
+ connect(ui.FinalRenderDeviceTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnDeviceTableCellChanged(int, int)), Qt::QueuedConnection);
SetupSpinner(ui.FinalRenderSizeTable, this, row, 1, m_WidthScaleSpin, spinHeight, 0.001, 99.99, 0.1, SIGNAL(valueChanged(double)), SLOT(OnWidthScaleChanged(double)), true, 1.0, 1.0, 1.0);
SetupSpinner(ui.FinalRenderSizeTable, this, row, 1, m_HeightScaleSpin, spinHeight, 0.001, 99.99, 0.1, SIGNAL(valueChanged(double)), SLOT(OnHeightScaleChanged(double)), true, 1.0, 1.0, 1.0);
@@ -79,11 +79,11 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
connect(m_PrefixEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnPrefixChanged(const QString&)), Qt::QueuedConnection);
connect(m_SuffixEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnSuffixChanged(const QString&)), Qt::QueuedConnection);
- ui.StartRenderButton->disconnect(SIGNAL(clicked(bool)));
- connect(ui.StartRenderButton, SIGNAL(clicked(bool)), this, SLOT(OnRenderClicked(bool)), Qt::QueuedConnection);
- connect(ui.StopRenderButton, SIGNAL(clicked(bool)), this, SLOT(OnCancelRenderClicked(bool)), Qt::QueuedConnection);
+ ui.FinalRenderStartButton->disconnect(SIGNAL(clicked(bool)));
+ connect(ui.FinalRenderStartButton, SIGNAL(clicked(bool)), this, SLOT(OnRenderClicked(bool)), Qt::QueuedConnection);
+ connect(ui.FinalRenderStopButton, SIGNAL(clicked(bool)), this, SLOT(OnCancelRenderClicked(bool)), Qt::QueuedConnection);
- table = ui.DeviceTable;
+ table = ui.FinalRenderDeviceTable;
table->clearContents();
table->setRowCount(0);
@@ -162,7 +162,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
w = SetTabOrder(this, w, ui.FinalRenderDoAllCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderDoSequenceCheckBox);
w = SetTabOrder(this, w, ui.FinalRenderCurrentSpin);
- w = SetTabOrder(this, w, ui.DeviceTable);
+ w = SetTabOrder(this, w, ui.FinalRenderDeviceTable);
w = SetTabOrder(this, w, ui.FinalRenderThreadCountSpin);
w = SetTabOrder(this, w, ui.FinalRenderThreadPriorityComboBox);
w = SetTabOrder(this, w, ui.FinalRenderApplyToAllCheckBox);
@@ -183,9 +183,9 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
w = SetTabOrder(this, w, m_PrefixEdit);
w = SetTabOrder(this, w, m_SuffixEdit);
w = SetTabOrder(this, w, ui.FinalRenderTextOutput);
- w = SetTabOrder(this, w, ui.StartRenderButton);
- w = SetTabOrder(this, w, ui.StopRenderButton);
- w = SetTabOrder(this, w, ui.CloseButton);
+ w = SetTabOrder(this, w, ui.FinalRenderStartButton);
+ w = SetTabOrder(this, w, ui.FinalRenderStopButton);
+ w = SetTabOrder(this, w, ui.FinalRenderCloseButton);
}
///
@@ -228,7 +228,7 @@ double FractoriumFinalRenderDialog::Quality() { return m_QualitySpin->value(); }
uint FractoriumFinalRenderDialog::TemporalSamples() { return m_TemporalSamplesSpin->value(); }
uint FractoriumFinalRenderDialog::Supersample() { return m_SupersampleSpin->value(); }
uint FractoriumFinalRenderDialog::Strips() { return m_StripsSpin->value(); }
-QList FractoriumFinalRenderDialog::Devices() { return DeviceTableToSettings(ui.DeviceTable); }
+QList FractoriumFinalRenderDialog::Devices() { return DeviceTableToSettings(ui.FinalRenderDeviceTable); }
///
/// Capture the current state of the Gui.
@@ -347,8 +347,9 @@ void FractoriumFinalRenderDialog::OnOpenCLCheckBoxStateChanged(int state)
{
bool checked = state == Qt::Checked;
- ui.DeviceTable->setEnabled(checked);
+ ui.FinalRenderDeviceTable->setEnabled(checked);
ui.FinalRenderThreadCountSpin->setEnabled(!checked);
+ ui.FinalRenderThreadPriorityLabel->setEnabled(!checked);
ui.FinalRenderThreadPriorityComboBox->setEnabled(!checked);
SetMemory();
}
@@ -480,9 +481,9 @@ void FractoriumFinalRenderDialog::OnScaleRadioButtonChanged(bool checked)
/// The column of the cell
void FractoriumFinalRenderDialog::OnDeviceTableCellChanged(int row, int col)
{
- if (auto item = ui.DeviceTable->item(row, col))
+ if (auto item = ui.FinalRenderDeviceTable->item(row, col))
{
- HandleDeviceTableCheckChanged(ui.DeviceTable, row, col);
+ HandleDeviceTableCheckChanged(ui.FinalRenderDeviceTable, row, col);
SetMemory();
}
}
@@ -497,7 +498,7 @@ void FractoriumFinalRenderDialog::OnDeviceTableRadioToggled(bool checked)
{
int row;
auto s = sender();
- auto table = ui.DeviceTable;
+ auto table = ui.FinalRenderDeviceTable;
QRadioButton* radio = nullptr;
if (s)
@@ -506,7 +507,7 @@ void FractoriumFinalRenderDialog::OnDeviceTableRadioToggled(bool checked)
if (radio = qobject_cast(table->cellWidget(row, 1)))
if (s == radio)
{
- HandleDeviceTableCheckChanged(ui.DeviceTable, row, 1);
+ HandleDeviceTableCheckChanged(ui.FinalRenderDeviceTable, row, 1);
break;
}
}
diff --git a/Source/Fractorium/FinalRenderDialog.ui b/Source/Fractorium/FinalRenderDialog.ui
index 3ca4ccc..79e463b 100644
--- a/Source/Fractorium/FinalRenderDialog.ui
+++ b/Source/Fractorium/FinalRenderDialog.ui
@@ -45,7 +45,7 @@
6
-
-
+
Qt::NoFocus
@@ -58,7 +58,7 @@
true
-
+
0
@@ -84,7 +84,7 @@
0
-
-
+
-
@@ -168,7 +168,7 @@
-
-
+
QLayout::SetNoConstraint
@@ -240,7 +240,7 @@
-
-
+
0
@@ -461,13 +461,13 @@
0
- 46
+ 45
16777215
- 46
+ 45
@@ -670,13 +670,13 @@
0
- 200
+ 199
16777215
- 200
+ 199
@@ -939,7 +939,7 @@
-
-
+
QLayout::SetDefaultConstraint
@@ -1105,7 +1105,7 @@
-
-
+
Qt::TabFocus
@@ -1118,7 +1118,7 @@
-
-
+
Qt::TabFocus
@@ -1128,7 +1128,7 @@
-
-
+
Qt::TabFocus
@@ -1165,14 +1165,14 @@
FinalRenderOpenCLCheckBox
FinalRenderParamsTable
FinalRenderTextOutput
- StartRenderButton
- StopRenderButton
- CloseButton
+ FinalRenderStartButton
+ FinalRenderStopButton
+ FinalRenderCloseButton
- StartRenderButton
+ FinalRenderStartButton
clicked()
FinalRenderDialog
accept()
@@ -1188,7 +1188,7 @@
- CloseButton
+ FinalRenderCloseButton
clicked()
FinalRenderDialog
reject()
diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp
index 83a2ff0..c6a9de0 100644
--- a/Source/Fractorium/FinalRenderEmberController.cpp
+++ b/Source/Fractorium/FinalRenderEmberController.cpp
@@ -881,7 +881,7 @@ void FinalRenderEmberController::RenderComplete(Ember& ember, const EmberS
ember.m_Edits = m_XmlWriter.CreateNewEditdoc(&ember, nullptr, "edit", m_Settings->Nick().toStdString(), m_Settings->Url().toStdString(), m_Settings->Id().toStdString(), "", 0, 0);
m_XmlWriter.Save(newPath.toStdString().c_str(), ember, 0, true, false, true);//Note that the ember passed is used, rather than m_Ember because it's what was actually rendered.
- if (tempEdit != nullptr)
+ if (tempEdit)
xmlFreeDoc(tempEdit);
}
diff --git a/Source/Fractorium/Fractorium.cpp b/Source/Fractorium/Fractorium.cpp
index 8cad6df..59015db 100644
--- a/Source/Fractorium/Fractorium.cpp
+++ b/Source/Fractorium/Fractorium.cpp
@@ -1,5 +1,6 @@
#include "FractoriumPch.h"
#include "Fractorium.h"
+#include "QssDialog.h"
// X11 headers on Linux define this, causing build errors.
#ifdef KeyRelease
@@ -13,14 +14,16 @@
/// is present here, it's safe to assume it can't be done in the designer.
///
/// The parent widget of this item
-Fractorium::Fractorium(QWidget* p)
+Fractorium::Fractorium(QWidget* p)
: QMainWindow(p),
m_Info(OpenCLInfo::Instance())
{
int spinHeight = 20, iconSize_ = 9;
size_t i = 0;
+ string s;
Timing t;
ui.setupUi(this);
+
qRegisterMetaType>("QVector");//For previews.
qRegisterMetaType>("vector");
qRegisterMetaType("EmberTreeWidgetItemBase*");
@@ -33,7 +36,7 @@ Fractorium::Fractorium(QWidget* p)
tabifyDockWidget(ui.XformsDockWidget, ui.XaosDockWidget);
tabifyDockWidget(ui.XaosDockWidget, ui.PaletteDockWidget);
tabifyDockWidget(ui.PaletteDockWidget, ui.InfoDockWidget);
-
+
m_Docks.reserve(8);
m_Docks.push_back(ui.LibraryDockWidget);
m_Docks.push_back(ui.FlameDockWidget);
@@ -47,6 +50,7 @@ Fractorium::Fractorium(QWidget* p)
m_PaletteSortMode = 0;//Sort by palette ascending by default.
m_ColorDialog = new QColorDialog(this);
m_Settings = new FractoriumSettings(this);
+ m_QssDialog = new QssDialog(this);
m_FileDialog = nullptr;//Use lazy instantiation upon first use.
m_FolderDialog = nullptr;
@@ -121,19 +125,19 @@ Fractorium::Fractorium(QWidget* p)
m_QualitySpin->setValue(30 * m_Settings->Devices().size());
int statusBarHeight = 20 * devicePixelRatio();
- ui.statusBar->setMinimumHeight(statusBarHeight);
- ui.statusBar->setMaximumHeight(statusBarHeight);
+ ui.StatusBar->setMinimumHeight(statusBarHeight);
+ ui.StatusBar->setMaximumHeight(statusBarHeight);
m_RenderStatusLabel = new QLabel(this);
m_RenderStatusLabel->setMinimumWidth(200);
m_RenderStatusLabel->setAlignment(Qt::AlignRight);
- ui.statusBar->addPermanentWidget(m_RenderStatusLabel);
+ ui.StatusBar->addPermanentWidget(m_RenderStatusLabel);
m_CoordinateStatusLabel = new QLabel(this);
m_CoordinateStatusLabel->setMinimumWidth(300);
m_CoordinateStatusLabel->setMaximumWidth(300);
m_CoordinateStatusLabel->setAlignment(Qt::AlignLeft);
- ui.statusBar->addWidget(m_CoordinateStatusLabel);
+ ui.StatusBar->addWidget(m_CoordinateStatusLabel);
int progressBarHeight = 15;
int progressBarWidth = 300;
@@ -144,7 +148,7 @@ Fractorium::Fractorium(QWidget* p)
m_ProgressBar->setMaximumHeight(progressBarHeight);
m_ProgressBar->setMinimumWidth(progressBarWidth);
m_ProgressBar->setMaximumWidth(progressBarWidth);
- ui.statusBar->addPermanentWidget(m_ProgressBar);
+ ui.StatusBar->addPermanentWidget(m_ProgressBar);
//Setup pointer in the GL window to point back to here.
ui.GLDisplay->SetMainWindow(this);
@@ -162,29 +166,43 @@ Fractorium::Fractorium(QWidget* p)
ui.XformsTabWidget->setCurrentIndex(2);//Make variations tab the currently selected one under the Xforms tab.
}
- //Setting certain values will completely throw off the GUI, doing everything
- //from setting strange margins, to arbitrarily changing the fonts used.
- //For these cases, the only way to fix the problem is to use style sheets.
- ui.ColorTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.GeometryTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.FilterTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.IterationTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.XformAffineTab->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.XformWeightNameTable->setStyleSheet("QTableWidget::item { padding: 0px; }");
- ui.XformColorIndexTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.XformColorValuesTable->setStyleSheet("QTableWidget::item { padding: 1px; }");
- ui.XformPaletteRefTable->setStyleSheet("QTableWidget::item { padding: 0px; border: none; margin: 0px; }");
- ui.PaletteAdjustTable->setStyleSheet("QTableWidget::item { padding: 1px; }");//Need this to avoid covering the top border pixel with the spinners.
- ui.statusBar->setStyleSheet("QStatusBar QLabel { padding-left: 2px; padding-right: 2px; }");
- ui.XaosTableView->setStyleSheet("QTableView { margin: 1px}");
-
- //setStyleSheet("QGroupBox { border: 2px solid gray; border-radius: 3px; } ");
-
m_PreviousPaletteRow = -1;//Force click handler the first time through.
SetCoordinateStatus(0, 0, 0, 0);
-
SetTabOrders();
-
+ m_SettingsPath = QFileInfo(m_Settings->fileName()).absoluteDir().absolutePath();
+ ifstream ifs((m_SettingsPath + "/default.qss").toStdString().c_str(), ifstream::in);
+
+ if (ifs.is_open())
+ {
+ string total, qs;
+
+ while (std::getline(ifs, qs))
+ total += qs + "\n";
+
+ m_Style = QString::fromStdString(total);
+ }
+ else
+ m_Style = BaseStyle();
+
+ setStyleSheet(m_Style);
+
+ if (!m_Settings->Theme().isEmpty())
+ {
+ if (auto theme = QStyleFactory::create(m_Settings->Theme()))
+ {
+ m_Theme = theme;
+ setStyle(m_Theme);
+ }
+ }
+ else
+ {
+ if (!QStyleFactory::keys().empty())
+ {
+ m_Theme = QStyleFactory::create(qApp->style()->objectName());
+ setStyle(m_Theme);
+ }
+ }
+
//At this point, everything has been setup except the renderer. Shortly after
//this constructor exits, GLWidget::InitGL() will create the initial flock and start the rendering timer
//which executes whenever the program is idle. Upon starting the timer, the renderer
@@ -764,7 +782,7 @@ void Fractorium::SetTabOrders()
w = SetTabOrder(this, w, ui.PaletteListTable);
- w = SetTabOrder(this, ui.SummaryTableWidget, ui.SummaryTreeWidget);//Info summary.
+ w = SetTabOrder(this, ui.SummaryTable, ui.SummaryTree);//Info summary.
w = SetTabOrder(this, ui.InfoBoundsGroupBox, ui.InfoBoundsFrame);//Info bounds.
diff --git a/Source/Fractorium/Fractorium.h b/Source/Fractorium/Fractorium.h
index d94d379..0657f6c 100644
--- a/Source/Fractorium/Fractorium.h
+++ b/Source/Fractorium/Fractorium.h
@@ -19,6 +19,7 @@
///
class GLWidget;
+class QssDialog;
class FractoriumOptionsDialog;
class FractoriumVariationsDialog;
class FractoriumFinalRenderDialog;
@@ -42,9 +43,9 @@ template class FinalRenderEmberController;
/// certain parameters don't require a full render, the minimum necessary processing will be ran.
/// When the user changes something on the GUI, the required processing action is added to a vector.
/// Upon the next execution of the idle timer function, the most significant action will be extracted
-/// and applied to the renderer. The vector is then cleared.
+/// and applied to the renderer. The state change vector is then cleared.
/// On the left side of the window is a dock widget which contains all controls needed for
-/// manipulating embers.
+/// manipulating embers. It's tabs can be floated, dragged, docked and nested elsewhere.
/// Qt takes very long to create file dialog windows, so they are kept as members and initialized
/// upon first use with lazy instantiation and then kept around for the remainder of the program.
/// Additional dialogs are for the about box, options, and final rendering out to a file.
@@ -53,9 +54,6 @@ template class FinalRenderEmberController;
/// Fractorium.cpp and the other functional areas are each broken out into their own files.
/// The order of the functions in each .cpp file should roughly match the order they appear in the .h file.
/// Future todo list:
-/// Add all of the plugins/variations that work with Apophysis and are open source.
-/// Allow specifying variations to include/exclude from random generation.
-/// Allow the option to specify a different palette file rather than the default flam3-palettes.xml.
/// Implement more rendering types.
/// Add support for animation previewing.
/// Add support for full animation editing and rendering.
@@ -66,6 +64,7 @@ class Fractorium : public QMainWindow
Q_OBJECT
friend GLWidget;
+ friend QssDialog;
friend FractoriumOptionsDialog;
friend FractoriumFinalRenderDialog;
friend FractoriumAboutDialog;
@@ -149,6 +148,7 @@ public slots:
void OnActionCL(bool checked);
void OnActionSP(bool checked);
void OnActionDP(bool checked);
+ void OnActionStyle(bool checked);
//Library.
void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col);
@@ -472,8 +472,12 @@ private:
//Files.
QFileDialog* m_FileDialog;
QFileDialog* m_FolderDialog;
+ QssDialog* m_QssDialog;
QString m_LastSaveAll;
QString m_LastSaveCurrent;
+ QString m_Style;
+ QStyle* m_Theme;
+ QString m_SettingsPath;
//QMenu* m_FileTreeMenu;
QProgressBar* m_ProgressBar;
diff --git a/Source/Fractorium/Fractorium.qrc b/Source/Fractorium/Fractorium.qrc
index d73965c..b8604ce 100644
--- a/Source/Fractorium/Fractorium.qrc
+++ b/Source/Fractorium/Fractorium.qrc
@@ -44,5 +44,7 @@
Icons/square.png
Icons/cube.png
Icons/table_gear.png
+ Icons/checkbox_checked.png
+ Icons/checkbox_unchecked.png
diff --git a/Source/Fractorium/Fractorium.rc b/Source/Fractorium/Fractorium.rc
index 0c3971e..92599df 100644
Binary files a/Source/Fractorium/Fractorium.rc and b/Source/Fractorium/Fractorium.rc differ
diff --git a/Source/Fractorium/Fractorium.ui b/Source/Fractorium/Fractorium.ui
index 4665e4c..b29f075 100644
--- a/Source/Fractorium/Fractorium.ui
+++ b/Source/Fractorium/Fractorium.ui
@@ -6,8 +6,8 @@
0
0
- 1442
- 926
+ 1451
+ 953
@@ -74,8 +74,8 @@
0
0
- 1175
- 859
+ 1184
+ 886
@@ -99,7 +99,7 @@
- 40
+ 0
0
240
881
@@ -123,7 +123,7 @@
Flame
-
+
0
@@ -355,13 +355,13 @@
0
- 156
+ 154
16777215
- 156
+ 154
@@ -579,13 +579,13 @@
0
- 156
+ 154
16777215
- 156
+ 154
@@ -956,13 +956,13 @@
0
- 156
+ 154
16777215
- 156
+ 154
@@ -1203,13 +1203,13 @@
0
- 266
+ 264
16777215
- 266
+ 264
@@ -1524,7 +1524,7 @@
- 550
+ 530
0
240
881
@@ -1545,7 +1545,7 @@
Xaos
-
+
4
@@ -1727,7 +1727,7 @@
- 790
+ 770
0
240
881
@@ -1748,7 +1748,7 @@
Palette
-
+
5
@@ -1773,13 +1773,13 @@
0
- 22
+ 21
16777215
- 22
+ 21
@@ -1865,7 +1865,11 @@
0
-
-
+
+
+ true
+
+
-
@@ -1966,7 +1970,14 @@
-
-
+
+
+
+ 0
+ 0
+
+
+
-
@@ -2167,15 +2178,15 @@
- 280
+ 240
0
- 267
+ 291
881
- 267
+ 291
613
@@ -2188,7 +2199,7 @@
Xforms
-
+
5
@@ -2210,6 +2221,9 @@
2
+
+ 0
+
-
@@ -2227,7 +2241,7 @@
60
- 16777215
+ 22
@@ -2464,13 +2478,13 @@
0
- 45
+ 44
16777215
- 45
+ 44
@@ -2926,7 +2940,7 @@
16777215
- 68
+ 67
@@ -3286,8 +3300,8 @@
0
0
- 239
- 742
+ 263
+ 743
@@ -3493,11 +3507,26 @@
0
+
+ 0
+
- 4
+ 3
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform 90 degrees counter clockwise
@@ -3512,6 +3541,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform 90 degrees clockwise
@@ -3526,6 +3567,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units right
@@ -3549,7 +3602,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -3587,6 +3646,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units up
@@ -3601,6 +3672,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units down
@@ -3624,7 +3707,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -3642,6 +3731,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units left
@@ -3665,7 +3766,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -3724,6 +3831,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform x degrees counter clockwise
@@ -3738,6 +3857,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform x degrees clockwise
@@ -3758,6 +3889,18 @@
0
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Flip xform vertically
@@ -3781,7 +3924,13 @@
75
- 0
+ 24
+
+
+
+
+ 16777215
+ 24
@@ -3800,6 +3949,18 @@
0
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Flip xform horizontally
@@ -3814,6 +3975,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Scale xform x percent down
@@ -3828,6 +4001,18 @@
-
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Scale xform x percent up
@@ -4089,13 +4274,25 @@
0
- 4
+ 3
-
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform 90 degrees counter clockwise
@@ -4113,6 +4310,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform 90 degrees clockwise
@@ -4130,6 +4339,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units right
@@ -4156,7 +4377,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -4197,6 +4424,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units up
@@ -4214,6 +4453,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units down
@@ -4240,7 +4491,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -4261,6 +4518,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Move xform x units left
@@ -4287,7 +4556,13 @@
75
- 22
+ 23
+
+
+
+
+ 16777215
+ 23
@@ -4349,6 +4624,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform x degrees counter clockwise
@@ -4366,6 +4653,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Rotate xform x degrees clockwise
@@ -4383,6 +4682,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Flip xform horizontally
@@ -4400,6 +4711,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Flip xform vertically
@@ -4426,7 +4749,13 @@
75
- 0
+ 24
+
+
+
+
+ 16777215
+ 24
@@ -4442,6 +4771,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Scale xform x percent up
@@ -4459,6 +4800,18 @@
true
+
+
+ 0
+ 24
+
+
+
+
+ 16777215
+ 24
+
+
Scale xform x percent down
@@ -4646,20 +4999,33 @@
0
-
-
+
+
+
+ 0
+ 22
+
+
+
+
+ 16777215
+ 22
+
+
+
-
30
- 0
+ 23
30
- 16777215
+ 23
@@ -4860,7 +5226,7 @@
5
- 4
+ 5
5
@@ -4946,7 +5312,7 @@
0
0
- 235
+ 259
673
@@ -5003,7 +5369,7 @@
- 1000
+ 1010
0
301
881
@@ -5113,7 +5479,7 @@
QTabWidget::Triangular
- 0
+ 1
@@ -5130,7 +5496,7 @@
5
- 4
+ 5
5
@@ -5139,7 +5505,7 @@
4
-
-
+
0
@@ -5149,13 +5515,13 @@
0
- 128
+ 126
16777215
- 128
+ 126
@@ -5207,7 +5573,7 @@
true
- true
+ false
false
@@ -5289,7 +5655,7 @@
-
-
+
0
@@ -5324,7 +5690,7 @@
2
- true
+ false
false
@@ -5461,16 +5827,16 @@
0
- 0
+ 5
0
- 0
+ 5
- 0
+ 5
-
@@ -5933,12 +6299,12 @@
-
@@ -6145,6 +6511,9 @@
false
+
+ 27
+
Current Flame File
@@ -6159,7 +6528,7 @@
-
+
toolBar
@@ -6198,6 +6567,8 @@
+
+
@@ -6330,6 +6701,9 @@
Add R&eflective Symmetry
+
+ Add reflective symmetry
+
@@ -6339,11 +6713,17 @@
Add R&otational Symmetry
+
+ Add rotational symmetry
+
Add Reflective &and Rotational Symmetry
+
+ Add reflective and rotational symmetry
+
@@ -6401,7 +6781,7 @@
Paste Xml &Over
- Paste Xml as a new flame in the current file
+ Paste Xml over the current flame in the current file
Ctrl+Shift+V
@@ -6426,6 +6806,9 @@
&Stop Rendering Previews
+
+ Stop rendering previews
+
@@ -6435,6 +6818,9 @@
Render &Previews
+
+ Render previews
+
@@ -6468,6 +6854,9 @@
Paste Xml A&ppend
+
+ Paste Xml as a new flame in the current file
+
Ctrl+V
@@ -6481,7 +6870,7 @@
&Flatten
- Add the Flatten variation to each xform
+ Add the flatten variation to each xform
@@ -6493,7 +6882,7 @@
&Unflatten
- Remove the Flatten variation from each xform
+ Remove the flatten variation from each xform
@@ -6527,6 +6916,9 @@
&Reset Workspace
+
+ Reset workspace
+
@@ -6584,6 +6976,17 @@
Use double precision to render
+
+
+ true
+
+
+ Style
+
+
+ Show QSS style editor
+
+
diff --git a/Source/Fractorium/FractoriumCommon.h b/Source/Fractorium/FractoriumCommon.h
index fbe7516..29081d5 100644
--- a/Source/Fractorium/FractoriumCommon.h
+++ b/Source/Fractorium/FractoriumCommon.h
@@ -357,3 +357,44 @@ static void HandleDeviceTableCheckChanged(QTableWidget* table, int row, int col)
if (primaryItem->checkState() == Qt::Unchecked)
primaryItem->setCheckState(Qt::Checked);
}
+
+///
+/// The basic style that is needed for things to look right, this varies by OS.
+///
+/// The base style
+static QString BaseStyle()
+{
+ return "/*---Base Style---\n"
+ "This is needed to deal with the large tabs in the fusion theme which is the default on Linux, and optional on Windows.\n"
+ "It's not needed for other themes."
+ "You should keep this at the top of whatever custom style you make to ensure the tabs aren't unusually large.*/\n"
+#ifndef WIN32
+ "QTabBar::tab { height: 3ex; }\n\n"
+#else
+ "QTabBar::tab { height: 5ex; }\n\n"
+#endif
+ "/*This is needed to give the labels on the status bar some padding.*/\n"
+ "QStatusBar QLabel { padding-left: 2px; padding-right: 2px; }\n\n"
+ ;
+}
+
+///
+/// Get all parent objects of the passed in widget.
+///
+/// The widget whose parents will be retrieved
+/// The entire parent object chain in a QList
+template
+static QList GetAllParents(QWidget* widget)
+{
+ QList parents;
+
+ while (auto parent = qobject_cast(widget->parent()))
+ {
+ if (auto parentT = qobject_cast(parent))
+ parents.push_back(parentT);
+
+ widget = parent;
+ }
+
+ return parents;
+}
\ No newline at end of file
diff --git a/Source/Fractorium/FractoriumInfo.cpp b/Source/Fractorium/FractoriumInfo.cpp
index ca99b6d..58c4b6c 100644
--- a/Source/Fractorium/FractoriumInfo.cpp
+++ b/Source/Fractorium/FractoriumInfo.cpp
@@ -6,22 +6,22 @@
///
void Fractorium::InitInfoUI()
{
- auto treeHeader = ui.SummaryTreeWidget->header();
- auto tableHeader = ui.SummaryTableWidget->horizontalHeader();
+ auto treeHeader = ui.SummaryTree->header();
+ auto tableHeader = ui.SummaryTable->horizontalHeader();
treeHeader->setVisible(true);
treeHeader->setSectionsClickable(true);
treeHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
connect(treeHeader, SIGNAL(sectionClicked(int)), this, SLOT(OnSummaryTreeHeaderSectionClicked(int)), Qt::QueuedConnection);
connect(tableHeader, SIGNAL(sectionResized(int, int, int)), this, SLOT(OnSummaryTableHeaderResized(int, int, int)), Qt::QueuedConnection);
- SetFixedTableHeader(ui.SummaryTableWidget->verticalHeader());
+ SetFixedTableHeader(ui.SummaryTable->verticalHeader());
- ui.SummaryTableWidget->setItem(0, 0, m_InfoNameItem = new QTableWidgetItem(""));
- ui.SummaryTableWidget->setItem(1, 0, m_InfoPaletteItem = new QTableWidgetItem(""));
- ui.SummaryTableWidget->setItem(2, 0, m_Info3dItem = new QTableWidgetItem(""));
- ui.SummaryTableWidget->setItem(3, 0, m_InfoXaosItem = new QTableWidgetItem(""));
- ui.SummaryTableWidget->setItem(4, 0, m_InfoXformCountItem = new QTableWidgetItem(""));
- ui.SummaryTableWidget->setItem(5, 0, m_InfoFinalXformItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(0, 0, m_InfoNameItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(1, 0, m_InfoPaletteItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(2, 0, m_Info3dItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(3, 0, m_InfoXaosItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(4, 0, m_InfoXformCountItem = new QTableWidgetItem(""));
+ ui.SummaryTable->setItem(5, 0, m_InfoFinalXformItem = new QTableWidgetItem(""));
}
///
@@ -34,7 +34,7 @@ void Fractorium::InitInfoUI()
void Fractorium::OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize)
{
QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage());//Create a QPixmap out of the QImage, will be empty on startup.
- SetPaletteTableItem(&pixmap, ui.SummaryTableWidget, m_InfoPaletteItem, 1, 0);
+ SetPaletteTableItem(&pixmap, ui.SummaryTable, m_InfoPaletteItem, 1, 0);
}
///
@@ -44,7 +44,7 @@ void Fractorium::OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int
/// The column which was clicked
void Fractorium::OnSummaryTreeHeaderSectionClicked(int logicalIndex)
{
- auto tree = ui.SummaryTreeWidget;
+ auto tree = ui.SummaryTree;
if (logicalIndex)
tree->expandAll();
@@ -73,8 +73,8 @@ void FractoriumEmberController::FillSummary()
size_t x = 0, total = m_Ember.TotalXformCount();
Xform* xform = nullptr;
QColor color;
- auto table = m_Fractorium->ui.SummaryTableWidget;
- auto tree = m_Fractorium->ui.SummaryTreeWidget;
+ auto table = m_Fractorium->ui.SummaryTable;
+ auto tree = m_Fractorium->ui.SummaryTree;
QVariantList states;
QTreeWidgetItemIterator it(tree);
diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp
index d44dc8d..eb659c9 100644
--- a/Source/Fractorium/FractoriumMenus.cpp
+++ b/Source/Fractorium/FractoriumMenus.cpp
@@ -82,7 +82,7 @@ void FractoriumEmberController::NewFlock(size_t count)
/// Ignored
void Fractorium::OnActionNewFlock(bool checked)
{
- m_Controller->NewFlock(10);
+ m_Controller->NewFlock(m_Settings->RandomCount());
m_Controller->SetEmber(0);
}
@@ -285,7 +285,7 @@ void FractoriumEmberController::SaveCurrentAsXml()
ApplyXmlSavingTemplate(ember);
ember.m_Edits = writer.CreateNewEditdoc(&ember, nullptr, "edit", s->Nick().toStdString(), s->Url().toStdString(), s->Id().toStdString(), "", 0, 0);
- if (tempEdit != nullptr)
+ if (tempEdit)
xmlFreeDoc(tempEdit);
if (writer.Save(filename.toStdString().c_str(), ember, 0, true, false, true))
diff --git a/Source/Fractorium/FractoriumPch.h b/Source/Fractorium/FractoriumPch.h
index c9fba54..b8af03b 100644
--- a/Source/Fractorium/FractoriumPch.h
+++ b/Source/Fractorium/FractoriumPch.h
@@ -23,26 +23,52 @@
#endif
#include
-#include
-#include
+#include "qfunctions.h"
+#include
+#include
+#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
-#include
-#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp
index 371eb25..1178f1e 100644
--- a/Source/Fractorium/FractoriumRender.cpp
+++ b/Source/Fractorium/FractoriumRender.cpp
@@ -712,7 +712,7 @@ bool Fractorium::CreateControllerFromOptions()
}
}
- return m_Controller.get() != nullptr;
+ return m_Controller.get();
}
///
diff --git a/Source/Fractorium/FractoriumSettings.cpp b/Source/Fractorium/FractoriumSettings.cpp
index efe1182..8056d07 100644
--- a/Source/Fractorium/FractoriumSettings.cpp
+++ b/Source/Fractorium/FractoriumSettings.cpp
@@ -46,11 +46,9 @@ void FractoriumSettings::EnsureDefaults()
FinalThreadPriority(Clamp(FinalThreadPriority(), (int)eThreadPriority::LOWEST, (int)eThreadPriority::HIGHEST));
- if (CpuSubBatch() < 1)
- CpuSubBatch(1);
-
- if (OpenCLSubBatch() < 1)
- OpenCLSubBatch(1);
+ CpuSubBatch(std::max(1u, CpuSubBatch()));
+ OpenCLSubBatch(std::max(1u, OpenCLSubBatch()));
+ RandomCount(std::max(1u, RandomCount()));
if (FinalScale() > SCALE_HEIGHT)
FinalScale(0);
@@ -124,6 +122,9 @@ void FractoriumSettings::CpuSubBatch(uint i) { setValue(CPUSUBBATCH, i);
uint FractoriumSettings::OpenCLSubBatch() { return value(OPENCLSUBBATCH).toUInt(); }
void FractoriumSettings::OpenCLSubBatch(uint i) { setValue(OPENCLSUBBATCH, i); }
+
+uint FractoriumSettings::RandomCount() { return value(RANDOMCOUNT).toUInt(); }
+void FractoriumSettings::RandomCount(uint i) { setValue(RANDOMCOUNT, i); }
///
/// Final render settings.
@@ -232,3 +233,7 @@ void FractoriumSettings::SaveAutoUnique(bool b) { setValue(AUTOUNIQUE, b)
QMap FractoriumSettings::Variations() { return value(UIVARIATIONS).toMap(); }
void FractoriumSettings::Variations(const QMap& m) { setValue(UIVARIATIONS, m); }
+
+QString FractoriumSettings::Theme() { return value(STYLETHEME).toString(); }
+void FractoriumSettings::Theme(const QString& s) { setValue(STYLETHEME, s); }
+
diff --git a/Source/Fractorium/FractoriumSettings.h b/Source/Fractorium/FractoriumSettings.h
index 71c2754..36612ac 100644
--- a/Source/Fractorium/FractoriumSettings.h
+++ b/Source/Fractorium/FractoriumSettings.h
@@ -19,6 +19,7 @@
#define OPENCLDEFILTER "render/opencldefilter"
#define CPUSUBBATCH "render/cpusubbatch"
#define OPENCLSUBBATCH "render/openclsubbatch"
+#define RANDOMCOUNT "render/randomcount"
#define FINALEARLYCLIP "finalrender/earlyclip"
#define FINALYAXISUP "finalrender/finalyaxisup"
@@ -60,6 +61,8 @@
#define UIVARIATIONS "ui/variations"
+#define STYLETHEME "style/theme"
+
///
/// Class for preserving various program options between
/// runs of Fractorium. Each of these generally corresponds
@@ -111,6 +114,9 @@ public:
uint OpenCLSubBatch();
void OpenCLSubBatch(uint i);
+ uint RandomCount();
+ void RandomCount(uint i);
+
bool FinalEarlyClip();
void FinalEarlyClip(bool b);
@@ -206,4 +212,7 @@ public:
QMap Variations();
void Variations(const QMap& m);
+
+ QString Theme();
+ void Theme(const QString& s);
};
diff --git a/Source/Fractorium/FractoriumToolbar.cpp b/Source/Fractorium/FractoriumToolbar.cpp
index 2d3f630..181c2fe 100644
--- a/Source/Fractorium/FractoriumToolbar.cpp
+++ b/Source/Fractorium/FractoriumToolbar.cpp
@@ -1,5 +1,6 @@
#include "FractoriumPch.h"
#include "Fractorium.h"
+#include "QssDialog.h"
///
/// Initialize the toolbar UI.
@@ -15,10 +16,11 @@ void Fractorium::InitToolbarUI()
spGroup->addAction(ui.ActionDP);
SyncOptionsToToolbar();
- connect(ui.ActionCpu, SIGNAL(triggered(bool)), this, SLOT(OnActionCpu(bool)), Qt::QueuedConnection);
- connect(ui.ActionCL, SIGNAL(triggered(bool)), this, SLOT(OnActionCL(bool)), Qt::QueuedConnection);
- connect(ui.ActionSP, SIGNAL(triggered(bool)), this, SLOT(OnActionSP(bool)), Qt::QueuedConnection);
- connect(ui.ActionDP, SIGNAL(triggered(bool)), this, SLOT(OnActionDP(bool)), Qt::QueuedConnection);
+ connect(ui.ActionCpu, SIGNAL(triggered(bool)), this, SLOT(OnActionCpu(bool)), Qt::QueuedConnection);
+ connect(ui.ActionCL, SIGNAL(triggered(bool)), this, SLOT(OnActionCL(bool)), Qt::QueuedConnection);
+ connect(ui.ActionSP, SIGNAL(triggered(bool)), this, SLOT(OnActionSP(bool)), Qt::QueuedConnection);
+ connect(ui.ActionDP, SIGNAL(triggered(bool)), this, SLOT(OnActionDP(bool)), Qt::QueuedConnection);
+ connect(ui.ActionStyle, SIGNAL(triggered(bool)), this, SLOT(OnActionStyle(bool)), Qt::QueuedConnection);
}
///
@@ -73,6 +75,15 @@ void Fractorium::OnActionDP(bool checked)
}
}
+///
+/// Called when the show style button is clicked.
+///
+/// Ignored
+void Fractorium::OnActionStyle(bool checked)
+{
+ m_QssDialog->show();
+}
+
///
/// Sync options data to the check state of the toolbar buttons.
/// This does not trigger a clicked() event.
diff --git a/Source/Fractorium/FractoriumXaos.cpp b/Source/Fractorium/FractoriumXaos.cpp
index 9ed25d1..d930fae 100644
--- a/Source/Fractorium/FractoriumXaos.cpp
+++ b/Source/Fractorium/FractoriumXaos.cpp
@@ -12,10 +12,11 @@ void Fractorium::InitXaosUI()
ui.XaosTableView->horizontalHeader()->setSectionsClickable(true);
m_XaosSpinBox = new DoubleSpinBox(nullptr, spinHeight, 0.1);
- m_XaosSpinBox->setFixedWidth(35);
m_XaosSpinBox->DoubleClick(true);
m_XaosSpinBox->DoubleClickZero(1);
m_XaosSpinBox->DoubleClickNonZero(0);
+ m_XaosSpinBox->setDecimals(6);
+ m_XaosSpinBox->setObjectName("XaosSpinBox");
m_XaosTableModel = nullptr;
m_XaosTableItemDelegate = new DoubleSpinBoxTableItemDelegate(m_XaosSpinBox, this);
@@ -146,6 +147,12 @@ void Fractorium::FillXaosTable()
if (oldModel)
delete oldModel;
+
+ //Needed to get the dark stylesheet to correctly color the top left corner button.
+ auto widgetList = ui.XaosTableView->findChildren();
+
+ for (auto& it : widgetList)
+ it->setEnabled(true);
}
///
diff --git a/Source/Fractorium/FractoriumXforms.cpp b/Source/Fractorium/FractoriumXforms.cpp
index d63b2b1..3aec572 100644
--- a/Source/Fractorium/FractoriumXforms.cpp
+++ b/Source/Fractorium/FractoriumXforms.cpp
@@ -31,32 +31,6 @@ void Fractorium::InitXformsUI()
connect(ui.XformWeightNameTable, SIGNAL(cellChanged(int, int)), this, SLOT(OnXformNameChanged(int, int)), Qt::QueuedConnection);
ui.CurrentXformCombo->setProperty("soloxform", -1);
-/*
- ui.XformsTabWidget->setStyleSheet(
-
- "QTabWidget::pane \n"
- "{\n"
- " border: 5px solid #898C95;\n"
- " font: 9pt "Segoe UI";\n"
- "}\n"
- "\n"
- "QTabWidget::tab-bar \n"
- "{\n"
- " bottom: -8px;\n"
- "}\n"
- "\n"
- "DoubleSpinBox \n"
- "{\n"
- " font: 9pt "Segoe UI";\n"
- "}\n"
- "\n"
- "SpinBox \n"
- "{\n"
- " font: 9pt "Segoe UI";\n"
- "}"
- );
- */
-
#ifndef WIN32
//For some reason linux makes these 24x24, even though the designer explicitly says 16x16.
ui.AddXformButton->setIconSize(QSize(16, 16));
diff --git a/Source/Fractorium/FractoriumXformsAffine.cpp b/Source/Fractorium/FractoriumXformsAffine.cpp
index 4ffe748..42c042b 100644
--- a/Source/Fractorium/FractoriumXformsAffine.cpp
+++ b/Source/Fractorium/FractoriumXformsAffine.cpp
@@ -16,8 +16,7 @@ void Fractorium::InitXformsAffineUI()
table->horizontalHeader()->setSectionsClickable(true);
table->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
-
- connect(table->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnPreAffineRowDoubleClicked(int)), Qt::QueuedConnection);
+ connect(table->verticalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnPreAffineRowDoubleClicked(int)), Qt::QueuedConnection);
connect(table->horizontalHeader(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(OnPreAffineColDoubleClicked(int)), Qt::QueuedConnection);
//Pre affine spinners.
@@ -169,8 +168,10 @@ void Fractorium::InitXformsAffineUI()
m_PostSpins[4] = m_PostY2Spin;
m_PostSpins[5] = m_PostO2Spin;
- ui.PostAffineGroupBox->setChecked(true);//Flip it once to force the disabling of the group box.
- ui.PostAffineGroupBox->setChecked(false);
+ ui.PreAffineGroupBox->setChecked(false);//Flip both once to force enabling/disabling the disabling of the group boxes and the corner buttons.
+ ui.PreAffineGroupBox->setChecked(true);//Pre affine enabled.
+ ui.PostAffineGroupBox->setChecked(true);
+ ui.PostAffineGroupBox->setChecked(false);//Post affine disabled.
}
///
@@ -604,11 +605,20 @@ void FractoriumEmberController::FillAffineWithXform(Xform* xform, bool pre
///
/// Trigger a redraw which will show or hide the circle affine transforms
/// based on whether each group box is checked or not.
+/// Note that all sub buttons must manually be disabled/enabled in order to
+/// get the top left corner button in the proper state. This is needed so
+/// any style sheets can properly draw it based on its state.
+/// Without explicitly setting it, that button is never actually disabled.
/// Called when the group box check box for pre or post affine is checked.
///
/// Ignored
void Fractorium::OnAffineGroupBoxToggled(bool on)
{
+ auto widgetList = sender()->findChildren();
+
+ for (auto& it : widgetList)
+ it->setEnabled(on);
+
ui.GLDisplay->update();
}
diff --git a/Source/Fractorium/FractoriumXformsVariations.cpp b/Source/Fractorium/FractoriumXformsVariations.cpp
index 66160fa..9079a01 100644
--- a/Source/Fractorium/FractoriumXformsVariations.cpp
+++ b/Source/Fractorium/FractoriumXformsVariations.cpp
@@ -239,7 +239,6 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would
if (xformVar)
xform->DeleteVariationById(var->VariationId());
- //widgetItem->setBackgroundColor(0, Qt::darkGray);//Ensure background is always white if weight goes to zero.
widgetItem->setBackgroundColor(0, QColor(255, 255, 255));//Ensure background is always white if weight goes to zero.
}
else
@@ -256,7 +255,6 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would
newVar->m_Weight = d;
xform->AddVariation(newVar);
- //widgetItem->setBackgroundColor(0, Qt::darkGray);//Set background to gray when a variation has non-zero weight in this xform.
widgetItem->setBackgroundColor(0, QColor(200, 200, 200));//Set background to gray when a variation has non-zero weight in this xform.
//If they've added a new parametric variation, then grab the values currently in the spinners
diff --git a/Source/Fractorium/GLWidget.cpp b/Source/Fractorium/GLWidget.cpp
index 0768969..0d0051e 100644
--- a/Source/Fractorium/GLWidget.cpp
+++ b/Source/Fractorium/GLWidget.cpp
@@ -1084,7 +1084,7 @@ int GLEmberController::UpdateHover(v3T& glCoords)
m_HoverType = HoverNone;
//If there's a selected/current xform, check it first so it gets precedence over the others.
- if (m_SelectedXform != nullptr)
+ if (m_SelectedXform)
{
//These checks prevent highlighting the pre/post selected xform circle, when one is set to show all, and the other
//is set to show current, and the user hovers over another xform, but doesn't select it, then moves the mouse
diff --git a/Source/Fractorium/Icons/checkbox_checked.png b/Source/Fractorium/Icons/checkbox_checked.png
new file mode 100644
index 0000000..cbf06f6
Binary files /dev/null and b/Source/Fractorium/Icons/checkbox_checked.png differ
diff --git a/Source/Fractorium/Icons/checkbox_unchecked.png b/Source/Fractorium/Icons/checkbox_unchecked.png
new file mode 100644
index 0000000..5f54655
Binary files /dev/null and b/Source/Fractorium/Icons/checkbox_unchecked.png differ
diff --git a/Source/Fractorium/Main.cpp b/Source/Fractorium/Main.cpp
index 8282cf4..6337e0d 100644
--- a/Source/Fractorium/Main.cpp
+++ b/Source/Fractorium/Main.cpp
@@ -30,63 +30,10 @@ int main(int argc, char *argv[])
putenv(const_cast("GPU_MAX_ALLOC_PERCENT=100"));
#endif
-#ifndef WIN32
- a.setStyleSheet("QGroupBox { border: 1px solid gray; border-radius: 3px; margin-top: 1.1em; background-color: transparent; } \n"
- "QTabBar::tab { height: 2.8ex; } \n"
- "QGroupBox::title "
- "{"
- " background-color: transparent;"
- " subcontrol-origin: margin; "
- //" left: 3px; "
- " subcontrol-position: top left;"
- " padding: 0 3px 0 3px;"
- //" padding: 2px;"
- "} \n"
- "QComboBox { margin-top: 0px; padding-bottom: 0px; }"
- );
-#endif
-
int rv = -1;
try
{
- //a.setStyle(QStyleFactory::create("Fusion"));
- //QPalette darkPalette;
- /*darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
- darkPalette.setColor(QPalette::WindowText, Qt::white);
- darkPalette.setColor(QPalette::Base, QColor(25, 25, 25));
- darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
- darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
- darkPalette.setColor(QPalette::ToolTipText, Qt::white);
- darkPalette.setColor(QPalette::Text, Qt::white);
- darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
- darkPalette.setColor(QPalette::ButtonText, Qt::white);
- darkPalette.setColor(QPalette::BrightText, Qt::red);
- darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
-
- darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
- darkPalette.setColor(QPalette::HighlightedText, Qt::black);;*/
-
- //darkPalette.setColor(QPalette::, Qt::lightGray);
- //darkPalette.setColor(QPalette::Window, Qt::darkGray);
- //darkPalette.setColor(QPalette::Disabled, QPalette::WindowText, Qt::red);
- //darkPalette.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::blue);//Works for disabled buttons, but not for disabled menus.
-
- //a.setPalette(darkPalette);
- //a.setStyleSheet("QToolTip { color: #ffffff; background-color: darkgray; border: 1px solid white; }");
- //a.setStyleSheet("QTableWidget { border-color: darkgray; }")
- //QString s;
-
- //s = "QTableView, QSpinBox, QDoubleSpinBox, QGroupBox, QTreeWidget { background-color: darkGray; } ";
- //s += "QComboBox, QTextEdit, QLineEdit { background - color: lightGray; } ";
- //s += "QTabWidget { window-color: darkGray; } ";
- //a.setStyleSheet("{ color: rgb(85, 170, 0); }");
- //a.setStyleSheet("GLWidget { background-color: darkgray; }");
- //a.setStyleSheet("QTableView, QDoubleSpinBox { background-color: darkgray; }");//Works!
- //a.setStyleSheet(s);//Works!
- //a.setStyleSheet("QTableView, QSpinBox, QDoubleSpinBox, QTreeWidget, QTreeWidgetItem { background-color: darkgray; }");//QTreeWidgetItem not needed.
- //a.setStyleSheet("QTableView, DoubleSpinBox { background-color: darkgray; }");//Works!
-
Fractorium w;
w.show();
a.installEventFilter(&w);
diff --git a/Source/Fractorium/OptionsDialog.cpp b/Source/Fractorium/OptionsDialog.cpp
index 99cd953..dc7e10e 100644
--- a/Source/Fractorium/OptionsDialog.cpp
+++ b/Source/Fractorium/OptionsDialog.cpp
@@ -74,6 +74,7 @@ bool FractoriumOptionsDialog::Double() { return ui.DoublePrecisionCheckBox->isCh
bool FractoriumOptionsDialog::ShowAllXforms() { return ui.ShowAllXformsCheckBox->isChecked(); }
bool FractoriumOptionsDialog::AutoUnique() { return ui.AutoUniqueCheckBox->isChecked(); }
uint FractoriumOptionsDialog::ThreadCount() { return ui.ThreadCountSpin->value(); }
+uint FractoriumOptionsDialog::RandomCount() { return ui.RandomCountSpin->value(); }
///
/// The check state of one of the OpenCL devices was changed.
@@ -130,6 +131,7 @@ void FractoriumOptionsDialog::OnOpenCLCheckBoxStateChanged(int state)
ui.CpuFilteringLogRadioButton->setEnabled(!checked);
ui.OpenCLFilteringDERadioButton->setEnabled(checked);
ui.OpenCLFilteringLogRadioButton->setEnabled(checked);
+ ui.InteraciveCpuFilteringGroupBox->setEnabled(!checked);
ui.InteraciveGpuFilteringGroupBox->setEnabled(checked);
}
@@ -178,6 +180,7 @@ void FractoriumOptionsDialog::GuiToData()
m_Settings->Double(Double());
m_Settings->ShowAllXforms(ShowAllXforms());
m_Settings->ThreadCount(ThreadCount());
+ m_Settings->RandomCount(RandomCount());
m_Settings->CpuSubBatch(ui.CpuSubBatchSpin->value());
m_Settings->OpenCLSubBatch(ui.OpenCLSubBatchSpin->value());
m_Settings->CpuDEFilter(ui.CpuFilteringDERadioButton->isChecked());
@@ -212,6 +215,7 @@ void FractoriumOptionsDialog::DataToGui()
ui.DoublePrecisionCheckBox->setChecked(m_Settings->Double());
ui.ShowAllXformsCheckBox->setChecked(m_Settings->ShowAllXforms());
ui.ThreadCountSpin->setValue(m_Settings->ThreadCount());
+ ui.RandomCountSpin->setValue(m_Settings->RandomCount());
ui.CpuSubBatchSpin->setValue(m_Settings->CpuSubBatch());
ui.OpenCLSubBatchSpin->setValue(m_Settings->OpenCLSubBatch());
SettingsToDeviceTable(ui.DeviceTable, devices);
diff --git a/Source/Fractorium/OptionsDialog.h b/Source/Fractorium/OptionsDialog.h
index 4fc02ca..790e96f 100644
--- a/Source/Fractorium/OptionsDialog.h
+++ b/Source/Fractorium/OptionsDialog.h
@@ -47,6 +47,7 @@ private:
bool ShowAllXforms();
bool AutoUnique();
uint ThreadCount();
+ uint RandomCount();
void DataToGui();
void GuiToData();
diff --git a/Source/Fractorium/OptionsDialog.ui b/Source/Fractorium/OptionsDialog.ui
index 525b5e5..bce1238 100644
--- a/Source/Fractorium/OptionsDialog.ui
+++ b/Source/Fractorium/OptionsDialog.ui
@@ -32,7 +32,7 @@
Options
- true
+ false
@@ -112,7 +112,7 @@
-
- <html><head/><body><p>Use OpenCL to render if your video card supports it.</p><p>This is highly recommended as it will give fluid, real-time interactive editing.</p></body></html>
+ <html><head/><body><p>Use OpenCL to render if your video card supports it.</p><p>This is highly recommended as it will provide fluid, real-time interactive editing.</p></body></html>
Use OpenCL
@@ -257,7 +257,7 @@
- -
+
-
<html><head/><body><p>The number of threads to use with CPU rendering.</p><p>Decrease for more responsive editing, increase for better performance.</p></body></html>
@@ -273,7 +273,7 @@
- -
+
-
The number of 10,000 iteration chunks ran per thread on the CPU
@@ -290,7 +290,7 @@ in interactive mode for each mouse movement
- -
+
-
The number of ~8M iteration chunks ran using OpenCL
@@ -307,7 +307,7 @@ in interactive mode for each mouse movement
- -
+
-
CPU Filtering
@@ -354,7 +354,7 @@ in interactive mode for each mouse movement
- -
+
-
OpenCL Filtering
@@ -398,6 +398,22 @@ in interactive mode for each mouse movement
+ -
+
+
+ <html><head/><body><p>The number of random flames to generate on startup.</p><p>These are usually of low quality, so leave the count as 1 unless you are searching for good randoms.</p></body></html>
+
+
+ Randoms
+
+
+ 1
+
+
+ 99999
+
+
+
@@ -431,13 +447,13 @@ in interactive mode for each mouse movement
0
- 68
+ 67
16777215
- 68
+ 67
@@ -624,13 +640,13 @@ in interactive mode for each mouse movement
120
- 68
+ 67
16777215
- 68
+ 67
@@ -820,6 +836,7 @@ in interactive mode for each mouse movement
TransparencyCheckBox
ShowAllXformsCheckBox
ContinuousUpdateCheckBox
+ RandomCountSpin
ThreadCountSpin
CpuSubBatchSpin
OpenCLSubBatchSpin
diff --git a/Source/Fractorium/QssDialog.cpp b/Source/Fractorium/QssDialog.cpp
new file mode 100644
index 0000000..330043a
--- /dev/null
+++ b/Source/Fractorium/QssDialog.cpp
@@ -0,0 +1,694 @@
+#include "FractoriumPch.h"
+#include "QssDialog.h"
+#include "ui_QssDialog.h"
+#include "qcssscanner.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+///
+/// Comparison for sorting object names.
+/// Strings not starting with the letter 'Q' take precedence.
+/// This has the effect of putting custom derived classes first before
+/// all Q* classes.
+///
+/// The first string to compare
+/// The second string to compare
+/// True if s1 < s2 with special rules for 'Q' taken into account.
+bool CaseInsensitiveLessThanQ(const QString& s1, const QString& s2)
+{
+ if (s1.length() && s2.length())
+ {
+ if (s1[0] == 'Q' && s2[0] == 'Q')
+ return s1.toLower() < s2.toLower();
+ else if (s1[0] == 'Q')
+ return false;
+ else if (s2[0] == 'Q')
+ return true;
+ else
+ return s1.toLower() < s2.toLower();
+ }
+
+ return false;
+}
+
+///
+/// Construct a QssDialog.
+/// This manually constructs much of the menu GUI via code rather
+/// than in the designer.
+///
+/// The main Fractorium window.
+QssDialog::QssDialog(Fractorium* parent) :
+ QDialog(parent),
+ ui(new Ui::QssDialog),
+ m_FileDialog(nullptr),
+ m_AddColorAction(new QAction(tr("Add Color"), this)),
+ m_AddGeomAction(new QAction(tr("Add Geometry"), this)),
+ m_AddBorderAction(new QAction(tr("Add Border"), this)),
+ m_AddFontAction(new QAction(tr("Add Font..."), this)),
+ m_AddStyleAction(new QAction(tr("Set Theme"), this))
+{
+ ui->setupUi(this);
+ m_Parent = parent;
+ m_LastStyle = m_Parent->styleSheet();
+ setWindowTitle("QSS Editor - default.qss");
+ connect(ui->QssEdit, SIGNAL(textChanged()), this, SLOT(SlotTextChanged()));
+
+ QToolBar* toolBar = new QToolBar(this);
+ QMenu* colorActionMenu = new QMenu(this);
+ QMenu* geomActionMenu = new QMenu(this);
+ QMenu* borderActionMenu = new QMenu(this);
+ QMenu* styleActionMenu = new QMenu(this);
+
+ (m_ColorActionMapper = new QSignalMapper(this))->setMapping(m_AddColorAction, QString());
+ (m_GeomActionMapper = new QSignalMapper(this))->setMapping(m_AddGeomAction, QString());
+ (m_BorderActionMapper = new QSignalMapper(this))->setMapping(m_AddBorderAction, QString());
+ (m_StyleActionMapper = new QSignalMapper(this))->setMapping(m_AddStyleAction, QString());
+
+ connect(ui->QssLoadButton, SIGNAL(clicked()), this, SLOT(LoadButton_clicked()), Qt::QueuedConnection);
+ connect(ui->QssSaveButton, SIGNAL(clicked()), this, SLOT(SaveButton_clicked()), Qt::QueuedConnection);
+ connect(ui->QssSaveDefaultButton, SIGNAL(clicked()), this, SLOT(SaveDefaultButton_clicked()), Qt::QueuedConnection);
+ connect(ui->QssBasicButton, SIGNAL(clicked()), this, SLOT(BasicButton_clicked()), Qt::QueuedConnection);
+ connect(ui->QssMediumButton, SIGNAL(clicked()), this, SLOT(MediumButton_clicked()), Qt::QueuedConnection);
+ connect(ui->QssAdvancedButton, SIGNAL(clicked()), this, SLOT(AdvancedButton_clicked()), Qt::QueuedConnection);
+ connect(m_AddFontAction, SIGNAL(triggered()), this, SLOT(SlotAddFont()));
+
+ QVector> colorVec;
+
+ colorVec.reserve(12);
+ colorVec.push_back(QPair("color", ""));
+ colorVec.push_back(QPair("background-color", ""));
+ colorVec.push_back(QPair("alternate-background-color", ""));
+ colorVec.push_back(QPair("border-color", ""));
+ colorVec.push_back(QPair("border-top-color", ""));
+ colorVec.push_back(QPair("border-right-color", ""));
+ colorVec.push_back(QPair("border-bottom-color", ""));
+ colorVec.push_back(QPair("border-left-color", ""));
+ colorVec.push_back(QPair("gridline-color", ""));
+ colorVec.push_back(QPair("selection-color", ""));
+ colorVec.push_back(QPair("selection-background-color", ""));
+
+ for (auto& c : colorVec)
+ {
+ auto colorAction = colorActionMenu->addAction(c.first);
+
+ m_ColorMap[c.first] = c.second;
+ connect(colorAction, SIGNAL(triggered()), m_ColorActionMapper, SLOT(map()));
+ m_ColorActionMapper->setMapping(colorAction, c.first);
+ }
+
+ QVector> geomVec;
+
+ geomVec.reserve(12);
+ geomVec.push_back(QPair("width", "100px"));
+ geomVec.push_back(QPair("height", "50px"));
+ geomVec.push_back(QPair("spacing", "10"));
+ geomVec.push_back(QPair("padding", "3px"));
+ geomVec.push_back(QPair("padding-top", "3px"));
+ geomVec.push_back(QPair("padding-right", "3px"));
+ geomVec.push_back(QPair("padding-bottom", "3px"));
+ geomVec.push_back(QPair("padding-left", "3px"));
+ geomVec.push_back(QPair("margin", "3px"));
+ geomVec.push_back(QPair("margin-top", "3px"));
+ geomVec.push_back(QPair("margin-right", "3px"));
+ geomVec.push_back(QPair("margin-bottom", "3px"));
+ geomVec.push_back(QPair("margin-left", "3px"));
+
+ for (auto& g : geomVec)
+ {
+ auto geomAction = geomActionMenu->addAction(g.first);
+
+ m_GeomMap[g.first] = g.second;
+ connect(geomAction, SIGNAL(triggered()), m_GeomActionMapper, SLOT(map()));
+ m_GeomActionMapper->setMapping(geomAction, g.first);
+ }
+
+ QVector> borderVec;
+
+ borderVec.reserve(8);
+ borderVec.push_back(QPair("border", "1px solid black"));
+ borderVec.push_back(QPair("border-top", "1px inset black"));
+ borderVec.push_back(QPair("border-right", "1px outset black"));
+ borderVec.push_back(QPair("border-bottom", "1px ridge black"));
+ borderVec.push_back(QPair("border-left", "1px groove black"));
+ borderVec.push_back(QPair("border-style", "double"));
+ borderVec.push_back(QPair("border-width", "1px"));
+ borderVec.push_back(QPair("border-radius", "10px"));
+
+ for (auto& b : borderVec)
+ {
+ auto borderAction = borderActionMenu->addAction(b.first);
+
+ m_BorderMap[b.first] = b.second;
+ connect(borderAction, SIGNAL(triggered()), m_BorderActionMapper, SLOT(map()));
+ m_BorderActionMapper->setMapping(borderAction, b.first);
+ }
+
+ auto styles = QStyleFactory::keys();
+
+ for (auto& s : styles)
+ {
+ auto styleAction = styleActionMenu->addAction(s);
+
+ m_StyleMap[s] = s;
+ connect(styleAction, SIGNAL(triggered()), m_StyleActionMapper, SLOT(map()));
+ m_StyleActionMapper->setMapping(styleAction, s);
+ }
+
+ connect(m_ColorActionMapper, SIGNAL(mapped(QString)), this, SLOT(SlotAddColor(QString)));
+ connect(m_GeomActionMapper, SIGNAL(mapped(QString)), this, SLOT(SlotAddGeom(QString)));
+ connect(m_BorderActionMapper, SIGNAL(mapped(QString)), this, SLOT(SlotAddBorder(QString)));
+ connect(m_StyleActionMapper, SIGNAL(mapped(QString)), this, SLOT(SlotSetTheme(QString)));
+
+ m_AddColorAction->setMenu(colorActionMenu);
+ m_AddGeomAction->setMenu(geomActionMenu);
+ m_AddBorderAction->setMenu(borderActionMenu);
+ m_AddStyleAction->setMenu(styleActionMenu);
+
+ toolBar->addAction(m_AddColorAction);
+ toolBar->addAction(m_AddGeomAction);
+ toolBar->addAction(m_AddBorderAction);
+ toolBar->addAction(m_AddFontAction);
+ toolBar->addAction(m_AddStyleAction);
+ ui->verticalLayout->insertWidget(0, toolBar);
+ ui->QssEdit->setFocus();
+ m_ApplyTimer = new QTimer(this);
+ m_ApplyTimer->setSingleShot(true);
+ m_ApplyTimer->setInterval(1000);
+ connect(m_ApplyTimer, SIGNAL(timeout()), this, SLOT(SlotApplyCss()));
+}
+
+///
+/// Destructor that stops the apply timer and deletes the ui.
+///
+QssDialog::~QssDialog()
+{
+ m_ApplyTimer->stop();
+ delete ui;
+}
+
+///
+/// Thin wrapper around getting the text from the main text box as plain text.
+///
+/// The plain text of the main text box
+QString QssDialog::Text() const
+{
+ return ui->QssEdit->toPlainText();
+}
+
+///
+/// Thin wrapper around setting the text of the main text box.
+///
+/// The text to set
+void QssDialog::SetText(const QString& t)
+{
+ ui->QssEdit->setText(t);
+}
+
+///
+/// Get the class names of all objects in the application.
+/// This only makes one entry for each class type.
+/// It will also optionally return the object names as well for advanced QSS editing.
+///
+/// Whether to get the individual object names as well
+/// A list of all class names with optional entries for each individual object
+QList QssDialog::GetClassNames(bool includeObjectNames)
+{
+ QSet classNames;
+ QList> dialogClassNames;
+ auto widgetList = m_Parent->findChildren();
+
+ for (int i = 0; i < widgetList.size(); i++)
+ {
+ auto classAndName = QString(widgetList[i]->metaObject()->className());
+
+ if (!includeObjectNames)
+ {
+ classNames.insert(classAndName);
+ }
+ else
+ {
+ auto dlg = qobject_cast(widgetList[i]);
+
+ if (dlg)//Dialogs only nest one level deep, so no need for generalized recursion.
+ {
+ QSet dlgSet;
+ auto dlgWidgetList = dlg->findChildren();//Find all children of the dialog.
+
+ dlgSet.insert(classAndName);//Add the basic dialog class name, opening curly brace will be added later.
+ classAndName += " ";
+
+ for (int i = 0; i < dlgWidgetList.size(); i++)
+ {
+ auto dlgClassAndName = classAndName + QString(dlgWidgetList[i]->metaObject()->className());
+ dlgSet.insert(dlgClassAndName);
+
+ if (!dlgWidgetList[i]->objectName().isEmpty())//Add the class with object name for individual control customization.
+ {
+ dlgClassAndName += "#" + dlgWidgetList[i]->objectName();
+ dlgSet.insert(dlgClassAndName);
+ }
+ }
+
+ auto dlgList = dlgSet.toList();//Convert set to list and sort.
+ qSort(dlgList.begin(), dlgList.end(), CaseInsensitiveLessThanQ);
+ dialogClassNames.push_back(dlgList);//Add this to the full list after sorting at the end.
+ }
+ else if (GetAllParents(widgetList[i]).empty())//Skip widgets on dialogs, they are added above.
+ {
+ classNames.insert(classAndName);//Add the basic class name.
+
+ if (!widgetList[i]->objectName().isEmpty())//Add the class with object name for individual control customization.
+ {
+ classAndName += "#" + widgetList[i]->objectName();
+ classNames.insert(classAndName);
+ }
+ }
+ }
+ }
+
+ auto l = classNames.toList();
+ qSort(l.begin(), l.end(), CaseInsensitiveLessThanQ);
+
+ for (auto& d : dialogClassNames)
+ l.append(d);
+
+ return l;
+}
+
+///
+/// Determines whether the passed in stylesheet text is valid.
+/// If the initial parse fails, a second attempt is made by wrapping the entire
+/// text in curly braces.
+///
+/// The stylesheet text to analyze.
+/// True if valid, else false.
+bool QssDialog::IsStyleSheetValid(const QString& styleSheet)
+{
+ QCss::Parser parser(styleSheet);
+ QCss::StyleSheet sheet;
+ if (parser.parse(&sheet))
+ return true;
+ QString fullSheet = QStringLiteral("* { ");
+ fullSheet += styleSheet;
+ fullSheet += QLatin1Char('}');
+ QCss::Parser parser2(fullSheet);
+ return parser2.parse(&sheet);
+}
+
+///
+/// Save the current stylesheet text to default.qss.
+/// Also save the selected theme to the settings.
+/// Called when the user clicks ok.
+/// Not called if cancelled or closed with the X.
+///
+void QssDialog::accept()
+{
+ if (m_Theme)
+ m_Parent->m_Settings->Theme(m_Theme->objectName());
+
+ SaveDefaultButton_clicked();
+ QDialog::accept();
+}
+
+///
+/// Restore the stylesheet and theme to what it was when the dialog was opened.
+/// Called when the user clicks cancel or closes with the X.
+///
+void QssDialog::reject()
+{
+ if (!m_LastStyle.isEmpty())
+ m_Parent->setStyleSheet(m_LastStyle);
+
+ if (m_LastTheme)
+ {
+ m_Parent->setStyle(m_LastTheme);
+ m_Parent->m_Settings->Theme(m_LastTheme->objectName());
+ }
+
+ QDialog::reject();
+}
+
+///
+/// Shows the event.
+///
+/// The e.
+void QssDialog::showEvent(QShowEvent* e)
+{
+ if (m_Parent)
+ {
+ m_LastStyle = m_Parent->styleSheet();
+ m_LastTheme = m_Parent->m_Theme;//The style() member cannot be relied upon, it is *not* the same object passed to setStyle();
+ SetText(m_LastStyle);
+ }
+
+ QDialog::showEvent(e);
+}
+
+///
+/// Start the timer which will analyze and apply the current stylesheet text.
+/// Each successive keystroke will reset the timer if it has not timed out yet.
+/// This is only called when the dialog is visible because it seems to be spurriously
+/// called on startup.
+/// Called when the user changes the text in main text box.
+///
+void QssDialog::SlotTextChanged()
+{
+ if (isVisible())//Sometimes this fires even though the window is not shown yet.
+ m_ApplyTimer->start();
+}
+
+///
+/// Add a color string to the stylesheet text.
+/// Called when the user clicks the add color menu.
+///
+/// The color string selector to add
+void QssDialog::SlotAddColor(const QString& s)
+{
+ const QColor color = QColorDialog::getColor(0xffffffff, this, QString(), QColorDialog::ShowAlphaChannel);
+
+ if (!color.isValid())
+ return;
+
+ QString colorStr;
+
+ if (color.alpha() == 255)
+ {
+ colorStr = QString(QStringLiteral("rgb(%1, %2, %3)")).arg(
+ color.red()).arg(color.green()).arg(color.blue());
+ }
+ else
+ {
+ colorStr = QString(QStringLiteral("rgba(%1, %2, %3, %4)")).arg(
+ color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
+ }
+
+ InsertCssProperty(s, colorStr);
+}
+
+///
+/// Adds a geometry string to the stylesheet text.
+///
+/// The geometry string to add
+void QssDialog::SlotAddGeom(const QString& s)
+{
+ auto val = m_GeomMap[s];
+
+ InsertCssProperty(s, val);
+}
+
+///
+/// Adds a border string to the stylesheet text.
+///
+/// The border string to add
+void QssDialog::SlotAddBorder(const QString& s)
+{
+ auto val = m_BorderMap[s];
+
+ InsertCssProperty(s, val);
+}
+
+///
+/// Set the theme to the user selection.
+/// Called when the user selects an item on the theme combo box.
+///
+/// The s.
+void QssDialog::SlotSetTheme(const QString& s)
+{
+ if (auto theme = QStyleFactory::create(s))
+ {
+ m_Theme = theme;
+ m_Parent->setStyle(m_Theme);
+ }
+}
+
+///
+/// Add a font string.
+/// Called when the user clicks the add font menu button.
+///
+void QssDialog::SlotAddFont()
+{
+ bool ok;
+ auto font = QFontDialog::getFont(&ok, this);
+
+ if (ok)
+ {
+ QString fontStr;
+
+ if (font.weight() != QFont::Normal)
+ {
+ fontStr += QString::number(font.weight());
+ fontStr += QLatin1Char(' ');
+ }
+
+ switch (font.style())
+ {
+ case QFont::StyleItalic:
+ fontStr += QStringLiteral("italic ");
+ break;
+ case QFont::StyleOblique:
+ fontStr += QStringLiteral("oblique ");
+ break;
+ default:
+ break;
+ }
+
+ fontStr += QString::number(font.pointSize());
+ fontStr += QStringLiteral("pt \"");
+ fontStr += font.family();
+ fontStr += QLatin1Char('"');
+ InsertCssProperty(QStringLiteral("font"), fontStr);
+ }
+}
+
+///
+/// Check if the current stylesheet is valid and apply it if so.
+/// Also indicate via label whether it was valid.
+///
+void QssDialog::SlotApplyCss()
+{
+ auto label = ui->QssValidityLabel;
+ auto style = Text();
+ const bool valid = IsStyleSheetValid(style);
+ ui->QssButtonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
+
+ if (valid)
+ {
+ label->setText(tr("Valid Style Sheet"));
+ label->setStyleSheet(QStringLiteral("color: green"));
+ m_Parent->setStyleSheet(style);
+ }
+ else
+ {
+ label->setText(tr("Invalid Style Sheet"));
+ label->setStyleSheet(QStringLiteral("color: red"));
+ }
+}
+
+///
+/// Load a stylesheet from disk.
+/// Called when the user clicks the load button.
+///
+void QssDialog::LoadButton_clicked()
+{
+ string s;
+ auto f = OpenFile();
+
+ if (!f.isEmpty() && ReadFile(f.toStdString().c_str(), s) && !s.empty())
+ SetText(QString::fromStdString(s));
+
+ setWindowTitle("QSS Editor - " + f);
+}
+
+///
+/// Save the stylesheet to disk.
+/// Called when the user clicks the save button.
+///
+void QssDialog::SaveButton_clicked()
+{
+ auto path = SaveFile();
+
+ if (!path.isEmpty())
+ {
+ ofstream of(path.toStdString());
+ string s = Text().toStdString();
+
+ if (of.is_open())
+ {
+ of << s;
+ of.close();
+ }
+ else
+ QMessageBox::critical(this, "File open error", "Failed to open " + path + ", style will not be set as default");
+ }
+}
+
+///
+/// Save the stylesheet to the default.qss on disk.
+/// This will be loaded the next time Fractorium runs.
+/// Called when the user clicks the save as default button.
+///
+void QssDialog::SaveDefaultButton_clicked()
+{
+ auto path = m_Parent->m_SettingsPath + "/default.qss";
+ ofstream of(path.toStdString());
+ auto s = Text().toStdString();
+
+ if (of.is_open())
+ {
+ of << s;
+ of.close();
+ }
+ else
+ QMessageBox::critical(this, "File open error", "Failed to open " + path + ", style will not be set as default");
+}
+
+///
+/// Fill the main text box with the most basic style.
+/// Called when the Basic button is clicked.
+///
+void QssDialog::BasicButton_clicked()
+{
+ SetText(BaseStyle());
+ setWindowTitle("QSS Editor");
+}
+
+///
+/// Fill the main text box with a medium specificity style.
+/// This will expose all control types in the application.
+/// Called when the Medium button is clicked.
+///
+void QssDialog::MediumButton_clicked()
+{
+ QString str = BaseStyle();
+ auto names = GetClassNames(false);
+
+ for (auto& it : names)
+ str += it + QString("\n{\n\t\n}\n\n");
+
+ SetText(str);
+ setWindowTitle("QSS Editor");
+}
+
+///
+/// Fill the main text box with the most advanced style.
+/// This will expose all control types in the application as well as their named instances.
+/// Called when the Advanced button is clicked.
+///
+void QssDialog::AdvancedButton_clicked()
+{
+ QString str = BaseStyle();
+ auto names = GetClassNames(true);
+
+ for (auto& it : names)
+ str += it + QString("\n{\n\t\n}\n\n");
+
+ SetText(str);
+ setWindowTitle("QSS Editor");
+}
+
+///
+/// Insert a CSS property.
+/// This is called whenever the user inserts a value via the menus.
+///
+/// The name of the property to insert
+/// The value of the property to insert
+void QssDialog::InsertCssProperty(const QString& name, const QString& value)
+{
+ auto editor = ui->QssEdit;
+ auto cursor = editor->textCursor();
+
+ if (!name.isEmpty())
+ {
+ cursor.beginEditBlock();
+ cursor.removeSelectedText();
+ cursor.movePosition(QTextCursor::EndOfLine);
+
+ //Simple check to see if we're in a selector scope.
+ const QTextDocument* doc = editor->document();
+ const QTextCursor closing = doc->find(QStringLiteral("}"), cursor, QTextDocument::FindBackward);
+ const QTextCursor opening = doc->find(QStringLiteral("{"), cursor, QTextDocument::FindBackward);
+ const bool inSelector = !opening.isNull() && (closing.isNull() ||
+ closing.position() < opening.position());
+ QString insertion;
+
+ //Reasonable attempt at positioning things correctly. This can and often is wrong, but is sufficient for our purposes.
+ if (editor->textCursor().block().length() != 1 && !editor->textCursor().block().text().isEmpty())
+ insertion += QLatin1Char('\n');
+
+ if (inSelector && editor->textCursor().block().text() != "\t")
+ insertion += QLatin1Char('\t');
+
+ insertion += name;
+ insertion += QStringLiteral(": ");
+ insertion += value;
+ insertion += QLatin1Char(';');
+ cursor.insertText(insertion);
+ cursor.endEditBlock();
+ }
+ else
+ {
+ cursor.insertText(value);
+ }
+}
+
+///
+/// Initial file dialog creation.
+/// This will perform lazy instantiation since it takes a long time.
+///
+void QssDialog::SetupFileDialog()
+{
+ if (!m_FileDialog)
+ {
+ auto path = m_Parent->m_SettingsPath;
+ m_FileDialog = new QFileDialog(this);
+ m_FileDialog->setDirectory(path);
+ m_FileDialog->setViewMode(QFileDialog::List);
+ }
+}
+
+///
+/// Present a file open dialog and retun the file selected.
+///
+/// The file selected if any, else empty string.
+QString QssDialog::OpenFile()
+{
+ QStringList filenames;
+
+ SetupFileDialog();
+
+ m_FileDialog->setFileMode(QFileDialog::ExistingFile);
+ m_FileDialog->setAcceptMode(QFileDialog::AcceptOpen);
+ m_FileDialog->setNameFilter("Qss (*.qss)");
+ m_FileDialog->setWindowTitle("Open Stylesheet");
+ m_FileDialog->selectNameFilter("*.qss");
+
+ if (m_FileDialog->exec() == QDialog::Accepted)
+ filenames = m_FileDialog->selectedFiles();
+
+ return !filenames.empty() ? filenames[0] : "";
+}
+
+///
+/// Present a file save dialog and retun the file selected.
+///
+/// The file selected for saving if any, else empty string.
+QString QssDialog::SaveFile()
+{
+ QStringList filenames;
+
+ SetupFileDialog();
+ m_FileDialog->setFileMode(QFileDialog::AnyFile);
+ m_FileDialog->setAcceptMode(QFileDialog::AcceptSave);
+ m_FileDialog->setNameFilter("Qss (*.qss)");
+ m_FileDialog->setWindowTitle("Save Stylesheet");
+ m_FileDialog->selectNameFilter("*.qss");
+
+ if (m_FileDialog->exec() == QDialog::Accepted)
+ filenames = m_FileDialog->selectedFiles();
+
+ return !filenames.empty() ? filenames[0] : "";
+}
diff --git a/Source/Fractorium/QssDialog.h b/Source/Fractorium/QssDialog.h
new file mode 100644
index 0000000..958d556
--- /dev/null
+++ b/Source/Fractorium/QssDialog.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+
+#include "Fractorium.h"
+#include "FractoriumCommon.h"
+#include "QssTextEdit.h"
+#include "qcssparser.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+namespace Ui
+{
+ class QssDialog;
+}
+
+///
+/// A dialog for editing the stylesheet used in the application.
+/// This is meant to be used in the following way:
+/// On first run, no stylesheet is present/selected, so a basic style
+/// is used on startup. This style differs slightly between Windows and Linux. See BaseStyle() for details.
+/// If the user clicks Save as default or ok to exit the dialog, the text of this stylesheet will
+/// be saved to the application settings folder in the file default.qss.
+/// On all subsequent runs, the main window will detect the presence of default.qss and load it.
+/// The user can load a different stylesheet from disk, such as dark.qss which comes with the installation.
+/// They can save this back to disk (under a different name because dark.qss is made read only by the installer),
+/// however it will not become the default until they explicitly click the Save as default button or click ok.
+/// The other buttons Basic, Medium and Advanced produce an empty style sheet that gives access to various controls.
+/// Basic: Just the base style.
+/// Medium: Basic + every type of control in the application.
+/// Advanced: Medium + the name of every individual control in the application. It is not intended that the user fill
+/// out a custom style for every single control. Rather, it's to make them aware of the names of the controls in the
+/// event they want to set some custom styling for a specific control.
+/// For all practical purposes, the user will probably start with dark.qss, edit what they need and save to a new stylesheet,
+// then set that one as the default.
+///
+class QssDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit QssDialog(Fractorium* parent);
+ ~QssDialog();
+
+ QString Text() const;
+ void SetText(const QString& t);
+ QList GetClassNames(bool includeObjectNames);
+ static bool IsStyleSheetValid(const QString& styleSheet);
+
+public slots:
+ virtual void accept() override;
+ virtual void reject() override;
+
+protected:
+ virtual void showEvent(QShowEvent* e) override;
+
+private slots:
+ void SlotTextChanged();
+ void SlotAddColor(const QString& p);
+ void SlotAddGeom(const QString& p);
+ void SlotAddBorder(const QString& p);
+ void SlotSetTheme(const QString& s);
+ void SlotAddFont();
+ void SlotApplyCss();
+
+ void LoadButton_clicked();
+ void SaveButton_clicked();
+ void SaveDefaultButton_clicked();
+ void BasicButton_clicked();
+ void MediumButton_clicked();
+ void AdvancedButton_clicked();
+
+private:
+ void InsertCssProperty(const QString &name, const QString &value);
+ void SetupFileDialog();
+ QString OpenFile();
+ QString SaveFile();
+
+ QStyle* m_Theme;
+ QStyle* m_LastTheme;
+ QString m_LastStyle;
+ QAction* m_AddColorAction;
+ QAction* m_AddGeomAction;
+ QAction* m_AddBorderAction;
+ QAction* m_AddFontAction;
+ QAction* m_AddStyleAction;
+ QSignalMapper* m_ColorActionMapper;
+ QSignalMapper* m_GeomActionMapper;
+ QSignalMapper* m_BorderActionMapper;
+ QSignalMapper* m_StyleActionMapper;
+ QHash m_ColorMap;
+ QHash m_GeomMap;
+ QHash m_BorderMap;
+ QHash m_StyleMap;
+ QTimer* m_ApplyTimer;
+ Fractorium* m_Parent;
+ QFileDialog* m_FileDialog;
+ Ui::QssDialog *ui;
+};
diff --git a/Source/Fractorium/QssDialog.ui b/Source/Fractorium/QssDialog.ui
new file mode 100644
index 0000000..5120819
--- /dev/null
+++ b/Source/Fractorium/QssDialog.ui
@@ -0,0 +1,160 @@
+
+
+ QssDialog
+
+
+
+ 0
+ 0
+ 1041
+ 644
+
+
+
+ QSS Editor
+
+
+
+ 6
+
+
+ 6
+
+
+ 6
+
+
+ 6
+
+ -
+
+
-
+
+
+ -
+
+
-
+
+
+ Load...
+
+
+
+ -
+
+
+ Save...
+
+
+
+ -
+
+
+ Save as default
+
+
+
+ -
+
+
+ Basic
+
+
+
+ -
+
+
+ Medium
+
+
+
+ -
+
+
+ Advanced
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Valid Qss
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+
+ QssTextEdit
+ QTextEdit
+
+
+
+
+
+
+ QssButtonBox
+ accepted()
+ QssDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ QssButtonBox
+ rejected()
+ QssDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/Source/Fractorium/QssTextEdit.cpp b/Source/Fractorium/QssTextEdit.cpp
new file mode 100644
index 0000000..e42428c
--- /dev/null
+++ b/Source/Fractorium/QssTextEdit.cpp
@@ -0,0 +1,10 @@
+#include "FractoriumPch.h"
+#include "QssTextEdit.h"
+
+QssTextEdit::QssTextEdit(QWidget* parent) :
+ QTextEdit(parent)
+{
+ setTabStopWidth(fontMetrics().width(QLatin1Char(' '))*4);
+ setAcceptRichText(false);
+ new CssHighlighter(document());
+}
diff --git a/Source/Fractorium/QssTextEdit.h b/Source/Fractorium/QssTextEdit.h
new file mode 100644
index 0000000..dceabed
--- /dev/null
+++ b/Source/Fractorium/QssTextEdit.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+
+#include "FractoriumPch.h"
+#include "csshighlighter.h"
+
+class QssTextEdit : public QTextEdit
+{
+ Q_OBJECT
+public:
+ QssTextEdit(QWidget* parent = nullptr);
+
+signals:
+
+public slots:
+
+};
diff --git a/Source/Fractorium/VariationsDialog.ui b/Source/Fractorium/VariationsDialog.ui
index 2da42a0..3631f1b 100644
--- a/Source/Fractorium/VariationsDialog.ui
+++ b/Source/Fractorium/VariationsDialog.ui
@@ -98,7 +98,7 @@
-
-
+
-
diff --git a/Source/Fractorium/csshighlighter.cpp b/Source/Fractorium/csshighlighter.cpp
new file mode 100644
index 0000000..73a7ed2
--- /dev/null
+++ b/Source/Fractorium/csshighlighter.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "FractoriumPch.h"
+#include "csshighlighter.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+CssHighlighter::CssHighlighter(QTextDocument *document)
+: QSyntaxHighlighter(document)
+{
+}
+
+void CssHighlighter::highlightBlock(const QString& text)
+{
+ enum Token { ALNUM, LBRACE, RBRACE, COLON, SEMICOLON, COMMA, QUOTE, SLASH, STAR };
+ static const int transitions[10][9] = {
+ { Selector, Property, Selector, Pseudo, Property, Selector, Quote, MaybeComment, Selector }, // Selector
+ { Property, Property, Selector, Value, Property, Property, Quote, MaybeComment, Property }, // Property
+ { Value, Property, Selector, Value, Property, Value, Quote, MaybeComment, Value }, // Value
+ { Pseudo1, Property, Selector, Pseudo2, Selector, Selector, Quote, MaybeComment, Pseudo }, // Pseudo
+ { Pseudo1, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo1 }, // Pseudo1
+ { Pseudo2, Property, Selector, Pseudo, Selector, Selector, Quote, MaybeComment, Pseudo2 }, // Pseudo2
+ { Quote, Quote, Quote, Quote, Quote, Quote, -1, Quote, Quote }, // Quote
+ { -1, -1, -1, -1, -1, -1, -1, -1, Comment }, // MaybeComment
+ { Comment, Comment, Comment, Comment, Comment, Comment, Comment, Comment, MaybeCommentEnd }, // Comment
+ { Comment, Comment, Comment, Comment, Comment, Comment, Comment, -1, MaybeCommentEnd } // MaybeCommentEnd
+ };
+
+ int lastIndex = 0;
+ bool lastWasSlash = false;
+ int state = previousBlockState(), save_state;
+ if (state == -1) {
+ // As long as the text is empty, leave the state undetermined
+ if (text.isEmpty()) {
+ setCurrentBlockState(-1);
+ return;
+ }
+ // The initial state is based on the precense of a : and the absense of a {.
+ // This is because Qt style sheets support both a full stylesheet as well as
+ // an inline form with just properties.
+ state = save_state = (text.indexOf(QLatin1Char(':')) > -1 &&
+ text.indexOf(QLatin1Char('{')) == -1) ? Property : Selector;
+ } else {
+ save_state = state>>16;
+ state &= 0x00ff;
+ }
+
+ if (state == MaybeCommentEnd) {
+ state = Comment;
+ } else if (state == MaybeComment) {
+ state = save_state;
+ }
+
+ for (int i = 0; i < text.length(); i++) {
+ int token = ALNUM;
+ const QChar c = text.at(i);
+ const char a = c.toLatin1();
+
+ if (state == Quote) {
+ if (a == '\\') {
+ lastWasSlash = true;
+ } else {
+ if (a == '\"' && !lastWasSlash) {
+ token = QUOTE;
+ }
+ lastWasSlash = false;
+ }
+ } else {
+ switch (a) {
+ case '{': token = LBRACE; break;
+ case '}': token = RBRACE; break;
+ case ':': token = COLON; break;
+ case ';': token = SEMICOLON; break;
+ case ',': token = COMMA; break;
+ case '\"': token = QUOTE; break;
+ case '/': token = SLASH; break;
+ case '*': token = STAR; break;
+ default: break;
+ }
+ }
+
+ int new_state = transitions[state][token];
+
+ if (new_state != state) {
+ bool include_token = new_state == MaybeCommentEnd || (state == MaybeCommentEnd && new_state!= Comment)
+ || state == Quote;
+ highlight(text, lastIndex, i-lastIndex+include_token, state);
+
+ if (new_state == Comment) {
+ lastIndex = i-1; // include the slash and star
+ } else {
+ lastIndex = i + ((token == ALNUM || new_state == Quote) ? 0 : 1);
+ }
+ }
+
+ if (new_state == -1) {
+ state = save_state;
+ } else if (state <= Pseudo2) {
+ save_state = state;
+ state = new_state;
+ } else {
+ state = new_state;
+ }
+ }
+
+ highlight(text, lastIndex, text.length() - lastIndex, state);
+ setCurrentBlockState(state + (save_state<<16));
+}
+
+void CssHighlighter::highlight(const QString &text, int start, int length, int state)
+{
+ if (start >= text.length() || length <= 0)
+ return;
+
+ QTextCharFormat format;
+
+ switch (state) {
+ case Selector:
+ setFormat(start, length, QColor::fromRgb(43, 145, 175));//Teal, like the Visual Studio default for classes in C++ and C#.
+ break;
+ case Property:
+ setFormat(start, length, Qt::darkBlue);
+ break;
+ case Value:
+ setFormat(start, length, Qt::black);
+ break;
+ case Pseudo1:
+ setFormat(start, length, Qt::darkRed);
+ break;
+ case Pseudo2:
+ setFormat(start, length, Qt::black);
+ break;
+ case Quote:
+ setFormat(start, length, Qt::darkMagenta);
+ break;
+ case Comment:
+ case MaybeCommentEnd:
+ format.setForeground(Qt::darkGreen);
+ setFormat(start, length, format);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/Source/Fractorium/csshighlighter.h b/Source/Fractorium/csshighlighter.h
new file mode 100644
index 0000000..2ff91c0
--- /dev/null
+++ b/Source/Fractorium/csshighlighter.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+#pragma once
+
+#include "FractoriumPch.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+class CssHighlighter : public QSyntaxHighlighter
+{
+ Q_OBJECT
+public:
+ explicit CssHighlighter(QTextDocument *document);
+
+protected:
+ void highlightBlock(const QString&);
+ void highlight(const QString&, int, int, int/*State*/);
+
+private:
+ enum State { Selector, Property, Value, Pseudo, Pseudo1, Pseudo2, Quote,
+ MaybeComment, Comment, MaybeCommentEnd };
+};
diff --git a/Source/Fractorium/qcssparser.cpp b/Source/Fractorium/qcssparser.cpp
new file mode 100644
index 0000000..9f444b7
--- /dev/null
+++ b/Source/Fractorium/qcssparser.cpp
@@ -0,0 +1,2697 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "FractoriumPch.h"
+#include "qcssparser.h"
+#include "qcssscanner.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+using namespace QCss;
+
+struct QCssKnownValue
+{
+ const char *name;
+ quint64 id;
+};
+
+static const QCssKnownValue properties[NumProperties - 1] = {
+ { "-qt-background-role", QtBackgroundRole },
+ { "-qt-block-indent", QtBlockIndent },
+ { "-qt-list-indent", QtListIndent },
+ { "-qt-list-number-prefix", QtListNumberPrefix },
+ { "-qt-list-number-suffix", QtListNumberSuffix },
+ { "-qt-paragraph-type", QtParagraphType },
+ { "-qt-style-features", QtStyleFeatures },
+ { "-qt-table-type", QtTableType },
+ { "-qt-user-state", QtUserState },
+ { "alternate-background-color", QtAlternateBackground },
+ { "background", Background },
+ { "background-attachment", BackgroundAttachment },
+ { "background-clip", BackgroundClip },
+ { "background-color", BackgroundColor },
+ { "background-image", BackgroundImage },
+ { "background-origin", BackgroundOrigin },
+ { "background-position", BackgroundPosition },
+ { "background-repeat", BackgroundRepeat },
+ { "border", Border },
+ { "border-bottom", BorderBottom },
+ { "border-bottom-color", BorderBottomColor },
+ { "border-bottom-left-radius", BorderBottomLeftRadius },
+ { "border-bottom-right-radius", BorderBottomRightRadius },
+ { "border-bottom-style", BorderBottomStyle },
+ { "border-bottom-width", BorderBottomWidth },
+ { "border-color", BorderColor },
+ { "border-image", BorderImage },
+ { "border-left", BorderLeft },
+ { "border-left-color", BorderLeftColor },
+ { "border-left-style", BorderLeftStyle },
+ { "border-left-width", BorderLeftWidth },
+ { "border-radius", BorderRadius },
+ { "border-right", BorderRight },
+ { "border-right-color", BorderRightColor },
+ { "border-right-style", BorderRightStyle },
+ { "border-right-width", BorderRightWidth },
+ { "border-style", BorderStyles },
+ { "border-top", BorderTop },
+ { "border-top-color", BorderTopColor },
+ { "border-top-left-radius", BorderTopLeftRadius },
+ { "border-top-right-radius", BorderTopRightRadius },
+ { "border-top-style", BorderTopStyle },
+ { "border-top-width", BorderTopWidth },
+ { "border-width", BorderWidth },
+ { "bottom", Bottom },
+ { "color", Property::Color },
+ { "float", Float },
+ { "font", QCss::Font },
+ { "font-family", FontFamily },
+ { "font-size", FontSize },
+ { "font-style", FontStyle },
+ { "font-variant", FontVariant },
+ { "font-weight", FontWeight },
+ { "height", Height },
+ { "image", QtImage },
+ { "image-position", QtImageAlignment },
+ { "left", Left },
+ { "line-height", LineHeight },
+ { "list-style", ListStyle },
+ { "list-style-type", ListStyleType },
+ { "margin" , Margin },
+ { "margin-bottom", MarginBottom },
+ { "margin-left", MarginLeft },
+ { "margin-right", MarginRight },
+ { "margin-top", MarginTop },
+ { "max-height", MaximumHeight },
+ { "max-width", MaximumWidth },
+ { "min-height", MinimumHeight },
+ { "min-width", MinimumWidth },
+ { "outline", Outline },
+ { "outline-bottom-left-radius", OutlineBottomLeftRadius },
+ { "outline-bottom-right-radius", OutlineBottomRightRadius },
+ { "outline-color", OutlineColor },
+ { "outline-offset", OutlineOffset },
+ { "outline-radius", OutlineRadius },
+ { "outline-style", OutlineStyle },
+ { "outline-top-left-radius", OutlineTopLeftRadius },
+ { "outline-top-right-radius", OutlineTopRightRadius },
+ { "outline-width", OutlineWidth },
+ { "padding", Padding },
+ { "padding-bottom", PaddingBottom },
+ { "padding-left", PaddingLeft },
+ { "padding-right", PaddingRight },
+ { "padding-top", PaddingTop },
+ { "page-break-after", PageBreakAfter },
+ { "page-break-before", PageBreakBefore },
+ { "position", Position },
+ { "right", Right },
+ { "selection-background-color", QtSelectionBackground },
+ { "selection-color", QtSelectionForeground },
+ { "spacing", QtSpacing },
+ { "subcontrol-origin", QtOrigin },
+ { "subcontrol-position", QtPosition },
+ { "text-align", TextAlignment },
+ { "text-decoration", TextDecoration },
+ { "text-indent", TextIndent },
+ { "text-transform", TextTransform },
+ { "text-underline-style", TextUnderlineStyle },
+ { "top", Top },
+ { "vertical-align", VerticalAlignment },
+ { "white-space", Whitespace },
+ { "width", Width }
+};
+
+static const QCssKnownValue values[NumKnownValues - 1] = {
+ { "active", Value_Active },
+ { "alternate-base", Value_AlternateBase },
+ { "always", Value_Always },
+ { "auto", Value_Auto },
+ { "base", Value_Base },
+ { "bold", Value_Bold },
+ { "bottom", Value_Bottom },
+ { "bright-text", Value_BrightText },
+ { "button", Value_Button },
+ { "button-text", Value_ButtonText },
+ { "center", Value_Center },
+ { "circle", Value_Circle },
+ { "dark", Value_Dark },
+ { "dashed", Value_Dashed },
+ { "decimal", Value_Decimal },
+ { "disabled", Value_Disabled },
+ { "disc", Value_Disc },
+ { "dot-dash", Value_DotDash },
+ { "dot-dot-dash", Value_DotDotDash },
+ { "dotted", Value_Dotted },
+ { "double", Value_Double },
+ { "groove", Value_Groove },
+ { "highlight", Value_Highlight },
+ { "highlighted-text", Value_HighlightedText },
+ { "inset", Value_Inset },
+ { "italic", Value_Italic },
+ { "large", Value_Large },
+ { "left", Value_Left },
+ { "light", Value_Light },
+ { "line-through", Value_LineThrough },
+ { "link", Value_Link },
+ { "link-visited", Value_LinkVisited },
+ { "lower-alpha", Value_LowerAlpha },
+ { "lower-roman", Value_LowerRoman },
+ { "lowercase", Value_Lowercase },
+ { "medium", Value_Medium },
+ { "mid", Value_Mid },
+ { "middle", Value_Middle },
+ { "midlight", Value_Midlight },
+ { "native", Value_Native },
+ { "none", Value_None },
+ { "normal", Value_Normal },
+ { "nowrap", Value_NoWrap },
+ { "oblique", Value_Oblique },
+ { "off", Value_Off },
+ { "on", Value_On },
+ { "outset", Value_Outset },
+ { "overline", Value_Overline },
+ { "pre", Value_Pre },
+ { "pre-wrap", Value_PreWrap },
+ { "ridge", Value_Ridge },
+ { "right", Value_Right },
+ { "selected", Value_Selected },
+ { "shadow", Value_Shadow },
+ { "small" , Value_Small },
+ { "small-caps", Value_SmallCaps },
+ { "solid", Value_Solid },
+ { "square", Value_Square },
+ { "sub", Value_Sub },
+ { "super", Value_Super },
+ { "text", Value_Text },
+ { "top", Value_Top },
+ { "transparent", Value_Transparent },
+ { "underline", Value_Underline },
+ { "upper-alpha", Value_UpperAlpha },
+ { "upper-roman", Value_UpperRoman },
+ { "uppercase", Value_Uppercase },
+ { "wave", Value_Wave },
+ { "window", Value_Window },
+ { "window-text", Value_WindowText },
+ { "x-large", Value_XLarge },
+ { "xx-large", Value_XXLarge }
+};
+
+//Map id to strings as they appears in the 'values' array above
+static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 54, 35, 26, 70, 71, 25, 43, 5, 63, 47,
+ 29, 58, 59, 27, 51, 61, 6, 10, 39, 56, 19, 13, 17, 18, 20, 21, 50, 24, 46, 67, 37, 3, 2, 40, 62, 16,
+ 11, 57, 14, 32, 64, 33, 65, 55, 66, 34, 69, 8, 28, 38, 12, 36, 60, 7, 9, 4, 68, 53, 22, 23, 30, 31,
+ 1, 15, 0, 52, 45, 44 };
+
+QString Value::toString() const
+{
+ if (type == KnownIdentifier) {
+ return QLatin1String(values[indexOfId[variant.toInt()]].name);
+ } else {
+ return variant.toString();
+ }
+}
+
+static const QCssKnownValue pseudos[NumPseudos - 1] = {
+ { "active", PseudoClass_Active },
+ { "adjoins-item", PseudoClass_Item },
+ { "alternate", PseudoClass_Alternate },
+ { "bottom", PseudoClass_Bottom },
+ { "checked", PseudoClass_Checked },
+ { "closable", PseudoClass_Closable },
+ { "closed", PseudoClass_Closed },
+ { "default", PseudoClass_Default },
+ { "disabled", PseudoClass_Disabled },
+ { "edit-focus", PseudoClass_EditFocus },
+ { "editable", PseudoClass_Editable },
+ { "enabled", PseudoClass_Enabled },
+ { "exclusive", PseudoClass_Exclusive },
+ { "first", PseudoClass_First },
+ { "flat", PseudoClass_Flat },
+ { "floatable", PseudoClass_Floatable },
+ { "focus", PseudoClass_Focus },
+ { "has-children", PseudoClass_Children },
+ { "has-siblings", PseudoClass_Sibling },
+ { "horizontal", PseudoClass_Horizontal },
+ { "hover", PseudoClass_Hover },
+ { "indeterminate" , PseudoClass_Indeterminate },
+ { "last", PseudoClass_Last },
+ { "left", PseudoClass_Left },
+ { "maximized", PseudoClass_Maximized },
+ { "middle", PseudoClass_Middle },
+ { "minimized", PseudoClass_Minimized },
+ { "movable", PseudoClass_Movable },
+ { "next-selected", PseudoClass_NextSelected },
+ { "no-frame", PseudoClass_Frameless },
+ { "non-exclusive", PseudoClass_NonExclusive },
+ { "off", PseudoClass_Unchecked },
+ { "on", PseudoClass_Checked },
+ { "only-one", PseudoClass_OnlyOne },
+ { "open", PseudoClass_Open },
+ { "pressed", PseudoClass_Pressed },
+ { "previous-selected", PseudoClass_PreviousSelected },
+ { "read-only", PseudoClass_ReadOnly },
+ { "right", PseudoClass_Right },
+ { "selected", PseudoClass_Selected },
+ { "top", PseudoClass_Top },
+ { "unchecked" , PseudoClass_Unchecked },
+ { "vertical", PseudoClass_Vertical },
+ { "window", PseudoClass_Window }
+};
+
+static const QCssKnownValue origins[NumKnownOrigins - 1] = {
+ { "border", Origin_Border },
+ { "content", Origin_Content },
+ { "margin", Origin_Margin }, // not in css
+ { "padding", Origin_Padding }
+};
+
+static const QCssKnownValue repeats[NumKnownRepeats - 1] = {
+ { "no-repeat", Repeat_None },
+ { "repeat-x", Repeat_X },
+ { "repeat-xy", Repeat_XY },
+ { "repeat-y", Repeat_Y }
+};
+
+static const QCssKnownValue tileModes[NumKnownTileModes - 1] = {
+ { "repeat", TileMode_Repeat },
+ { "round", TileMode_Round },
+ { "stretch", TileMode_Stretch },
+};
+
+static const QCssKnownValue positions[NumKnownPositionModes - 1] = {
+ { "absolute", PositionMode_Absolute },
+ { "fixed", PositionMode_Fixed },
+ { "relative", PositionMode_Relative },
+ { "static", PositionMode_Static }
+};
+
+static const QCssKnownValue attachments[NumKnownAttachments - 1] = {
+ { "fixed", Attachment_Fixed },
+ { "scroll", Attachment_Scroll }
+};
+
+static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = {
+ { "background-color", StyleFeature_BackgroundColor },
+ { "background-gradient", StyleFeature_BackgroundGradient },
+ { "none", StyleFeature_None }
+};
+
+#if defined(Q_CC_MSVC) && _MSC_VER < 1600
+Q_STATIC_GLOBAL_OPERATOR bool operator<(const QCssKnownValue &prop1, const QCssKnownValue &prop2)
+{
+ return QString::compare(QString::fromLatin1(prop1.name), QLatin1String(prop2.name), Qt::CaseInsensitive) < 0;
+}
+#endif
+
+Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &name, const QCssKnownValue &prop)
+{
+ return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0;
+}
+
+Q_STATIC_GLOBAL_OPERATOR bool operator<(const QCssKnownValue &prop, const QString &name)
+{
+ return QString::compare(QLatin1String(prop.name), name, Qt::CaseInsensitive) < 0;
+}
+
+static quint64 findKnownValue(const QString &name, const QCssKnownValue *start, int numValues)
+{
+ const QCssKnownValue *end = &start[numValues - 1];
+ const QCssKnownValue *prop = std::lower_bound(start, end, name);
+ if ((prop == end) || (name < *prop))
+ return 0;
+ return prop->id;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Value Extractor
+ValueExtractor::ValueExtractor(const QVector &decls, const QPalette &pal)
+: declarations(decls), adjustment(0), fontExtracted(false), pal(pal)
+{
+}
+
+LengthData ValueExtractor::lengthValue(const Value& v)
+{
+ QString s = v.variant.toString();
+ s.reserve(s.length());
+ LengthData data;
+ data.unit = LengthData::NONE;
+ if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive))
+ data.unit = LengthData::Px;
+ else if (s.endsWith(QLatin1String("ex"), Qt::CaseInsensitive))
+ data.unit = LengthData::Ex;
+ else if (s.endsWith(QLatin1String("em"), Qt::CaseInsensitive))
+ data.unit = LengthData::Em;
+
+ if (data.unit != LengthData::NONE)
+ s.chop(2);
+
+ data.number = s.toDouble();
+ return data;
+}
+
+static int lengthValueFromData(const LengthData& data, const QFont& f)
+{
+ if (data.unit == LengthData::Ex)
+ return qRound(QFontMetrics(f).xHeight() * data.number);
+ else if (data.unit == LengthData::Em)
+ return qRound(QFontMetrics(f).height() * data.number);
+ return qRound(data.number);
+}
+
+int ValueExtractor::lengthValue(const Declaration &decl)
+{
+ if (decl.d->parsed.isValid())
+ return lengthValueFromData(qvariant_cast(decl.d->parsed), f);
+ if (decl.d->values.count() < 1)
+ return 0;
+ LengthData data = lengthValue(decl.d->values.at(0));
+ decl.d->parsed = QVariant::fromValue(data);
+ return lengthValueFromData(data,f);
+}
+
+void ValueExtractor::lengthValues(const Declaration &decl, int *m)
+{
+ if (decl.d->parsed.isValid()) {
+ QList v = decl.d->parsed.toList();
+ for (int i = 0; i < 4; i++)
+ m[i] = lengthValueFromData(qvariant_cast(v.at(i)), f);
+ return;
+ }
+
+ LengthData datas[4];
+ int i;
+ for (i = 0; i < qMin(decl.d->values.count(), 4); i++)
+ datas[i] = lengthValue(decl.d->values[i]);
+
+ if (i == 0) {
+ LengthData zero = {0.0, LengthData::NONE};
+ datas[0] = datas[1] = datas[2] = datas[3] = zero;
+ } else if (i == 1) {
+ datas[3] = datas[2] = datas[1] = datas[0];
+ } else if (i == 2) {
+ datas[2] = datas[0];
+ datas[3] = datas[1];
+ } else if (i == 3) {
+ datas[3] = datas[1];
+ }
+
+ QList v;
+ for (i = 0; i < 4; i++) {
+ v += QVariant::fromValue(datas[i]);
+ m[i] = lengthValueFromData(datas[i], f);
+ }
+ decl.d->parsed = v;
+}
+
+bool ValueExtractor::extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh)
+{
+ extractFont();
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case Width: *w = lengthValue(decl); break;
+ case Height: *h = lengthValue(decl); break;
+ case MinimumWidth: *minw = lengthValue(decl); break;
+ case MinimumHeight: *minh = lengthValue(decl); break;
+ case MaximumWidth: *maxw = lengthValue(decl); break;
+ case MaximumHeight: *maxh = lengthValue(decl); break;
+ default: continue;
+ }
+ hit = true;
+ }
+
+ return hit;
+}
+
+bool ValueExtractor::extractPosition(int *left, int *top, int *right, int *bottom, QCss::Origin *origin,
+ Qt::Alignment *position, QCss::PositionMode *mode, Qt::Alignment *textAlignment)
+{
+ extractFont();
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case Left: *left = lengthValue(decl); break;
+ case Top: *top = lengthValue(decl); break;
+ case Right: *right = lengthValue(decl); break;
+ case Bottom: *bottom = lengthValue(decl); break;
+ case QtOrigin: *origin = decl.originValue(); break;
+ case QtPosition: *position = decl.alignmentValue(); break;
+ case TextAlignment: *textAlignment = decl.alignmentValue(); break;
+ case Position: *mode = decl.positionValue(); break;
+ default: continue;
+ }
+ hit = true;
+ }
+
+ return hit;
+}
+
+bool ValueExtractor::extractBox(int *margins, int *paddings, int *spacing)
+{
+ extractFont();
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case PaddingLeft: paddings[LeftEdge] = lengthValue(decl); break;
+ case PaddingRight: paddings[RightEdge] = lengthValue(decl); break;
+ case PaddingTop: paddings[TopEdge] = lengthValue(decl); break;
+ case PaddingBottom: paddings[BottomEdge] = lengthValue(decl); break;
+ case Padding: lengthValues(decl, paddings); break;
+
+ case MarginLeft: margins[LeftEdge] = lengthValue(decl); break;
+ case MarginRight: margins[RightEdge] = lengthValue(decl); break;
+ case MarginTop: margins[TopEdge] = lengthValue(decl); break;
+ case MarginBottom: margins[BottomEdge] = lengthValue(decl); break;
+ case Margin: lengthValues(decl, margins); break;
+ case QtSpacing: if (spacing) *spacing = lengthValue(decl); break;
+
+ default: continue;
+ }
+ hit = true;
+ }
+
+ return hit;
+}
+
+int ValueExtractor::extractStyleFeatures()
+{
+ int features = StyleFeature_None;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ if (decl.d->propertyId == QtStyleFeatures)
+ features = decl.styleFeaturesValue();
+ }
+ return features;
+}
+
+QSize ValueExtractor::sizeValue(const Declaration &decl)
+{
+ if (decl.d->parsed.isValid()) {
+ QList v = decl.d->parsed.toList();
+ return QSize(lengthValueFromData(qvariant_cast(v.at(0)), f),
+ lengthValueFromData(qvariant_cast(v.at(1)), f));
+ }
+
+ LengthData x[2] = { {0, LengthData::NONE }, {0, LengthData::NONE} };
+ if (decl.d->values.count() > 0)
+ x[0] = lengthValue(decl.d->values.at(0));
+ if (decl.d->values.count() > 1)
+ x[1] = lengthValue(decl.d->values.at(1));
+ else
+ x[1] = x[0];
+ QList v;
+ v << QVariant::fromValue(x[0]) << QVariant::fromValue(x[1]);
+ decl.d->parsed = v;
+ return QSize(lengthValueFromData(x[0], f), lengthValueFromData(x[1], f));
+}
+
+void ValueExtractor::sizeValues(const Declaration &decl, QSize *radii)
+{
+ radii[0] = sizeValue(decl);
+ for (int i = 1; i < 4; i++)
+ radii[i] = radii[0];
+}
+
+bool ValueExtractor::extractBorder(int *borders, QBrush *colors, BorderStyle *styles,
+ QSize *radii)
+{
+ extractFont();
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case BorderLeftWidth: borders[LeftEdge] = lengthValue(decl); break;
+ case BorderRightWidth: borders[RightEdge] = lengthValue(decl); break;
+ case BorderTopWidth: borders[TopEdge] = lengthValue(decl); break;
+ case BorderBottomWidth: borders[BottomEdge] = lengthValue(decl); break;
+ case BorderWidth: lengthValues(decl, borders); break;
+
+ case BorderLeftColor: colors[LeftEdge] = decl.brushValue(pal); break;
+ case BorderRightColor: colors[RightEdge] = decl.brushValue(pal); break;
+ case BorderTopColor: colors[TopEdge] = decl.brushValue(pal); break;
+ case BorderBottomColor: colors[BottomEdge] = decl.brushValue(pal); break;
+ case BorderColor: decl.brushValues(colors, pal); break;
+
+ case BorderTopStyle: styles[TopEdge] = decl.styleValue(); break;
+ case BorderBottomStyle: styles[BottomEdge] = decl.styleValue(); break;
+ case BorderLeftStyle: styles[LeftEdge] = decl.styleValue(); break;
+ case BorderRightStyle: styles[RightEdge] = decl.styleValue(); break;
+ case BorderStyles: decl.styleValues(styles); break;
+
+#ifndef QT_OS_ANDROID_GCC_48_WORKAROUND
+ case BorderTopLeftRadius: radii[0] = sizeValue(decl); break;
+#else
+ case BorderTopLeftRadius: new(radii)QSize(sizeValue(decl)); break;
+#endif
+ case BorderTopRightRadius: radii[1] = sizeValue(decl); break;
+ case BorderBottomLeftRadius: radii[2] = sizeValue(decl); break;
+ case BorderBottomRightRadius: radii[3] = sizeValue(decl); break;
+ case BorderRadius: sizeValues(decl, radii); break;
+
+ case BorderLeft:
+ borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
+ break;
+ case BorderTop:
+ borderValue(decl, &borders[TopEdge], &styles[TopEdge], &colors[TopEdge]);
+ break;
+ case BorderRight:
+ borderValue(decl, &borders[RightEdge], &styles[RightEdge], &colors[RightEdge]);
+ break;
+ case BorderBottom:
+ borderValue(decl, &borders[BottomEdge], &styles[BottomEdge], &colors[BottomEdge]);
+ break;
+ case Border:
+ borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
+ borders[TopEdge] = borders[RightEdge] = borders[BottomEdge] = borders[LeftEdge];
+ styles[TopEdge] = styles[RightEdge] = styles[BottomEdge] = styles[LeftEdge];
+ colors[TopEdge] = colors[RightEdge] = colors[BottomEdge] = colors[LeftEdge];
+ break;
+
+ default: continue;
+ }
+ hit = true;
+ }
+
+ return hit;
+}
+
+bool ValueExtractor::extractOutline(int *borders, QBrush *colors, BorderStyle *styles,
+ QSize *radii, int *offsets)
+{
+ extractFont();
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); i++) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case OutlineWidth: lengthValues(decl, borders); break;
+ case OutlineColor: decl.brushValues(colors, pal); break;
+ case OutlineStyle: decl.styleValues(styles); break;
+
+ case OutlineTopLeftRadius: radii[0] = sizeValue(decl); break;
+ case OutlineTopRightRadius: radii[1] = sizeValue(decl); break;
+ case OutlineBottomLeftRadius: radii[2] = sizeValue(decl); break;
+ case OutlineBottomRightRadius: radii[3] = sizeValue(decl); break;
+ case OutlineRadius: sizeValues(decl, radii); break;
+ case OutlineOffset: lengthValues(decl, offsets); break;
+
+ case Outline:
+ borderValue(decl, &borders[LeftEdge], &styles[LeftEdge], &colors[LeftEdge]);
+ borders[TopEdge] = borders[RightEdge] = borders[BottomEdge] = borders[LeftEdge];
+ styles[TopEdge] = styles[RightEdge] = styles[BottomEdge] = styles[LeftEdge];
+ colors[TopEdge] = colors[RightEdge] = colors[BottomEdge] = colors[LeftEdge];
+ break;
+
+ default: continue;
+ }
+ hit = true;
+ }
+
+ return hit;
+}
+
+static Qt::Alignment parseAlignment(const QCss::Value *values, int count)
+{
+ Qt::Alignment a[2] = { 0, 0 };
+ for (int i = 0; i < qMin(2, count); i++) {
+ if (values[i].type != Value::KnownIdentifier)
+ break;
+ switch (values[i].variant.toInt()) {
+ case Value_Left: a[i] = Qt::AlignLeft; break;
+ case Value_Right: a[i] = Qt::AlignRight; break;
+ case Value_Top: a[i] = Qt::AlignTop; break;
+ case Value_Bottom: a[i] = Qt::AlignBottom; break;
+ case Value_Center: a[i] = Qt::AlignCenter; break;
+ default: break;
+ }
+ }
+
+ if (a[0] == Qt::AlignCenter && a[1] != 0 && a[1] != Qt::AlignCenter)
+ a[0] = (a[1] == Qt::AlignLeft || a[1] == Qt::AlignRight) ? Qt::AlignVCenter : Qt::AlignHCenter;
+ if ((a[1] == 0 || a[1] == Qt::AlignCenter) && a[0] != Qt::AlignCenter)
+ a[1] = (a[0] == Qt::AlignLeft || a[0] == Qt::AlignRight) ? Qt::AlignVCenter : Qt::AlignHCenter;
+ return a[0] | a[1];
+}
+
+static ColorData parseColorValue(QCss::Value v)
+{
+ if (v.type == Value::Identifier || v.type == Value::String) {
+ v.variant.convert(QVariant::Color);
+ v.type = Value::Color;
+ }
+
+ if (v.type == Value::Color)
+ return qvariant_cast(v.variant);
+
+ if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_Transparent)
+ return QColor(Qt::transparent);
+
+ if (v.type != Value::Function)
+ return ColorData();
+
+ QStringList lst = v.variant.toStringList();
+ if (lst.count() != 2)
+ return ColorData();
+
+ if ((lst.at(0).compare(QLatin1String("palette"), Qt::CaseInsensitive)) == 0) {
+ int role = findKnownValue(lst.at(1).trimmed(), values, NumKnownValues);
+ if (role >= Value_FirstColorRole && role <= Value_LastColorRole)
+ return (QPalette::ColorRole)(role-Value_FirstColorRole);
+
+ return ColorData();
+ }
+
+ bool rgb = lst.at(0).startsWith(QLatin1String("rgb"));
+ bool rgba = lst.at(0).startsWith(QLatin1String("rgba"));
+
+ Parser p(lst.at(1));
+ if (!p.testExpr())
+ return ColorData();
+
+ QVector colorDigits;
+ if (!p.parseExpr(&colorDigits))
+ return ColorData();
+
+ for (int i = 0; i < qMin(colorDigits.count(), 7); i += 2) {
+ if (colorDigits.at(i).type == Value::Percentage) {
+ colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (255. / 100.);
+ colorDigits[i].type = Value::Number;
+ } else if (colorDigits.at(i).type != Value::Number) {
+ return ColorData();
+ }
+ }
+
+ int v1 = colorDigits.at(0).variant.toInt();
+ int v2 = colorDigits.at(2).variant.toInt();
+ int v3 = colorDigits.at(4).variant.toInt();
+ int alpha = 255;
+ if (colorDigits.count() >= 7) {
+ int alphaValue = colorDigits.at(6).variant.toInt();
+ if (rgba && alphaValue <= 1)
+ alpha = colorDigits.at(6).variant.toReal() * 255.;
+ else
+ alpha = alphaValue;
+ }
+
+ return rgb ? QColor::fromRgb(v1, v2, v3, alpha)
+ : QColor::fromHsv(v1, v2, v3, alpha);
+}
+
+static QColor colorFromData(const ColorData& c, const QPalette &pal)
+{
+ if (c.type == ColorData::Color) {
+ return c.color;
+ } else if (c.type == ColorData::Role) {
+ return pal.color(c.role);
+ }
+ return QColor();
+}
+
+static BrushData parseBrushValue(const QCss::Value &v, const QPalette &pal)
+{
+ ColorData c = parseColorValue(v);
+ if (c.type == ColorData::Color) {
+ return QBrush(c.color);
+ } else if (c.type == ColorData::Role) {
+ return c.role;
+ }
+
+ if (v.type != Value::Function)
+ return BrushData();
+
+ QStringList lst = v.variant.toStringList();
+ if (lst.count() != 2)
+ return BrushData();
+
+ QStringList gradFuncs;
+ gradFuncs << QLatin1String("qlineargradient") << QLatin1String("qradialgradient") << QLatin1String("qconicalgradient") << QLatin1String("qgradient");
+ int gradType = -1;
+
+ if ((gradType = gradFuncs.indexOf(lst.at(0).toLower())) == -1)
+ return BrushData();
+
+ QHash vars;
+ QVector stops;
+
+ int spread = -1;
+ QStringList spreads;
+ spreads << QLatin1String("pad") << QLatin1String("reflect") << QLatin1String("repeat");
+
+ bool dependsOnThePalette = false;
+ Parser parser(lst.at(1));
+ while (parser.hasNext()) {
+ parser.skipSpace();
+ if (!parser.test(IDENT))
+ return BrushData();
+ QString attr = parser.lexem();
+ parser.skipSpace();
+ if (!parser.test(COLON))
+ return BrushData();
+ parser.skipSpace();
+ if (attr.compare(QLatin1String("stop"), Qt::CaseInsensitive) == 0) {
+ QCss::Value stop, color;
+ parser.next();
+ if (!parser.parseTerm(&stop)) return BrushData();
+ parser.skipSpace();
+ parser.next();
+ if (!parser.parseTerm(&color)) return BrushData();
+ ColorData cd = parseColorValue(color);
+ if(cd.type == ColorData::Role)
+ dependsOnThePalette = true;
+ stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal)));
+ } else {
+ parser.next();
+ QCss::Value value;
+ (void)parser.parseTerm(&value);
+ if (attr.compare(QLatin1String("spread"), Qt::CaseInsensitive) == 0) {
+ spread = spreads.indexOf(value.variant.toString());
+ } else {
+ vars[attr] = value.variant.toReal();
+ }
+ }
+ parser.skipSpace();
+ (void)parser.test(COMMA);
+ }
+
+ if (gradType == 0) {
+ QLinearGradient lg(vars.value(QLatin1String("x1")), vars.value(QLatin1String("y1")),
+ vars.value(QLatin1String("x2")), vars.value(QLatin1String("y2")));
+ lg.setCoordinateMode(QGradient::ObjectBoundingMode);
+ lg.setStops(stops);
+ if (spread != -1)
+ lg.setSpread(QGradient::Spread(spread));
+ BrushData bd = QBrush(lg);
+ if (dependsOnThePalette)
+ bd.type = BrushData::DependsOnThePalette;
+ return bd;
+ }
+
+ if (gradType == 1) {
+ QRadialGradient rg(vars.value(QLatin1String("cx")), vars.value(QLatin1String("cy")),
+ vars.value(QLatin1String("radius")), vars.value(QLatin1String("fx")),
+ vars.value(QLatin1String("fy")));
+ rg.setCoordinateMode(QGradient::ObjectBoundingMode);
+ rg.setStops(stops);
+ if (spread != -1)
+ rg.setSpread(QGradient::Spread(spread));
+ BrushData bd = QBrush(rg);
+ if (dependsOnThePalette)
+ bd.type = BrushData::DependsOnThePalette;
+ return bd;
+ }
+
+ if (gradType == 2) {
+ QConicalGradient cg(vars.value(QLatin1String("cx")), vars.value(QLatin1String("cy")),
+ vars.value(QLatin1String("angle")));
+ cg.setCoordinateMode(QGradient::ObjectBoundingMode);
+ cg.setStops(stops);
+ if (spread != -1)
+ cg.setSpread(QGradient::Spread(spread));
+ BrushData bd = QBrush(cg);
+ if (dependsOnThePalette)
+ bd.type = BrushData::DependsOnThePalette;
+ return bd;
+ }
+
+ return BrushData();
+}
+
+static QBrush brushFromData(const BrushData& c, const QPalette &pal)
+{
+ if (c.type == BrushData::Role) {
+ return pal.color(c.role);
+ } else {
+ return c.brush;
+ }
+}
+
+static BorderStyle parseStyleValue(QCss::Value v)
+{
+ if (v.type == Value::KnownIdentifier) {
+ switch (v.variant.toInt()) {
+ case Value_None:
+ return BorderStyle_None;
+ case Value_Dotted:
+ return BorderStyle_Dotted;
+ case Value_Dashed:
+ return BorderStyle_Dashed;
+ case Value_Solid:
+ return BorderStyle_Solid;
+ case Value_Double:
+ return BorderStyle_Double;
+ case Value_DotDash:
+ return BorderStyle_DotDash;
+ case Value_DotDotDash:
+ return BorderStyle_DotDotDash;
+ case Value_Groove:
+ return BorderStyle_Groove;
+ case Value_Ridge:
+ return BorderStyle_Ridge;
+ case Value_Inset:
+ return BorderStyle_Inset;
+ case Value_Outset:
+ return BorderStyle_Outset;
+ case Value_Native:
+ return BorderStyle_Native;
+ default:
+ break;
+ }
+ }
+
+ return BorderStyle_Unknown;
+}
+
+void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::BorderStyle *style, QBrush *color)
+{
+ if (decl.d->parsed.isValid()) {
+ BorderData data = qvariant_cast(decl.d->parsed);
+ *width = lengthValueFromData(data.width, f);
+ *style = data.style;
+ *color = data.color.type != BrushData::Invalid ? brushFromData(data.color, pal) : QBrush(QColor());
+ return;
+ }
+
+ *width = 0;
+ *style = BorderStyle_None;
+ *color = QColor();
+
+ if (decl.d->values.isEmpty())
+ return;
+
+ BorderData data;
+ data.width.number = 0;
+ data.width.unit = LengthData::NONE;
+ data.style = BorderStyle_None;
+
+ int i = 0;
+ if (decl.d->values.at(i).type == Value::Length || decl.d->values.at(i).type == Value::Number) {
+ data.width = lengthValue(decl.d->values.at(i));
+ *width = lengthValueFromData(data.width, f);
+ if (++i >= decl.d->values.count()) {
+ decl.d->parsed = QVariant::fromValue(data);
+ return;
+ }
+ }
+
+ data.style = parseStyleValue(decl.d->values.at(i));
+ if (data.style != BorderStyle_Unknown) {
+ *style = data.style;
+ if (++i >= decl.d->values.count()) {
+ decl.d->parsed = QVariant::fromValue(data);
+ return;
+ }
+ } else {
+ data.style = BorderStyle_None;
+ }
+
+ data.color = parseBrushValue(decl.d->values.at(i), pal);
+ *color = brushFromData(data.color, pal);
+ if (data.color.type != BrushData::DependsOnThePalette)
+ decl.d->parsed = QVariant::fromValue(data);
+}
+
+static void parseShorthandBackgroundProperty(const QVector &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal)
+{
+ *brush = BrushData();
+ *image = QString();
+ *repeat = Repeat_XY;
+ *alignment = Qt::AlignTop | Qt::AlignLeft;
+
+ for (int i = 0; i < values.count(); ++i) {
+ const QCss::Value &v = values.at(i);
+ if (v.type == Value::Uri) {
+ *image = v.variant.toString();
+ continue;
+ } else if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_None) {
+ *image = QString();
+ continue;
+ } else if (v.type == Value::KnownIdentifier && v.variant.toInt() == Value_Transparent) {
+ *brush = QBrush(Qt::transparent);
+ }
+
+ Repeat repeatAttempt = static_cast(findKnownValue(v.variant.toString(),
+ repeats, NumKnownRepeats));
+ if (repeatAttempt != Repeat_Unknown) {
+ *repeat = repeatAttempt;
+ continue;
+ }
+
+ if (v.type == Value::KnownIdentifier) {
+ const int start = i;
+ int count = 1;
+ if (i < values.count() - 1
+ && values.at(i + 1).type == Value::KnownIdentifier) {
+ ++i;
+ ++count;
+ }
+ Qt::Alignment a = parseAlignment(values.constData() + start, count);
+ if (int(a) != 0) {
+ *alignment = a;
+ continue;
+ }
+ i -= count - 1;
+ }
+
+ *brush = parseBrushValue(v, pal);
+ }
+}
+
+bool ValueExtractor::extractBackground(QBrush *brush, QString *image, Repeat *repeat,
+ Qt::Alignment *alignment, Origin *origin, Attachment *attachment,
+ Origin *clip)
+{
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); ++i) {
+ const Declaration &decl = declarations.at(i);
+ if (decl.d->values.isEmpty())
+ continue;
+ const QCss::Value &val = decl.d->values.at(0);
+ switch (decl.d->propertyId) {
+ case BackgroundColor:
+ *brush = decl.brushValue();
+ break;
+ case BackgroundImage:
+ if (val.type == Value::Uri)
+ *image = val.variant.toString();
+ break;
+ case BackgroundRepeat:
+ if (decl.d->parsed.isValid()) {
+ *repeat = static_cast(decl.d->parsed.toInt());
+ } else {
+ *repeat = static_cast(findKnownValue(val.variant.toString(),
+ repeats, NumKnownRepeats));
+ decl.d->parsed = *repeat;
+ }
+ break;
+ case BackgroundPosition:
+ *alignment = decl.alignmentValue();
+ break;
+ case BackgroundOrigin:
+ *origin = decl.originValue();
+ break;
+ case BackgroundClip:
+ *clip = decl.originValue();
+ break;
+ case Background:
+ if (decl.d->parsed.isValid()) {
+ BackgroundData data = qvariant_cast(decl.d->parsed);
+ *brush = brushFromData(data.brush, pal);
+ *image = data.image;
+ *repeat = data.repeat;
+ *alignment = data.alignment;
+ } else {
+ BrushData brushData;
+ parseShorthandBackgroundProperty(decl.d->values, &brushData, image, repeat, alignment, pal);
+ *brush = brushFromData(brushData, pal);
+ if (brushData.type != BrushData::DependsOnThePalette) {
+ BackgroundData data = { brushData, *image, *repeat, *alignment };
+ decl.d->parsed = QVariant::fromValue(data);
+ }
+ }
+ break;
+ case BackgroundAttachment:
+ *attachment = decl.attachmentValue();
+ break;
+ default: continue;
+ }
+ hit = true;
+ }
+ return hit;
+}
+
+static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAdjustment)
+{
+ if (value.type == Value::KnownIdentifier) {
+ bool valid = true;
+ switch (value.variant.toInt()) {
+ case Value_Small: *fontSizeAdjustment = -1; break;
+ case Value_Medium: *fontSizeAdjustment = 0; break;
+ case Value_Large: *fontSizeAdjustment = 1; break;
+ case Value_XLarge: *fontSizeAdjustment = 2; break;
+ case Value_XXLarge: *fontSizeAdjustment = 3; break;
+ default: valid = false; break;
+ }
+ return valid;
+ }
+ if (value.type != Value::Length)
+ return false;
+
+ bool valid = false;
+ QString s = value.variant.toString();
+ if (s.endsWith(QLatin1String("pt"), Qt::CaseInsensitive)) {
+ s.chop(2);
+ value.variant = s;
+ if (value.variant.convert((QVariant::Type)qMetaTypeId())) {
+ font->setPointSizeF(value.variant.toReal());
+ valid = true;
+ }
+ } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) {
+ s.chop(2);
+ value.variant = s;
+ if (value.variant.convert(QVariant::Int)) {
+ font->setPixelSize(value.variant.toInt());
+ valid = true;
+ }
+ }
+ return valid;
+}
+
+static bool setFontStyleFromValue(const QCss::Value &value, QFont *font)
+{
+ if (value.type != Value::KnownIdentifier)
+ return false ;
+ switch (value.variant.toInt()) {
+ case Value_Normal: font->setStyle(QFont::StyleNormal); return true;
+ case Value_Italic: font->setStyle(QFont::StyleItalic); return true;
+ case Value_Oblique: font->setStyle(QFont::StyleOblique); return true;
+ default: break;
+ }
+ return false;
+}
+
+static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
+{
+ if (value.type == Value::KnownIdentifier) {
+ switch (value.variant.toInt()) {
+ case Value_Normal: font->setWeight(QFont::Normal); return true;
+ case Value_Bold: font->setWeight(QFont::Bold); return true;
+ default: break;
+ }
+ return false;
+ }
+ if (value.type != Value::Number)
+ return false;
+ font->setWeight(qMin(value.variant.toInt() / 8, 99));
+ return true;
+}
+
+/** \internal
+ * parse the font family from the values (starting from index \a start)
+ * and set it the \a font
+ * The function returns \c true if a family was extracted.
+ */
+static bool setFontFamilyFromValues(const QVector &values, QFont *font, int start = 0)
+{
+ QString family;
+ bool shouldAddSpace = false;
+ for (int i = start; i < values.count(); ++i) {
+ const QCss::Value &v = values.at(i);
+ if (v.type == Value::TermOperatorComma) {
+ family += QLatin1Char(',');
+ shouldAddSpace = false;
+ continue;
+ }
+ const QString str = v.variant.toString();
+ if (str.isEmpty())
+ break;
+ if (shouldAddSpace)
+ family += QLatin1Char(' ');
+ family += str;
+ shouldAddSpace = true;
+ }
+ if (family.isEmpty())
+ return false;
+ font->setFamily(family);
+ return true;
+}
+
+static void setTextDecorationFromValues(const QVector &values, QFont *font)
+{
+ for (int i = 0; i < values.count(); ++i) {
+ if (values.at(i).type != Value::KnownIdentifier)
+ continue;
+ switch (values.at(i).variant.toInt()) {
+ case Value_Underline: font->setUnderline(true); break;
+ case Value_Overline: font->setOverline(true); break;
+ case Value_LineThrough: font->setStrikeOut(true); break;
+ case Value_None:
+ font->setUnderline(false);
+ font->setOverline(false);
+ font->setStrikeOut(false);
+ break;
+ default: break;
+ }
+ }
+}
+
+static void parseShorthandFontProperty(const QVector &values, QFont *font, int *fontSizeAdjustment)
+{
+ font->setStyle(QFont::StyleNormal);
+ font->setWeight(QFont::Normal);
+ *fontSizeAdjustment = -255;
+
+ int i = 0;
+ while (i < values.count()) {
+ if (setFontStyleFromValue(values.at(i), font)
+ || setFontWeightFromValue(values.at(i), font))
+ ++i;
+ else
+ break;
+ }
+
+ if (i < values.count()) {
+ setFontSizeFromValue(values.at(i), font, fontSizeAdjustment);
+ ++i;
+ }
+
+ if (i < values.count()) {
+ setFontFamilyFromValues(values, font, i);
+ }
+}
+
+static void setFontVariantFromValue(const QCss::Value &value, QFont *font)
+{
+ if (value.type == Value::KnownIdentifier) {
+ switch (value.variant.toInt()) {
+ case Value_Normal: font->setCapitalization(QFont::MixedCase); break;
+ case Value_SmallCaps: font->setCapitalization(QFont::SmallCaps); break;
+ default: break;
+ }
+ }
+}
+
+static void setTextTransformFromValue(const QCss::Value &value, QFont *font)
+{
+ if (value.type == Value::KnownIdentifier) {
+ switch (value.variant.toInt()) {
+ case Value_None: font->setCapitalization(QFont::MixedCase); break;
+ case Value_Uppercase: font->setCapitalization(QFont::AllUppercase); break;
+ case Value_Lowercase: font->setCapitalization(QFont::AllLowercase); break;
+ default: break;
+ }
+ }
+}
+
+bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment)
+{
+ if (fontExtracted) {
+ *font = f;
+ *fontSizeAdjustment = adjustment;
+ return fontExtracted == 1;
+ }
+
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); ++i) {
+ const Declaration &decl = declarations.at(i);
+ if (decl.d->values.isEmpty())
+ continue;
+ const QCss::Value &val = decl.d->values.at(0);
+ switch (decl.d->propertyId) {
+ case FontSize: setFontSizeFromValue(val, font, fontSizeAdjustment); break;
+ case FontStyle: setFontStyleFromValue(val, font); break;
+ case FontWeight: setFontWeightFromValue(val, font); break;
+ case FontFamily: setFontFamilyFromValues(decl.d->values, font); break;
+ case TextDecoration: setTextDecorationFromValues(decl.d->values, font); break;
+ case Font: parseShorthandFontProperty(decl.d->values, font, fontSizeAdjustment); break;
+ case FontVariant: setFontVariantFromValue(val, font); break;
+ case TextTransform: setTextTransformFromValue(val, font); break;
+ default: continue;
+ }
+ hit = true;
+ }
+
+ f = *font;
+ adjustment = *fontSizeAdjustment;
+ fontExtracted = hit ? 1 : 2;
+ return hit;
+}
+
+bool ValueExtractor::extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg)
+{
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); ++i) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case Color: *fg = decl.brushValue(pal); break;
+ case QtSelectionForeground: *sfg = decl.brushValue(pal); break;
+ case QtSelectionBackground: *sbg = decl.brushValue(pal); break;
+ case QtAlternateBackground: *abg = decl.brushValue(pal); break;
+ default: continue;
+ }
+ hit = true;
+ }
+ return hit;
+}
+
+void ValueExtractor::extractFont()
+{
+ if (fontExtracted)
+ return;
+ int dummy = -255;
+ extractFont(&f, &dummy);
+}
+
+bool ValueExtractor::extractImage(QIcon *icon, Qt::Alignment *a, QSize *size)
+{
+ bool hit = false;
+ for (int i = 0; i < declarations.count(); ++i) {
+ const Declaration &decl = declarations.at(i);
+ switch (decl.d->propertyId) {
+ case QtImage:
+ *icon = decl.iconValue();
+ if (decl.d->values.count() > 0 && decl.d->values.at(0).type == Value::Uri) {
+ // try to pull just the size from the image...
+ QImageReader imageReader(decl.d->values.at(0).variant.toString());
+ if ((*size = imageReader.size()).isNull()) {
+ // but we'll have to load the whole image if the
+ // format doesn't support just reading the size
+ *size = imageReader.read().size();
+ }
+ }
+ break;
+ case QtImageAlignment: *a = decl.alignmentValue(); break;
+ default: continue;
+ }
+ hit = true;
+ }
+ return hit;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Declaration
+QColor Declaration::colorValue(const QPalette &pal) const
+{
+ if (d->values.count() != 1)
+ return QColor();
+
+ if (d->parsed.isValid()) {
+ if (d->parsed.type() == QVariant::Color)
+ return qvariant_cast(d->parsed);
+ if (d->parsed.type() == QVariant::Int)
+ return pal.color((QPalette::ColorRole)(d->parsed.toInt()));
+ }
+
+ ColorData color = parseColorValue(d->values.at(0));
+ if(color.type == ColorData::Role) {
+ d->parsed = QVariant::fromValue(color.role);
+ return pal.color((QPalette::ColorRole)(color.role));
+ } else {
+ d->parsed = QVariant::fromValue(color.color);
+ return color.color;
+ }
+}
+
+QBrush Declaration::brushValue(const QPalette &pal) const
+{
+ if (d->values.count() != 1)
+ return QBrush();
+
+ if (d->parsed.isValid()) {
+ if (d->parsed.type() == QVariant::Brush)
+ return qvariant_cast(d->parsed);
+ if (d->parsed.type() == QVariant::Int)
+ return pal.color((QPalette::ColorRole)(d->parsed.toInt()));
+ }
+
+ BrushData data = parseBrushValue(d->values.at(0), pal);
+
+ if(data.type == BrushData::Role) {
+ d->parsed = QVariant::fromValue(data.role);
+ return pal.color((QPalette::ColorRole)(data.role));
+ } else {
+ if (data.type != BrushData::DependsOnThePalette)
+ d->parsed = QVariant::fromValue(data.brush);
+ return data.brush;
+ }
+}
+
+void Declaration::brushValues(QBrush *c, const QPalette &pal) const
+{
+ int needParse = 0x1f; // bits 0..3 say if we should parse the corresponding value.
+ // the bit 4 say we need to update d->parsed
+ int i = 0;
+ if (d->parsed.isValid()) {
+ needParse = 0;
+ QList v = d->parsed.toList();
+ for (i = 0; i < qMin(v.count(), 4); i++) {
+ if (v.at(i).type() == QVariant::Brush) {
+ c[i] = qvariant_cast(v.at(i));
+ } else if (v.at(i).type() == QVariant::Int) {
+ c[i] = pal.color((QPalette::ColorRole)(v.at(i).toInt()));
+ } else {
+ needParse |= (1< v;
+ for (i = 0; i < qMin(d->values.count(), 4); i++) {
+ if (!(needParse & (1<values.at(i), pal);
+ if(data.type == BrushData::Role) {
+ v += QVariant::fromValue(data.role);
+ c[i] = pal.color((QPalette::ColorRole)(data.role));
+ } else {
+ if (data.type != BrushData::DependsOnThePalette) {
+ v += QVariant::fromValue(data.brush);
+ } else {
+ v += QVariant();
+ }
+ c[i] = data.brush;
+ }
+ }
+ if (needParse & 0x10)
+ d->parsed = v;
+ }
+ if (i == 0) c[0] = c[1] = c[2] = c[3] = QBrush();
+ else if (i == 1) c[3] = c[2] = c[1] = c[0];
+ else if (i == 2) c[2] = c[0], c[3] = c[1];
+ else if (i == 3) c[3] = c[1];
+}
+
+bool Declaration::realValue(qreal *real, const char *unit) const
+{
+ if (d->values.count() != 1)
+ return false;
+ const Value &v = d->values.at(0);
+ if (unit && v.type != Value::Length)
+ return false;
+ QString s = v.variant.toString();
+ if (unit) {
+ if (!s.endsWith(QLatin1String(unit), Qt::CaseInsensitive))
+ return false;
+ s.chop(qstrlen(unit));
+ }
+ bool ok = false;
+ qreal val = s.toDouble(&ok);
+ if (ok)
+ *real = val;
+ return ok;
+}
+
+static bool intValueHelper(const QCss::Value &v, int *i, const char *unit)
+{
+ if (unit && v.type != Value::Length)
+ return false;
+ QString s = v.variant.toString();
+ if (unit) {
+ if (!s.endsWith(QLatin1String(unit), Qt::CaseInsensitive))
+ return false;
+ s.chop(qstrlen(unit));
+ }
+ bool ok = false;
+ int val = s.toInt(&ok);
+ if (ok)
+ *i = val;
+ return ok;
+}
+
+bool Declaration::intValue(int *i, const char *unit) const
+{
+ if (d->values.count() != 1)
+ return false;
+ return intValueHelper(d->values.at(0), i, unit);
+}
+
+QSize Declaration::sizeValue() const
+{
+ if (d->parsed.isValid())
+ return qvariant_cast(d->parsed);
+
+ int x[2] = { 0, 0 };
+ if (d->values.count() > 0)
+ intValueHelper(d->values.at(0), &x[0], "px");
+ if (d->values.count() > 1)
+ intValueHelper(d->values.at(1), &x[1], "px");
+ else
+ x[1] = x[0];
+ QSize size(x[0], x[1]);
+ d->parsed = QVariant::fromValue(size);
+ return size;
+}
+
+QRect Declaration::rectValue() const
+{
+ if (d->values.count() != 1)
+ return QRect();
+
+ if (d->parsed.isValid())
+ return qvariant_cast(d->parsed);
+
+ const QCss::Value &v = d->values.at(0);
+ if (v.type != Value::Function)
+ return QRect();
+ QStringList func = v.variant.toStringList();
+ if (func.count() != 2 || func.at(0).compare(QLatin1String("rect")) != 0)
+ return QRect();
+ QStringList args = func[1].split(QLatin1Char(' '), QString::SkipEmptyParts);
+ if (args.count() != 4)
+ return QRect();
+ QRect rect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt());
+ d->parsed = QVariant::fromValue(rect);
+ return rect;
+}
+
+void Declaration::colorValues(QColor *c, const QPalette &pal) const
+{
+ int i;
+ if (d->parsed.isValid()) {
+ QList v = d->parsed.toList();
+ for (i = 0; i < qMin(d->values.count(), 4); i++) {
+ if (v.at(i).type() == QVariant::Color) {
+ c[i] = qvariant_cast(v.at(i));
+ } else {
+ c[i] = pal.color((QPalette::ColorRole)(v.at(i).toInt()));
+ }
+ }
+ } else {
+ QList v;
+ for (i = 0; i < qMin(d->values.count(), 4); i++) {
+ ColorData color = parseColorValue(d->values.at(i));
+ if(color.type == ColorData::Role) {
+ v += QVariant::fromValue(color.role);
+ c[i] = pal.color((QPalette::ColorRole)(color.role));
+ } else {
+ v += QVariant::fromValue(color.color);
+ c[i] = color.color;
+ }
+ }
+ d->parsed = v;
+ }
+
+ if (i == 0) c[0] = c[1] = c[2] = c[3] = QColor();
+ else if (i == 1) c[3] = c[2] = c[1] = c[0];
+ else if (i == 2) c[2] = c[0], c[3] = c[1];
+ else if (i == 3) c[3] = c[1];
+}
+
+BorderStyle Declaration::styleValue() const
+{
+ if (d->values.count() != 1)
+ return BorderStyle_None;
+ return parseStyleValue(d->values.at(0));
+}
+
+void Declaration::styleValues(BorderStyle *s) const
+{
+ int i;
+ for (i = 0; i < qMin(d->values.count(), 4); i++)
+ s[i] = parseStyleValue(d->values.at(i));
+ if (i == 0) s[0] = s[1] = s[2] = s[3] = BorderStyle_None;
+ else if (i == 1) s[3] = s[2] = s[1] = s[0];
+ else if (i == 2) s[2] = s[0], s[3] = s[1];
+ else if (i == 3) s[3] = s[1];
+}
+
+Repeat Declaration::repeatValue() const
+{
+ if (d->parsed.isValid())
+ return static_cast(d->parsed.toInt());
+ if (d->values.count() != 1)
+ return Repeat_Unknown;
+ int v = findKnownValue(d->values.at(0).variant.toString(),
+ repeats, NumKnownRepeats);
+ d->parsed = v;
+ return static_cast(v);
+}
+
+Origin Declaration::originValue() const
+{
+ if (d->parsed.isValid())
+ return static_cast(d->parsed.toInt());
+ if (d->values.count() != 1)
+ return Origin_Unknown;
+ int v = findKnownValue(d->values.at(0).variant.toString(),
+ origins, NumKnownOrigins);
+ d->parsed = v;
+ return static_cast(v);
+}
+
+PositionMode Declaration::positionValue() const
+{
+ if (d->parsed.isValid())
+ return static_cast(d->parsed.toInt());
+ if (d->values.count() != 1)
+ return PositionMode_Unknown;
+ int v = findKnownValue(d->values.at(0).variant.toString(),
+ positions, NumKnownPositionModes);
+ d->parsed = v;
+ return static_cast(v);
+}
+
+Attachment Declaration::attachmentValue() const
+{
+ if (d->parsed.isValid())
+ return static_cast(d->parsed.toInt());
+ if (d->values.count() != 1)
+ return Attachment_Unknown;
+ int v = findKnownValue(d->values.at(0).variant.toString(),
+ attachments, NumKnownAttachments);
+ d->parsed = v;
+ return static_cast(v);
+}
+
+int Declaration::styleFeaturesValue() const
+{
+ Q_ASSERT(d->propertyId == QtStyleFeatures);
+ if (d->parsed.isValid())
+ return d->parsed.toInt();
+ int features = StyleFeature_None;
+ for (int i = 0; i < d->values.count(); i++) {
+ features |= static_cast(findKnownValue(d->values.value(i).variant.toString(),
+ styleFeatures, NumKnownStyleFeatures));
+ }
+ d->parsed = features;
+ return features;
+}
+
+QString Declaration::uriValue() const
+{
+ if (d->values.isEmpty() || d->values.at(0).type != Value::Uri)
+ return QString();
+ return d->values.at(0).variant.toString();
+}
+
+Qt::Alignment Declaration::alignmentValue() const
+{
+ if (d->parsed.isValid())
+ return Qt::Alignment(d->parsed.toInt());
+ if (d->values.isEmpty() || d->values.count() > 2)
+ return Qt::AlignLeft | Qt::AlignTop;
+
+ Qt::Alignment v = parseAlignment(d->values.constData(), d->values.count());
+ d->parsed = int(v);
+ return v;
+}
+
+void Declaration::borderImageValue(QString *image, int *cuts,
+ TileMode *h, TileMode *v) const
+{
+ *image = uriValue();
+ for (int i = 0; i < 4; i++)
+ cuts[i] = -1;
+ *h = *v = TileMode_Stretch;
+
+ if (d->values.count() < 2)
+ return;
+
+ if (d->values.at(1).type == Value::Number) { // cuts!
+ int i;
+ for (i = 0; i < qMin(d->values.count()-1, 4); i++) {
+ const Value& v = d->values.at(i+1);
+ if (v.type != Value::Number)
+ break;
+ cuts[i] = v.variant.toString().toInt();
+ }
+ if (i == 0) cuts[0] = cuts[1] = cuts[2] = cuts[3] = 0;
+ else if (i == 1) cuts[3] = cuts[2] = cuts[1] = cuts[0];
+ else if (i == 2) cuts[2] = cuts[0], cuts[3] = cuts[1];
+ else if (i == 3) cuts[3] = cuts[1];
+ }
+
+ if (d->values.last().type == Value::Identifier) {
+ *v = static_cast(findKnownValue(d->values.last().variant.toString(),
+ tileModes, NumKnownTileModes));
+ }
+ if (d->values[d->values.count() - 2].type == Value::Identifier) {
+ *h = static_cast
+ (findKnownValue(d->values[d->values.count()-2].variant.toString(),
+ tileModes, NumKnownTileModes));
+ } else
+ *h = *v;
+}
+
+QIcon Declaration::iconValue() const
+{
+ if (d->parsed.isValid())
+ return qvariant_cast(d->parsed);
+
+ QIcon icon;
+ for (int i = 0; i < d->values.count();) {
+ const Value &value = d->values.at(i++);
+ if (value.type != Value::Uri)
+ break;
+ QString uri = value.variant.toString();
+ QIcon::Mode mode = QIcon::Normal;
+ QIcon::State state = QIcon::Off;
+ for (int j = 0; j < 2; j++) {
+ if (i != d->values.count() && d->values.at(i).type == Value::KnownIdentifier) {
+ switch (d->values.at(i).variant.toInt()) {
+ case Value_Disabled: mode = QIcon::Disabled; break;
+ case Value_Active: mode = QIcon::Active; break;
+ case Value_Selected: mode = QIcon::Selected; break;
+ case Value_Normal: mode = QIcon::Normal; break;
+ case Value_On: state = QIcon::On; break;
+ case Value_Off: state = QIcon::Off; break;
+ default: break;
+ }
+ ++i;
+ } else {
+ break;
+ }
+ }
+
+ // QIcon is soo broken
+ if (icon.isNull())
+ icon = QIcon(uri);
+ else
+ icon.addPixmap(uri, mode, state);
+
+ if (i == d->values.count())
+ break;
+
+ if (d->values.at(i).type == Value::TermOperatorComma)
+ i++;
+ }
+
+ d->parsed = QVariant::fromValue(icon);
+ return icon;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Selector
+int Selector::specificity() const
+{
+ int val = 0;
+ for (int i = 0; i < basicSelectors.count(); ++i) {
+ const BasicSelector &sel = basicSelectors.at(i);
+ if (!sel.elementName.isEmpty())
+ val += 1;
+
+ val += (sel.pseudos.count() + sel.attributeSelectors.count()) * 0x10;
+ val += sel.ids.count() * 0x100;
+ }
+ return val;
+}
+
+QString Selector::pseudoElement() const
+{
+ const BasicSelector& bs = basicSelectors.last();
+ if (!bs.pseudos.isEmpty() && bs.pseudos.at(0).type == PseudoClass_Unknown)
+ return bs.pseudos.at(0).name;
+ return QString();
+}
+
+quint64 Selector::pseudoClass(quint64 *negated) const
+{
+ const BasicSelector& bs = basicSelectors.last();
+ if (bs.pseudos.isEmpty())
+ return PseudoClass_Unspecified;
+ quint64 pc = PseudoClass_Unknown;
+ for (int i = !pseudoElement().isEmpty(); i < bs.pseudos.count(); i++) {
+ const Pseudo &pseudo = bs.pseudos.at(i);
+ if (pseudo.type == PseudoClass_Unknown)
+ return PseudoClass_Unknown;
+ if (!pseudo.negated)
+ pc |= pseudo.type;
+ else if (negated)
+ *negated |= pseudo.type;
+ }
+ return pc;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// StyleSheet
+void StyleSheet::buildIndexes(Qt::CaseSensitivity nameCaseSensitivity)
+{
+ QVector universals;
+ for (int i = 0; i < styleRules.count(); ++i) {
+ const StyleRule &rule = styleRules.at(i);
+ QVector universalsSelectors;
+ for (int j = 0; j < rule.selectors.count(); ++j) {
+ const Selector& selector = rule.selectors.at(j);
+
+ if (selector.basicSelectors.isEmpty())
+ continue;
+
+ if (selector.basicSelectors.at(0).relationToNext == BasicSelector::NoRelation) {
+ if (selector.basicSelectors.count() != 1)
+ continue;
+ } else if (selector.basicSelectors.count() <= 1) {
+ continue;
+ }
+
+ const BasicSelector &sel = selector.basicSelectors.at(selector.basicSelectors.count() - 1);
+
+ if (!sel.ids.isEmpty()) {
+ StyleRule nr;
+ nr.selectors += selector;
+ nr.declarations = rule.declarations;
+ nr.order = i;
+ idIndex.insert(sel.ids.at(0), nr);
+ } else if (!sel.elementName.isEmpty()) {
+ StyleRule nr;
+ nr.selectors += selector;
+ nr.declarations = rule.declarations;
+ nr.order = i;
+ QString name = sel.elementName;
+ if (nameCaseSensitivity == Qt::CaseInsensitive)
+ name=name.toLower();
+ nameIndex.insert(name, nr);
+ } else {
+ universalsSelectors += selector;
+ }
+ }
+ if (!universalsSelectors.isEmpty()) {
+ StyleRule nr;
+ nr.selectors = universalsSelectors;
+ nr.declarations = rule.declarations;
+ nr.order = i;
+ universals << nr;
+ }
+ }
+ styleRules = universals;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// StyleSelector
+StyleSelector::~StyleSelector()
+{
+}
+
+bool StyleSelector::nodeNameEquals(NodePtr node, const QString& nodeName) const
+{
+ return nodeNames(node).contains(nodeName, nameCaseSensitivity);
+}
+
+QStringList StyleSelector::nodeIds(NodePtr node) const
+{
+ return QStringList(attribute(node, QLatin1String("id")));
+}
+
+bool StyleSelector::selectorMatches(const Selector &selector, NodePtr node)
+{
+ if (selector.basicSelectors.isEmpty())
+ return false;
+
+ if (selector.basicSelectors.at(0).relationToNext == BasicSelector::NoRelation) {
+ if (selector.basicSelectors.count() != 1)
+ return false;
+ return basicSelectorMatches(selector.basicSelectors.at(0), node);
+ }
+ if (selector.basicSelectors.count() <= 1)
+ return false;
+
+ int i = selector.basicSelectors.count() - 1;
+ node = duplicateNode(node);
+ bool match = true;
+
+ BasicSelector sel = selector.basicSelectors.at(i);
+ do {
+ match = basicSelectorMatches(sel, node);
+ if (!match) {
+ if (sel.relationToNext == BasicSelector::MatchNextSelectorIfParent
+ || i == selector.basicSelectors.count() - 1) // first element must always match!
+ break;
+ }
+
+ if (match || sel.relationToNext != BasicSelector::MatchNextSelectorIfAncestor)
+ --i;
+
+ if (i < 0)
+ break;
+
+ sel = selector.basicSelectors.at(i);
+ if (sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor
+ || sel.relationToNext == BasicSelector::MatchNextSelectorIfParent) {
+
+ NodePtr nextParent = parentNode(node);
+ freeNode(node);
+ node = nextParent;
+ } else if (sel.relationToNext == BasicSelector::MatchNextSelectorIfPreceeds) {
+ NodePtr previousSibling = previousSiblingNode(node);
+ freeNode(node);
+ node = previousSibling;
+ }
+ if (isNullNode(node)) {
+ match = false;
+ break;
+ }
+ } while (i >= 0 && (match || sel.relationToNext == BasicSelector::MatchNextSelectorIfAncestor));
+
+ freeNode(node);
+
+ return match;
+}
+
+bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node)
+{
+ if (!sel.attributeSelectors.isEmpty()) {
+ if (!hasAttributes(node))
+ return false;
+
+ for (int i = 0; i < sel.attributeSelectors.count(); ++i) {
+ const QCss::AttributeSelector &a = sel.attributeSelectors.at(i);
+
+ const QString attrValue = attribute(node, a.name);
+ if (attrValue.isNull())
+ return false;
+
+ if (a.valueMatchCriterium == QCss::AttributeSelector::MatchContains) {
+
+ QStringList lst = attrValue.split(QLatin1Char(' '));
+ if (!lst.contains(a.value))
+ return false;
+ } else if (
+ (a.valueMatchCriterium == QCss::AttributeSelector::MatchEqual
+ && attrValue != a.value)
+ ||
+ (a.valueMatchCriterium == QCss::AttributeSelector::MatchBeginsWith
+ && !attrValue.startsWith(a.value))
+ )
+ return false;
+ }
+ }
+
+ if (!sel.elementName.isEmpty()
+ && !nodeNameEquals(node, sel.elementName))
+ return false;
+
+ if (!sel.ids.isEmpty()
+ && sel.ids != nodeIds(node))
+ return false;
+
+ return true;
+}
+
+void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOrigin origin,
+ int depth, QMap *weightedRules)
+{
+ for (int j = 0; j < rule.selectors.count(); ++j) {
+ const Selector& selector = rule.selectors.at(j);
+ if (selectorMatches(selector, node)) {
+ uint weight = rule.order
+ + selector.specificity() *0x100
+ + (uint(origin) + depth)*0x100000;
+ StyleRule newRule = rule;
+ if(rule.selectors.count() > 1) {
+ newRule.selectors.resize(1);
+ newRule.selectors[0] = selector;
+ }
+ //We might have rules with the same weight if they came from a rule with several selectors
+ weightedRules->insertMulti(weight, newRule);
+ }
+ }
+}
+
+// Returns style rules that are in ascending order of specificity
+// Each of the StyleRule returned will contain exactly one Selector
+QVector StyleSelector::styleRulesForNode(NodePtr node)
+{
+ QVector rules;
+ if (styleSheets.isEmpty())
+ return rules;
+
+ QMap weightedRules; // (spec, rule) that will be sorted below
+
+ //prune using indexed stylesheet
+ for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) {
+ const StyleSheet &styleSheet = styleSheets.at(sheetIdx);
+ for (int i = 0; i < styleSheet.styleRules.count(); ++i) {
+ matchRule(node, styleSheet.styleRules.at(i), styleSheet.origin, styleSheet.depth, &weightedRules);
+ }
+
+ if (!styleSheet.idIndex.isEmpty()) {
+ QStringList ids = nodeIds(node);
+ for (int i = 0; i < ids.count(); i++) {
+ const QString &key = ids.at(i);
+ QMultiHash::const_iterator it = styleSheet.idIndex.constFind(key);
+ while (it != styleSheet.idIndex.constEnd() && it.key() == key) {
+ matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
+ ++it;
+ }
+ }
+ }
+ if (!styleSheet.nameIndex.isEmpty()) {
+ QStringList names = nodeNames(node);
+ for (int i = 0; i < names.count(); i++) {
+ QString name = names.at(i);
+ if (nameCaseSensitivity == Qt::CaseInsensitive)
+ name = name.toLower();
+ QMultiHash::const_iterator it = styleSheet.nameIndex.constFind(name);
+ while (it != styleSheet.nameIndex.constEnd() && it.key() == name) {
+ matchRule(node, it.value(), styleSheet.origin, styleSheet.depth, &weightedRules);
+ ++it;
+ }
+ }
+ }
+ if (!medium.isEmpty()) {
+ for (int i = 0; i < styleSheet.mediaRules.count(); ++i) {
+ if (styleSheet.mediaRules.at(i).media.contains(medium, Qt::CaseInsensitive)) {
+ for (int j = 0; j < styleSheet.mediaRules.at(i).styleRules.count(); ++j) {
+ matchRule(node, styleSheet.mediaRules.at(i).styleRules.at(j), styleSheet.origin,
+ styleSheet.depth, &weightedRules);
+ }
+ }
+ }
+ }
+ }
+
+ rules.reserve(weightedRules.count());
+ QMap::const_iterator it = weightedRules.constBegin();
+ for ( ; it != weightedRules.constEnd() ; ++it)
+ rules += *it;
+
+ return rules;
+}
+
+// for qtexthtmlparser which requires just the declarations with Enabled state
+// and without pseudo elements
+QVector StyleSelector::declarationsForNode(NodePtr node, const char *extraPseudo)
+{
+ QVector decls;
+ QVector rules = styleRulesForNode(node);
+ for (int i = 0; i < rules.count(); i++) {
+ const Selector& selector = rules.at(i).selectors.at(0);
+ const QString pseudoElement = selector.pseudoElement();
+
+ if (extraPseudo && pseudoElement == QLatin1String(extraPseudo)) {
+ decls += rules.at(i).declarations;
+ continue;
+ }
+
+ if (!pseudoElement.isEmpty()) // skip rules with pseudo elements
+ continue;
+ quint64 pseudoClass = selector.pseudoClass();
+ if (pseudoClass == PseudoClass_Enabled || pseudoClass == PseudoClass_Unspecified)
+ decls += rules.at(i).declarations;
+ }
+ return decls;
+}
+
+QString Symbol::lexem() const
+{
+ QString result;
+ if (len > 0)
+ result.reserve(len);
+ for (int i = 0; i < len; ++i) {
+ if (text.at(start + i) == QLatin1Char('\\') && i < len - 1)
+ ++i;
+ result += text.at(start + i);
+ }
+ return result;
+}
+
+Parser::Parser(const QString &css, bool isFile)
+{
+ init(css, isFile);
+}
+
+Parser::Parser()
+{
+ index = 0;
+ errorIndex = -1;
+ hasEscapeSequences = false;
+}
+
+void Parser::init(const QString &css, bool isFile)
+{
+ QString styleSheet = css;
+ if (isFile) {
+ QFile file(css);
+ if (file.open(QFile::ReadOnly)) {
+ sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/');
+ QTextStream stream(&file);
+ styleSheet = stream.readAll();
+ } else {
+ qWarning() << "QCss::Parser - Failed to load file " << css;
+ styleSheet.clear();
+ }
+ } else {
+ sourcePath.clear();
+ }
+
+ hasEscapeSequences = false;
+ symbols.resize(0);
+ symbols.reserve(8);
+ Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
+ index = 0;
+ errorIndex = -1;
+}
+
+bool Parser::parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity)
+{
+ if (testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("charset"))) {
+ if (!next(STRING)) return false;
+ if (!next(SEMICOLON)) return false;
+ }
+
+ while (test(S) || test(CDO) || test(CDC)) {}
+
+ while (testImport()) {
+ ImportRule rule;
+ if (!parseImport(&rule)) return false;
+ styleSheet->importRules.append(rule);
+ while (test(S) || test(CDO) || test(CDC)) {}
+ }
+
+ do {
+ if (testMedia()) {
+ MediaRule rule;
+ if (!parseMedia(&rule)) return false;
+ styleSheet->mediaRules.append(rule);
+ } else if (testPage()) {
+ PageRule rule;
+ if (!parsePage(&rule)) return false;
+ styleSheet->pageRules.append(rule);
+ } else if (testRuleset()) {
+ StyleRule rule;
+ if (!parseRuleset(&rule)) return false;
+ styleSheet->styleRules.append(rule);
+ } else if (test(ATKEYWORD_SYM)) {
+ if (!until(RBRACE)) return false;
+ } else if (hasNext()) {
+ return false;
+ }
+ while (test(S) || test(CDO) || test(CDC)) {}
+ } while (hasNext());
+ styleSheet->buildIndexes(nameCaseSensitivity);
+ return true;
+}
+
+Symbol Parser::errorSymbol()
+{
+ if (errorIndex == -1) return Symbol();
+ return symbols.at(errorIndex);
+}
+
+static inline void removeOptionalQuotes(QString *str)
+{
+ if (!str->startsWith(QLatin1Char('\''))
+ && !str->startsWith(QLatin1Char('\"')))
+ return;
+ str->remove(0, 1);
+ str->chop(1);
+}
+
+bool Parser::parseImport(ImportRule *importRule)
+{
+ skipSpace();
+
+ if (test(STRING)) {
+ importRule->href = lexem();
+ } else {
+ if (!testAndParseUri(&importRule->href)) return false;
+ }
+ removeOptionalQuotes(&importRule->href);
+
+ skipSpace();
+
+ if (testMedium()) {
+ if (!parseMedium(&importRule->media)) return false;
+
+ while (test(COMMA)) {
+ skipSpace();
+ if (!parseNextMedium(&importRule->media)) return false;
+ }
+ }
+
+ if (!next(SEMICOLON)) return false;
+
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseMedia(MediaRule *mediaRule)
+{
+ do {
+ skipSpace();
+ if (!parseNextMedium(&mediaRule->media)) return false;
+ } while (test(COMMA));
+
+ if (!next(LBRACE)) return false;
+ skipSpace();
+
+ while (testRuleset()) {
+ StyleRule rule;
+ if (!parseRuleset(&rule)) return false;
+ mediaRule->styleRules.append(rule);
+ }
+
+ if (!next(RBRACE)) return false;
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseMedium(QStringList *media)
+{
+ media->append(lexem());
+ skipSpace();
+ return true;
+}
+
+bool Parser::parsePage(PageRule *pageRule)
+{
+ skipSpace();
+
+ if (testPseudoPage())
+ if (!parsePseudoPage(&pageRule->selector)) return false;
+
+ skipSpace();
+ if (!next(LBRACE)) return false;
+
+ do {
+ skipSpace();
+ Declaration decl;
+ if (!parseNextDeclaration(&decl)) return false;
+ if (!decl.isEmpty())
+ pageRule->declarations.append(decl);
+ } while (test(SEMICOLON));
+
+ if (!next(RBRACE)) return false;
+ skipSpace();
+ return true;
+}
+
+bool Parser::parsePseudoPage(QString *selector)
+{
+ if (!next(IDENT)) return false;
+ *selector = lexem();
+ return true;
+}
+
+bool Parser::parseNextOperator(Value *value)
+{
+ if (!hasNext()) return true;
+ switch (next()) {
+ case SLASH: value->type = Value::TermOperatorSlash; skipSpace(); break;
+ case COMMA: value->type = Value::TermOperatorComma; skipSpace(); break;
+ default: prev(); break;
+ }
+ return true;
+}
+
+bool Parser::parseCombinator(BasicSelector::Relation *relation)
+{
+ *relation = BasicSelector::NoRelation;
+ if (lookup() == S) {
+ *relation = BasicSelector::MatchNextSelectorIfAncestor;
+ skipSpace();
+ } else {
+ prev();
+ }
+ if (test(PLUS)) {
+ *relation = BasicSelector::MatchNextSelectorIfPreceeds;
+ } else if (test(GREATER)) {
+ *relation = BasicSelector::MatchNextSelectorIfParent;
+ }
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseProperty(Declaration *decl)
+{
+ decl->d->property = lexem();
+ decl->d->propertyId = static_cast(findKnownValue(decl->d->property, properties, NumProperties));
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseRuleset(StyleRule *styleRule)
+{
+ Selector sel;
+ if (!parseSelector(&sel)) return false;
+ styleRule->selectors.append(sel);
+
+ while (test(COMMA)) {
+ skipSpace();
+ Selector sel;
+ if (!parseNextSelector(&sel)) return false;
+ styleRule->selectors.append(sel);
+ }
+
+ skipSpace();
+ if (!next(LBRACE)) return false;
+ const int declarationStart = index;
+
+ do {
+ skipSpace();
+ Declaration decl;
+ const int rewind = index;
+ if (!parseNextDeclaration(&decl)) {
+ index = rewind;
+ const bool foundSemicolon = until(SEMICOLON);
+ const int semicolonIndex = index;
+
+ index = declarationStart;
+ const bool foundRBrace = until(RBRACE);
+
+ if (foundSemicolon && semicolonIndex < index) {
+ decl = Declaration();
+ index = semicolonIndex - 1;
+ } else {
+ skipSpace();
+ return foundRBrace;
+ }
+ }
+ if (!decl.isEmpty())
+ styleRule->declarations.append(decl);
+ } while (test(SEMICOLON));
+
+ if (!next(RBRACE)) return false;
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseSelector(Selector *sel)
+{
+ BasicSelector basicSel;
+ if (!parseSimpleSelector(&basicSel)) return false;
+ while (testCombinator()) {
+ if (!parseCombinator(&basicSel.relationToNext)) return false;
+
+ if (!testSimpleSelector()) break;
+ sel->basicSelectors.append(basicSel);
+
+ basicSel = BasicSelector();
+ if (!parseSimpleSelector(&basicSel)) return false;
+ }
+ sel->basicSelectors.append(basicSel);
+ return true;
+}
+
+bool Parser::parseSimpleSelector(BasicSelector *basicSel)
+{
+ int minCount = 0;
+ if (lookupElementName()) {
+ if (!parseElementName(&basicSel->elementName)) return false;
+ } else {
+ prev();
+ minCount = 1;
+ }
+ bool onceMore;
+ int count = 0;
+ do {
+ onceMore = false;
+ if (test(HASH)) {
+ QString theid = lexem();
+ // chop off leading #
+ theid.remove(0, 1);
+ basicSel->ids.append(theid);
+ onceMore = true;
+ } else if (testClass()) {
+ onceMore = true;
+ AttributeSelector a;
+ a.name = QLatin1String("class");
+ a.valueMatchCriterium = AttributeSelector::MatchContains;
+ if (!parseClass(&a.value)) return false;
+ basicSel->attributeSelectors.append(a);
+ } else if (testAttrib()) {
+ onceMore = true;
+ AttributeSelector a;
+ if (!parseAttrib(&a)) return false;
+ basicSel->attributeSelectors.append(a);
+ } else if (testPseudo()) {
+ onceMore = true;
+ Pseudo ps;
+ if (!parsePseudo(&ps)) return false;
+ basicSel->pseudos.append(ps);
+ }
+ if (onceMore) ++count;
+ } while (onceMore);
+ return count >= minCount;
+}
+
+bool Parser::parseClass(QString *name)
+{
+ if (!next(IDENT)) return false;
+ *name = lexem();
+ return true;
+}
+
+bool Parser::parseElementName(QString *name)
+{
+ switch (lookup()) {
+ case STAR: name->clear(); break;
+ case IDENT: *name = lexem(); break;
+ default: return false;
+ }
+ return true;
+}
+
+bool Parser::parseAttrib(AttributeSelector *attr)
+{
+ skipSpace();
+ if (!next(IDENT)) return false;
+ attr->name = lexem();
+ skipSpace();
+
+ if (test(EQUAL)) {
+ attr->valueMatchCriterium = AttributeSelector::MatchEqual;
+ } else if (test(INCLUDES)) {
+ attr->valueMatchCriterium = AttributeSelector::MatchContains;
+ } else if (test(DASHMATCH)) {
+ attr->valueMatchCriterium = AttributeSelector::MatchBeginsWith;
+ } else {
+ return next(RBRACKET);
+ }
+
+ skipSpace();
+
+ if (!test(IDENT) && !test(STRING)) return false;
+ attr->value = unquotedLexem();
+
+ skipSpace();
+ return next(RBRACKET);
+}
+
+bool Parser::parsePseudo(Pseudo *pseudo)
+{
+ (void)test(COLON);
+ pseudo->negated = test(EXCLAMATION_SYM);
+ if (test(IDENT)) {
+ pseudo->name = lexem();
+ pseudo->type = static_cast(findKnownValue(pseudo->name, pseudos, NumPseudos));
+ return true;
+ }
+ if (!next(FUNCTION)) return false;
+ pseudo->function = lexem();
+ // chop off trailing parenthesis
+ pseudo->function.chop(1);
+ skipSpace();
+ if (!test(IDENT)) return false;
+ pseudo->name = lexem();
+ skipSpace();
+ return next(RPAREN);
+}
+
+bool Parser::parseNextDeclaration(Declaration *decl)
+{
+ if (!testProperty())
+ return true; // not an error!
+ if (!parseProperty(decl)) return false;
+ if (!next(COLON)) return false;
+ skipSpace();
+ if (!parseNextExpr(&decl->d->values)) return false;
+ if (testPrio())
+ if (!parsePrio(decl)) return false;
+ return true;
+}
+
+bool Parser::testPrio()
+{
+ const int rewind = index;
+ if (!test(EXCLAMATION_SYM)) return false;
+ skipSpace();
+ if (!test(IDENT)) {
+ index = rewind;
+ return false;
+ }
+ if (lexem().compare(QLatin1String("important"), Qt::CaseInsensitive) != 0) {
+ index = rewind;
+ return false;
+ }
+ return true;
+}
+
+bool Parser::parsePrio(Declaration *declaration)
+{
+ declaration->d->important = true;
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseExpr(QVector *values)
+{
+ Value val;
+ if (!parseTerm(&val)) return false;
+ values->append(val);
+ bool onceMore;
+ do {
+ onceMore = false;
+ val = Value();
+ if (!parseNextOperator(&val)) return false;
+ if (val.type != QCss::Value::Unknown)
+ values->append(val);
+ if (testTerm()) {
+ onceMore = true;
+ val = Value();
+ if (!parseTerm(&val)) return false;
+ values->append(val);
+ }
+ } while (onceMore);
+ return true;
+}
+
+bool Parser::testTerm()
+{
+ return test(PLUS) || test(MINUS)
+ || test(NUMBER)
+ || test(PERCENTAGE)
+ || test(LENGTH)
+ || test(STRING)
+ || test(IDENT)
+ || testHexColor()
+ || testFunction();
+}
+
+bool Parser::parseTerm(Value *value)
+{
+ QString str = lexem();
+ bool haveUnary = false;
+ if (lookup() == PLUS || lookup() == MINUS) {
+ haveUnary = true;
+ if (!hasNext()) return false;
+ next();
+ str += lexem();
+ }
+
+ value->variant = str;
+ value->type = QCss::Value::String;
+ switch (lookup()) {
+ case NUMBER:
+ value->type = Value::Number;
+ value->variant.convert(QVariant::Double);
+ break;
+ case PERCENTAGE:
+ value->type = Value::Percentage;
+ str.chop(1); // strip off %
+ value->variant = str;
+ break;
+ case LENGTH:
+ value->type = Value::Length;
+ break;
+
+ case STRING:
+ if (haveUnary) return false;
+ value->type = Value::String;
+ str.chop(1);
+ str.remove(0, 1);
+ value->variant = str;
+ break;
+ case IDENT: {
+ if (haveUnary) return false;
+ value->type = Value::Identifier;
+ const int theid = findKnownValue(str, values, NumKnownValues);
+ if (theid != 0) {
+ value->type = Value::KnownIdentifier;
+ value->variant = theid;
+ }
+ break;
+ }
+ default: {
+ if (haveUnary) return false;
+ prev();
+ if (testHexColor()) {
+ QColor col;
+ if (!parseHexColor(&col)) return false;
+ value->type = Value::Color;
+ value->variant = col;
+ } else if (testFunction()) {
+ QString name, args;
+ if (!parseFunction(&name, &args)) return false;
+ if (name == QLatin1String("url")) {
+ value->type = Value::Uri;
+ removeOptionalQuotes(&args);
+ if (QFileInfo(args).isRelative() && !sourcePath.isEmpty()) {
+ args.prepend(sourcePath);
+ }
+ value->variant = args;
+ } else {
+ value->type = Value::Function;
+ value->variant = QStringList() << name << args;
+ }
+ } else {
+ return recordError();
+ }
+ return true;
+ }
+ }
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseFunction(QString *name, QString *args)
+{
+ *name = lexem();
+ name->chop(1);
+ skipSpace();
+ const int start = index;
+ if (!until(RPAREN)) return false;
+ for (int i = start; i < index - 1; ++i)
+ args->append(symbols.at(i).lexem());
+ /*
+ if (!nextExpr(&arguments)) return false;
+ if (!next(RPAREN)) return false;
+ */
+ skipSpace();
+ return true;
+}
+
+bool Parser::parseHexColor(QColor *col)
+{
+ col->setNamedColor(lexem());
+ if (!col->isValid()) {
+ qWarning("QCssParser::parseHexColor: Unknown color name '%s'",lexem().toLatin1().constData());
+ return false;
+ }
+ skipSpace();
+ return true;
+}
+
+bool Parser::testAndParseUri(QString *uri)
+{
+ const int rewind = index;
+ if (!testFunction()) return false;
+
+ QString name, args;
+ if (!parseFunction(&name, &args)) {
+ index = rewind;
+ return false;
+ }
+ if (name.toLower() != QLatin1String("url")) {
+ index = rewind;
+ return false;
+ }
+ *uri = args;
+ removeOptionalQuotes(uri);
+ return true;
+}
+
+bool Parser::testSimpleSelector()
+{
+ return testElementName()
+ || (test(HASH))
+ || testClass()
+ || testAttrib()
+ || testPseudo();
+}
+
+bool Parser::next(QCss::TokenType t)
+{
+ if (hasNext() && next() == t)
+ return true;
+ return recordError();
+}
+
+bool Parser::test(QCss::TokenType t)
+{
+ if (index >= symbols.count())
+ return false;
+ if (symbols.at(index).token == t) {
+ ++index;
+ return true;
+ }
+ return false;
+}
+
+QString Parser::unquotedLexem() const
+{
+ QString s = lexem();
+ if (lookup() == STRING) {
+ s.chop(1);
+ s.remove(0, 1);
+ }
+ return s;
+}
+
+QString Parser::lexemUntil(QCss::TokenType t)
+{
+ QString lexem;
+ while (hasNext() && next() != t)
+ lexem += symbol().lexem();
+ return lexem;
+}
+
+bool Parser::until(QCss::TokenType target, QCss::TokenType target2)
+{
+ int braceCount = 0;
+ int brackCount = 0;
+ int parenCount = 0;
+ if (index) {
+ switch(symbols.at(index-1).token) {
+ case LBRACE: ++braceCount; break;
+ case LBRACKET: ++brackCount; break;
+ case FUNCTION:
+ case LPAREN: ++parenCount; break;
+ default: ;
+ }
+ }
+ while (index < symbols.size()) {
+ QCss::TokenType t = symbols.at(index++).token;
+ switch (t) {
+ case LBRACE: ++braceCount; break;
+ case RBRACE: --braceCount; break;
+ case LBRACKET: ++brackCount; break;
+ case RBRACKET: --brackCount; break;
+ case FUNCTION:
+ case LPAREN: ++parenCount; break;
+ case RPAREN: --parenCount; break;
+ default: break;
+ }
+ if ((t == target || (target2 != NONE && t == target2))
+ && braceCount <= 0
+ && brackCount <= 0
+ && parenCount <= 0)
+ return true;
+
+ if (braceCount < 0 || brackCount < 0 || parenCount < 0) {
+ --index;
+ break;
+ }
+ }
+ return false;
+}
+
+bool Parser::testTokenAndEndsWith(QCss::TokenType t, QLatin1String str)
+{
+ if (!test(t)) return false;
+ if (!lexem().endsWith(str, Qt::CaseInsensitive)) {
+ prev();
+ return false;
+ }
+ return true;
+}
diff --git a/Source/Fractorium/qcssparser.h b/Source/Fractorium/qcssparser.h
new file mode 100644
index 0000000..c78dfe5
--- /dev/null
+++ b/Source/Fractorium/qcssparser.h
@@ -0,0 +1,832 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+
+#include "FractoriumPch.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class QIcon;
+
+namespace QCss
+{
+
+enum Property {
+ UnknownProperty,
+ BackgroundColor,
+ Color,
+ Float,
+ Font,
+ FontFamily,
+ FontSize,
+ FontStyle,
+ FontWeight,
+ Margin,
+ MarginBottom,
+ MarginLeft,
+ MarginRight,
+ MarginTop,
+ QtBlockIndent,
+ QtListIndent,
+ QtParagraphType,
+ QtTableType,
+ QtUserState,
+ TextDecoration,
+ TextIndent,
+ TextUnderlineStyle,
+ VerticalAlignment,
+ Whitespace,
+ QtSelectionForeground,
+ QtSelectionBackground,
+ Border,
+ BorderLeft,
+ BorderRight,
+ BorderTop,
+ BorderBottom,
+ Padding,
+ PaddingLeft,
+ PaddingRight,
+ PaddingTop,
+ PaddingBottom,
+ PageBreakBefore,
+ PageBreakAfter,
+ QtAlternateBackground,
+ BorderLeftStyle,
+ BorderRightStyle,
+ BorderTopStyle,
+ BorderBottomStyle,
+ BorderStyles,
+ BorderLeftColor,
+ BorderRightColor,
+ BorderTopColor,
+ BorderBottomColor,
+ BorderColor,
+ BorderLeftWidth,
+ BorderRightWidth,
+ BorderTopWidth,
+ BorderBottomWidth,
+ BorderWidth,
+ BorderTopLeftRadius,
+ BorderTopRightRadius,
+ BorderBottomLeftRadius,
+ BorderBottomRightRadius,
+ BorderRadius,
+ Background,
+ BackgroundOrigin,
+ BackgroundClip,
+ BackgroundRepeat,
+ BackgroundPosition,
+ BackgroundAttachment,
+ BackgroundImage,
+ BorderImage,
+ QtSpacing,
+ Width,
+ Height,
+ MinimumWidth,
+ MinimumHeight,
+ MaximumWidth,
+ MaximumHeight,
+ QtImage,
+ Left,
+ Right,
+ Top,
+ Bottom,
+ QtOrigin,
+ QtPosition,
+ Position,
+ QtStyleFeatures,
+ QtBackgroundRole,
+ ListStyleType,
+ ListStyle,
+ QtImageAlignment,
+ TextAlignment,
+ Outline,
+ OutlineOffset,
+ OutlineWidth,
+ OutlineColor,
+ OutlineStyle,
+ OutlineRadius,
+ OutlineTopLeftRadius,
+ OutlineTopRightRadius,
+ OutlineBottomLeftRadius,
+ OutlineBottomRightRadius,
+ FontVariant,
+ TextTransform,
+ QtListNumberPrefix,
+ QtListNumberSuffix,
+ LineHeight,
+ NumProperties
+};
+
+enum KnownValue {
+ UnknownValue,
+ Value_Normal,
+ Value_Pre,
+ Value_NoWrap,
+ Value_PreWrap,
+ Value_Small,
+ Value_Medium,
+ Value_Large,
+ Value_XLarge,
+ Value_XXLarge,
+ Value_Italic,
+ Value_Oblique,
+ Value_Bold,
+ Value_Underline,
+ Value_Overline,
+ Value_LineThrough,
+ Value_Sub,
+ Value_Super,
+ Value_Left,
+ Value_Right,
+ Value_Top,
+ Value_Bottom,
+ Value_Center,
+ Value_Native,
+ Value_Solid,
+ Value_Dotted,
+ Value_Dashed,
+ Value_DotDash,
+ Value_DotDotDash,
+ Value_Double,
+ Value_Groove,
+ Value_Ridge,
+ Value_Inset,
+ Value_Outset,
+ Value_Wave,
+ Value_Middle,
+ Value_Auto,
+ Value_Always,
+ Value_None,
+ Value_Transparent,
+ Value_Disc,
+ Value_Circle,
+ Value_Square,
+ Value_Decimal,
+ Value_LowerAlpha,
+ Value_UpperAlpha,
+ Value_LowerRoman,
+ Value_UpperRoman,
+ Value_SmallCaps,
+ Value_Uppercase,
+ Value_Lowercase,
+
+ /* keep these in same order as QPalette::ColorRole */
+ Value_FirstColorRole,
+ Value_WindowText = Value_FirstColorRole,
+ Value_Button,
+ Value_Light,
+ Value_Midlight,
+ Value_Dark,
+ Value_Mid,
+ Value_Text,
+ Value_BrightText,
+ Value_ButtonText,
+ Value_Base,
+ Value_Window,
+ Value_Shadow,
+ Value_Highlight,
+ Value_HighlightedText,
+ Value_Link,
+ Value_LinkVisited,
+ Value_AlternateBase,
+ Value_LastColorRole = Value_AlternateBase,
+
+ Value_Disabled,
+ Value_Active,
+ Value_Selected,
+ Value_On,
+ Value_Off,
+
+ NumKnownValues
+};
+
+enum BorderStyle {
+ BorderStyle_Unknown,
+ BorderStyle_None,
+ BorderStyle_Dotted,
+ BorderStyle_Dashed,
+ BorderStyle_Solid,
+ BorderStyle_Double,
+ BorderStyle_DotDash,
+ BorderStyle_DotDotDash,
+ BorderStyle_Groove,
+ BorderStyle_Ridge,
+ BorderStyle_Inset,
+ BorderStyle_Outset,
+ BorderStyle_Native,
+ NumKnownBorderStyles
+};
+
+enum Edge {
+ TopEdge,
+ RightEdge,
+ BottomEdge,
+ LeftEdge,
+ NumEdges
+};
+
+enum Corner {
+ TopLeftCorner,
+ TopRightCorner,
+ BottomLeftCorner,
+ BottomRightCorner
+};
+
+enum TileMode {
+ TileMode_Unknown,
+ TileMode_Round,
+ TileMode_Stretch,
+ TileMode_Repeat,
+ NumKnownTileModes
+};
+
+enum Repeat {
+ Repeat_Unknown,
+ Repeat_None,
+ Repeat_X,
+ Repeat_Y,
+ Repeat_XY,
+ NumKnownRepeats
+};
+
+enum Origin {
+ Origin_Unknown,
+ Origin_Padding,
+ Origin_Border,
+ Origin_Content,
+ Origin_Margin,
+ NumKnownOrigins
+};
+
+enum PositionMode {
+ PositionMode_Unknown,
+ PositionMode_Static,
+ PositionMode_Relative,
+ PositionMode_Absolute,
+ PositionMode_Fixed,
+ NumKnownPositionModes
+};
+
+enum Attachment {
+ Attachment_Unknown,
+ Attachment_Fixed,
+ Attachment_Scroll,
+ NumKnownAttachments
+};
+
+enum StyleFeature {
+ StyleFeature_None = 0,
+ StyleFeature_BackgroundColor = 1,
+ StyleFeature_BackgroundGradient = 2,
+ NumKnownStyleFeatures = 4
+};
+
+static inline bool isHexDigit(const char c)
+{
+ return (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'f')
+ || (c >= 'A' && c <= 'F')
+ ;
+}
+
+struct Value
+{
+ enum Type {
+ Unknown,
+ Number,
+ Percentage,
+ Length,
+ String,
+ Identifier,
+ KnownIdentifier,
+ Uri,
+ Color,
+ Function,
+ TermOperatorSlash,
+ TermOperatorComma
+ };
+ inline Value() : type(Unknown) { }
+ Type type;
+ QVariant variant;
+ QString toString() const;
+};
+
+struct ColorData {
+ ColorData() : role(QPalette::NoRole), type(Invalid) {}
+ ColorData(const QColor &col) : color(col), role(QPalette::NoRole), type(Color) {}
+ ColorData(QPalette::ColorRole r) : role(r), type(Role) {}
+ QColor color;
+ QPalette::ColorRole role;
+ enum { Invalid, Color, Role} type;
+};
+
+struct BrushData {
+ BrushData() : role(QPalette::NoRole), type(Invalid) {}
+ BrushData(const QBrush &br) : brush(br), role(QPalette::NoRole), type(Brush) {}
+ BrushData(QPalette::ColorRole r) : role(r), type(Role) {}
+ QBrush brush;
+ QPalette::ColorRole role;
+ enum { Invalid, Brush, Role, DependsOnThePalette } type;
+};
+
+struct BackgroundData {
+ BrushData brush;
+ QString image;
+ Repeat repeat;
+ Qt::Alignment alignment;
+};
+
+struct LengthData {
+ qreal number;
+ enum { NONE, Px, Ex, Em } unit;
+};
+
+struct BorderData {
+ LengthData width;
+ BorderStyle style;
+ BrushData color;
+};
+
+
+// 1. StyleRule - x:hover, y:clicked > z:checked { prop1: value1; prop2: value2; }
+// 2. QVector - x:hover, y:clicked z:checked
+// 3. QVector - y:clicked z:checked
+// 4. QVector - { prop1: value1; prop2: value2; }
+// 5. Declaration - prop1: value1;
+
+struct Declaration
+{
+ struct DeclarationData : public QSharedData
+ {
+ inline DeclarationData() : propertyId(UnknownProperty), important(false) {}
+ QString property;
+ Property propertyId;
+ QVector values;
+ QVariant parsed;
+ bool important;
+ };
+ QExplicitlySharedDataPointer d;
+ inline Declaration() : d(new DeclarationData()) {}
+ inline bool isEmpty() const { return d->property.isEmpty() && d->propertyId == UnknownProperty; }
+
+ // helper functions
+ QColor colorValue(const QPalette & = QPalette()) const;
+ void colorValues(QColor *c, const QPalette & = QPalette()) const;
+ QBrush brushValue(const QPalette & = QPalette()) const;
+ void brushValues(QBrush *c, const QPalette & = QPalette()) const;
+
+ BorderStyle styleValue() const;
+ void styleValues(BorderStyle *s) const;
+
+ Origin originValue() const;
+ Repeat repeatValue() const;
+ Qt::Alignment alignmentValue() const;
+ PositionMode positionValue() const;
+ Attachment attachmentValue() const;
+ int styleFeaturesValue() const;
+
+ bool intValue(int *i, const char *unit = 0) const;
+ bool realValue(qreal *r, const char *unit = 0) const;
+
+ QSize sizeValue() const;
+ QRect rectValue() const;
+ QString uriValue() const;
+ QIcon iconValue() const;
+
+ void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
+};
+
+const quint64 PseudoClass_Unknown = Q_UINT64_C(0x0000000000000000);
+const quint64 PseudoClass_Enabled = Q_UINT64_C(0x0000000000000001);
+const quint64 PseudoClass_Disabled = Q_UINT64_C(0x0000000000000002);
+const quint64 PseudoClass_Pressed = Q_UINT64_C(0x0000000000000004);
+const quint64 PseudoClass_Focus = Q_UINT64_C(0x0000000000000008);
+const quint64 PseudoClass_Hover = Q_UINT64_C(0x0000000000000010);
+const quint64 PseudoClass_Checked = Q_UINT64_C(0x0000000000000020);
+const quint64 PseudoClass_Unchecked = Q_UINT64_C(0x0000000000000040);
+const quint64 PseudoClass_Indeterminate = Q_UINT64_C(0x0000000000000080);
+const quint64 PseudoClass_Unspecified = Q_UINT64_C(0x0000000000000100);
+const quint64 PseudoClass_Selected = Q_UINT64_C(0x0000000000000200);
+const quint64 PseudoClass_Horizontal = Q_UINT64_C(0x0000000000000400);
+const quint64 PseudoClass_Vertical = Q_UINT64_C(0x0000000000000800);
+const quint64 PseudoClass_Window = Q_UINT64_C(0x0000000000001000);
+const quint64 PseudoClass_Children = Q_UINT64_C(0x0000000000002000);
+const quint64 PseudoClass_Sibling = Q_UINT64_C(0x0000000000004000);
+const quint64 PseudoClass_Default = Q_UINT64_C(0x0000000000008000);
+const quint64 PseudoClass_First = Q_UINT64_C(0x0000000000010000);
+const quint64 PseudoClass_Last = Q_UINT64_C(0x0000000000020000);
+const quint64 PseudoClass_Middle = Q_UINT64_C(0x0000000000040000);
+const quint64 PseudoClass_OnlyOne = Q_UINT64_C(0x0000000000080000);
+const quint64 PseudoClass_PreviousSelected = Q_UINT64_C(0x0000000000100000);
+const quint64 PseudoClass_NextSelected = Q_UINT64_C(0x0000000000200000);
+const quint64 PseudoClass_Flat = Q_UINT64_C(0x0000000000400000);
+const quint64 PseudoClass_Left = Q_UINT64_C(0x0000000000800000);
+const quint64 PseudoClass_Right = Q_UINT64_C(0x0000000001000000);
+const quint64 PseudoClass_Top = Q_UINT64_C(0x0000000002000000);
+const quint64 PseudoClass_Bottom = Q_UINT64_C(0x0000000004000000);
+const quint64 PseudoClass_Exclusive = Q_UINT64_C(0x0000000008000000);
+const quint64 PseudoClass_NonExclusive = Q_UINT64_C(0x0000000010000000);
+const quint64 PseudoClass_Frameless = Q_UINT64_C(0x0000000020000000);
+const quint64 PseudoClass_ReadOnly = Q_UINT64_C(0x0000000040000000);
+const quint64 PseudoClass_Active = Q_UINT64_C(0x0000000080000000);
+const quint64 PseudoClass_Closable = Q_UINT64_C(0x0000000100000000);
+const quint64 PseudoClass_Movable = Q_UINT64_C(0x0000000200000000);
+const quint64 PseudoClass_Floatable = Q_UINT64_C(0x0000000400000000);
+const quint64 PseudoClass_Minimized = Q_UINT64_C(0x0000000800000000);
+const quint64 PseudoClass_Maximized = Q_UINT64_C(0x0000001000000000);
+const quint64 PseudoClass_On = Q_UINT64_C(0x0000002000000000);
+const quint64 PseudoClass_Off = Q_UINT64_C(0x0000004000000000);
+const quint64 PseudoClass_Editable = Q_UINT64_C(0x0000008000000000);
+const quint64 PseudoClass_Item = Q_UINT64_C(0x0000010000000000);
+const quint64 PseudoClass_Closed = Q_UINT64_C(0x0000020000000000);
+const quint64 PseudoClass_Open = Q_UINT64_C(0x0000040000000000);
+const quint64 PseudoClass_EditFocus = Q_UINT64_C(0x0000080000000000);
+const quint64 PseudoClass_Alternate = Q_UINT64_C(0x0000100000000000);
+// The Any specifier is never generated, but can be used as a wildcard in searches.
+const quint64 PseudoClass_Any = Q_UINT64_C(0x0000ffffffffffff);
+const int NumPseudos = 45;
+
+struct Pseudo
+{
+ Pseudo() : type(0), negated(false) { }
+ quint64 type;
+ QString name;
+ QString function;
+ bool negated;
+};
+
+struct AttributeSelector
+{
+ enum ValueMatchType {
+ NoMatch,
+ MatchEqual,
+ MatchContains,
+ MatchBeginsWith
+ };
+ inline AttributeSelector() : valueMatchCriterium(NoMatch) {}
+
+ QString name;
+ QString value;
+ ValueMatchType valueMatchCriterium;
+};
+
+struct BasicSelector
+{
+ inline BasicSelector() : relationToNext(NoRelation) {}
+
+ enum Relation {
+ NoRelation,
+ MatchNextSelectorIfAncestor,
+ MatchNextSelectorIfParent,
+ MatchNextSelectorIfPreceeds
+ };
+
+ QString elementName;
+
+ QStringList ids;
+ QVector pseudos;
+ QVector attributeSelectors;
+
+ Relation relationToNext;
+};
+
+struct Selector
+{
+ QVector basicSelectors;
+ int specificity() const;
+ quint64 pseudoClass(quint64 *negated = 0) const;
+ QString pseudoElement() const;
+};
+
+struct StyleRule;
+struct MediaRule;
+struct PageRule;
+struct ImportRule;
+
+struct ValueExtractor
+{
+ ValueExtractor(const QVector &declarations, const QPalette & = QPalette());
+
+ bool extractFont(QFont *font, int *fontSizeAdjustment);
+ bool extractBackground(QBrush *, QString *, Repeat *, Qt::Alignment *, QCss::Origin *, QCss::Attachment *,
+ QCss::Origin *);
+ bool extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh);
+ bool extractPosition(int *l, int *t, int *r, int *b, QCss::Origin *, Qt::Alignment *,
+ QCss::PositionMode *, Qt::Alignment *);
+ bool extractBox(int *margins, int *paddings, int *spacing = 0);
+ bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii);
+ bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets);
+ bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg);
+ int extractStyleFeatures();
+ bool extractImage(QIcon *icon, Qt::Alignment *a, QSize *size);
+
+ int lengthValue(const Declaration &decl);
+
+private:
+ void extractFont();
+ void borderValue(const Declaration &decl, int *width, QCss::BorderStyle *style, QBrush *color);
+ LengthData lengthValue(const Value& v);
+ void lengthValues(const Declaration &decl, int *m);
+ QSize sizeValue(const Declaration &decl);
+ void sizeValues(const Declaration &decl, QSize *radii);
+
+ QVector declarations;
+ QFont f;
+ int adjustment;
+ int fontExtracted;
+ QPalette pal;
+};
+
+struct StyleRule
+{
+ StyleRule() : order(0) { }
+ QVector selectors;
+ QVector declarations;
+ int order;
+};
+
+struct MediaRule
+{
+ QStringList media;
+ QVector styleRules;
+};
+
+struct PageRule
+{
+ QString selector;
+ QVector declarations;
+};
+
+struct ImportRule
+{
+ QString href;
+ QStringList media;
+};
+
+enum StyleSheetOrigin {
+ StyleSheetOrigin_Unspecified,
+ StyleSheetOrigin_UserAgent,
+ StyleSheetOrigin_User,
+ StyleSheetOrigin_Author,
+ StyleSheetOrigin_Inline
+};
+
+struct StyleSheet
+{
+ StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { }
+ QVector styleRules; //only contains rules that are not indexed
+ QVector mediaRules;
+ QVector pageRules;
+ QVector importRules;
+ StyleSheetOrigin origin;
+ int depth; // applicable only for inline style sheets
+ QMultiHash nameIndex;
+ QMultiHash idIndex;
+ void buildIndexes(Qt::CaseSensitivity nameCaseSensitivity = Qt::CaseSensitive);
+};
+
+class StyleSelector
+{
+public:
+ StyleSelector() : nameCaseSensitivity(Qt::CaseSensitive) {}
+ virtual ~StyleSelector();
+
+ union NodePtr {
+ void *ptr;
+ int id;
+ };
+
+ QVector styleRulesForNode(NodePtr node);
+ QVector declarationsForNode(NodePtr node, const char *extraPseudo = 0);
+
+ virtual bool nodeNameEquals(NodePtr node, const QString& nodeName) const;
+ virtual QString attribute(NodePtr node, const QString &name) const = 0;
+ virtual bool hasAttributes(NodePtr node) const = 0;
+ virtual QStringList nodeIds(NodePtr node) const;
+ virtual QStringList nodeNames(NodePtr node) const = 0;
+ virtual bool isNullNode(NodePtr node) const = 0;
+ virtual NodePtr parentNode(NodePtr node) const = 0;
+ virtual NodePtr previousSiblingNode(NodePtr node) const = 0;
+ virtual NodePtr duplicateNode(NodePtr node) const = 0;
+ virtual void freeNode(NodePtr node) const = 0;
+
+ QVector styleSheets;
+ QString medium;
+ Qt::CaseSensitivity nameCaseSensitivity;
+private:
+ void matchRule(NodePtr node, const StyleRule &rules, StyleSheetOrigin origin,
+ int depth, QMap *weightedRules);
+ bool selectorMatches(const Selector &rule, NodePtr node);
+ bool basicSelectorMatches(const BasicSelector &rule, NodePtr node);
+};
+
+enum TokenType {
+ NONE,
+
+ S,
+
+ CDO,
+ CDC,
+ INCLUDES,
+ DASHMATCH,
+
+ LBRACE,
+ PLUS,
+ GREATER,
+ COMMA,
+
+ STRING,
+ INVALID,
+
+ IDENT,
+
+ HASH,
+
+ ATKEYWORD_SYM,
+
+ EXCLAMATION_SYM,
+
+ LENGTH,
+
+ PERCENTAGE,
+ NUMBER,
+
+ FUNCTION,
+
+ COLON,
+ SEMICOLON,
+ RBRACE,
+ SLASH,
+ MINUS,
+ DOT,
+ STAR,
+ LBRACKET,
+ RBRACKET,
+ EQUAL,
+ LPAREN,
+ RPAREN,
+ OR
+};
+
+struct Symbol
+{
+ inline Symbol() : token(NONE), start(0), len(-1) {}
+ TokenType token;
+ QString text;
+ int start, len;
+ QString lexem() const;
+};
+
+class Scanner
+{
+public:
+ static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
+ static void scan(const QString &preprocessedInput, QVector *symbols);
+};
+
+class Parser
+{
+public:
+ Parser();
+ explicit Parser(const QString &css, bool file = false);
+
+ void init(const QString &css, bool file = false);
+ bool parse(StyleSheet *styleSheet, Qt::CaseSensitivity nameCaseSensitivity = Qt::CaseSensitive);
+ Symbol errorSymbol();
+
+ bool parseImport(ImportRule *importRule);
+ bool parseMedia(MediaRule *mediaRule);
+ bool parseMedium(QStringList *media);
+ bool parsePage(PageRule *pageRule);
+ bool parsePseudoPage(QString *selector);
+ bool parseNextOperator(Value *value);
+ bool parseCombinator(BasicSelector::Relation *relation);
+ bool parseProperty(Declaration *decl);
+ bool parseRuleset(StyleRule *styleRule);
+ bool parseSelector(Selector *sel);
+ bool parseSimpleSelector(BasicSelector *basicSel);
+ bool parseClass(QString *name);
+ bool parseElementName(QString *name);
+ bool parseAttrib(AttributeSelector *attr);
+ bool parsePseudo(Pseudo *pseudo);
+ bool parseNextDeclaration(Declaration *declaration);
+ bool parsePrio(Declaration *declaration);
+ bool parseExpr(QVector *values);
+ bool parseTerm(Value *value);
+ bool parseFunction(QString *name, QString *args);
+ bool parseHexColor(QColor *col);
+ bool testAndParseUri(QString *uri);
+
+ inline bool testRuleset() { return testSelector(); }
+ inline bool testSelector() { return testSimpleSelector(); }
+ inline bool parseNextSelector(Selector *sel) { if (!testSelector()) return recordError(); return parseSelector(sel); }
+ bool testSimpleSelector();
+ inline bool parseNextSimpleSelector(BasicSelector *basicSel) { if (!testSimpleSelector()) return recordError(); return parseSimpleSelector(basicSel); }
+ inline bool testElementName() { return test(IDENT) || test(STAR); }
+ inline bool testClass() { return test(DOT); }
+ inline bool testAttrib() { return test(LBRACKET); }
+ inline bool testPseudo() { return test(COLON); }
+ inline bool testMedium() { return test(IDENT); }
+ inline bool parseNextMedium(QStringList *media) { if (!testMedium()) return recordError(); return parseMedium(media); }
+ inline bool testPseudoPage() { return test(COLON); }
+ inline bool testImport() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("import")); }
+ inline bool testMedia() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("media")); }
+ inline bool testPage() { return testTokenAndEndsWith(ATKEYWORD_SYM, QLatin1String("page")); }
+ inline bool testCombinator() { return test(PLUS) || test(GREATER) || test(S); }
+ inline bool testProperty() { return test(IDENT); }
+ bool testTerm();
+ inline bool testExpr() { return testTerm(); }
+ inline bool parseNextExpr(QVector *values) { if (!testExpr()) return recordError(); return parseExpr(values); }
+ bool testPrio();
+ inline bool testHexColor() { return test(HASH); }
+ inline bool testFunction() { return test(FUNCTION); }
+ inline bool parseNextFunction(QString *name, QString *args) { if (!testFunction()) return recordError(); return parseFunction(name, args); }
+
+ inline bool lookupElementName() const { return lookup() == IDENT || lookup() == STAR; }
+
+ inline void skipSpace() { while (test(S)) {}; }
+
+ inline bool hasNext() const { return index < symbols.count(); }
+ inline TokenType next() { return symbols.at(index++).token; }
+ bool next(TokenType t);
+ bool test(TokenType t);
+ inline void prev() { index--; }
+ inline const Symbol &symbol() const { return symbols.at(index - 1); }
+ inline QString lexem() const { return symbol().lexem(); }
+ QString unquotedLexem() const;
+ QString lexemUntil(TokenType t);
+ bool until(TokenType target, TokenType target2 = NONE);
+ inline TokenType lookup() const {
+ return (index - 1) < symbols.count() ? symbols.at(index - 1).token : NONE;
+ }
+
+ bool testTokenAndEndsWith(TokenType t, QLatin1String str);
+
+ inline bool recordError() { errorIndex = index; return false; }
+
+ QVector symbols;
+ int index;
+ int errorIndex;
+ bool hasEscapeSequences;
+ QString sourcePath;
+};
+
+} // namespace QCss
+
+Q_DECLARE_METATYPE( QCss::BackgroundData )
+Q_DECLARE_METATYPE( QCss::LengthData )
+Q_DECLARE_METATYPE( QCss::BorderData )
diff --git a/Source/Fractorium/qcssscanner.cpp b/Source/Fractorium/qcssscanner.cpp
new file mode 100644
index 0000000..f4c3c57
--- /dev/null
+++ b/Source/Fractorium/qcssscanner.cpp
@@ -0,0 +1,1171 @@
+#include "FractoriumPch.h"
+#include "qcssscanner.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+namespace QCss
+{
+QCssScanner::QCssScanner(const QString &inp)
+{
+ input = inp;
+ pos = 0;
+ lexemStart = 0;
+ lexemLength = 0;
+}
+
+int QCssScanner::handleCommentStart()
+{
+ while (pos < input.size() - 1) {
+ if (input.at(pos) == QLatin1Char('*')
+ && input.at(pos + 1) == QLatin1Char('/')) {
+ pos += 2;
+ break;
+ }
+ ++pos;
+ }
+ return QCss::TokenType::S;
+}
+
+int QCssScanner::lex()
+{
+ lexemStart = pos;
+ lexemLength = 0;
+ int lastAcceptingPos = -1;
+ int token = -1;
+ QChar ch;
+
+ // initial state
+ ch = next();
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
+ goto state_1;
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ goto state_1;
+ if (ch.unicode() == 32)
+ goto state_1;
+ if (ch.unicode() == 33) {
+ token = QCss::EXCLAMATION_SYM;
+ goto found;
+ }
+ if (ch.unicode() == 34)
+ goto state_3;
+ if (ch.unicode() == 35)
+ goto state_4;
+ if (ch.unicode() == 39)
+ goto state_5;
+ if (ch.unicode() == 40) {
+ token = QCss::LPAREN;
+ goto found;
+ }
+ if (ch.unicode() == 41) {
+ token = QCss::RPAREN;
+ goto found;
+ }
+ if (ch.unicode() == 42) {
+ token = QCss::STAR;
+ goto found;
+ }
+ if (ch.unicode() == 43)
+ goto state_9;
+ if (ch.unicode() == 44)
+ goto state_10;
+ if (ch.unicode() == 45)
+ goto state_11;
+ if (ch.unicode() == 46)
+ goto state_12;
+ if (ch.unicode() == 47)
+ goto state_13;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_14;
+ if (ch.unicode() == 58) {
+ token = QCss::COLON;
+ goto found;
+ }
+ if (ch.unicode() == 59) {
+ token = QCss::SEMICOLON;
+ goto found;
+ }
+ if (ch.unicode() == 60)
+ goto state_17;
+ if (ch.unicode() == 61) {
+ token = QCss::EQUAL;
+ goto found;
+ }
+ if (ch.unicode() == 62)
+ goto state_19;
+ if (ch.unicode() == 64)
+ goto state_20;
+ if (ch.unicode() == 91) {
+ token = QCss::LBRACKET;
+ goto found;
+ }
+ if (ch.unicode() == 92)
+ goto state_22;
+ if (ch.unicode() == 93) {
+ token = QCss::RBRACKET;
+ goto found;
+ }
+ if (ch.unicode() == 95)
+ goto state_24;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_24;
+ if (ch.unicode() == 123)
+ goto state_25;
+ if (ch.unicode() == 124)
+ goto state_26;
+ if (ch.unicode() == 125) {
+ token = QCss::RBRACE;
+ goto found;
+ }
+ if (ch.unicode() == 126)
+ goto state_28;
+ goto out;
+state_1:
+ lastAcceptingPos = pos;
+ token = QCss::S;
+ ch = next();
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
+ goto state_29;
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ goto state_29;
+ if (ch.unicode() == 32)
+ goto state_29;
+ if (ch.unicode() == 43)
+ goto state_9;
+ if (ch.unicode() == 44)
+ goto state_10;
+ if (ch.unicode() == 62)
+ goto state_19;
+ if (ch.unicode() == 123)
+ goto state_25;
+ goto out;
+state_3:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_4:
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_33;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_33;
+ if (ch.unicode() == 92)
+ goto state_34;
+ if (ch.unicode() == 95)
+ goto state_33;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_33;
+ goto out;
+state_5:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_9:
+ lastAcceptingPos = pos;
+ token = QCss::PLUS;
+ goto out;
+state_10:
+ lastAcceptingPos = pos;
+ token = QCss::COMMA;
+ goto out;
+state_11:
+ lastAcceptingPos = pos;
+ token = QCss::MINUS;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_38;
+ if (ch.unicode() == 92)
+ goto state_22;
+ if (ch.unicode() == 95)
+ goto state_24;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_24;
+ goto out;
+state_12:
+ lastAcceptingPos = pos;
+ token = QCss::DOT;
+ ch = next();
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_39;
+ goto out;
+state_13:
+ lastAcceptingPos = pos;
+ token = QCss::SLASH;
+ ch = next();
+ if (ch.unicode() == 42) {
+ token = handleCommentStart();
+ goto found;
+ }
+ goto out;
+state_14:
+ lastAcceptingPos = pos;
+ token = QCss::NUMBER;
+ ch = next();
+ if (ch.unicode() == 37)
+ goto state_41;
+ if (ch.unicode() == 45)
+ goto state_42;
+ if (ch.unicode() == 46)
+ goto state_43;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
+ if (ch.unicode() == 92)
+ goto state_45;
+ if (ch.unicode() == 95)
+ goto state_46;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_46;
+ goto out;
+state_17:
+ ch = next();
+ if (ch.unicode() == 33)
+ goto state_47;
+ goto out;
+state_19:
+ lastAcceptingPos = pos;
+ token = QCss::GREATER;
+ goto out;
+state_20:
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_48;
+ if (ch.unicode() == 92)
+ goto state_49;
+ if (ch.unicode() == 95)
+ goto state_50;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_50;
+ goto out;
+state_22:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_51;
+ if (ch.unicode() == 11)
+ goto state_51;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_51;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_51;
+ if (ch.unicode() >= 103)
+ goto state_51;
+ goto out;
+state_24:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
+ ch = next();
+ if (ch.unicode() == 40)
+ goto state_52;
+ if (ch.unicode() == 45)
+ goto state_53;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_53;
+ if (ch.unicode() == 92)
+ goto state_54;
+ if (ch.unicode() == 95)
+ goto state_53;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_53;
+ goto out;
+state_25:
+ lastAcceptingPos = pos;
+ token = QCss::LBRACE;
+ goto out;
+state_26:
+ lastAcceptingPos = pos;
+ token = QCss::OR;
+ ch = next();
+ if (ch.unicode() == 61) {
+ token = QCss::DASHMATCH;
+ goto found;
+ }
+ goto out;
+state_28:
+ ch = next();
+ if (ch.unicode() == 61) {
+ token = QCss::INCLUDES;
+ goto found;
+ }
+ goto out;
+state_29:
+ lastAcceptingPos = pos;
+ token = QCss::S;
+ ch = next();
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
+ goto state_29;
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ goto state_29;
+ if (ch.unicode() == 32)
+ goto state_29;
+ if (ch.unicode() == 43)
+ goto state_9;
+ if (ch.unicode() == 44)
+ goto state_10;
+ if (ch.unicode() == 62)
+ goto state_19;
+ if (ch.unicode() == 123)
+ goto state_25;
+ goto out;
+state_30:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_31:
+ lastAcceptingPos = pos;
+ token = QCss::STRING;
+ goto out;
+state_32:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_57;
+ if (ch.unicode() == 10)
+ goto state_58;
+ if (ch.unicode() == 11)
+ goto state_57;
+ if (ch.unicode() == 12)
+ goto state_59;
+ if (ch.unicode() == 13)
+ goto state_60;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_57;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_57;
+ if (ch.unicode() >= 103)
+ goto state_57;
+ goto out;
+state_33:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_61;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_61;
+ if (ch.unicode() == 92)
+ goto state_62;
+ if (ch.unicode() == 95)
+ goto state_61;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_61;
+ goto out;
+state_34:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_63;
+ if (ch.unicode() == 11)
+ goto state_63;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_63;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_63;
+ if (ch.unicode() >= 103)
+ goto state_63;
+ goto out;
+state_35:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_36:
+ lastAcceptingPos = pos;
+ token = QCss::STRING;
+ goto out;
+state_37:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_64;
+ if (ch.unicode() == 10)
+ goto state_65;
+ if (ch.unicode() == 11)
+ goto state_64;
+ if (ch.unicode() == 12)
+ goto state_66;
+ if (ch.unicode() == 13)
+ goto state_67;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_64;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_64;
+ if (ch.unicode() >= 103)
+ goto state_64;
+ goto out;
+state_38:
+ ch = next();
+ if (ch.unicode() == 62) {
+ token = QCss::CDC;
+ goto found;
+ }
+ goto out;
+state_39:
+ lastAcceptingPos = pos;
+ token = QCss::NUMBER;
+ ch = next();
+ if (ch.unicode() == 37)
+ goto state_41;
+ if (ch.unicode() == 45)
+ goto state_42;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_69;
+ if (ch.unicode() == 92)
+ goto state_45;
+ if (ch.unicode() == 95)
+ goto state_46;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_46;
+ goto out;
+state_41:
+ lastAcceptingPos = pos;
+ token = QCss::PERCENTAGE;
+ goto out;
+state_42:
+ ch = next();
+ if (ch.unicode() == 92)
+ goto state_45;
+ if (ch.unicode() == 95)
+ goto state_46;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_46;
+ goto out;
+state_43:
+ ch = next();
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_39;
+ goto out;
+state_44:
+ lastAcceptingPos = pos;
+ token = QCss::NUMBER;
+ ch = next();
+ if (ch.unicode() == 37)
+ goto state_41;
+ if (ch.unicode() == 45)
+ goto state_42;
+ if (ch.unicode() == 46)
+ goto state_43;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
+ if (ch.unicode() == 92)
+ goto state_45;
+ if (ch.unicode() == 95)
+ goto state_46;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_46;
+ goto out;
+state_45:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_70;
+ if (ch.unicode() == 11)
+ goto state_70;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_70;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_70;
+ if (ch.unicode() >= 103)
+ goto state_70;
+ goto out;
+state_46:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_71;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_71;
+ if (ch.unicode() == 92)
+ goto state_72;
+ if (ch.unicode() == 95)
+ goto state_71;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_71;
+ goto out;
+state_47:
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_73;
+ goto out;
+state_48:
+ ch = next();
+ if (ch.unicode() == 92)
+ goto state_49;
+ if (ch.unicode() == 95)
+ goto state_50;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_50;
+ goto out;
+state_49:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_74;
+ if (ch.unicode() == 11)
+ goto state_74;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_74;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_74;
+ if (ch.unicode() >= 103)
+ goto state_74;
+ goto out;
+state_50:
+ lastAcceptingPos = pos;
+ token = QCss::ATKEYWORD_SYM;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_75;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_75;
+ if (ch.unicode() == 92)
+ goto state_76;
+ if (ch.unicode() == 95)
+ goto state_75;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_75;
+ goto out;
+state_51:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
+ ch = next();
+ if (ch.unicode() == 40)
+ goto state_52;
+ if (ch.unicode() == 45)
+ goto state_53;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_53;
+ if (ch.unicode() == 92)
+ goto state_54;
+ if (ch.unicode() == 95)
+ goto state_53;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_53;
+ goto out;
+state_52:
+ lastAcceptingPos = pos;
+ token = QCss::FUNCTION;
+ goto out;
+state_53:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
+ ch = next();
+ if (ch.unicode() == 40)
+ goto state_52;
+ if (ch.unicode() == 45)
+ goto state_53;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_53;
+ if (ch.unicode() == 92)
+ goto state_54;
+ if (ch.unicode() == 95)
+ goto state_53;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_53;
+ goto out;
+state_54:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_77;
+ if (ch.unicode() == 11)
+ goto state_77;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_77;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_77;
+ if (ch.unicode() >= 103)
+ goto state_77;
+ goto out;
+state_57:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_58:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_59:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_60:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 10)
+ goto state_78;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_61:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_61;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_61;
+ if (ch.unicode() == 92)
+ goto state_62;
+ if (ch.unicode() == 95)
+ goto state_61;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_61;
+ goto out;
+state_62:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_79;
+ if (ch.unicode() == 11)
+ goto state_79;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_79;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_79;
+ if (ch.unicode() >= 103)
+ goto state_79;
+ goto out;
+state_63:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_61;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_61;
+ if (ch.unicode() == 92)
+ goto state_62;
+ if (ch.unicode() == 95)
+ goto state_61;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_61;
+ goto out;
+state_64:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_65:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_66:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_67:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 10)
+ goto state_80;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_69:
+ lastAcceptingPos = pos;
+ token = QCss::NUMBER;
+ ch = next();
+ if (ch.unicode() == 37)
+ goto state_41;
+ if (ch.unicode() == 45)
+ goto state_42;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_69;
+ if (ch.unicode() == 92)
+ goto state_45;
+ if (ch.unicode() == 95)
+ goto state_46;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_46;
+ goto out;
+state_70:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_71;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_71;
+ if (ch.unicode() == 92)
+ goto state_72;
+ if (ch.unicode() == 95)
+ goto state_71;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_71;
+ goto out;
+state_71:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_71;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_71;
+ if (ch.unicode() == 92)
+ goto state_72;
+ if (ch.unicode() == 95)
+ goto state_71;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_71;
+ goto out;
+state_72:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_81;
+ if (ch.unicode() == 11)
+ goto state_81;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_81;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_81;
+ if (ch.unicode() >= 103)
+ goto state_81;
+ goto out;
+state_73:
+ ch = next();
+ if (ch.unicode() == 45) {
+ token = QCss::CDO;
+ goto found;
+ }
+ goto out;
+state_74:
+ lastAcceptingPos = pos;
+ token = QCss::ATKEYWORD_SYM;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_75;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_75;
+ if (ch.unicode() == 92)
+ goto state_76;
+ if (ch.unicode() == 95)
+ goto state_75;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_75;
+ goto out;
+state_75:
+ lastAcceptingPos = pos;
+ token = QCss::ATKEYWORD_SYM;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_75;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_75;
+ if (ch.unicode() == 92)
+ goto state_76;
+ if (ch.unicode() == 95)
+ goto state_75;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_75;
+ goto out;
+state_76:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_83;
+ if (ch.unicode() == 11)
+ goto state_83;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_83;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_83;
+ if (ch.unicode() >= 103)
+ goto state_83;
+ goto out;
+state_77:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
+ ch = next();
+ if (ch.unicode() == 40)
+ goto state_52;
+ if (ch.unicode() == 45)
+ goto state_53;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_53;
+ if (ch.unicode() == 92)
+ goto state_54;
+ if (ch.unicode() == 95)
+ goto state_53;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_53;
+ goto out;
+state_78:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_30;
+ if (ch.unicode() == 11)
+ goto state_30;
+ if (ch.unicode() >= 14 && ch.unicode() <= 33)
+ goto state_30;
+ if (ch.unicode() == 34)
+ goto state_31;
+ if (ch.unicode() >= 35 && ch.unicode() <= 91)
+ goto state_30;
+ if (ch.unicode() == 92)
+ goto state_32;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_30;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_30;
+ if (ch.unicode() >= 123)
+ goto state_30;
+ goto out;
+state_79:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_61;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_61;
+ if (ch.unicode() == 92)
+ goto state_62;
+ if (ch.unicode() == 95)
+ goto state_61;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_61;
+ goto out;
+state_80:
+ lastAcceptingPos = pos;
+ token = QCss::INVALID;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_35;
+ if (ch.unicode() == 11)
+ goto state_35;
+ if (ch.unicode() >= 14 && ch.unicode() <= 38)
+ goto state_35;
+ if (ch.unicode() == 39)
+ goto state_36;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_35;
+ if (ch.unicode() == 92)
+ goto state_37;
+ if (ch.unicode() >= 93 && ch.unicode() <= 96)
+ goto state_35;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_35;
+ if (ch.unicode() >= 123)
+ goto state_35;
+ goto out;
+state_81:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_71;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_71;
+ if (ch.unicode() == 92)
+ goto state_72;
+ if (ch.unicode() == 95)
+ goto state_71;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_71;
+ goto out;
+state_83:
+ lastAcceptingPos = pos;
+ token = QCss::ATKEYWORD_SYM;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_75;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_75;
+ if (ch.unicode() == 92)
+ goto state_76;
+ if (ch.unicode() == 95)
+ goto state_75;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_75;
+ goto out;
+found:
+ lastAcceptingPos = pos;
+
+out:
+ if (lastAcceptingPos != -1) {
+ lexemLength = lastAcceptingPos - lexemStart;
+ pos = lastAcceptingPos;
+ }
+ return token;
+}
+
+
+QString Scanner::preprocess(const QString &input, bool *hasEscapeSequences)
+{
+ QString output = input;
+
+ if (hasEscapeSequences)
+ *hasEscapeSequences = false;
+
+ int i = 0;
+ while (i < output.size()) {
+ if (output.at(i) == QLatin1Char('\\')) {
+
+ ++i;
+ // test for unicode hex escape
+ int hexCount = 0;
+ const int hexStart = i;
+ while (i < output.size()
+ && isHexDigit(output.at(i).toLatin1())
+ && hexCount < 7) {
+ ++hexCount;
+ ++i;
+ }
+ if (hexCount == 0) {
+ if (hasEscapeSequences)
+ *hasEscapeSequences = true;
+ continue;
+ }
+
+ hexCount = qMin(hexCount, 6);
+ bool ok = false;
+ ushort code = output.mid(hexStart, hexCount).toUShort(&ok, 16);
+ if (ok) {
+ output.replace(hexStart - 1, hexCount + 1, QChar(code));
+ i = hexStart;
+ }
+ else {
+ i = hexStart;
+ }
+ }
+ else {
+ ++i;
+ }
+ }
+ return output;
+}
+
+void Scanner::scan(const QString &preprocessedInput, QVector *symbols)
+{
+ QCssScanner scanner(preprocessedInput);
+ Symbol sym;
+ int tok = scanner.lex();
+ while (tok != -1) {
+ sym.token = static_cast(tok);
+ sym.text = scanner.input;
+ sym.start = scanner.lexemStart;
+ sym.len = scanner.lexemLength;
+ symbols->append(sym);
+ tok = scanner.lex();
+ }
+}
+}
\ No newline at end of file
diff --git a/Source/Fractorium/qcssscanner.h b/Source/Fractorium/qcssscanner.h
new file mode 100644
index 0000000..5e2ac61
--- /dev/null
+++ b/Source/Fractorium/qcssscanner.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+#include "FractoriumPch.h"
+#include "qcssparser.h"
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+namespace QCss
+{
+// auto generated. DO NOT EDIT.
+class QCssScanner
+{
+public:
+ QCssScanner(const QString &inp);
+
+ inline QChar next() {
+ return (pos < input.length()) ? input.at(pos++) : QChar();
+ }
+ int handleCommentStart();
+ int lex();
+
+ QString input;
+ int pos;
+ int lexemStart;
+ int lexemLength;
+};
+}
\ No newline at end of file
diff --git a/Source/Fractorium/qfunctions.h b/Source/Fractorium/qfunctions.h
new file mode 100644
index 0000000..9099dc9
--- /dev/null
+++ b/Source/Fractorium/qfunctions.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qfunctions_*. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+#pragma once
+
+///
+/// The code in this file did not originate in Fractorium.
+/// It was taken either in whole or in part from the source code
+/// of Qt Creator. Their license applies.
+///
+
+#if defined(Q_OS_WINCE)
+# include "QtCore/qfunctions_wince.h"
+#elif defined(Q_OS_VXWORKS)
+# include "QtCore/qfunctions_vxworks.h"
+#elif defined(Q_OS_NACL)
+# include "QtCore/qfunctions_nacl.h"
+#elif defined(Q_OS_WINRT)
+# include "QtCore/qfunctions_winrt.h"
+#endif
+
+#ifdef Q_CC_RVCT
+// rvct doesn't see static operators when using our qalgorithms
+# define Q_STATIC_GLOBAL_OPERATOR inline
+# define Q_STATIC_GLOBAL_INLINE_OPERATOR inline
+#else
+# define Q_STATIC_GLOBAL_OPERATOR static
+# define Q_STATIC_GLOBAL_INLINE_OPERATOR static inline
+#endif