diff --git a/krita/data/aboutdata/credits.txt b/krita/data/aboutdata/credits.txt
index a3b6f1df68..5b9efe7042 100644
--- a/krita/data/aboutdata/credits.txt
+++ b/krita/data/aboutdata/credits.txt
@@ -1,6 +1,8 @@
Peter Sikking:Project Vision
Ramon Miranda:Artist, Muses author, brush and preset creator
David Revoy:Brushes and Palettes
Ilya Portnov:MyPaint shade selector
Martin Renold:MyPaint shade selector
+Saisho Kazuki:Japanese Animation template
Pasquale D'Antuono:Donor
+
diff --git a/krita/data/templates/CMakeLists.txt b/krita/data/templates/CMakeLists.txt
index d139bf84ee..26ed3a8713 100644
--- a/krita/data/templates/CMakeLists.txt
+++ b/krita/data/templates/CMakeLists.txt
@@ -1,4 +1,5 @@
+add_subdirectory( animation )
add_subdirectory( comics )
add_subdirectory( design )
add_subdirectory( dslr )
add_subdirectory( texture )
diff --git a/krita/data/templates/animation/Anim-Jp-EN.desktop b/krita/data/templates/animation/Anim-Jp-EN.desktop
new file mode 100644
index 0000000000..235bc65c98
--- /dev/null
+++ b/krita/data/templates/animation/Anim-Jp-EN.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Type=Link
+URL=.source/Anim-Jp-EN.kra
+Icon=template_animation
+Name=Animation-Japanese-En
+Name[ca]=Animació-Japonès-EN
+Name[es]=Animación-Japonés-En
+Name[nl]=Animatie-Japans-En
+Name[pl]=Animacja-Japońska-En
+Name[pt]=Animação-Japonês-EN
+Name[sv]=Animering-japanska-en
+Name[uk]=Японська анімація (англійською)
+Name[x-test]=xxAnimation-Japanese-Enxx
diff --git a/krita/data/templates/animation/Anim-Jp-EN.kra b/krita/data/templates/animation/Anim-Jp-EN.kra
new file mode 100644
index 0000000000..122a0e7af2
Binary files /dev/null and b/krita/data/templates/animation/Anim-Jp-EN.kra differ
diff --git a/krita/data/templates/animation/Anim-Jp-JP.desktop b/krita/data/templates/animation/Anim-Jp-JP.desktop
new file mode 100644
index 0000000000..bc1fb3284b
--- /dev/null
+++ b/krita/data/templates/animation/Anim-Jp-JP.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Type=Link
+URL=.source/Anim-Jp-JP.kra
+Icon=template_animation
+Name=Animation-Japanese-JP
+Name[ca]=Animació-Japonès-JP
+Name[es]=Animación-Japonés-JP
+Name[nl]=Animatie-Japans-JP
+Name[pl]=Animacja-Japońska-JP
+Name[pt]=Animação-Japonês-JP
+Name[sv]=Animering-japanska-jp
+Name[uk]=Японська анімація (японською)
+Name[x-test]=xxAnimation-Japanese-JPxx
diff --git a/krita/data/templates/animation/Anim-Jp-JP.kra b/krita/data/templates/animation/Anim-Jp-JP.kra
new file mode 100644
index 0000000000..87847d73db
Binary files /dev/null and b/krita/data/templates/animation/Anim-Jp-JP.kra differ
diff --git a/krita/data/templates/animation/CMakeLists.txt b/krita/data/templates/animation/CMakeLists.txt
new file mode 100644
index 0000000000..5f1622220b
--- /dev/null
+++ b/krita/data/templates/animation/CMakeLists.txt
@@ -0,0 +1,15 @@
+install( FILES
+template_animation.png
+DESTINATION
+${DATA_INSTALL_DIR}/krita/pics
+)
+
+install( FILES
+ Anim-Jp-EN.kra
+ Anim-Jp-JP.kra
+DESTINATION ${DATA_INSTALL_DIR}/krita/templates/animation/.source)
+
+install( FILES
+ Anim-Jp-EN.desktop
+ Anim-Jp-JP.desktop
+DESTINATION ${DATA_INSTALL_DIR}/krita/templates/animation)
diff --git a/krita/data/templates/animation/template_animation.png b/krita/data/templates/animation/template_animation.png
new file mode 100644
index 0000000000..1c359f732f
Binary files /dev/null and b/krita/data/templates/animation/template_animation.png differ
diff --git a/krita/data/templates/animation/template_animation.svg b/krita/data/templates/animation/template_animation.svg
new file mode 100644
index 0000000000..4f19375fb8
--- /dev/null
+++ b/krita/data/templates/animation/template_animation.svg
@@ -0,0 +1,167 @@
+
+
diff --git a/krita/data/themes/BreezeDark.colors b/krita/data/themes/BreezeDark.colors
new file mode 100644
index 0000000000..e3e3a401dd
--- /dev/null
+++ b/krita/data/themes/BreezeDark.colors
@@ -0,0 +1,119 @@
+[ColorEffects:Disabled]
+Color=56,56,56
+ColorAmount=0
+ColorEffect=0
+ContrastAmount=0.65
+ContrastEffect=1
+IntensityAmount=0.1
+IntensityEffect=2
+
+[ColorEffects:Inactive]
+ChangeSelectionColor=true
+Color=112,111,110
+ColorAmount=0.025
+ColorEffect=2
+ContrastAmount=0.1
+ContrastEffect=2
+Enable=false
+IntensityAmount=0
+IntensityEffect=0
+
+[Colors:Button]
+BackgroundAlternate=77,77,77
+BackgroundNormal=49,54,59
+DecorationFocus=61,174,233
+DecorationHover=61,174,233
+ForegroundActive=61,174,233
+ForegroundInactive=189,195,199
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Selection]
+BackgroundAlternate=29,153,243
+BackgroundNormal=61,174,233
+DecorationFocus=61,174,233
+DecorationHover=61,174,233
+ForegroundActive=252,252,252
+ForegroundInactive=239,240,241
+ForegroundLink=253,188,75
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=189,195,199
+
+[Colors:Tooltip]
+BackgroundAlternate=77,77,77
+BackgroundNormal=49,54,59
+DecorationFocus=61,174,233
+DecorationHover=61,174,233
+ForegroundActive=61,174,233
+ForegroundInactive=189,195,199
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:View]
+BackgroundAlternate=49,54,59
+BackgroundNormal=35,38,41
+DecorationFocus=61,174,233
+DecorationHover=61,174,233
+ForegroundActive=61,174,233
+ForegroundInactive=189,195,199
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Window]
+BackgroundAlternate=77,77,77
+BackgroundNormal=49,54,59
+DecorationFocus=61,174,233
+DecorationHover=61,174,233
+ForegroundActive=61,174,233
+ForegroundInactive=189,195,199
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Complementary]
+BackgroundAlternate=59,64,69
+BackgroundNormal=49,54,59
+DecorationFocus=30,146,255
+DecorationHover=61,174,230
+ForegroundActive=246,116,0
+ForegroundInactive=175,176,179
+ForegroundLink=61,174,230
+ForegroundNegative=237,21,21
+ForegroundNeutral=201,206,59
+ForegroundNormal=239,240,241
+ForegroundPositive=17,209,22
+ForegroundVisited=61,174,230
+
+[General]
+ColorScheme=Breeze Dark
+Name=Breeze Dark
+shadeSortColumn=true
+
+[KDE]
+contrast=4
+
+[WM]
+activeBackground=49,54,59
+activeBlend=255,255,255
+activeForeground=239,240,241
+inactiveBackground=49,54,59
+inactiveBlend=75,71,67
+inactiveForeground=127,140,141
diff --git a/krita/data/themes/BreezeHighContrast.colors b/krita/data/themes/BreezeHighContrast.colors
new file mode 100644
index 0000000000..758f1e9048
--- /dev/null
+++ b/krita/data/themes/BreezeHighContrast.colors
@@ -0,0 +1,119 @@
+[ColorEffects:Disabled]
+Color=56,56,56
+ColorAmount=0
+ColorEffect=0
+ContrastAmount=0.65
+ContrastEffect=1
+IntensityAmount=0.1
+IntensityEffect=2
+
+[ColorEffects:Inactive]
+ChangeSelectionColor=true
+Color=112,111,110
+ColorAmount=0.025
+ColorEffect=2
+ContrastAmount=0.1
+ContrastEffect=2
+Enable=false
+IntensityAmount=0
+IntensityEffect=0
+
+[Colors:Button]
+BackgroundAlternate=189,195,199
+BackgroundNormal=77,77,77
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=61,174,233
+ForegroundInactive=127,140,141
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=252,252,252
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Selection]
+BackgroundAlternate=29,153,243
+BackgroundNormal=52,73,94
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=252,252,252
+ForegroundInactive=252,252,252
+ForegroundLink=253,188,75
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=239,240,241
+ForegroundPositive=39,174,96
+ForegroundVisited=189,195,199
+
+[Colors:Tooltip]
+BackgroundAlternate=77,77,77
+BackgroundNormal=29,153,243
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=61,174,233
+ForegroundInactive=127,140,141
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=252,252,252
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:View]
+BackgroundAlternate=41,44,48
+BackgroundNormal=35,38,41
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=61,174,233
+ForegroundInactive=127,140,141
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=252,252,252
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Window]
+BackgroundAlternate=189,195,199
+BackgroundNormal=49,54,59
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=61,174,233
+ForegroundInactive=127,140,141
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=252,252,252
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[Colors:Complementary]
+BackgroundAlternate=41,44,48
+BackgroundNormal=35,38,41
+DecorationFocus=29,153,243
+DecorationHover=77,77,77
+ForegroundActive=61,174,233
+ForegroundInactive=127,140,141
+ForegroundLink=41,128,185
+ForegroundNegative=218,68,83
+ForegroundNeutral=246,116,0
+ForegroundNormal=252,252,252
+ForegroundPositive=39,174,96
+ForegroundVisited=127,140,141
+
+[General]
+ColorScheme=Breeze High Conttrast
+Name=Breeze High Contrast
+shadeSortColumn=true
+
+[KDE]
+contrast=9
+
+[WM]
+activeBackground=29,153,243
+activeBlend=29,153,243
+activeForeground=252,252,252
+inactiveBackground=49,54,59
+inactiveBlend=26,188,156
+inactiveForeground=252,252,252
diff --git a/krita/data/themes/BreezeLight.colors b/krita/data/themes/BreezeLight.colors
new file mode 100644
index 0000000000..aada764375
--- /dev/null
+++ b/krita/data/themes/BreezeLight.colors
@@ -0,0 +1,119 @@
+[ColorEffects:Disabled]
+Color=56,56,56
+ColorAmount=0
+ColorEffect=0
+ContrastAmount=0.65
+ContrastEffect=1
+IntensityAmount=0.1
+IntensityEffect=2
+
+[ColorEffects:Inactive]
+ChangeSelectionColor=true
+Color=112,111,110
+ColorAmount=0.025
+ColorEffect=2
+ContrastAmount=0.1
+ContrastEffect=2
+Enable=false
+IntensityAmount=0
+IntensityEffect=0
+
+[Colors:Button]
+BackgroundAlternate=224,223,222
+BackgroundNormal=239,240,241
+DecorationFocus=61,174,233
+DecorationHover=142,203,233
+ForegroundActive=255,128,224
+ForegroundInactive=136,135,134
+ForegroundLink=0,87,174
+ForegroundNegative=191,3,3
+ForegroundNeutral=176,128,0
+ForegroundNormal=49,54,59
+ForegroundPositive=0,110,40
+ForegroundVisited=69,40,134
+
+[Colors:Selection]
+BackgroundAlternate=62,138,204
+BackgroundNormal=61,174,233
+DecorationFocus=61,174,233
+DecorationHover=142,203,233
+ForegroundActive=255,128,224
+ForegroundInactive=142,203,233
+ForegroundLink=0,49,110
+ForegroundNegative=156,14,14
+ForegroundNeutral=255,221,0
+ForegroundNormal=252,252,252
+ForegroundPositive=128,255,128
+ForegroundVisited=69,40,134
+
+[Colors:Tooltip]
+BackgroundAlternate=196,224,255
+BackgroundNormal=252,252,252
+DecorationFocus=61,174,233
+DecorationHover=142,203,233
+ForegroundActive=255,128,224
+ForegroundInactive=96,112,128
+ForegroundLink=0,87,174
+ForegroundNegative=191,3,3
+ForegroundNeutral=176,128,0
+ForegroundNormal=49,54,59
+ForegroundPositive=0,110,40
+ForegroundVisited=69,40,134
+
+[Colors:View]
+BackgroundAlternate=248,247,246
+BackgroundNormal=252,252,252
+DecorationFocus=61,174,233
+DecorationHover=142,203,233
+ForegroundActive=255,128,224
+ForegroundInactive=136,135,134
+ForegroundLink=0,87,174
+ForegroundNegative=191,3,3
+ForegroundNeutral=176,128,0
+ForegroundNormal=49,54,59
+ForegroundPositive=0,110,40
+ForegroundVisited=69,40,134
+
+[Colors:Window]
+BackgroundAlternate=218,217,216
+BackgroundNormal=239,240,241
+DecorationFocus=61,174,233
+DecorationHover=142,203,233
+ForegroundActive=255,128,224
+ForegroundInactive=136,135,134
+ForegroundLink=0,87,174
+ForegroundNegative=191,3,3
+ForegroundNeutral=176,128,0
+ForegroundNormal=49,54,59
+ForegroundPositive=0,110,40
+ForegroundVisited=69,40,134
+
+[Colors:Complementary]
+BackgroundAlternate=59,64,69
+BackgroundNormal=49,54,59
+DecorationFocus=30,146,255
+DecorationHover=61,174,230
+ForegroundActive=246,116,0
+ForegroundInactive=175,176,179
+ForegroundLink=61,174,230
+ForegroundNegative=237,21,21
+ForegroundNeutral=201,206,59
+ForegroundNormal=239,240,241
+ForegroundPositive=17,209,22
+ForegroundVisited=61,174,230
+
+[General]
+ColorScheme=Breeze Light
+Name=Breeze Light
+shadeSortColumn=true
+
+[KDE]
+contrast=4
+
+[WM]
+activeBackground=239,240,241
+activeBlend=255,255,255
+activeForeground=49,54,59
+inactiveBackground=239,240,241
+inactiveBlend=75,71,67
+inactiveForeground=137,142,146
diff --git a/krita/data/themes/CMakeLists.txt b/krita/data/themes/CMakeLists.txt
index 0a8b08d9c5..4a5b3fa495 100644
--- a/krita/data/themes/CMakeLists.txt
+++ b/krita/data/themes/CMakeLists.txt
@@ -1,10 +1,13 @@
########### install files ###############
install(FILES
+BreezeDark.colors
+BreezeHighContrast.colors
+BreezeLight.colors
KritaNeutral.colors
KritaBlender.colors
KritaBright.colors
KritaDark.colors
${schemefiles} DESTINATION ${DATA_INSTALL_DIR}/color-schemes
)
diff --git a/krita/pics/Breeze-dark/breeze-dark-icons.qrc b/krita/pics/Breeze-dark/breeze-dark-icons.qrc
index 345a8a9c2d..396a806e69 100644
--- a/krita/pics/Breeze-dark/breeze-dark-icons.qrc
+++ b/krita/pics/Breeze-dark/breeze-dark-icons.qrc
@@ -1,89 +1,89 @@
dark_application-exit.svg
dark_application-pdf.svg
dark_applications-system.svg
dark_arrow-down.svg
dark_arrow-downright.svg
dark_arrow-downleft.svg
dark_arrow-topright.svg
dark_arrow-topleft.svg
dark_arrow-left.svg
dark_arrow-right.svg
dark_arrow-up.svg
dark_bookmarks.svg
dark_configure-shortcuts.svg
dark_configure.svg
dark_configure-toolbars.svg
dark_dialog-cancel.svg
dark_dialog-close.svg
dark_dialog-ok.svg
dark_dialog-warning.svg
dark_document-edit.svg
dark_document-export.svg
dark_document-import.svg
dark_document-new.svg
dark_document-open-recent.svg
dark_document-open.svg
dark_document-print-preview.svg
- dark_document-print.svg
+ dark_document-properties.svg
dark_document-save-as.svg
dark_document-save.svg
dark_download.svg
dark_drive-harddisk.svg
dark_edit-clear.svg
dark_edit-copy.svg
dark_edit-cut.svg
dark_edit-delete.svg
dark_edit-paste.svg
dark_edit-redo.svg
dark_edit-undo.svg
dark_folder-documents.svg
dark_folder-pictures.svg
dark_folder.svg
dark_format-list-unordered.svg
dark_go-home.svg
dark_go-next.svg
dark_go-previous.svg
dark_go-up.svg
dark_help-contents.svg
dark_im-user.svg
dark_kde.svg
dark_layer-visible-off.svg
dark_link.svg
dark_list-add.svg
dark_locked.svg
dark_media-playback-start.svg
dark_media-playback-stop.svg
dark_media-record.svg
dark_object-locked.svg
dark_object-rotate-left.svg
dark_object-rotate-right.svg
dark_object-unlocked.svg
dark_preferences-desktop-color.svg
dark_preferences-desktop-display.svg
dark_preferences-desktop-locale.svg
dark_process-stop.svg
dark_select-all.svg
dark_select-clear.svg
dark_system-help.svg
dark_tools-report-bug.svg
dark_tools-wizard.svg
dark_unlocked.svg
dark_view-choose.svg
dark_view-filter.svg
dark_view-fullscreen.svg
dark_view-grid.svg
dark_view-list-details.svg
dark_view-list-text.svg
dark_view-preview.svg
dark_view-refresh.svg
dark_window-close.svg
dark_window-new.svg
dark_zoom-in.svg
dark_zoom-original.svg
dark_zoom-out.svg
diff --git a/krita/pics/Breeze-dark/dark_document-properties.svg b/krita/pics/Breeze-dark/dark_document-properties.svg
new file mode 120000
index 0000000000..489d15bce0
--- /dev/null
+++ b/krita/pics/Breeze-dark/dark_document-properties.svg
@@ -0,0 +1 @@
+dark_configure.svg
\ No newline at end of file
diff --git a/krita/pics/Breeze-light/breeze-light-icons.qrc b/krita/pics/Breeze-light/breeze-light-icons.qrc
index ea891c07fc..3cfa9133d2 100644
--- a/krita/pics/Breeze-light/breeze-light-icons.qrc
+++ b/krita/pics/Breeze-light/breeze-light-icons.qrc
@@ -1,89 +1,90 @@
light_application-exit.svg
light_application-pdf.svg
light_applications-system.svg
light_arrow-down.svg
light_arrow-downright.svg
light_arrow-downleft.svg
light_arrow-topright.svg
light_arrow-topleft.svg
light_arrow-left.svg
light_arrow-right.svg
light_arrow-up.svg
light_bookmarks.svg
light_configure-shortcuts.svg
light_configure.svg
light_configure-toolbars.svg
light_dialog-cancel.svg
light_dialog-close.svg
light_dialog-ok.svg
light_dialog-warning.svg
light_document-edit.svg
light_document-export.svg
light_document-import.svg
light_document-new.svg
light_document-open-recent.svg
light_document-open.svg
light_document-print-preview.svg
light_document-print.svg
+ light_document-properties.svg
light_document-save-as.svg
light_document-save.svg
light_download.svg
light_drive-harddisk.svg
light_edit-clear.svg
light_edit-copy.svg
light_edit-cut.svg
light_edit-delete.svg
light_edit-paste.svg
light_edit-redo.svg
light_edit-undo.svg
light_folder-documents.svg
light_folder-pictures.svg
light_folder.svg
light_format-list-unordered.svg
light_go-home.svg
light_go-next.svg
light_go-previous.svg
light_go-up.svg
light_help-contents.svg
light_im-user.svg
light_kde.svg
light_layer-visible-off.svg
light_link.svg
light_list-add.svg
light_locked.svg
light_media-playback-start.svg
light_media-playback-stop.svg
light_media-record.svg
light_object-locked.svg
light_object-rotate-left.svg
light_object-rotate-right.svg
light_object-unlocked.svg
light_preferences-desktop-color.svg
light_preferences-desktop-display.svg
light_preferences-desktop-locale.svg
light_process-stop.svg
light_select-all.svg
light_select-clear.svg
light_system-help.svg
light_tools-report-bug.svg
light_tools-wizard.svg
light_unlocked.svg
light_view-choose.svg
light_view-filter.svg
light_view-fullscreen.svg
light_view-grid.svg
light_view-list-details.svg
light_view-list-text.svg
light_view-preview.svg
light_view-refresh.svg
light_window-close.svg
light_window-new.svg
light_zoom-in.svg
light_zoom-original.svg
light_zoom-out.svg
diff --git a/krita/pics/Breeze-light/light_document-properties.svg b/krita/pics/Breeze-light/light_document-properties.svg
new file mode 120000
index 0000000000..b0c09418e0
--- /dev/null
+++ b/krita/pics/Breeze-light/light_document-properties.svg
@@ -0,0 +1 @@
+light_configure.svg
\ No newline at end of file
diff --git a/krita/pics/app/sc-apps-calligrakrita.svgz b/krita/pics/app/sc-apps-calligrakrita.svgz
index 494468ec7c..a2ad31fcfd 100644
Binary files a/krita/pics/app/sc-apps-calligrakrita.svgz and b/krita/pics/app/sc-apps-calligrakrita.svgz differ
diff --git a/krita/pics/mimetypes/128/application-x-krita.png b/krita/pics/mimetypes/128/application-x-krita.png
new file mode 100644
index 0000000000..07479934d1
Binary files /dev/null and b/krita/pics/mimetypes/128/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/16/application-x-krita.png b/krita/pics/mimetypes/16/application-x-krita.png
new file mode 100644
index 0000000000..53e73f45dc
Binary files /dev/null and b/krita/pics/mimetypes/16/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/22/application-x-krita.png b/krita/pics/mimetypes/22/application-x-krita.png
new file mode 100644
index 0000000000..2ee2bfce3a
Binary files /dev/null and b/krita/pics/mimetypes/22/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/32/application-x-krita.png b/krita/pics/mimetypes/32/application-x-krita.png
new file mode 100644
index 0000000000..0960a9ea11
Binary files /dev/null and b/krita/pics/mimetypes/32/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/48/application-x-krita.png b/krita/pics/mimetypes/48/application-x-krita.png
new file mode 100644
index 0000000000..3d03c0827b
Binary files /dev/null and b/krita/pics/mimetypes/48/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/64/application-x-krita.png b/krita/pics/mimetypes/64/application-x-krita.png
new file mode 100644
index 0000000000..3c7b37c9a4
Binary files /dev/null and b/krita/pics/mimetypes/64/application-x-krita.png differ
diff --git a/krita/pics/mimetypes/sources/application-x-krita-16.svg b/krita/pics/mimetypes/sources/application-x-krita-16.svg
new file mode 100644
index 0000000000..b5aaeee97e
--- /dev/null
+++ b/krita/pics/mimetypes/sources/application-x-krita-16.svg
@@ -0,0 +1,1628 @@
+
+
+
+
diff --git a/krita/pics/mimetypes/sources/application-x-krita-22.svg b/krita/pics/mimetypes/sources/application-x-krita-22.svg
new file mode 100644
index 0000000000..0881839f7f
--- /dev/null
+++ b/krita/pics/mimetypes/sources/application-x-krita-22.svg
@@ -0,0 +1,1727 @@
+
+
+
+
diff --git a/krita/pics/mimetypes/sources/application-x-krita.svg b/krita/pics/mimetypes/sources/application-x-krita.svg
new file mode 100644
index 0000000000..7cc04e6f86
--- /dev/null
+++ b/krita/pics/mimetypes/sources/application-x-krita.svg
@@ -0,0 +1,1762 @@
+
+
diff --git a/libs/flake/KoTosContainer.cpp b/libs/flake/KoTosContainer.cpp
index 697a489323..78909eeee5 100644
--- a/libs/flake/KoTosContainer.cpp
+++ b/libs/flake/KoTosContainer.cpp
@@ -1,352 +1,352 @@
/* This file is part of the KDE project
* Copyright (C) 2010 Thomas Zander
* Copyright (C) 2010 KO GmbH
* Copyright (C) 2010 Thorsten Zachmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoTosContainer.h"
#include "KoTosContainer_p.h"
#include "KoShapeRegistry.h"
#include "KoShapeFactoryBase.h"
#include "KoShapeLoadingContext.h"
#include "KoTextShapeDataBase.h"
#include "KoTosContainerModel.h"
#include "KoStyleStack.h"
#include "KoOdfLoadingContext.h"
#include "KoXmlNS.h"
#include "KoGenStyle.h"
#include
#include
#include
KoTosContainerPrivate::KoTosContainerPrivate(KoShapeContainer *q)
: KoShapeContainerPrivate(q)
, resizeBehavior(KoTosContainer::IndependentSizes)
{
}
KoTosContainerPrivate::~KoTosContainerPrivate()
{
}
KoTosContainer::KoTosContainer()
: KoShapeContainer(*(new KoTosContainerPrivate(this)))
{
}
KoTosContainer::~KoTosContainer()
{
delete textShape();
}
KoTosContainer::KoTosContainer(KoTosContainerPrivate &dd)
: KoShapeContainer(dd)
{
}
void KoTosContainer::paintComponent(QPainter &, const KoViewConverter &, KoShapePaintingContext &)
{
}
bool KoTosContainer::loadText(const KoXmlElement &element, KoShapeLoadingContext &context)
{
Q_D(const KoTosContainer);
KoXmlElement child;
forEachElement(child, element) {
// only recreate the text shape if there's something to be loaded
if (child.localName() == "p" || child.localName() == "list") {
KoShape *textShape = createTextShape(context.documentResourceManager());
if (!textShape) {
return false;
}
//apply the style properties to the loaded text
setTextAlignment(d->alignment);
// In the case of text on shape, we cannot ask the text shape to load
// the odf, since it expects a complete document with style info and
// everything, so we have to use the KoTextShapeData object instead.
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
Q_ASSERT(shapeData);
shapeData->loadStyle(element, context);
bool loadOdf = shapeData->loadOdf(element, context);
return loadOdf;
}
}
return true;
}
void KoTosContainer::loadStyle(const KoXmlElement &element, KoShapeLoadingContext &context)
{
Q_D(KoTosContainer);
KoShapeContainer::loadStyle(element, context);
KoStyleStack &styleStack = context.odfLoadingContext().styleStack();
styleStack.setTypeProperties("graphic");
QString verticalAlign(styleStack.property(KoXmlNS::draw, "textarea-vertical-align"));
Qt::Alignment vAlignment(Qt::AlignTop);
if (verticalAlign == "bottom") {
vAlignment = Qt::AlignBottom;
} else if (verticalAlign == "justify") {
// not yet supported
vAlignment = Qt::AlignVCenter;
} else if (verticalAlign == "middle") {
vAlignment = Qt::AlignVCenter;
}
QString horizontalAlign(styleStack.property(KoXmlNS::draw, "textarea-horizontal-align"));
Qt::Alignment hAlignment(Qt::AlignLeft);
if (horizontalAlign == "center") {
hAlignment = Qt::AlignCenter;
} else if (horizontalAlign == "justify") {
// not yet supported
hAlignment = Qt::AlignCenter;
} else if (horizontalAlign == "right") {
hAlignment = Qt::AlignRight;
}
d->alignment = vAlignment | hAlignment;
}
QString KoTosContainer::saveStyle(KoGenStyle &style, KoShapeSavingContext &context) const
{
Qt::Alignment alignment = textAlignment();
QString verticalAlignment = "top";
Qt::Alignment vAlignment(alignment & Qt::AlignVertical_Mask);
if (vAlignment == Qt::AlignBottom) {
verticalAlignment = "bottom";
} else if (vAlignment == Qt::AlignVCenter || vAlignment == Qt::AlignCenter) {
verticalAlignment = "middle";
}
style.addProperty("draw:textarea-vertical-align", verticalAlignment);
QString horizontalAlignment = "left";
Qt::Alignment hAlignment(alignment & Qt::AlignHorizontal_Mask);
if (hAlignment == Qt::AlignCenter || hAlignment == Qt::AlignHCenter) {
horizontalAlignment = "center";
} else if (hAlignment == Qt::AlignJustify) {
horizontalAlignment = "justify";
} else if (hAlignment == Qt::AlignRight) {
horizontalAlignment = "right";
}
style.addProperty("draw:textarea-horizontal-align", horizontalAlignment);
return KoShapeContainer::saveStyle(style, context);
}
void KoTosContainer::saveText(KoShapeSavingContext &context) const
{
KoShape *textShape = this->textShape();
if (!textShape) {
return;
}
// In the case of text on shape, we cannot ask the text shape to save
// the odf, since it would save all the frame information as well, which
// is wrong.
// Only save the text shape if it has content.
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
if (shapeData && !shapeData->document()->isEmpty()) {
shapeData->saveOdf(context);
}
}
void KoTosContainer::setPlainText(const QString &text)
{
KoShape *textShape = this->textShape();
if (textShape == 0) {
warnFlake << "No text shape present in KoTosContainer";
return;
}
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
Q_ASSERT(shapeData->document());
shapeData->document()->setPlainText(text);
}
void KoTosContainer::setResizeBehavior(ResizeBehavior resizeBehavior)
{
Q_D(KoTosContainer);
if (d->resizeBehavior == resizeBehavior) {
return;
}
d->resizeBehavior = resizeBehavior;
if (d->model) {
d->model->containerChanged(this, KoShape::SizeChanged);
}
}
KoTosContainer::ResizeBehavior KoTosContainer::resizeBehavior() const
{
Q_D(const KoTosContainer);
return d->resizeBehavior;
}
void KoTosContainer::setTextAlignment(Qt::Alignment alignment)
{
Q_D(KoTosContainer);
KoShape *textShape = this->textShape();
if (textShape == 0) {
warnFlake << "No text shape present in KoTosContainer";
return;
}
// vertical
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
shapeData->setVerticalAlignment(alignment);
// horizontal
Q_ASSERT(shapeData->document());
QTextBlockFormat bf;
bf.setAlignment(alignment & Qt::AlignHorizontal_Mask);
QTextCursor cursor(shapeData->document());
- cursor.setPosition(QTextCursor::End, QTextCursor::KeepAnchor);
+ cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
cursor.mergeBlockFormat(bf);
d->alignment = alignment;
}
Qt::Alignment KoTosContainer::textAlignment() const
{
KoShape *textShape = this->textShape();
if (textShape == 0) {
warnFlake << "No text shape present in KoTosContainer";
return Qt::AlignTop;
}
// vertical
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
// the model makes sure it contains a shape that has a KoTextShapeDataBase set so no need to check that
Qt::Alignment answer = shapeData->verticalAlignment() & Qt::AlignVertical_Mask;
// horizontal
Q_ASSERT(shapeData->document());
QTextCursor cursor(shapeData->document());
answer = answer | (cursor.blockFormat().alignment() & Qt::AlignHorizontal_Mask);
return answer;
}
void KoTosContainer::setPreferredTextRect(const QRectF &rect)
{
Q_D(KoTosContainer);
d->preferredTextRect = rect;
KoShape *textShape = this->textShape();
//debugFlake << rect << textShape << d->resizeBehavior;
if (d->resizeBehavior == TextFollowsPreferredTextRect && textShape) {
//debugFlake << rect;
textShape->setPosition(rect.topLeft());
textShape->setSize(rect.size());
}
}
QRectF KoTosContainer::preferredTextRect() const
{
Q_D(const KoTosContainer);
return d->preferredTextRect;
}
KoShape *KoTosContainer::createTextShape(KoDocumentResourceManager *documentResources)
{
if (!documentResources) {
warnFlake << "KoDocumentResourceManager not found";
return 0;
}
Q_D(KoTosContainer);
delete textShape();
delete d->model;
d->model = new KoTosContainerModel();
QSet delegates;
delegates << this;
KoShape *textShape = 0;
KoShapeFactoryBase *factory = KoShapeRegistry::instance()->get("TextShapeID");
if (factory) { // not installed, thats too bad, but allowed
textShape = factory->createDefaultShape(documentResources);
Q_ASSERT(textShape); // would be a bug in the text shape;
if (d->resizeBehavior == TextFollowsPreferredTextRect) {
textShape->setSize(d->preferredTextRect.size());
} else {
textShape->setSize(size());
}
if (d->resizeBehavior == TextFollowsPreferredTextRect) {
textShape->setPosition(d->preferredTextRect.topLeft());
} else {
textShape->setPosition(QPointF(0, 0));
}
textShape->setSelectable(false);
textShape->setRunThrough(runThrough());
KoTextShapeDataBase *shapeData = qobject_cast(textShape->userData());
Q_ASSERT(shapeData); // would be a bug in kotext
// TODO check if that is correct depending on the resize mode
shapeData->setVerticalAlignment(Qt::AlignVCenter);
addShape(textShape);
// textShape->setZIndex(zIndex() + 1); // not needed as there as the text shape is the only sub shape
delegates << textShape;
} else {
warnFlake << "Text shape factory not found";
}
setToolDelegates(delegates);
return textShape;
}
KoShape *KoTosContainer::textShape() const
{
const QList subShapes = shapes();
return subShapes.isEmpty() ? 0 : subShapes.at(0);
}
void KoTosContainer::shapeChanged(ChangeType type, KoShape *shape)
{
Q_UNUSED(shape);
Q_D(KoTosContainer);
if (d->model == 0) {
return;
}
if (type == SizeChanged || type == ContentChanged) {
d->model->containerChanged(this, type);
}
// TODO is this needed?
#if 0
Q_FOREACH (KoShape *shape, d->model->shapes())
shape->notifyChanged();
#endif
}
void KoTosContainer::setRunThrough(short int runThrough)
{
KoShape::setRunThrough(runThrough);
KoShape *textShape = this->textShape();
if (textShape) {
textShape->setRunThrough(runThrough);
}
}
diff --git a/libs/image/brushengine/kis_paintop.cc b/libs/image/brushengine/kis_paintop.cc
index cd25d953a4..072dbbea2a 100644
--- a/libs/image/brushengine/kis_paintop.cc
+++ b/libs/image/brushengine/kis_paintop.cc
@@ -1,196 +1,171 @@
/*
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt
* Copyright (c) 2004 Clarence Dang
* Copyright (c) 2004 Adrian Page
* Copyright (c) 2004,2007,2010 Cyrille Berger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_paintop.h"
#include
#include
#include
#include
#include "kis_painter.h"
#include "kis_layer.h"
#include "kis_image.h"
#include "kis_paint_device.h"
#include "kis_global.h"
#include "kis_datamanager.h"
#include
#include
#include "kis_vec.h"
#include "kis_perspective_math.h"
#include "kis_fixed_paint_device.h"
#include "kis_paintop_utils.h"
#define BEZIER_FLATNESS_THRESHOLD 0.5
#include
#include
struct Q_DECL_HIDDEN KisPaintOp::Private {
Private(KisPaintOp *_q)
: q(_q), dab(0),
- currentScale(1.0),
- currentRotation(0),
fanCornersEnabled(false),
fanCornersStep(1.0) {}
KisPaintOp *q;
KisFixedPaintDeviceSP dab;
KisPainter* painter;
- qreal currentScale;
- qreal currentRotation;
bool fanCornersEnabled;
qreal fanCornersStep;
};
KisPaintOp::KisPaintOp(KisPainter * painter) : d(new Private(this))
{
d->painter = painter;
}
KisPaintOp::~KisPaintOp()
{
d->dab.clear();
delete d;
}
KisFixedPaintDeviceSP KisPaintOp::cachedDab()
{
return cachedDab(d->painter->device()->colorSpace());
}
KisFixedPaintDeviceSP KisPaintOp::cachedDab(const KoColorSpace *cs)
{
if (!d->dab || !(*d->dab->colorSpace() == *cs)) {
d->dab = new KisFixedPaintDevice(cs);
}
return d->dab;
}
void KisPaintOp::setFanCornersInfo(bool fanCornersEnabled, qreal fanCornersStep)
{
d->fanCornersEnabled = fanCornersEnabled;
d->fanCornersStep = fanCornersStep;
}
void KisPaintOp::splitCoordinate(qreal coordinate, qint32 *whole, qreal *fraction)
{
const qint32 i = std::floor(coordinate);
const qreal f = coordinate - i;
*whole = i;
*fraction = f;
}
static void paintBezierCurve(KisPaintOp *paintOp,
const KisPaintInformation &pi1,
const KisVector2D &control1,
const KisVector2D &control2,
const KisPaintInformation &pi2,
KisDistanceInformation *currentDistance)
{
LineEquation line = LineEquation::Through(toKisVector2D(pi1.pos()), toKisVector2D(pi2.pos()));
qreal d1 = line.absDistance(control1);
qreal d2 = line.absDistance(control2);
if ((d1 < BEZIER_FLATNESS_THRESHOLD && d2 < BEZIER_FLATNESS_THRESHOLD)
|| qIsNaN(d1) || qIsNaN(d2)) {
paintOp->paintLine(pi1, pi2, currentDistance);
} else {
// Midpoint subdivision. See Foley & Van Dam Computer Graphics P.508
KisVector2D l2 = (toKisVector2D(pi1.pos()) + control1) / 2;
KisVector2D h = (control1 + control2) / 2;
KisVector2D l3 = (l2 + h) / 2;
KisVector2D r3 = (control2 + toKisVector2D(pi2.pos())) / 2;
KisVector2D r2 = (h + r3) / 2;
KisVector2D l4 = (l3 + r2) / 2;
KisPaintInformation middlePI = KisPaintInformation::mix(toQPointF(l4), 0.5, pi1, pi2);
paintBezierCurve(paintOp, pi1, l2, l3, middlePI, currentDistance);
paintBezierCurve(paintOp, middlePI, r2, r3, pi2, currentDistance);
}
}
void KisPaintOp::paintBezierCurve(const KisPaintInformation &pi1,
const QPointF &control1,
const QPointF &control2,
const KisPaintInformation &pi2,
KisDistanceInformation *currentDistance)
{
return ::paintBezierCurve(this, pi1, toKisVector2D(control1), toKisVector2D(control2), pi2, currentDistance);
}
void KisPaintOp::paintLine(const KisPaintInformation &pi1,
const KisPaintInformation &pi2,
KisDistanceInformation *currentDistance)
{
KisPaintOpUtils::paintLine(*this, pi1, pi2, currentDistance,
d->fanCornersEnabled,
d->fanCornersStep);
}
void KisPaintOp::paintAt(const KisPaintInformation& info, KisDistanceInformation *currentDistance)
{
Q_ASSERT(currentDistance);
KisPaintInformation pi(info);
pi.paintAt(*this, currentDistance);
}
KisPainter* KisPaintOp::painter() const
{
return d->painter;
}
KisPaintDeviceSP KisPaintOp::source() const
{
return d->painter->device();
}
-
-qreal KisPaintOp::currentRotation() const
-{
- return d->currentRotation;
-}
-
-qreal KisPaintOp::currentScale() const
-{
- return d->currentScale;
-}
-
-void KisPaintOp::setCurrentRotation(qreal rotation)
-{
- d->currentRotation = rotation;
-}
-
-void KisPaintOp::setCurrentScale(qreal scale)
-{
- d->currentScale = scale;
-}
-
diff --git a/libs/image/brushengine/kis_paintop.h b/libs/image/brushengine/kis_paintop.h
index f12d8e77bd..adec15f84f 100644
--- a/libs/image/brushengine/kis_paintop.h
+++ b/libs/image/brushengine/kis_paintop.h
@@ -1,143 +1,129 @@
/*
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt
* Copyright (c) 2004 Clarence Dang
* Copyright (c) 2004 Adrian Page
* Copyright (c) 2004,2010 Cyrille Berger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_PAINTOP_H_
#define KIS_PAINTOP_H_
#include
#include "kis_shared.h"
#include "kis_types.h"
#include
class QPointF;
class KoColorSpace;
class KisPainter;
class KisPaintInformation;
/**
* KisPaintOp are use by tools to draw on a paint device. A paintop takes settings
* and input information, like pressure, tilt or motion and uses that to draw pixels
*/
class KRITAIMAGE_EXPORT KisPaintOp : public KisShared
{
struct Private;
public:
KisPaintOp(KisPainter * painter);
virtual ~KisPaintOp();
/**
* Paint at the subpixel point pos using the specified paint
* information..
*
* The distance between two calls of the paintAt is always
* specified by spacing, which is automatically saved into the
* current distance information object
*/
void paintAt(const KisPaintInformation& info, KisDistanceInformation *currentDistance);
/**
* Draw a line between pos1 and pos2 using the currently set brush and color.
* If savedDist is less than zero, the brush is painted at pos1 before being
* painted along the line using the spacing setting.
*
* @return the drag distance, that is the remains of the distance
* between p1 and p2 not covered because the currenlty set brush
* has a spacing greater than that distance.
*/
virtual void paintLine(const KisPaintInformation &pi1,
const KisPaintInformation &pi2,
KisDistanceInformation *currentDistance);
/**
* Draw a Bezier curve between pos1 and pos2 using control points 1 and 2.
* If savedDist is less than zero, the brush is painted at pos1 before being
* painted along the curve using the spacing setting.
* @return the drag distance, that is the remains of the distance between p1 and p2 not covered
* because the currenlty set brush has a spacing greater than that distance.
*/
virtual void paintBezierCurve(const KisPaintInformation &pi1,
const QPointF &control1,
const QPointF &control2,
const KisPaintInformation &pi2,
KisDistanceInformation *currentDistance);
/**
* Whether this paintop can paint. Can be false in case that some setting isn't read correctly.
* @return if paintop is ready for painting, default is true
*/
virtual bool canPaint() const {
return true;
}
/**
* Split the coordinate into whole + fraction, where fraction is always >= 0.
*/
static void splitCoordinate(qreal coordinate, qint32 *whole, qreal *fraction);
- /**
- * returns the scale and rotation dynamically computed for the single dab
- * rotation is in radians
- * This is used e.g. for dynamic brush outline
- */
- qreal currentScale() const;
- qreal currentRotation() const;
-
protected:
friend class KisPaintInformation;
/**
* The implementation of painting of a dab
*/
virtual KisSpacingInformation paintAt(const KisPaintInformation& info) = 0;
- void setCurrentScale(qreal scale);
- /**
- * Set rotation in radians
- */
- void setCurrentRotation(qreal rotation);
-
KisFixedPaintDeviceSP cachedDab();
KisFixedPaintDeviceSP cachedDab(const KoColorSpace *cs);
/**
* Return the painter this paintop is owned by
*/
KisPainter* painter() const;
/**
* Return the paintdevice the painter this paintop is owned by
*/
KisPaintDeviceSP source() const;
private:
friend class KisPressureRotationOption;
void setFanCornersInfo(bool fanCornersEnabled, qreal fanCornersStep);
private:
Private* const d;
};
#endif // KIS_PAINTOP_H_
diff --git a/libs/image/kis_image_lock_hijacker.h b/libs/image/kis_image_lock_hijacker.h
new file mode 100644
index 0000000000..e2f928ecc7
--- /dev/null
+++ b/libs/image/kis_image_lock_hijacker.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Dmitry Kazakov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_IMAGE_LOCK_HIJACKER_H
+#define __KIS_IMAGE_LOCK_HIJACKER_H
+
+#include
+#include
+
+
+#include "kis_image.h"
+#include "kis_debug.h"
+
+/**
+ * This class removes all the locks from the image on construction and
+ * resets them back on destruction. Never use this class unless you
+ * really know what you are doing!
+ *
+ * Never!
+ */
+
+class KisImageLockHijacker
+{
+public:
+ KisImageLockHijacker(KisImageSP image)
+ : m_image(image),
+ m_count(0)
+ {
+ QThread *currentThread = QThread::currentThread();
+ KIS_ASSERT_RECOVER_RETURN(image->thread() == currentThread);
+ KIS_ASSERT_RECOVER_RETURN(qApp->thread() == currentThread);
+
+ while(image->locked()) {
+ m_count++;
+ m_image->unlock();
+ }
+ }
+
+ ~KisImageLockHijacker() {
+ while (m_count--) {
+ m_image->barrierLock();
+ }
+ }
+
+private:
+ KisImageSP m_image;
+ int m_count;
+};
+
+#endif /* __KIS_IMAGE_LOCK_HIJACKER_H */
diff --git a/libs/pigment/KoBasicHistogramProducers.cpp b/libs/pigment/KoBasicHistogramProducers.cpp
index deab2d5ab1..2b5d1431cc 100644
--- a/libs/pigment/KoBasicHistogramProducers.cpp
+++ b/libs/pigment/KoBasicHistogramProducers.cpp
@@ -1,517 +1,525 @@
/*
* Copyright (c) 2005 Bart Coppens
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "KoBasicHistogramProducers.h"
#include
#include
#include
#ifdef HAVE_OPENEXR
#include
#endif
// #include "Ko_global.h"
#include "KoIntegerMaths.h"
#include "KoChannelInfo.h"
static const KoColorSpace* m_labCs = 0;
KoBasicHistogramProducer::KoBasicHistogramProducer(const KoID& id, int channelCount, int nrOfBins)
: m_channels(channelCount)
, m_nrOfBins(nrOfBins)
, m_colorSpace(0)
, m_id(id)
{
m_bins.resize(m_channels);
for (int i = 0; i < m_channels; i++)
m_bins[i].resize(m_nrOfBins);
m_outLeft.resize(m_channels);
m_outRight.resize(m_channels);
m_count = 0;
m_from = 0.0;
m_width = 1.0;
}
KoBasicHistogramProducer::KoBasicHistogramProducer(const KoID& id, int nrOfBins, const KoColorSpace *cs)
: m_nrOfBins(nrOfBins),
m_colorSpace(cs),
m_id(id)
{
Q_ASSERT(cs);
m_channels = cs->channelCount();
m_bins.resize(m_channels);
for (int i = 0; i < m_channels; i++)
m_bins[i].resize(m_nrOfBins);
m_outLeft.resize(m_channels);
m_outRight.resize(m_channels);
m_count = 0;
m_from = 0.0;
m_width = 1.0;
}
void KoBasicHistogramProducer::clear()
{
m_count = 0;
for (int i = 0; i < m_channels; i++) {
for (int j = 0; j < m_nrOfBins; j++) {
m_bins[i][j] = 0;
}
m_outRight[i] = 0;
m_outLeft[i] = 0;
}
}
void KoBasicHistogramProducer::makeExternalToInternal()
{
// This function assumes that the pixel is has no 'gaps'. That is to say: if we start
// at byte 0, we can get to the end of the pixel by adding consecutive size()s of
// the channels
QList c = channels();
uint count = c.count();
int currentPos = 0;
for (uint i = 0; i < count; i++) {
for (uint j = 0; j < count; j++) {
if (c[j]->pos() == currentPos) {
m_external.append(j);
break;
}
}
currentPos += c.at(m_external.at(m_external.count() - 1))->size();
}
}
// ------------ U8 ---------------------
KoBasicU8HistogramProducer::KoBasicU8HistogramProducer(const KoID& id, const KoColorSpace *cs)
: KoBasicHistogramProducer(id, 256, cs)
{
}
QString KoBasicU8HistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos * UINT8_MAX));
}
void KoBasicU8HistogramProducer::addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
- qint32 pSize = cs->pixelSize();
+ quint32 dstPixelSize = m_colorSpace->pixelSize();
+ quint8 *dstPixels = new quint8[nPixels * dstPixelSize];
+ cs->convertPixelsTo(pixels, dstPixels, m_colorSpace, nPixels, KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::Empty);
if (selectionMask) {
+ quint8 *dst = dstPixels;
while (nPixels > 0) {
- if (!(m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
+ if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
- for (int i = 0; i < m_channels; i++) {
- m_bins[i][pixels[i]]++;
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ m_bins[i][m_colorSpace->scaleToU8(dst,i)]++;
}
m_count++;
-
}
-
- pixels += pSize;
+ dst += dstPixelSize;
selectionMask++;
nPixels--;
}
} else {
+ quint8 *dst = dstPixels;
while (nPixels > 0) {
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
- for (int i = 0; i < m_channels; i++) {
- m_bins[i][pixels[i]]++;
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ m_bins[i][m_colorSpace->scaleToU8(dst,i)]++;
}
m_count++;
-
}
-
- pixels += pSize;
+ dst += dstPixelSize;
nPixels--;
}
}
}
// ------------ U16 ---------------------
KoBasicU16HistogramProducer::KoBasicU16HistogramProducer(const KoID& id, const KoColorSpace *cs)
: KoBasicHistogramProducer(id, 256, cs)
{
}
QString KoBasicU16HistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos * UINT8_MAX));
}
qreal KoBasicU16HistogramProducer::maximalZoom() const
{
return 1.0 / 255.0;
}
void KoBasicU16HistogramProducer::addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
// The view
quint16 from = static_cast(m_from * UINT16_MAX);
quint16 width = static_cast(m_width * UINT16_MAX + 0.5); // We include the end
quint16 to = from + width;
qreal factor = 255.0 / width;
- qint32 pSize = cs->pixelSize();
+ quint32 dstPixelSize = m_colorSpace->pixelSize();
+ quint8 *dstPixels = new quint8[nPixels * dstPixelSize];
+ cs->convertPixelsTo(pixels, dstPixels, m_colorSpace, nPixels, KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::Empty);
+ quint8 *dst = dstPixels;
+ QVector channels(m_colorSpace->channelCount());
if (selectionMask) {
- const quint16* pixel = reinterpret_cast(pixels);
while (nPixels > 0) {
if (!((m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8))) {
- for (int i = 0; i < m_channels; i++) {
- quint16 value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ quint16 value = channels[i]*UINT16_MAX;
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
- pixels += pSize;
+ dst += dstPixelSize;
selectionMask++;
nPixels--;
}
} else {
while (nPixels > 0) {
- const quint16* pixel = reinterpret_cast(pixels);
-
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
- for (int i = 0; i < m_channels; i++) {
- quint16 value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ quint16 value = channels[i]*UINT16_MAX;
+
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
- pixels += pSize;
+ dst += dstPixelSize;
nPixels--;
-
}
}
}
// ------------ Float32 ---------------------
KoBasicF32HistogramProducer::KoBasicF32HistogramProducer(const KoID& id, const KoColorSpace *cs)
: KoBasicHistogramProducer(id, 256, cs)
{
}
QString KoBasicF32HistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos)); // XXX I doubt this is correct!
}
qreal KoBasicF32HistogramProducer::maximalZoom() const
{
// XXX What _is_ the maximal zoom here? I don't think there is one with floats, so this seems a fine compromis for the moment
return 1.0 / 255.0;
}
void KoBasicF32HistogramProducer::addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
// The view
float from = static_cast(m_from);
float width = static_cast(m_width);
float to = from + width;
float factor = 255.0 / width;
- qint32 pSize = cs->pixelSize();
+ quint32 dstPixelSize = m_colorSpace->pixelSize();
+ quint8 *dstPixels = new quint8[nPixels * dstPixelSize];
+ cs->convertPixelsTo(pixels, dstPixels, m_colorSpace, nPixels, KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::Empty);
+ quint8 *dst = dstPixels;
+ QVector channels(m_colorSpace->channelCount());
if (selectionMask) {
while (nPixels > 0) {
-
- const float* pixel = reinterpret_cast(pixels);
if (!((m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8))) {
- for (int i = 0; i < m_channels; i++) {
- float value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ float value = channels[i];
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
-
- pixels += pSize;
+ dst += dstPixelSize;
selectionMask++;
nPixels--;
}
} else {
while (nPixels > 0) {
-
- const float* pixel = reinterpret_cast(pixels);
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
- for (int i = 0; i < m_channels; i++) {
- float value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ float value = channels[i];
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
-
- pixels += pSize;
+ dst += dstPixelSize;
nPixels--;
}
}
}
#ifdef HAVE_OPENEXR
// ------------ Float16 Half ---------------------
KoBasicF16HalfHistogramProducer::KoBasicF16HalfHistogramProducer(const KoID& id,
const KoColorSpace *cs)
: KoBasicHistogramProducer(id, 256, cs)
{
}
QString KoBasicF16HalfHistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos)); // XXX I doubt this is correct!
}
qreal KoBasicF16HalfHistogramProducer::maximalZoom() const
{
// XXX What _is_ the maximal zoom here? I don't think there is one with floats, so this seems a fine compromis for the moment
return 1.0 / 255.0;
}
void KoBasicF16HalfHistogramProducer::addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
// The view
float from = static_cast(m_from);
float width = static_cast(m_width);
float to = from + width;
float factor = 255.0 / width;
- qint32 pSize = cs->pixelSize();
+ quint32 dstPixelSize = m_colorSpace->pixelSize();
+ quint8 *dstPixels = new quint8[nPixels * dstPixelSize];
+ cs->convertPixelsTo(pixels, dstPixels, m_colorSpace, nPixels, KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::Empty);
+ quint8 *dst = dstPixels;
+ QVector channels(m_colorSpace->channelCount());
+
if (selectionMask) {
while (nPixels > 0) {
- const half* pixel = reinterpret_cast(pixels);
if (!((m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8))) {
- for (int i = 0; i < m_channels; i++) {
- float value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ float value = channels[i];
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
- pixels += pSize;
+ dst += dstPixelSize;
selectionMask++;
nPixels--;
}
} else {
while (nPixels > 0) {
- const half* pixel = reinterpret_cast(pixels);
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
- for (int i = 0; i < m_channels; i++) {
- float value = pixel[i];
+ m_colorSpace->normalisedChannelsValue(dst,channels);
+ for (int i = 0; i < (int)m_colorSpace->channelCount(); i++) {
+ float value = channels[i];
if (value > to)
m_outRight[i]++;
else if (value < from)
m_outLeft[i]++;
else
m_bins[i][static_cast((value - from) * factor)]++;
}
m_count++;
}
- pixels += pSize;
+ dst += dstPixelSize;
nPixels--;
}
}
}
#endif
// ------------ Generic RGB ---------------------
KoGenericRGBHistogramProducer::KoGenericRGBHistogramProducer()
: KoBasicHistogramProducer(KoID("GENRGBHISTO", i18n("Generic RGB Histogram")), 3, 256)
{
/* we set 0 as colorspece, because we are not based on a specific colorspace. This
is no problem for the superclass since we override channels() */
m_channelsList.append(new KoChannelInfo(i18n("R"), 0, 0, KoChannelInfo::COLOR, KoChannelInfo::UINT8, 1, QColor(255, 0, 0)));
m_channelsList.append(new KoChannelInfo(i18n("G"), 1, 1, KoChannelInfo::COLOR, KoChannelInfo::UINT8, 1, QColor(0, 255, 0)));
m_channelsList.append(new KoChannelInfo(i18n("B"), 2, 2, KoChannelInfo::COLOR, KoChannelInfo::UINT8, 1, QColor(0, 0, 255)));
}
QList KoGenericRGBHistogramProducer::channels()
{
return m_channelsList;
}
QString KoGenericRGBHistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos * UINT8_MAX));
}
qreal KoGenericRGBHistogramProducer::maximalZoom() const
{
return 1.0;
}
void KoGenericRGBHistogramProducer::addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
for (int i = 0; i < m_channels; i++) {
m_outRight[i] = 0;
m_outLeft[i] = 0;
}
QColor c;
qint32 pSize = cs->pixelSize();
if (selectionMask) {
while (nPixels > 0) {
if (!((m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8))) {
cs->toQColor(pixels, &c);
m_bins[0][c.red()]++;
m_bins[1][c.green()]++;
m_bins[2][c.blue()]++;
m_count++;
}
pixels += pSize;
selectionMask++;
nPixels--;
}
} else {
while (nPixels > 0) {
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
cs->toQColor(pixels, &c);
m_bins[0][c.red()]++;
m_bins[1][c.green()]++;
m_bins[2][c.blue()]++;
m_count++;
}
pixels += pSize;
nPixels--;
}
}
}
KoGenericRGBHistogramProducerFactory::KoGenericRGBHistogramProducerFactory()
: KoHistogramProducerFactory(KoID("GENRGBHISTO", i18n("Generic RGB Histogram")))
{
}
// ------------ Generic L*a*b* ---------------------
KoGenericLabHistogramProducer::KoGenericLabHistogramProducer()
: KoBasicHistogramProducer(KoID("GENLABHISTO", i18n("L*a*b* Histogram")), 3, 256)
{
/* we set 0 as colorspace, because we are not based on a specific colorspace. This
is no problem for the superclass since we override channels() */
m_channelsList.append(new KoChannelInfo(i18n("L*"), 0, 0, KoChannelInfo::COLOR, KoChannelInfo::UINT8));
m_channelsList.append(new KoChannelInfo(i18n("a*"), 1, 1, KoChannelInfo::COLOR, KoChannelInfo::UINT8));
m_channelsList.append(new KoChannelInfo(i18n("b*"), 2, 2, KoChannelInfo::COLOR, KoChannelInfo::UINT8));
if (!m_labCs) {
m_labCs = KoColorSpaceRegistry::instance()->lab16();
}
m_colorSpace = m_labCs;
}
KoGenericLabHistogramProducer::~KoGenericLabHistogramProducer()
{
delete m_channelsList[0];
delete m_channelsList[1];
delete m_channelsList[2];
}
QList KoGenericLabHistogramProducer::channels()
{
return m_channelsList;
}
QString KoGenericLabHistogramProducer::positionToString(qreal pos) const
{
return QString("%1").arg(static_cast(pos * UINT16_MAX));
}
qreal KoGenericLabHistogramProducer::maximalZoom() const
{
return 1.0;
}
void KoGenericLabHistogramProducer::addRegionToBin(const quint8 *pixels, const quint8 *selectionMask, quint32 nPixels, const KoColorSpace *cs)
{
for (int i = 0; i < m_channels; i++) {
m_outRight[i] = 0;
m_outLeft[i] = 0;
}
qint32 dstPixelSize = m_colorSpace->pixelSize();
quint8 *dstPixels = new quint8[nPixels * dstPixelSize];
cs->convertPixelsTo(pixels, dstPixels, m_colorSpace, nPixels, KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::Empty);
qint32 pSize = cs->pixelSize();
if (selectionMask) {
while (nPixels > 0) {
if (!((m_skipUnselected && *selectionMask == 0) || (m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8))) {
m_count++;
}
pixels += pSize;
selectionMask++;
nPixels--;
}
} else {
quint8 *dst = dstPixels;
while (nPixels > 0) {
if (!(m_skipTransparent && cs->opacityU8(pixels) == OPACITY_TRANSPARENT_U8)) {
m_bins[0][m_colorSpace->scaleToU8(dst, 0)]++;
m_bins[1][m_colorSpace->scaleToU8(dst, 1)]++;
m_bins[2][m_colorSpace->scaleToU8(dst, 2)]++;
m_count++;
}
dst+= dstPixelSize;
nPixels--;
}
}
delete[] dstPixels;
}
KoGenericLabHistogramProducerFactory::KoGenericLabHistogramProducerFactory()
: KoHistogramProducerFactory(KoID("GENLABHISTO", i18n("Generic L*a*b* Histogram")))
{
}
diff --git a/libs/pigment/KoBasicHistogramProducers.h b/libs/pigment/KoBasicHistogramProducers.h
index 9f89ddae5e..d62675a977 100644
--- a/libs/pigment/KoBasicHistogramProducers.h
+++ b/libs/pigment/KoBasicHistogramProducers.h
@@ -1,257 +1,262 @@
/*
* Copyright (c) 2005 Bart Coppens
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _Ko_BASIC_HISTOGRAM_PRODUCERS_
#define _Ko_BASIC_HISTOGRAM_PRODUCERS_
#include "KoHistogramProducer.h"
#include
#include
#include "KoColorSpace.h"
#include "KoID.h"
#include "kritapigment_export.h"
#include "KoColorSpaceRegistry.h"
class KRITAPIGMENT_EXPORT KoBasicHistogramProducer : public KoHistogramProducer
{
public:
explicit KoBasicHistogramProducer(const KoID& id, int channelCount, int nrOfBins);
explicit KoBasicHistogramProducer(const KoID& id, int nrOfBins, const KoColorSpace *colorSpace);
virtual ~KoBasicHistogramProducer() {}
virtual void clear();
virtual void setView(qreal from, qreal size) {
m_from = from; m_width = size;
}
virtual const KoID& id() const {
return m_id;
}
virtual QList channels() {
return m_colorSpace->channels();
}
virtual qint32 numberOfBins() {
return m_nrOfBins;
}
virtual qreal viewFrom() const {
return m_from;
}
virtual qreal viewWidth() const {
return m_width;
}
virtual qint32 count() {
return m_count;
}
virtual qint32 getBinAt(int channel, int position) {
return m_bins.at(externalToInternal(channel)).at(position);
}
virtual qint32 outOfViewLeft(int channel) {
return m_outLeft.at(externalToInternal(channel));
}
virtual qint32 outOfViewRight(int channel) {
return m_outRight.at(externalToInternal(channel));
}
protected:
/**
* The order in which channels() returns is not the same as the internal representation,
* that of the pixel internally. This method converts external usage to internal usage.
* This method uses some basic assumtpions about the layout of the pixel, so _extremely_
* exotic spaces might want to override this (see makeExternalToInternal source for
* those assumptions)
**/
virtual int externalToInternal(int ext) {
if (channels().count() > 0 && m_external.count() == 0) // Set up the translation table
makeExternalToInternal();
return m_external.at(ext);
}
// not virtual since that is useless: we call it from constructor
void makeExternalToInternal();
typedef QVector vBins;
QVector m_bins;
vBins m_outLeft, m_outRight;
qreal m_from, m_width;
qint32 m_count;
int m_channels, m_nrOfBins;
const KoColorSpace *m_colorSpace;
KoID m_id;
QVector m_external;
};
class KRITAPIGMENT_EXPORT KoBasicU8HistogramProducer : public KoBasicHistogramProducer
{
public:
KoBasicU8HistogramProducer(const KoID& id, const KoColorSpace *colorSpace);
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const {
return 1.0;
}
};
class KRITAPIGMENT_EXPORT KoBasicU16HistogramProducer : public KoBasicHistogramProducer
{
public:
KoBasicU16HistogramProducer(const KoID& id, const KoColorSpace *colorSpace);
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const;
};
class KRITAPIGMENT_EXPORT KoBasicF32HistogramProducer : public KoBasicHistogramProducer
{
public:
KoBasicF32HistogramProducer(const KoID& id, const KoColorSpace *colorSpace);
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const;
};
#ifdef HAVE_OPENEXR
class KRITAPIGMENT_EXPORT KoBasicF16HalfHistogramProducer : public KoBasicHistogramProducer
{
public:
KoBasicF16HalfHistogramProducer(const KoID& id, const KoColorSpace *colorSpace);
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const;
};
#endif
/**
* Parametrized on a specific KoHistogramProducer. Its generated producers
* will have the same KoID as the factory's. This is acceptable because we can't mix
* Factories with Producers in the code because they are incompatible types, and
* in the GUI we actually only need a producer's name, not a factory's.
*/
template class KoBasicHistogramProducerFactory : public KoHistogramProducerFactory
{
public:
KoBasicHistogramProducerFactory(const KoID& id, const QString& modelId, const QString& depthId )
: KoHistogramProducerFactory(id), m_modelId(modelId), m_depthId(depthId) {
}
virtual ~KoBasicHistogramProducerFactory() {}
virtual KoHistogramProducer *generate() {
KoHistogramProducer *producer = 0;
const KoColorSpace *cs = KoColorSpaceRegistry::instance()->colorSpace(m_modelId, m_depthId, 0);
if (cs) {
producer = new T(KoID(id(), name()), cs);
}
return producer;
}
- virtual bool isCompatibleWith(const KoColorSpace* colorSpace) const {
+ virtual bool isCompatibleWith(const KoColorSpace* colorSpace, bool strict = false) const {
+ if( strict ){
+ return colorSpace->colorDepthId().id() == m_depthId;
+ }
return colorSpace->colorModelId().id() == m_modelId || colorSpace->colorDepthId().id() == m_depthId;
}
virtual float preferrednessLevelWith(const KoColorSpace* colorSpace) const {
return 0.5 * ( (colorSpace->colorModelId().id() == m_modelId) + (colorSpace->colorDepthId().id() == m_depthId) );
}
protected:
QString m_modelId, m_depthId;
};
/**
* This is a Producer (with associated factory) that converts the pixels of the colorspace
* to RGB8 with toQColor, and then does its counting on RGB. This is NOT registered with the
* Registry, because it isCompatibleWith all colorspaces, and should only be used in extreme
* cases (like no other producer being available
**/
class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducer : public KoBasicHistogramProducer
{
public:
KoGenericRGBHistogramProducer();
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const;
virtual QList channels();
protected:
QList m_channelsList;
};
/** KoGenericRGBHistogramProducer his special Factory that isCompatibleWith everything. */
class KRITAPIGMENT_EXPORT KoGenericRGBHistogramProducerFactory : public KoHistogramProducerFactory
{
public:
KoGenericRGBHistogramProducerFactory();
virtual ~KoGenericRGBHistogramProducerFactory() {}
virtual KoHistogramProducer *generate() {
return new KoGenericRGBHistogramProducer();
}
- virtual bool isCompatibleWith(const KoColorSpace*) const {
+ virtual bool isCompatibleWith(const KoColorSpace*, bool strict = false) const {
+ Q_UNUSED(strict);
return true;
}
virtual float preferrednessLevelWith(const KoColorSpace*) const {
return 0.0;
}
};
/**
* This is a Producer (with associated factory) that converts the pixels of the colorspace
* to L*a*b*, and then does its counting.
* It isCompatibleWith all colorspaces
**/
class KRITAPIGMENT_EXPORT KoGenericLabHistogramProducer : public KoBasicHistogramProducer
{
public:
KoGenericLabHistogramProducer();
virtual ~KoGenericLabHistogramProducer();
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace *colorSpace);
virtual QString positionToString(qreal pos) const;
virtual qreal maximalZoom() const;
virtual QList channels();
protected:
QList m_channelsList;
};
/** KoGenericLabHistogramProducer his special Factory that isCompatibleWith everything. */
class /*KRITAPIGMENT_EXPORT*/ KoGenericLabHistogramProducerFactory : public KoHistogramProducerFactory
{
public:
KoGenericLabHistogramProducerFactory();
virtual ~KoGenericLabHistogramProducerFactory() {}
virtual KoHistogramProducer *generate() {
return new KoGenericLabHistogramProducer();
}
- virtual bool isCompatibleWith(const KoColorSpace*) const {
+ virtual bool isCompatibleWith(const KoColorSpace*, bool strict = false) const {
+ Q_UNUSED(strict);
return true;
}
virtual float preferrednessLevelWith(const KoColorSpace*) const {
return 0.0;
}
};
#endif // _Ko_BASIC_HISTOGRAM_PRODUCERS_
diff --git a/libs/pigment/KoHistogramProducer.cpp b/libs/pigment/KoHistogramProducer.cpp
index 5534e1f381..0d30a3e1c1 100644
--- a/libs/pigment/KoHistogramProducer.cpp
+++ b/libs/pigment/KoHistogramProducer.cpp
@@ -1,69 +1,70 @@
/*
* Copyright (c) 2005 Bart Coppens
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "KoHistogramProducer.h"
#include
#include
#include
#include "KoBasicHistogramProducers.h"
#include "KoColorSpace.h"
Q_GLOBAL_STATIC(KoHistogramProducerFactoryRegistry, s_instance)
KoHistogramProducerFactoryRegistry::KoHistogramProducerFactoryRegistry()
{
}
KoHistogramProducerFactoryRegistry::~KoHistogramProducerFactoryRegistry()
{
qDeleteAll(values());
}
KoHistogramProducerFactoryRegistry* KoHistogramProducerFactoryRegistry::instance()
{
return s_instance;
}
-QList KoHistogramProducerFactoryRegistry::keysCompatibleWith(const KoColorSpace* colorSpace) const
+QList KoHistogramProducerFactoryRegistry::keysCompatibleWith(const KoColorSpace* colorSpace, bool isStrict) const
{
QList list;
QList preferredList;
Q_FOREACH (const QString &id, keys()) {
KoHistogramProducerFactory *f = value(id);
- if (f->isCompatibleWith(colorSpace)) {
+
+ if (f->isCompatibleWith(colorSpace, isStrict)) {
float preferred = f->preferrednessLevelWith(colorSpace);
QList::iterator pit = preferredList.begin();
QList::iterator pend = preferredList.end();
QList::iterator lit = list.begin();
while (pit != pend && preferred <= *pit) {
++pit;
++lit;
}
list.insert(lit, id);
preferredList.insert(pit, preferred);
}
}
return list;
}
diff --git a/libs/pigment/KoHistogramProducer.h b/libs/pigment/KoHistogramProducer.h
index b97a334f1f..fc9956dcf3 100644
--- a/libs/pigment/KoHistogramProducer.h
+++ b/libs/pigment/KoHistogramProducer.h
@@ -1,143 +1,143 @@
/*
* Copyright (c) 2005 Bart Coppens
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _KO_HISTOGRAM_PRODUCER_
#define _KO_HISTOGRAM_PRODUCER_
#include
#include "kritapigment_export.h"
#include
#include
class QString;
class KoChannelInfo;
class KoColorSpace;
/**
* This class is an interface used in the generation of a histogram. It is a container of
* data, all mathematically interesting things will calculated by an histogram.
*
* The default view will be the entire range each color can be in. And don't let the
* numberOfBins return anything else then 256 unless you have a very good reason for it.
*
* About the views: a view is a zoom combined with a start level: the entire
* range of a channel is 0.0 - 1.0: this is the position. Combined with a zoom, we can
* calculate what part of a channel will fall in a bin. This gives us an interface to
* that the views that is not dependent of the actual colorspace of the histogram.
* The 'size' value is the size, again from 0.0 to 1.0 of the displayed range.
*
* For comfort of the GUI, and because it is logical, channels are accessed in the order
* in which they are found in the channels() method. This is potentially different from
* the order in which they are internally ordered!
**/
class KRITAPIGMENT_EXPORT KoHistogramProducer
{
public:
KoHistogramProducer() : m_skipTransparent(true), m_skipUnselected(true) {}
virtual ~KoHistogramProducer() {}
// Methods to change the bins
/** Clears the data in this producer, but keeps its other settings */
virtual void clear() = 0;
/**
* Adds the values from the specified array of pixels to the bins -- does not
* reset anything.
*
* @param pixels A pointer an array of pixeldata in the given colorspace
* @param selectionMask a pointer to an array of bytes, where 0 is unselected and 1-255 is degree of selectedness. The array
* must be just as long as the array of pixels.
* @param nPixels The number of pixels
* @param colorSpace the colorspace that can decode the pixel data.
*/
virtual void addRegionToBin(const quint8 * pixels, const quint8 * selectionMask, quint32 nPixels, const KoColorSpace* colorSpace) = 0;
// Methods to set what exactly is being added to the bins
virtual void setView(qreal from, qreal width) = 0;
virtual void setSkipTransparent(bool set) {
m_skipTransparent = set;
}
virtual void setSkipUnselected(bool set) {
m_skipUnselected = set;
}
// Methods with general information about this specific producer
virtual const KoID& id() const = 0;
virtual QList channels() = 0;
virtual qint32 numberOfBins() = 0;
virtual QString positionToString(qreal pos) const = 0;
virtual qreal viewFrom() const = 0;
virtual qreal viewWidth() const = 0;
virtual qreal maximalZoom() const = 0;
// Methods to get information on the data we have seen
virtual qint32 count() = 0;
virtual qint32 getBinAt(qint32 channel, qint32 position) = 0;
virtual qint32 outOfViewLeft(qint32 channel) = 0;
virtual qint32 outOfViewRight(qint32 channel) = 0;
protected:
bool m_skipTransparent;
bool m_skipUnselected;
};
class KRITAPIGMENT_EXPORT KoHistogramProducerFactory
{
public:
explicit KoHistogramProducerFactory(const KoID &id) : m_id(id) {}
virtual ~KoHistogramProducerFactory() {}
/// Factory method, generates a new KoHistogramProducer
virtual KoHistogramProducer *generate() = 0;
/// Returns if a colorspace can be used with this producer
- virtual bool isCompatibleWith(const KoColorSpace* colorSpace) const = 0;
+ virtual bool isCompatibleWith(const KoColorSpace* colorSpace, bool strict = false) const = 0;
/// Returns a float in the [0.0, 1.0] range, 0.0 means this is a very generic method
virtual float preferrednessLevelWith(const KoColorSpace* colorSpace) const = 0;
virtual QString id() const {
return m_id.id();
}
virtual QString name() const {
return m_id.name();
}
protected:
KoID m_id;
};
class KRITAPIGMENT_EXPORT KoHistogramProducerFactoryRegistry
: public KoGenericRegistry
{
public:
KoHistogramProducerFactoryRegistry();
virtual ~KoHistogramProducerFactoryRegistry();
static KoHistogramProducerFactoryRegistry* instance();
/// returns a list, sorted by preferrence: higher preferance comes first
- QList keysCompatibleWith(const KoColorSpace* colorSpace) const;
+ QList keysCompatibleWith(const KoColorSpace* colorSpace, bool isStrict=false) const;
private:
KoHistogramProducerFactoryRegistry(const KoHistogramProducerFactoryRegistry&);
KoHistogramProducerFactoryRegistry operator=(const KoHistogramProducerFactoryRegistry&);
};
#endif // _KO_HISTOGRAM_PRODUCER
diff --git a/libs/ui/KisTemplateCreateDia.cpp b/libs/ui/KisTemplateCreateDia.cpp
index b501f3da89..e0886e3875 100644
--- a/libs/ui/KisTemplateCreateDia.cpp
+++ b/libs/ui/KisTemplateCreateDia.cpp
@@ -1,523 +1,517 @@
/*
This file is part of the KDE project
Copyright (C) 1998, 1999 Reginald Stadlbauer
2000 Werner Trobin
Copyright (C) 2004 Nicolas GOUTTE
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#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
// ODF thumbnail extent
static const int thumbnailExtent = 128;
class KisTemplateCreateDiaPrivate {
public:
KisTemplateCreateDiaPrivate(const QString &templatesResourcePath,
const QString &filePath, const QPixmap &thumbnail)
: m_tree(templatesResourcePath, true)
, m_filePath(filePath)
, m_thumbnail(thumbnail)
{ }
KisTemplateTree m_tree;
QLineEdit *m_name;
QRadioButton *m_default;
QRadioButton *m_custom;
QPushButton *m_select;
QLabel *m_preview;
QString m_customFile;
QPixmap m_customPixmap;
QTreeWidget *m_groups;
QPushButton *m_add;
QPushButton *m_remove;
QCheckBox *m_defaultTemplate;
QString m_filePath;
QPixmap m_thumbnail;
bool m_changed;
};
/****************************************************************************
*
* Class: KisTemplateCreateDia
*
****************************************************************************/
KisTemplateCreateDia::KisTemplateCreateDia(const QString &templatesResourcePath,
const QString &filePath, const QPixmap &thumbnail, QWidget *parent)
: KoDialog(parent)
, d(new KisTemplateCreateDiaPrivate(templatesResourcePath, filePath, thumbnail))
{
-
setButtons( KoDialog::Ok|KoDialog::Cancel );
setDefaultButton( KoDialog::Ok );
setCaption( i18n( "Create Template" ) );
setModal( true );
setObjectName( "template create dia" );
QWidget *mainwidget = mainWidget();
QHBoxLayout *mbox=new QHBoxLayout( mainwidget );
QVBoxLayout* leftbox = new QVBoxLayout();
mbox->addLayout( leftbox );
QLabel *label=new QLabel(i18nc("Template name", "Name:"), mainwidget);
QHBoxLayout *namefield=new QHBoxLayout();
leftbox->addLayout( namefield );
namefield->addWidget(label);
d->m_name=new QLineEdit(mainwidget);
d->m_name->setFocus();
connect(d->m_name, SIGNAL(textChanged(const QString &)),
this, SLOT(slotNameChanged(const QString &)));
namefield->addWidget(d->m_name);
label=new QLabel(i18n("Group:"), mainwidget);
leftbox->addWidget(label);
d->m_groups = new QTreeWidget(mainwidget);
leftbox->addWidget(d->m_groups);
d->m_groups->setColumnCount(1);
d->m_groups->setHeaderHidden(true);
d->m_groups->setRootIsDecorated(true);
d->m_groups->setSortingEnabled(true);
fillGroupTree();
d->m_groups->sortItems(0, Qt::AscendingOrder);
QHBoxLayout *bbox=new QHBoxLayout();
leftbox->addLayout( bbox );
d->m_add=new QPushButton(i18n("&Add Group..."), mainwidget);
connect(d->m_add, SIGNAL(clicked()), this, SLOT(slotAddGroup()));
bbox->addWidget(d->m_add);
d->m_remove=new QPushButton(i18n("&Remove"), mainwidget);
connect(d->m_remove, SIGNAL(clicked()), this, SLOT(slotRemove()));
bbox->addWidget(d->m_remove);
QVBoxLayout *rightbox=new QVBoxLayout();
mbox->addLayout( rightbox );
QGroupBox *pixbox = new QGroupBox(i18n("Picture"), mainwidget);
rightbox->addWidget(pixbox);
QVBoxLayout *pixlayout=new QVBoxLayout(pixbox );
d->m_default=new QRadioButton(i18n("&Preview"), pixbox);
d->m_default->setChecked(true);
connect(d->m_default, SIGNAL(clicked()), this, SLOT(slotDefault()));
pixlayout->addWidget(d->m_default);
QHBoxLayout *custombox=new QHBoxLayout();
d->m_custom=new QRadioButton(i18n("Custom:"), pixbox);
d->m_custom->setChecked(false);
connect(d->m_custom, SIGNAL(clicked()), this, SLOT(slotCustom()));
custombox->addWidget(d->m_custom);
d->m_select=new QPushButton(i18n("&Select..."), pixbox);
connect(d->m_select, SIGNAL(clicked()), this, SLOT(slotSelect()));
custombox->addWidget(d->m_select);
custombox->addStretch(1);
pixlayout->addLayout(custombox);
d->m_preview=new QLabel(pixbox); // setPixmap() -> auto resize?
pixlayout->addWidget(d->m_preview, 0, Qt::AlignCenter);
pixlayout->addStretch(1);
d->m_defaultTemplate = new QCheckBox( i18n("Use the new template as default"), mainwidget );
d->m_defaultTemplate->setChecked( true );
d->m_defaultTemplate->setToolTip(i18n("Use the new template every time Krita starts"));
rightbox->addWidget( d->m_defaultTemplate );
enableButtonOk(false);
d->m_changed=false;
updatePixmap();
connect(d->m_groups, SIGNAL(itemSelectionChanged()), this, SLOT(slotSelectionChanged()));
d->m_remove->setEnabled(d->m_groups->currentItem());
- connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
+ connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
}
KisTemplateCreateDia::~KisTemplateCreateDia() {
delete d;
}
void KisTemplateCreateDia::slotSelectionChanged()
{
const QTreeWidgetItem* item = d->m_groups->currentItem();
d->m_remove->setEnabled( item );
if ( ! item )
return;
if ( item->parent() != 0 )
{
d->m_name->setText( item->text( 0 ) );
}
}
void KisTemplateCreateDia::createTemplate(const QString &templatesResourcePath,
const char *suffix,
KisDocument *document, QWidget *parent)
{
- QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/krita_XXXXXX") + QLatin1String(QLatin1String(suffix)));
- //Check that creation of temp file was successful
- if (!tempFile->open()) {
- delete tempFile;
- qWarning("Creation of temporary file to store template failed.");
+ Q_UNUSED(suffix);
+ QString fileName;
+ {
+ QTemporaryFile tempFile;
+ if (!tempFile.open()) {
+ qWarning("Creation of temporary file to store template failed.");
+ return;
+ }
+ fileName = tempFile.fileName();
+ }
+ bool retval = document->saveNativeFormat(fileName);
+ if (!retval) {
+ qWarning("Could not save template");
return;
}
- const QString fileName = tempFile->fileName();
- tempFile->close(); // need to close on Windows before we can open it again to save
- delete tempFile; // now the file has disappeared and we can create a new file with the generated name
-
- document->saveNativeFormat(fileName);
-
const QPixmap thumbnail = document->generatePreview(QSize(thumbnailExtent, thumbnailExtent));
-
KisTemplateCreateDia *dia = new KisTemplateCreateDia(templatesResourcePath, fileName, thumbnail, parent);
dia->exec();
delete dia;
QDir d;
d.remove(fileName);
}
static void
saveAsQuadraticPng(const QPixmap &pixmap, const QString &fileName)
{
QImage icon = pixmap.toImage();
icon = icon.convertToFormat(QImage::Format_ARGB32);
const int iconExtent = qMax(icon.width(), icon.height());
icon = icon.copy((icon.width() - iconExtent) / 2, (icon.height() - iconExtent) / 2, iconExtent, iconExtent);
icon.save(fileName, "PNG");
}
void KisTemplateCreateDia::slotOk() {
// get the current item, if there is one...
QTreeWidgetItem *item = d->m_groups->currentItem();
if(!item)
item = d->m_groups->topLevelItem(0);
if(!item) { // safe :)
d->m_tree.writeTemplateTree();
slotButtonClicked( KoDialog::Cancel );
return;
}
// is it a group or a template? anyway - get the group :)
if(item->parent() != 0)
item=item->parent();
if(!item) { // *very* safe :P
d->m_tree.writeTemplateTree();
slotButtonClicked( KoDialog::Cancel );
return;
}
KisTemplateGroup *group=d->m_tree.find(item->text(0));
if(!group) { // even safer
d->m_tree.writeTemplateTree();
slotButtonClicked( KoDialog::Cancel );
return;
}
if(d->m_name->text().isEmpty()) {
d->m_tree.writeTemplateTree();
slotButtonClicked( KoDialog::Cancel );
return;
}
// copy the tmp file and the picture the app provides
QString dir = KoResourcePaths::saveLocation("data", d->m_tree.templatesResourcePath());
- dir+=group->name();
- QString templateDir=dir+"/.source/";
- QString iconDir=dir+"/.icon/";
+ dir += group->name();
+ QString templateDir = dir+"/.source/";
+ QString iconDir = dir+"/.icon/";
- QString file=KisTemplates::trimmed(d->m_name->text());
- QString tmpIcon=".icon/"+file;
- tmpIcon+=".png";
+ QString file = KisTemplates::trimmed(d->m_name->text());
+ QString tmpIcon = ".icon/"+file;
+ tmpIcon += ".png";
QString icon=iconDir+file;
- icon+=".png";
+ icon += ".png";
- // try to find the extension for the template file :P
- const int pos = d->m_filePath.lastIndexOf(QLatin1Char('.'));
- QString ext;
- if ( pos > -1 )
- ext = d->m_filePath.mid(pos);
- else
- warnUI << "Template extension not found!";
+ QString ext = ".kra";
- QUrl dest;
- dest.setPath(templateDir+file+ext);
- if (QFile::exists(dest.toLocalFile())) {
+ QString dest = templateDir + file + ext;
+ if (QFile::exists(dest)) {
do {
- file.prepend( '_' );
- dest.setPath( templateDir + file + ext );
+ file = file.prepend( '_' );
+ dest = templateDir + file + ext;
tmpIcon=".icon/" + file + ".png";
icon=iconDir + file + ".png";
}
- while (QFile(dest.toLocalFile()).exists());
+ while (QFile(dest).exists());
}
bool ignore = false;
- dbgUI <<"Trying to create template:" << d->m_name->text() <<"URL=" <<".source/"+file+ext <<" ICON=" << tmpIcon;
- KisTemplate *t=new KisTemplate(d->m_name->text(), QString(), ".source/"+file+ext, tmpIcon, "", "", false, true);
+ KisTemplate *t = new KisTemplate(d->m_name->text(), QString(), ".source/ "+ file + ext, tmpIcon, "", "", false, true);
if (!group->add(t)) {
KisTemplate *existingTemplate=group->find(d->m_name->text());
if (existingTemplate && !existingTemplate->isHidden()) {
if (QMessageBox::warning(this,
i18nc("@title:window", "Krita"),
i18n("Do you really want to overwrite the existing '%1' template?", existingTemplate->name()),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
group->add(t, true);
}
else {
delete t;
return;
}
}
else {
ignore = true;
}
}
QDir path;
if (!path.mkpath(templateDir) || !path.mkpath(iconDir)) {
d->m_tree.writeTemplateTree();
slotButtonClicked( KoDialog::Cancel );
return;
}
- QUrl orig;
- orig.setPath(d->m_filePath);
+ QString orig;
+ orig = d->m_filePath;
// don't overwrite the hidden template file with a new non-hidden one
- if ( !ignore )
- {
- QFile::copy(d->m_filePath, dest.toLocalFile());
+ if (!ignore) {
+ if (!QFile::copy(d->m_filePath, dest)) {
+ qWarning() << QString("Could not copy %1 to %2.").arg(d->m_filePath).arg(dest).toUtf8();
+ }
+
// save the picture as icon
if(d->m_default->isChecked() && !d->m_thumbnail.isNull()) {
saveAsQuadraticPng(d->m_thumbnail, icon);
} else if(!d->m_customPixmap.isNull()) {
saveAsQuadraticPng(d->m_customPixmap, icon);
} else {
warnUI << "Could not save the preview picture!";
}
}
// if there's a .directory file, we copy this one, too
bool ready=false;
QStringList tmp=group->dirs();
for(QStringList::ConstIterator it=tmp.constBegin(); it!=tmp.constEnd() && !ready; ++it) {
if((*it).contains(dir)==0) {
- orig.setPath( (*it)+".directory" );
+ orig = (*it) + ".directory";
// Check if we can read the file
- if (QFile(orig.toLocalFile()).exists()) {
- dest.setPath(dir + "/.directory");
+ if (QFile(orig).exists()) {
+ dest = dir + "/.directory";
// We copy the file with overwrite
- if (!QFile(orig.toLocalFile()).copy(dest.toLocalFile())) {
- warnKrita << "Failed to copy from" << orig.toLocalFile() << "to" << dest.toLocalFile();
+ if (!QFile(orig).copy(dest)) {
+ warnKrita << "Failed to copy from" << orig << "to" << dest;
}
ready = true;
}
}
}
d->m_tree.writeTemplateTree();
if ( d->m_defaultTemplate->isChecked() )
{
KConfigGroup grp( KSharedConfig::openConfig(), "TemplateChooserDialog");
grp.writeEntry( "LastReturnType", "Template" );
grp.writePathEntry( "FullTemplateName", dir + '/' + t->file() );
grp.writePathEntry( "AlwaysUseTemplate", dir + '/' + t->file() );
}
}
void KisTemplateCreateDia::slotDefault() {
d->m_default->setChecked(true);
d->m_custom->setChecked(false);
updatePixmap();
}
void KisTemplateCreateDia::slotCustom() {
d->m_default->setChecked(false);
d->m_custom->setChecked(true);
if(d->m_customFile.isEmpty())
slotSelect();
else
updatePixmap();
}
void KisTemplateCreateDia::slotSelect() {
d->m_default->setChecked(false);
d->m_custom->setChecked(true);
// QT5TODO
// QString name = KIconDialog::getIcon();
// if( name.isEmpty() ) {
// if(d->m_customFile.isEmpty()) {
// d->m_default->setChecked(true);
// d->m_custom->setChecked(false);
// }
// return;
// }
// const QString path = KIconLoader::global()->iconPath(name, -thumbnailExtent);
d->m_customFile = QString();// path;
d->m_customPixmap = QPixmap();
updatePixmap();
}
void KisTemplateCreateDia::slotNameChanged(const QString &name) {
if( ( name.trimmed().isEmpty() || !d->m_groups->topLevelItem(0) ) && !d->m_changed )
enableButtonOk(false);
else
enableButtonOk(true);
}
void KisTemplateCreateDia::slotAddGroup() {
const QString name = QInputDialog::getText(this, i18n("Add Group"), i18n("Enter group name:"));
KisTemplateGroup *group = d->m_tree.find(name);
if (group && !group->isHidden()) {
QMessageBox::information( this, i18n("This name is already used."), i18n("Add Group") );
return;
}
QString dir = KoResourcePaths::saveLocation("data", d->m_tree.templatesResourcePath());
dir+=name;
KisTemplateGroup *newGroup=new KisTemplateGroup(name, dir, 0, true);
d->m_tree.add(newGroup);
QTreeWidgetItem *item = new QTreeWidgetItem(d->m_groups, QStringList() << name);
d->m_groups->setCurrentItem(item);
d->m_groups->sortItems(0, Qt::AscendingOrder);
d->m_name->setFocus();
enableButtonOk(true);
d->m_changed=true;
}
void KisTemplateCreateDia::slotRemove() {
QTreeWidgetItem *item = d->m_groups->currentItem();
if(!item)
return;
QString what;
QString removed;
if (item->parent() == 0) {
what = i18n("Do you really want to remove that group?");
removed = i18nc("@title:window", "Remove Group");
} else {
what = i18n("Do you really want to remove that template?");
removed = i18nc("@title:window", "Remove Template");
}
if (QMessageBox::warning(this,
removed,
what,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox:: No) {
d->m_name->setFocus();
return;
}
if(item->parent() == 0) {
KisTemplateGroup *group=d->m_tree.find(item->text(0));
if(group)
group->setHidden(true);
}
else {
bool done=false;
QList groups = d->m_tree.groups();
QList::const_iterator it = groups.constBegin();
for(; it != groups.constEnd() && !done; ++it) {
KisTemplate *t = (*it)->find(item->text(0));
if(t) {
t->setHidden(true);
done=true;
}
}
}
delete item;
item=0;
enableButtonOk(true);
d->m_name->setFocus();
d->m_changed=true;
}
void KisTemplateCreateDia::updatePixmap() {
if(d->m_default->isChecked() && !d->m_thumbnail.isNull())
d->m_preview->setPixmap(d->m_thumbnail);
else if(d->m_custom->isChecked() && !d->m_customFile.isEmpty()) {
if(d->m_customPixmap.isNull()) {
dbgUI <<"Trying to load picture" << d->m_customFile;
// use the code in KisTemplate to load the image... hacky, I know :)
KisTemplate t("foo", "bar", QString(), d->m_customFile);
d->m_customPixmap=t.loadPicture();
}
else
warnUI << "Trying to load picture";
if(!d->m_customPixmap.isNull())
d->m_preview->setPixmap(d->m_customPixmap);
else
d->m_preview->setText(i18n("Could not load picture."));
}
else
d->m_preview->setText(i18n("No picture available."));
}
void KisTemplateCreateDia::fillGroupTree() {
Q_FOREACH (KisTemplateGroup *group, d->m_tree.groups()) {
if(group->isHidden())
continue;
QTreeWidgetItem *groupItem=new QTreeWidgetItem(d->m_groups, QStringList() << group->name());
Q_FOREACH (KisTemplate *t, group->templates()) {
if(t->isHidden())
continue;
(void)new QTreeWidgetItem(groupItem, QStringList() << t->name());
}
}
}
diff --git a/libs/ui/canvas/kis_mirror_axis.cpp b/libs/ui/canvas/kis_mirror_axis.cpp
index 468dbf4ad8..8a0d6ca48a 100644
--- a/libs/ui/canvas/kis_mirror_axis.cpp
+++ b/libs/ui/canvas/kis_mirror_axis.cpp
@@ -1,359 +1,406 @@
/*
* Copyright (c) 2014 Arjen Hiemstra
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "kis_mirror_axis.h"
#include "KoConfig.h"
#include
#include
#include
#include
#include
#include
#include
#include "kis_canvas2.h"
#include "kis_canvas_resource_provider.h"
#include "KisViewManager.h"
#include "KisView.h"
#include "kis_image.h"
#include "canvas/kis_canvas_controller.h"
#include "input/kis_input_manager.h"
#include "kis_algebra_2d.h"
class KisMirrorAxis::Private
{
public:
Private(KisMirrorAxis* qq)
: q(qq)
, resourceProvider(0)
, mirrorHorizontal(false)
, mirrorVertical(false)
+ , lockHorizontal(false)
+ , lockVertical(false)
+ , hideVerticalDecoration(false)
+ , hideHorizontalDecoration(false)
, handleSize(32.f)
, xActive(false)
, yActive(false)
, horizontalHandlePosition(64.f)
, verticalHandlePosition(64.f)
, sideMargin(10.f)
, minHandlePosition(10.f + 32.f)
, horizontalContainsCursor(false)
, verticalContainsCursor(false)
, horizontalAxis(QLineF())
, verticalAxis(QLineF())
{ }
void setAxisPosition(float x, float y);
void recomputeVisibleAxes(QRect viewport);
KisMirrorAxis* q;
KisCanvasResourceProvider* resourceProvider;
+ KisImageWSP image;
bool mirrorHorizontal;
bool mirrorVertical;
+ bool lockHorizontal;
+ bool lockVertical;
+ bool hideVerticalDecoration;
+ bool hideHorizontalDecoration;
+
+
+
float handleSize;
QPixmap horizontalHandleIcon;
QPixmap verticalHandleIcon;
QPixmap horizontalIcon;
QPixmap verticalIcon;
QPointF axisPosition;
QRectF horizontalHandle;
QRectF verticalHandle;
bool xActive;
bool yActive;
float horizontalHandlePosition;
float verticalHandlePosition;
float sideMargin;
float minHandlePosition;
bool horizontalContainsCursor;
bool verticalContainsCursor;
QLineF horizontalAxis;
QLineF verticalAxis;
};
KisMirrorAxis::KisMirrorAxis(KisCanvasResourceProvider* provider, QPointerparent)
: KisCanvasDecoration("mirror_axis", parent)
, d(new Private(this))
{
d->resourceProvider = provider;
connect(d->resourceProvider, SIGNAL(mirrorModeChanged()), SLOT(mirrorModeChanged()));
+ connect(d->resourceProvider, SIGNAL(moveMirrorVerticalCenter()), SLOT(moveVerticalAxisToCenter()));
+ connect(d->resourceProvider, SIGNAL(moveMirrorHorizontalCenter()), SLOT(moveHorizontalAxisToCenter()));
+
d->mirrorHorizontal = d->resourceProvider->mirrorHorizontal();
d->mirrorVertical = d->resourceProvider->mirrorVertical();
d->horizontalIcon = KisIconUtils::loadIcon("mirrorAxis-HorizontalMove").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->verticalIcon = KisIconUtils::loadIcon("mirrorAxis-VerticalMove").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->horizontalHandleIcon = KisIconUtils::loadIcon("transform-move").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->verticalHandleIcon = KisIconUtils::loadIcon("transform-move").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
setVisible(d->mirrorHorizontal || d->mirrorVertical);
- int imageWidth = parent->canvasBase()->image()->width();
- int imageHeight = parent->canvasBase()->image()->height();
+
+ d->image = parent->canvasBase()->image();
+
+ int imageWidth = d->image->width();
+ int imageHeight = d->image->height();
QPointF point(imageWidth / 2, imageHeight / 2);
d->resourceProvider->resourceManager()->setResource(KisCanvasResourceProvider::MirrorAxesCenter, point);
}
KisMirrorAxis::~KisMirrorAxis()
{
delete d;
}
float KisMirrorAxis::handleSize() const
{
return d->handleSize;
}
void KisMirrorAxis::setHandleSize(float newSize)
{
if(d->handleSize != newSize) {
d->handleSize = newSize;
d->horizontalIcon = KisIconUtils::loadIcon("symmetry-horyzontal").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->verticalIcon = KisIconUtils::loadIcon("symmetry-vertical").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->horizontalHandleIcon = KisIconUtils::loadIcon("transform-move").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->verticalHandleIcon = KisIconUtils::loadIcon("transform-move").pixmap(d->handleSize, QIcon::Normal, QIcon::On);
d->minHandlePosition = d->sideMargin + newSize;
emit handleSizeChanged();
}
}
void KisMirrorAxis::drawDecoration(QPainter& gc, const QRectF& updateArea, const KisCoordinatesConverter* converter, KisCanvas2* canvas)
{
Q_UNUSED(updateArea);
Q_UNUSED(converter);
Q_UNUSED(canvas);
gc.setPen(QPen(QColor(0, 0, 0, 128), 1));
gc.setBrush(Qt::white);
gc.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QOpenGLContext *ctx = QOpenGLContext::currentContext();
bool hasMultisample = ((gc.paintEngine()->type() == QPaintEngine::OpenGL2) &&
(ctx->hasExtension("GL_ARB_multisample")));
// QPainter cannot anti-alias the edges of circles etc. when using OpenGL
// So instead, use native OpenGL anti-aliasing when available.
if (hasMultisample) {
gc.beginNativePainting();
ctx->functions()->glEnable(GL_MULTISAMPLE);
gc.endNativePainting();
}
float halfHandleSize = d->handleSize / 2;
d->recomputeVisibleAxes(gc.viewport());
- if(d->mirrorHorizontal) {
+ if(d->mirrorHorizontal && !d->hideHorizontalDecoration) {
if (!d->horizontalAxis.isNull()) {
// QPointF horizontalIndicatorCenter = d->horizontalAxis.unitVector().pointAt(15);
// QRectF horizontalIndicator = QRectF(horizontalIndicatorCenter.x() - halfHandleSize, horizontalIndicatorCenter.y() - halfHandleSize, d->handleSize, d->handleSize);
float horizontalHandlePosition = qBound(d->minHandlePosition, d->horizontalHandlePosition, d->horizontalAxis.length() - d->minHandlePosition);
QPointF horizontalHandleCenter = d->horizontalAxis.unitVector().pointAt(horizontalHandlePosition);
d->horizontalHandle = QRectF(horizontalHandleCenter.x() - halfHandleSize, horizontalHandleCenter.y() - halfHandleSize, d->handleSize, d->handleSize);
gc.setPen(QPen(QColor(0, 0, 0, 64), 2, Qt::DashDotDotLine, Qt::RoundCap, Qt::RoundJoin));
gc.drawLine(d->horizontalAxis);
// gc.drawEllipse(horizontalIndicator);
// gc.drawPixmap(horizontalIndicator.adjusted(5, 5, -5, -5).toRect(), d->horizontalIcon);
- gc.setPen(QPen(QColor(0, 0, 0, 128), 2));
- gc.drawEllipse(d->horizontalHandle);
- gc.drawPixmap(d->horizontalHandle.adjusted(5, 5, -5, -5).toRect(), d->horizontalIcon);
+ // don't draw the handles if we are locking the axis for movement
+ if (!d->lockHorizontal) {
+ gc.setPen(QPen(QColor(0, 0, 0, 128), 2));
+ gc.drawEllipse(d->horizontalHandle);
+ gc.drawPixmap(d->horizontalHandle.adjusted(5, 5, -5, -5).toRect(), d->horizontalIcon);
+ }
} else {
d->horizontalHandle = QRectF();
}
}
- if(d->mirrorVertical) {
+ if(d->mirrorVertical && !d->hideVerticalDecoration) {
if (!d->verticalAxis.isNull()) {
gc.setPen(QPen(QColor(0, 0, 0, 64), 2, Qt::DashDotDotLine, Qt::RoundCap, Qt::RoundJoin));
gc.drawLine(d->verticalAxis);
// QPointF verticalIndicatorCenter = d->verticalAxis.unitVector().pointAt(15);
// QRectF verticalIndicator = QRectF(verticalIndicatorCenter.x() - halfHandleSize, verticalIndicatorCenter.y() - halfHandleSize, d->handleSize, d->handleSize);
float verticalHandlePosition = qBound(d->minHandlePosition, d->verticalHandlePosition, d->verticalAxis.length() - d->minHandlePosition);
QPointF verticalHandleCenter = d->verticalAxis.unitVector().pointAt(verticalHandlePosition);
d->verticalHandle = QRectF(verticalHandleCenter.x() - halfHandleSize, verticalHandleCenter.y() - halfHandleSize, d->handleSize, d->handleSize);
- // gc.drawEllipse(verticalIndicator);
- // gc.drawPixmap(verticalIndicator.adjusted(5, 5, -5, -5).toRect(), d->verticalIcon);
- gc.setPen(QPen(QColor(0, 0, 0, 128), 2));
- gc.drawEllipse(d->verticalHandle);
- gc.drawPixmap(d->verticalHandle.adjusted(5, 5, -5, -5).toRect(), d->verticalIcon);
+ // don't draw the handles if we are locking the axis for movement
+ if (!d->lockVertical) {
+ gc.setPen(QPen(QColor(0, 0, 0, 128), 2));
+ gc.drawEllipse(d->verticalHandle);
+ gc.drawPixmap(d->verticalHandle.adjusted(5, 5, -5, -5).toRect(), d->verticalIcon);
+ }
+
} else {
d->verticalHandle = QRectF();
}
}
if (hasMultisample) {
gc.beginNativePainting();
ctx->functions()->glDisable(GL_MULTISAMPLE);
gc.endNativePainting();
}
}
bool KisMirrorAxis::eventFilter(QObject* target, QEvent* event)
{
if (!visible()) return false;
QObject *expectedCanvasWidget = view() ?
view()->canvasBase()->canvasWidget() : 0;
if (!expectedCanvasWidget || target != expectedCanvasWidget) return false;
if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::TabletPress) {
QMouseEvent *me = dynamic_cast(event);
QTabletEvent *te = dynamic_cast(event);
QPoint pos = me ? me->pos() : (te ? te->pos() : QPoint(77,77));
- if(d->mirrorHorizontal && d->horizontalHandle.contains(pos)) {
+
+
+
+ if(d->mirrorHorizontal && d->horizontalHandle.contains(pos) && !d->lockHorizontal && !d->hideHorizontalDecoration ) {
d->xActive = true;
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
event->accept();
return true;
}
- if(d->mirrorVertical && d->verticalHandle.contains(pos)) {
+ if(d->mirrorVertical && d->verticalHandle.contains(pos) && !d->lockVertical && !d->hideVerticalDecoration) {
d->yActive = true;
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
event->accept();
return true;
}
}
if(event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove) {
QMouseEvent *me = dynamic_cast(event);
QTabletEvent *te = dynamic_cast(event);
QPoint pos = me ? me->pos() : (te ? te->pos() : QPoint(77,77));
if(d->xActive) {
float axisX = view()->viewConverter()->widgetToImage(pos).x();
d->setAxisPosition(axisX, d->axisPosition.y());
d->horizontalHandlePosition = KisAlgebra2D::dotProduct(pos - d->horizontalAxis.p1(), d->horizontalAxis.unitVector().p2() - d->horizontalAxis.p1());
event->accept();
return true;
}
if(d->yActive) {
float axisY = view()->viewConverter()->widgetToImage(pos).y();
d->setAxisPosition(d->axisPosition.x(), axisY);
d->verticalHandlePosition = KisAlgebra2D::dotProduct(pos - d->verticalAxis.p1(), d->verticalAxis.unitVector().p2() - d->verticalAxis.p1());
event->accept();
return true;
}
- if(d->mirrorHorizontal) {
- if(d->horizontalHandle.contains(pos)) {
+ if(d->mirrorHorizontal && !d->hideHorizontalDecoration) {
+ if(d->horizontalHandle.contains(pos) && !d->lockHorizontal) {
if(!d->horizontalContainsCursor) {
QApplication::setOverrideCursor(Qt::OpenHandCursor);
d->horizontalContainsCursor = true;
}
} else if(d->horizontalContainsCursor) {
QApplication::restoreOverrideCursor();
d->horizontalContainsCursor = false;
}
}
- if(d->mirrorVertical) {
- if(d->verticalHandle.contains(pos)) {
+ if(d->mirrorVertical && !d->hideVerticalDecoration) {
+ if(d->verticalHandle.contains(pos) && !d->lockVertical) {
if(!d->verticalContainsCursor) {
QApplication::setOverrideCursor(Qt::OpenHandCursor);
d->verticalContainsCursor = true;
}
} else if(d->verticalContainsCursor) {
QApplication::restoreOverrideCursor();
d->verticalContainsCursor = false;
}
}
}
if(event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::TabletRelease) {
if(d->xActive) {
QApplication::restoreOverrideCursor();
d->xActive = false;
event->accept();
return true;
}
if(d->yActive) {
QApplication::restoreOverrideCursor();
d->yActive = false;
event->accept();
return true;
}
}
return QObject::eventFilter(target, event);
}
void KisMirrorAxis::mirrorModeChanged()
{
d->mirrorHorizontal = d->resourceProvider->mirrorHorizontal();
d->mirrorVertical = d->resourceProvider->mirrorVertical();
+
+ d->lockHorizontal = d->resourceProvider->mirrorHorizontalLock();
+ d->lockVertical = d->resourceProvider->mirrorVerticalLock();
+
+ d->hideHorizontalDecoration = d->resourceProvider->mirrorHorizontalHideDecorations();
+ d->hideVerticalDecoration = d->resourceProvider->mirrorVerticalHideDecorations();
+
setVisible(d->mirrorHorizontal || d->mirrorVertical);
+
}
void KisMirrorAxis::setVisible(bool v)
{
KisCanvasDecoration::setVisible(v);
KisInputManager *inputManager = view() ? view()->canvasBase()->globalInputManager() : 0;
if (!inputManager) return;
if (v) {
inputManager->attachPriorityEventFilter(this);
} else {
inputManager->detachPriorityEventFilter(this);
}
}
+void KisMirrorAxis::moveHorizontalAxisToCenter()
+{
+ d->setAxisPosition(d->image->width()/2, d->axisPosition.y());
+}
+
+void KisMirrorAxis::moveVerticalAxisToCenter()
+{
+ d->setAxisPosition(d->axisPosition.x(), d->image->height()/2 );
+}
+
+
+
void KisMirrorAxis::Private::setAxisPosition(float x, float y)
{
QPointF newPosition = QPointF(x, y);
resourceProvider->resourceManager()->setResource(KisCanvasResourceProvider::MirrorAxesCenter, newPosition);
q->view()->canvasBase()->updateCanvas();
}
+
void KisMirrorAxis::Private::recomputeVisibleAxes(QRect viewport)
{
KisCoordinatesConverter *converter = q->view()->viewConverter();
axisPosition = resourceProvider->resourceManager()->resource(KisCanvasResourceProvider::MirrorAxesCenter).toPointF();
QPointF samplePt1 = converter->imageToWidget(axisPosition);
QPointF samplePt2 = converter->imageToWidget(QPointF(axisPosition.x(), axisPosition.y() - 100));
horizontalAxis = QLineF(samplePt1, samplePt2);
if (!KisAlgebra2D::intersectLineRect(horizontalAxis, viewport)) horizontalAxis = QLineF();
samplePt2 = converter->imageToWidget(QPointF(axisPosition.x() - 100, axisPosition.y()));
verticalAxis = QLineF(samplePt1, samplePt2);
if (!KisAlgebra2D::intersectLineRect(verticalAxis, viewport)) verticalAxis = QLineF();
}
diff --git a/libs/ui/canvas/kis_mirror_axis.h b/libs/ui/canvas/kis_mirror_axis.h
index 99eda39cf6..5c5a3b0078 100644
--- a/libs/ui/canvas/kis_mirror_axis.h
+++ b/libs/ui/canvas/kis_mirror_axis.h
@@ -1,56 +1,58 @@
/*
* Copyright (c) 2014 Arjen Hiemstra
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef KISMIRRORAXIS_H
#define KISMIRRORAXIS_H
#include "kis_canvas_decoration.h"
class KisView;
class KisCanvasResourceProvider;
class KisMirrorAxis : public KisCanvasDecoration
{
Q_OBJECT
Q_PROPERTY(float handleSize READ handleSize WRITE setHandleSize NOTIFY handleSizeChanged)
public:
KisMirrorAxis(KisCanvasResourceProvider* provider, QPointer parent);
~KisMirrorAxis();
float handleSize() const;
void setHandleSize(float newSize);
void setVisible(bool v);
Q_SIGNALS:
void handleSizeChanged();
protected:
virtual void drawDecoration(QPainter& gc, const QRectF& updateArea, const KisCoordinatesConverter* converter, KisCanvas2* canvas);
virtual bool eventFilter(QObject* target, QEvent* event);
private:
class Private;
Private * const d;
private Q_SLOTS:
void mirrorModeChanged();
+ void moveHorizontalAxisToCenter();
+ void moveVerticalAxisToCenter();
};
#endif // KISMIRRORAXIS_H
diff --git a/libs/ui/kis_animation_exporter.cpp b/libs/ui/kis_animation_exporter.cpp
index 7ca3530bea..e8a102a259 100644
--- a/libs/ui/kis_animation_exporter.cpp
+++ b/libs/ui/kis_animation_exporter.cpp
@@ -1,227 +1,326 @@
/*
* Copyright (c) 2015 Jouni Pentikäinen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_animation_exporter.h"
#include
-#include
+#include
#include
#include
#include "KoFileDialog.h"
#include "KisDocument.h"
#include "kis_image.h"
#include "KisImportExportManager.h"
#include "kis_image_animation_interface.h"
#include "KisPart.h"
+#include "KisMainWindow.h"
+
#include "kis_paint_layer.h"
#include "kis_group_layer.h"
#include "kis_time_range.h"
#include "kis_painter.h"
+#include "kis_image_lock_hijacker.h"
+
+
struct KisAnimationExporterUI::Private
{
QWidget *parentWidget;
- KisAnimationExporter *exporter;
+ KisAnimationExportSaver *exporter;
Private(QWidget *parent)
: parentWidget(parent),
exporter(0)
{}
};
KisAnimationExporterUI::KisAnimationExporterUI(QWidget *parent)
: m_d(new Private(parent))
{
}
KisAnimationExporterUI::~KisAnimationExporterUI()
{
if (m_d->exporter) {
delete m_d->exporter;
}
}
KisImportExportFilter::ConversionStatus KisAnimationExporterUI::exportSequence(KisDocument *document)
{
KoFileDialog dialog(m_d->parentWidget, KoFileDialog::SaveFile, "exportsequence");
dialog.setCaption(i18n("Export sequence"));
dialog.setDefaultDir(QDesktopServices::storageLocation(QDesktopServices::PicturesLocation));
dialog.setMimeTypeFilters(KisImportExportManager::mimeFilter(KisImportExportManager::Export));
QString filename = dialog.filename();
// if the user presses cancel, it returns empty
if (filename.isEmpty()) return KisImportExportFilter::UserCancelled;
const KisTimeRange fullClipRange = document->image()->animationInterface()->fullClipRange();
int firstFrame = fullClipRange.start();
int lastFrame = fullClipRange.end();
- m_d->exporter = new KisAnimationExporter(document, filename, firstFrame, lastFrame);
+ m_d->exporter = new KisAnimationExportSaver(document, filename, firstFrame, lastFrame);
return m_d->exporter->exportAnimation();
}
struct KisAnimationExporter::Private
{
KisDocument *document;
KisImageWSP image;
- QString filenamePrefix;
- QString filenameSuffix;
-
int firstFrame;
- int currentFrame;
int lastFrame;
+ int currentFrame;
- QScopedPointer tmpDoc;
- KisImageWSP tmpImage;
- KisPaintDeviceSP tmpDevice;
-
- bool exporting;
bool batchMode;
+ bool isCancelled;
+
KisImportExportFilter::ConversionStatus status;
- QMutex mutex;
- QWaitCondition exportFinished;
+ SaveFrameCallback saveFrameCallback;
+
+ KisPaintDeviceSP tmpDevice;
Private(KisDocument *document, int fromTime, int toTime)
: document(document),
image(document->image()),
firstFrame(fromTime),
lastFrame(toTime),
- tmpDoc(KisPart::instance()->createDocument()),
- exporting(false),
- batchMode(false)
+ currentFrame(-1),
+ batchMode(document->fileBatchMode()),
+ isCancelled(false),
+ status(KisImportExportFilter::OK),
+ tmpDevice(new KisPaintDevice(image->colorSpace()))
{
- tmpDoc->setAutoSave(0);
-
- tmpImage = new KisImage(tmpDoc->createUndoStore(),
- image->bounds().width(),
- image->bounds().height(),
- image->colorSpace(),
- QString());
-
- tmpImage->setResolution(image->xRes(), image->yRes());
- tmpDoc->setCurrentImage(tmpImage);
-
- KisPaintLayer* paintLayer = new KisPaintLayer(tmpImage, "paint device", 255);
- tmpImage->addNode(paintLayer, tmpImage->rootLayer(), KisLayerSP(0));
-
- tmpDevice = paintLayer->paintDevice();
}
};
-KisAnimationExporter::KisAnimationExporter(KisDocument *document, const QString &baseFilename, int fromTime, int toTime)
+KisAnimationExporter::KisAnimationExporter(KisDocument *document, int fromTime, int toTime)
: m_d(new Private(document, fromTime, toTime))
{
- int baseLength = baseFilename.lastIndexOf(".");
- if (baseLength > -1) {
- m_d->filenamePrefix = baseFilename.left(baseLength);
- m_d->filenameSuffix = baseFilename.right(baseFilename.length() - baseLength);
- } else {
- m_d->filenamePrefix = baseFilename;
- }
- m_d->batchMode = document->fileBatchMode();
-
- QString mimefilter = KisMimeDatabase::mimeTypeForFile(baseFilename);
- m_d->tmpDoc->setOutputMimeType(mimefilter.toLatin1());
- m_d->tmpDoc->setFileBatchMode(true);
+ connect(m_d->image->animationInterface(), SIGNAL(sigFrameReady(int)),
+ this, SLOT(frameReadyToCopy(int)), Qt::DirectConnection);
- connect(this, SIGNAL(sigFrameReadyToSave()), this, SLOT(frameReadyToSave()), Qt::QueuedConnection);
+ connect(this, SIGNAL(sigFrameReadyToSave()),
+ this, SLOT(frameReadyToSave()), Qt::QueuedConnection);
}
KisAnimationExporter::~KisAnimationExporter()
{
}
+void KisAnimationExporter::setSaveFrameCallback(SaveFrameCallback func)
+{
+ m_d->saveFrameCallback = func;
+}
+
KisImportExportFilter::ConversionStatus KisAnimationExporter::exportAnimation()
{
+ QScopedPointer progress;
if (!m_d->batchMode) {
- emit m_d->document->statusBarMessage(i18n("Export frames"));
+ QString message = i18n("Export frames...");
+ progress.reset(new QProgressDialog(message, "", 0, 0, KisPart::instance()->currentMainwindow()));
+ progress->setWindowModality(Qt::ApplicationModal);
+ progress->setCancelButton(0);
+ progress->setMinimumDuration(0);
+ progress->setValue(0);
+
+ emit m_d->document->statusBarMessage(message);
emit m_d->document->sigProgress(0);
connect(m_d->document, SIGNAL(sigProgressCanceled()), this, SLOT(cancel()));
}
+
+ /**
+ * HACK ALERT: Here we remove the image lock! We do it in a GUI
+ * thread under the barrier lock held, so it is
+ * guaranteed no other stroke will accidentally be
+ * started by this. And showing an app-modal dialog to
+ * the user will prevent him from doing anything
+ * nasty.
+ */
+ KisImageLockHijacker badGuy(m_d->image);
+
+ KIS_ASSERT_RECOVER(!m_d->image->locked()) { return KisImportExportFilter::InternalError; }
+
m_d->status = KisImportExportFilter::OK;
- m_d->exporting = true;
m_d->currentFrame = m_d->firstFrame;
- connect(m_d->image->animationInterface(), SIGNAL(sigFrameReady(int)), this, SLOT(frameReadyToCopy(int)), Qt::DirectConnection);
m_d->image->animationInterface()->requestFrameRegeneration(m_d->currentFrame, m_d->image->bounds());
QEventLoop loop;
loop.connect(this, SIGNAL(sigFinished()), SLOT(quit()));
loop.exec();
- return m_d->status;
-}
-
-void KisAnimationExporter::stopExport()
-{
- if (!m_d->exporting) return;
-
- m_d->exporting = false;
-
- disconnect(m_d->image->animationInterface(), 0, this, 0);
-
if (!m_d->batchMode) {
disconnect(m_d->document, SIGNAL(sigProgressCanceled()), this, SLOT(cancel()));
emit m_d->document->sigProgress(100);
emit m_d->document->clearStatusBarMessage();
+ progress.reset();
}
- emit sigFinished();
+
+ return m_d->status;
}
void KisAnimationExporter::cancel()
{
- m_d->status = KisImportExportFilter::ProgressCancelled;
- stopExport();
+ m_d->isCancelled = true;
}
void KisAnimationExporter::frameReadyToCopy(int time)
{
if (time != m_d->currentFrame) return;
QRect rc = m_d->image->bounds();
KisPainter::copyAreaOptimized(rc.topLeft(), m_d->image->projection(), m_d->tmpDevice, rc);
emit sigFrameReadyToSave();
}
void KisAnimationExporter::frameReadyToSave()
{
- QString frameNumber = QString("%1").arg(m_d->currentFrame, 4, 10, QChar('0'));
- QString filename = m_d->filenamePrefix + frameNumber + m_d->filenameSuffix;
+ KIS_ASSERT_RECOVER(m_d->saveFrameCallback) {
+ m_d->status = KisImportExportFilter::InternalError;
+ emit sigFinished();
+ return;
+ }
- if (m_d->tmpDoc->exportDocument(QUrl::fromLocalFile(filename))) {
-
- if (m_d->exporting && m_d->currentFrame < m_d->lastFrame) {
- if (!m_d->batchMode) {
- emit m_d->document->sigProgress((m_d->currentFrame - m_d->firstFrame) * 100 /
- (m_d->lastFrame - m_d->firstFrame));
- }
- m_d->currentFrame++;
- m_d->image->animationInterface()->requestFrameRegeneration(m_d->currentFrame, m_d->image->bounds());
- return; //continue
- }
+ if (m_d->isCancelled) {
+ m_d->status = KisImportExportFilter::UserCancelled;
+ emit sigFinished();
+ return;
+ }
+
+ KisImportExportFilter::ConversionStatus result =
+ KisImportExportFilter::OK;
+ int time = m_d->currentFrame;
+
+ result = m_d->saveFrameCallback(time, m_d->tmpDevice);
+
+ if (!m_d->batchMode) {
+ emit m_d->document->sigProgress((time - m_d->firstFrame) * 100 /
+ (m_d->lastFrame - m_d->firstFrame));
+ }
+
+ if (result == KisImportExportFilter::OK &&
+ time < m_d->lastFrame) {
+
+ m_d->currentFrame = time + 1;
+ m_d->image->animationInterface()->requestFrameRegeneration(m_d->currentFrame, m_d->image->bounds());
} else {
- //error
- m_d->status = KisImportExportFilter::InternalError;
+ emit sigFinished();
}
- stopExport(); //finish
+}
+
+struct KisAnimationExportSaver::Private
+{
+ Private(KisDocument *document, int fromTime, int toTime)
+ : document(document),
+ image(document->image()),
+ firstFrame(fromTime),
+ lastFrame(toTime),
+ tmpDoc(KisPart::instance()->createDocument()),
+ exporter(document, fromTime, toTime)
+ {
+ tmpDoc->setAutoSave(0);
+
+ tmpImage = new KisImage(tmpDoc->createUndoStore(),
+ image->bounds().width(),
+ image->bounds().height(),
+ image->colorSpace(),
+ QString());
+
+ tmpImage->setResolution(image->xRes(), image->yRes());
+ tmpDoc->setCurrentImage(tmpImage);
+
+ KisPaintLayer* paintLayer = new KisPaintLayer(tmpImage, "paint device", 255);
+ tmpImage->addNode(paintLayer, tmpImage->rootLayer(), KisLayerSP(0));
+
+ tmpDevice = paintLayer->paintDevice();
+ }
+
+
+
+ KisDocument *document;
+ KisImageWSP image;
+ int firstFrame;
+ int lastFrame;
+
+ QScopedPointer tmpDoc;
+ KisImageSP tmpImage;
+ KisPaintDeviceSP tmpDevice;
+
+ KisAnimationExporter exporter;
+
+ QString filenamePrefix;
+ QString filenameSuffix;
+};
+
+KisAnimationExportSaver::KisAnimationExportSaver(KisDocument *document, const QString &baseFilename, int fromTime, int toTime)
+ : m_d(new Private(document, fromTime, toTime))
+{
+ int baseLength = baseFilename.lastIndexOf(".");
+ if (baseLength > -1) {
+ m_d->filenamePrefix = baseFilename.left(baseLength);
+ m_d->filenameSuffix = baseFilename.right(baseFilename.length() - baseLength);
+ } else {
+ m_d->filenamePrefix = baseFilename;
+ }
+
+ QString mimefilter = KisMimeDatabase::mimeTypeForFile(baseFilename);
+ m_d->tmpDoc->setOutputMimeType(mimefilter.toLatin1());
+ m_d->tmpDoc->setFileBatchMode(true);
+
+ using namespace std::placeholders; // For _1 placeholder
+ m_d->exporter.setSaveFrameCallback(std::bind(&KisAnimationExportSaver::saveFrameCallback, this, _1, _2));
+}
+
+KisAnimationExportSaver::~KisAnimationExportSaver()
+{
+}
+
+KisImportExportFilter::ConversionStatus KisAnimationExportSaver::exportAnimation()
+{
+ return m_d->exporter.exportAnimation();
+}
+
+KisImportExportFilter::ConversionStatus KisAnimationExportSaver::saveFrameCallback(int time, KisPaintDeviceSP frame)
+{
+ KisImportExportFilter::ConversionStatus status =
+ KisImportExportFilter::OK;
+
+ QString frameNumber = QString("%1").arg(time, 4, 10, QChar('0'));
+ QString filename = m_d->filenamePrefix + frameNumber + m_d->filenameSuffix;
+
+ QRect rc = m_d->image->bounds();
+ KisPainter::copyAreaOptimized(rc.topLeft(), frame, m_d->tmpDevice, rc);
+
+ if (!m_d->tmpDoc->exportDocument(QUrl::fromLocalFile(filename))) {
+ status = KisImportExportFilter::InternalError;
+ }
+
+ return status;
+}
+
+QString KisAnimationExportSaver::savedFilesMask() const
+{
+ return m_d->filenamePrefix + "%04d" + m_d->filenameSuffix;
}
diff --git a/libs/ui/kis_animation_exporter.h b/libs/ui/kis_animation_exporter.h
index 544e65ad35..1ba139571b 100644
--- a/libs/ui/kis_animation_exporter.h
+++ b/libs/ui/kis_animation_exporter.h
@@ -1,70 +1,94 @@
/*
* Copyright (c) 2015 Jouni Pentikäinen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_ANIMATION_EXPORTER_H
#define KIS_ANIMATION_EXPORTER_H
#include "kis_types.h"
#include "kritaui_export.h"
#include
+#include
+
+
class KisDocument;
class KRITAUI_EXPORT KisAnimationExporterUI : public QObject
{
Q_OBJECT
public:
KisAnimationExporterUI(QWidget *parent);
~KisAnimationExporterUI();
KisImportExportFilter::ConversionStatus exportSequence(KisDocument *document);
private:
struct Private;
QScopedPointer m_d;
};
class KRITAUI_EXPORT KisAnimationExporter : public QObject
{
Q_OBJECT
-
public:
- KisAnimationExporter(KisDocument *document, const QString &baseFilename, int fromTime, int toTime);
+ typedef std::function SaveFrameCallback;
+public:
+ KisAnimationExporter(KisDocument *document, int fromTime, int toTime);
~KisAnimationExporter();
KisImportExportFilter::ConversionStatus exportAnimation();
- void stopExport();
+
+ void setSaveFrameCallback(SaveFrameCallback func);
Q_SIGNALS:
// Internal, used for getting back to main thread
void sigFrameReadyToSave();
void sigFinished();
private Q_SLOTS:
void frameReadyToCopy(int time);
void frameReadyToSave();
void cancel();
private:
struct Private;
QScopedPointer m_d;
};
+class KRITAUI_EXPORT KisAnimationExportSaver : public QObject
+{
+ Q_OBJECT
+public:
+ KisAnimationExportSaver(KisDocument *document, const QString &baseFilename, int fromTime, int toTime);
+ ~KisAnimationExportSaver();
+
+ KisImportExportFilter::ConversionStatus exportAnimation();
+
+ QString savedFilesMask() const;
+
+private:
+ KisImportExportFilter::ConversionStatus saveFrameCallback(int time, KisPaintDeviceSP frame);
+
+private:
+ struct Private;
+ const QScopedPointer m_d;
+};
+
#endif
diff --git a/libs/ui/kis_canvas_resource_provider.cpp b/libs/ui/kis_canvas_resource_provider.cpp
index 2a879552a5..08646bd49e 100644
--- a/libs/ui/kis_canvas_resource_provider.cpp
+++ b/libs/ui/kis_canvas_resource_provider.cpp
@@ -1,447 +1,501 @@
/*
* Copyright (c) 2006 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_canvas_resource_provider.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_favorite_resource_manager.h"
#include "kis_config.h"
#include "KisViewManager.h"
#include "canvas/kis_canvas2.h"
KisCanvasResourceProvider::KisCanvasResourceProvider(KisViewManager * view)
: m_view(view)
{
m_fGChanged = true;
m_enablefGChange = true; // default to true, so that colour history is working without popup palette
}
KisCanvasResourceProvider::~KisCanvasResourceProvider()
{
disconnect(); // in case Qt gets confused
}
KoCanvasResourceManager* KisCanvasResourceProvider::resourceManager()
{
return m_resourceManager;
}
void KisCanvasResourceProvider::setResourceManager(KoCanvasResourceManager *resourceManager)
{
m_resourceManager = resourceManager;
QVariant v;
v.setValue(KoColor(Qt::black, KoColorSpaceRegistry::instance()->rgb8()));
m_resourceManager->setResource(KoCanvasResourceManager::ForegroundColor, v);
v.setValue(KoColor(Qt::white, KoColorSpaceRegistry::instance()->rgb8()));
m_resourceManager->setResource(KoCanvasResourceManager::BackgroundColor, v);
setCurrentCompositeOp(COMPOSITE_OVER);
setMirrorHorizontal(false);
setMirrorVertical(false);
m_resourceManager->setResource(HdrExposure, 0.0);
m_resourceManager->setResource(HdrGamma, 1.0);
m_resourceManager->setResource(EffectiveZoom, 1.0);
connect(m_resourceManager, SIGNAL(canvasResourceChanged(int,QVariant)),
this, SLOT(slotCanvasResourceChanged(int,QVariant)));
m_resourceManager->setResource(KoCanvasResourceManager::ApplicationSpeciality, KoCanvasResourceManager::NoAdvancedText);
}
KoCanvasBase * KisCanvasResourceProvider::canvas() const
{
return m_view->canvasBase();
}
KoColor KisCanvasResourceProvider::bgColor() const
{
return m_resourceManager->resource(KoCanvasResourceManager::BackgroundColor).value();
}
KoColor KisCanvasResourceProvider::fgColor() const
{
return m_resourceManager->resource(KoCanvasResourceManager::ForegroundColor).value();
}
float KisCanvasResourceProvider::HDRExposure() const
{
return static_cast(m_resourceManager->resource(HdrExposure).toDouble());
}
void KisCanvasResourceProvider::setHDRExposure(float exposure)
{
m_resourceManager->setResource(HdrExposure, static_cast(exposure));
}
float KisCanvasResourceProvider::HDRGamma() const
{
return static_cast(m_resourceManager->resource(HdrGamma).toDouble());
}
void KisCanvasResourceProvider::setHDRGamma(float gamma)
{
m_resourceManager->setResource(HdrGamma, static_cast(gamma));
}
KoPattern * KisCanvasResourceProvider::currentPattern() const
{
if (m_resourceManager->hasResource(CurrentPattern)) {
return m_resourceManager->resource(CurrentPattern).value();
}
else {
return 0;
}
}
KisFilterConfiguration * KisCanvasResourceProvider::currentGeneratorConfiguration() const
{
return m_resourceManager->resource(CurrentGeneratorConfiguration).value();
}
KoAbstractGradient* KisCanvasResourceProvider::currentGradient() const
{
if (m_resourceManager->hasResource(CurrentGradient)) {
return m_resourceManager->resource(CurrentGradient).value();
}
else {
return 0;
}
}
KisImageWSP KisCanvasResourceProvider::currentImage() const
{
return m_view->image();
}
KisNodeSP KisCanvasResourceProvider::currentNode() const
{
return m_view->activeNode();
}
KisPaintOpPresetSP KisCanvasResourceProvider::currentPreset() const
{
KisPaintOpPresetSP preset = m_resourceManager->resource(CurrentPaintOpPreset).value();
return preset;
}
void KisCanvasResourceProvider::setPaintOpPreset(const KisPaintOpPresetSP preset)
{
Q_ASSERT(preset->valid());
Q_ASSERT(!preset->paintOp().id().isEmpty());
Q_ASSERT(preset->settings());
if (!preset) return;
dbgUI << "setPaintOpPreset" << preset->paintOp();
QVariant v;
v.setValue(preset);
m_resourceManager->setResource(CurrentPaintOpPreset, v);
}
KisPaintOpPresetSP KisCanvasResourceProvider::previousPreset() const
{
KisPaintOpPresetSP preset = m_resourceManager->resource(PreviousPaintOpPreset).value();
return preset;
}
void KisCanvasResourceProvider::setPreviousPaintOpPreset(const KisPaintOpPresetSP preset)
{
Q_ASSERT(preset->valid());
Q_ASSERT(!preset->paintOp().id().isEmpty());
Q_ASSERT(preset->settings());
if (!preset) return;
dbgUI << "setPreviousPaintOpPreset" << preset->paintOp();
QVariant v;
v.setValue(preset);
m_resourceManager->setResource(PreviousPaintOpPreset, v);
}
void KisCanvasResourceProvider::slotPatternActivated(KoResource * res)
{
KoPattern *pattern = dynamic_cast(res);
QVariant v;
v.setValue(pattern);
m_resourceManager->setResource(CurrentPattern, v);
emit sigPatternChanged(pattern);
}
void KisCanvasResourceProvider::slotGeneratorConfigurationActivated(KisFilterConfiguration * res)
{
KisFilterConfiguration * generatorConfiguration = dynamic_cast(res);
QVariant v;
v.setValue(generatorConfiguration);
m_resourceManager->setResource(CurrentGeneratorConfiguration, v);
}
void KisCanvasResourceProvider::slotGradientActivated(KoResource *res)
{
KoAbstractGradient * gradient = dynamic_cast(res);
QVariant v;
v.setValue(gradient);
m_resourceManager->setResource(CurrentGradient, v);
emit sigGradientChanged(gradient);
}
void KisCanvasResourceProvider::setBGColor(const KoColor& c)
{
QVariant v;
v.setValue(c);
m_resourceManager->setResource(KoCanvasResourceManager::BackgroundColor, v);
emit sigBGColorChanged(c);
}
void KisCanvasResourceProvider::setFGColor(const KoColor& c)
{
m_fGChanged = true;
QVariant v;
v.setValue(c);
m_resourceManager->setResource(KoCanvasResourceManager::ForegroundColor, v);
emit sigFGColorChanged(c);
}
void KisCanvasResourceProvider::slotSetFGColor(const KoColor& c)
{
setFGColor(c);
}
void KisCanvasResourceProvider::slotSetBGColor(const KoColor& c)
{
setBGColor(c);
}
void KisCanvasResourceProvider::slotNodeActivated(const KisNodeSP node)
{
QVariant v;
v.setValue(KisNodeWSP(node));
m_resourceManager->setResource(CurrentKritaNode, v);
emit sigNodeChanged(currentNode());
}
void KisCanvasResourceProvider::slotImageSizeChanged()
{
if (KisImageWSP image = m_view->image()) {
float fw = image->width() / image->xRes();
float fh = image->height() / image->yRes();
QSizeF postscriptSize(fw, fh);
m_resourceManager->setResource(KoCanvasResourceManager::PageSize, postscriptSize);
}
}
void KisCanvasResourceProvider::slotOnScreenResolutionChanged()
{
KisImageWSP image = m_view->image();
KisCanvas2 *canvas = m_view->canvasBase();
if(!image || !canvas) return;
qreal zoomX, zoomY;
canvas->coordinatesConverter()->zoom(&zoomX, &zoomY);
qreal scaleX = zoomX / image->xRes();
qreal scaleY = zoomY / image->yRes();
emit sigOnScreenResolutionChanged(scaleX, scaleY);
}
void KisCanvasResourceProvider::slotCanvasResourceChanged(int key, const QVariant & res)
{
if(key == KoCanvasResourceManager::ForegroundColor || key == KoCanvasResourceManager::BackgroundColor) {
KoAbstractGradient* resource = KoResourceServerProvider::instance()->gradientServer()->resources()[0];
KoStopGradient* stopGradient = dynamic_cast(resource);
if(stopGradient) {
QList stops;
stops << KoGradientStop(0.0, fgColor()) << KoGradientStop(1.0, KoColor(QColor(0, 0, 0, 0), fgColor().colorSpace()));
stopGradient->setStops(stops);
KoResourceServerProvider::instance()->gradientServer()->updateResource(resource);
}
resource = KoResourceServerProvider::instance()->gradientServer()->resources()[1];
stopGradient = dynamic_cast(resource);
if(stopGradient) {
QList stops;
stops << KoGradientStop(0.0, fgColor()) << KoGradientStop(1.0, bgColor());
stopGradient->setStops(stops);
KoResourceServerProvider::instance()->gradientServer()->updateResource(resource);
}
}
switch (key) {
case(KoCanvasResourceManager::ForegroundColor):
m_fGChanged = true;
emit sigFGColorChanged(res.value());
break;
case(KoCanvasResourceManager::BackgroundColor):
emit sigBGColorChanged(res.value());
break;
case(CurrentPattern):
emit sigPatternChanged(static_cast(res.value()));
break;
case(CurrentGradient):
emit sigGradientChanged(static_cast(res.value()));
break;
case(CurrentKritaNode) :
emit sigNodeChanged(currentNode());
break;
case (Opacity):
{
emit sigOpacityChanged(res.toDouble());
}
default:
;
// Do nothing
};
}
void KisCanvasResourceProvider::setCurrentCompositeOp(const QString& compositeOp)
{
m_resourceManager->setResource(CurrentCompositeOp,
QVariant::fromValue(compositeOp));
}
QString KisCanvasResourceProvider::currentCompositeOp() const
{
return m_resourceManager->resource(CurrentCompositeOp).value();
}
bool KisCanvasResourceProvider::eraserMode() const
{
return m_resourceManager->resource(EraserMode).toBool();
}
void KisCanvasResourceProvider::setEraserMode(bool value)
{
m_resourceManager->setResource(EraserMode,
QVariant::fromValue(value));
}
void KisCanvasResourceProvider::slotPainting()
{
if (m_fGChanged && m_enablefGChange) {
emit sigFGColorUsed(fgColor());
m_fGChanged = false;
}
}
void KisCanvasResourceProvider::slotResetEnableFGChange(bool b)
{
m_enablefGChange = b;
}
QList > KisCanvasResourceProvider::perspectiveGrids() const
{
return m_perspectiveGrids;
}
void KisCanvasResourceProvider::addPerspectiveGrid(KisAbstractPerspectiveGrid* grid)
{
m_perspectiveGrids.append(grid);
}
void KisCanvasResourceProvider::removePerspectiveGrid(KisAbstractPerspectiveGrid* grid)
{
m_perspectiveGrids.removeOne(grid);
}
void KisCanvasResourceProvider::clearPerspectiveGrids()
{
m_perspectiveGrids.clear();
}
void KisCanvasResourceProvider::setMirrorHorizontal(bool mirrorHorizontal)
{
m_resourceManager->setResource(MirrorHorizontal, mirrorHorizontal);
emit mirrorModeChanged();
}
bool KisCanvasResourceProvider::mirrorHorizontal() const
{
return m_resourceManager->resource(MirrorHorizontal).toBool();
}
void KisCanvasResourceProvider::setMirrorVertical(bool mirrorVertical)
{
m_resourceManager->setResource(MirrorVertical, mirrorVertical);
emit mirrorModeChanged();
}
bool KisCanvasResourceProvider::mirrorVertical() const
{
return m_resourceManager->resource(MirrorVertical).toBool();
}
+void KisCanvasResourceProvider::setMirrorHorizontalLock(bool isLocked)
+{
+ m_resourceManager->setResource(MirrorHorizontalLock, isLocked);
+ emit mirrorModeChanged();
+}
+
+bool KisCanvasResourceProvider::mirrorHorizontalLock() {
+ return m_resourceManager->resource(MirrorHorizontalLock).toBool();
+}
+
+void KisCanvasResourceProvider::setMirrorVerticalLock(bool isLocked)
+{
+ m_resourceManager->setResource(MirrorVerticalLock, isLocked);
+ emit mirrorModeChanged();
+}
+
+
+
+bool KisCanvasResourceProvider::mirrorVerticalHideDecorations() {
+ return m_resourceManager->resource(MirrorVerticalHideDecorations).toBool();
+}
+
+void KisCanvasResourceProvider::setMirrorVerticalHideDecorations(bool hide)
+{
+ m_resourceManager->setResource(MirrorVerticalHideDecorations, hide);
+ emit mirrorModeChanged();
+}
+
+
+bool KisCanvasResourceProvider::mirrorHorizontalHideDecorations() {
+ return m_resourceManager->resource(MirrorHorizontalHideDecorations).toBool();
+}
+
+void KisCanvasResourceProvider::setMirrorHorizontalHideDecorations(bool hide)
+{
+ m_resourceManager->setResource(MirrorHorizontalHideDecorations, hide);
+ emit mirrorModeChanged();
+}
+
+
+bool KisCanvasResourceProvider::mirrorVerticalLock() {
+ return m_resourceManager->resource(MirrorVerticalLock).toBool();
+}
+
+void KisCanvasResourceProvider::mirrorVerticalMoveCanvasToCenter() {
+ emit moveMirrorVerticalCenter();
+}
+
+void KisCanvasResourceProvider::mirrorHorizontalMoveCanvasToCenter() {
+ emit moveMirrorHorizontalCenter();
+}
+
+
+
void KisCanvasResourceProvider::setOpacity(qreal opacity)
{
m_resourceManager->setResource(Opacity, opacity);
}
qreal KisCanvasResourceProvider::opacity() const
{
return m_resourceManager->resource(Opacity).toReal();
}
void KisCanvasResourceProvider::setGlobalAlphaLock(bool lock)
{
m_resourceManager->setResource(GlobalAlphaLock, lock);
}
bool KisCanvasResourceProvider::globalAlphaLock() const
{
return m_resourceManager->resource(GlobalAlphaLock).toBool();
}
void KisCanvasResourceProvider::notifyLoadingWorkspace(KisWorkspaceResource* workspace)
{
emit sigLoadingWorkspace(workspace);
}
void KisCanvasResourceProvider::notifySavingWorkspace(KisWorkspaceResource* workspace)
{
emit sigSavingWorkspace(workspace);
}
diff --git a/libs/ui/kis_canvas_resource_provider.h b/libs/ui/kis_canvas_resource_provider.h
index 8a0878ca45..27bea92f16 100644
--- a/libs/ui/kis_canvas_resource_provider.h
+++ b/libs/ui/kis_canvas_resource_provider.h
@@ -1,205 +1,229 @@
/*
* Copyright (c) 2006 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_CANVAS_RESOURCE_PROVIDER_H_
#define KIS_CANVAS_RESOURCE_PROVIDER_H_
#include
#include
#include
#include
#include "kis_types.h"
#include "kritaui_export.h"
class KisWorkspaceResource;
class KoColorProfile;
class KoAbstractGradient;
class KoResource;
class KoCanvasBase;
class KisViewManager;
class KoPattern;
class KisFilterConfiguration;
#include
/**
* KisCanvasResourceProvider contains the per-window current settings that
* influence painting, like paintop, color, gradients and so on.
*/
class KRITAUI_EXPORT KisCanvasResourceProvider : public QObject
{
Q_OBJECT
public:
enum Resources {
HdrExposure = KoCanvasResourceManager::KritaStart + 1,
CurrentPattern,
CurrentGradient,
CurrentDisplayProfile,
CurrentImage,
CurrentKritaNode,
CurrentPaintOpPreset,
CurrentGeneratorConfiguration,
CurrentCompositeOp,
CurrentEffectiveCompositeOp,
LodAvailability,
EraserMode,
MirrorHorizontal,
MirrorVertical,
+ MirrorHorizontalLock,
+ MirrorVerticalLock,
+ MirrorVerticalHideDecorations,
+ MirrorHorizontalHideDecorations,
MirrorAxesCenter,
Opacity,
HdrGamma,
GlobalAlphaLock,
PreviousPaintOpPreset,
EffectiveZoom, ///<-Used only by painting tools for non-displaying purposes
PresetAllowsLod
};
KisCanvasResourceProvider(KisViewManager * view);
~KisCanvasResourceProvider();
void setResourceManager(KoCanvasResourceManager *resourceManager);
KoCanvasResourceManager* resourceManager();
KoCanvasBase * canvas() const;
KoColor bgColor() const;
void setBGColor(const KoColor& c);
KoColor fgColor() const;
void setFGColor(const KoColor& c);
float HDRExposure() const;
void setHDRExposure(float exposure);
float HDRGamma() const;
void setHDRGamma(float gamma);
bool eraserMode() const;
void setEraserMode(bool value);
KoPattern *currentPattern() const;
KoAbstractGradient *currentGradient() const;
KisImageWSP currentImage() const;
KisNodeSP currentNode() const;
KisPaintOpPresetSP currentPreset() const;
void setPaintOpPreset(const KisPaintOpPresetSP preset);
KisPaintOpPresetSP previousPreset() const;
void setPreviousPaintOpPreset(const KisPaintOpPresetSP preset);
KisFilterConfiguration* currentGeneratorConfiguration() const;
void setCurrentCompositeOp(const QString& compositeOp);
QString currentCompositeOp() const;
QList > perspectiveGrids() const;
void addPerspectiveGrid(KisAbstractPerspectiveGrid*);
void removePerspectiveGrid(KisAbstractPerspectiveGrid*);
void clearPerspectiveGrids();
void setMirrorHorizontal(bool mirrorHorizontal);
bool mirrorHorizontal() const;
void setMirrorVertical(bool mirrorVertical);
bool mirrorVertical() const;
+ // options for horizontal and vertical mirror toolbar
+ void setMirrorHorizontalLock(bool isLocked);
+ bool mirrorHorizontalLock();
+ void setMirrorVerticalLock(bool isLocked);
+ bool mirrorVerticalLock();
+
+ void setMirrorVerticalHideDecorations(bool hide);
+ bool mirrorVerticalHideDecorations();
+
+ void setMirrorHorizontalHideDecorations(bool hide);
+ bool mirrorHorizontalHideDecorations();
+
+ void mirrorVerticalMoveCanvasToCenter();
+ void mirrorHorizontalMoveCanvasToCenter();
+
+
+
void setOpacity(qreal opacity);
qreal opacity() const;
void setGlobalAlphaLock(bool lock);
bool globalAlphaLock() const;
///Notify that the workspace is saved and settings should be saved to it
void notifySavingWorkspace(KisWorkspaceResource* workspace);
///Notify that the workspace is loaded and settings can be read
void notifyLoadingWorkspace(KisWorkspaceResource* workspace);
public Q_SLOTS:
void slotSetFGColor(const KoColor& c);
void slotSetBGColor(const KoColor& c);
void slotPatternActivated(KoResource *pattern);
void slotGradientActivated(KoResource *gradient);
void slotNodeActivated(const KisNodeSP node);
void slotGeneratorConfigurationActivated(KisFilterConfiguration * generatorConfiguration);
void slotPainting();
/**
* Set the image size in pixels. The resource provider will store
* the image size in postscript points.
*/
// FIXME: this slot doesn't catch the case when image resolution is changed
void slotImageSizeChanged();
void slotOnScreenResolutionChanged();
// This is a flag to handle a bug:
// If pop up palette is visible and a new colour is selected, the new colour
// will be added when the user clicks on the canvas to hide the palette
// In general, we want to be able to store recent color if the pop up palette
// is not visible
void slotResetEnableFGChange(bool);
private Q_SLOTS:
void slotCanvasResourceChanged(int key, const QVariant & res);
Q_SIGNALS:
void sigFGColorChanged(const KoColor &);
void sigBGColorChanged(const KoColor &);
void sigGradientChanged(KoAbstractGradient *);
void sigPatternChanged(KoPattern *);
void sigNodeChanged(const KisNodeSP);
void sigDisplayProfileChanged(const KoColorProfile *);
void sigFGColorUsed(const KoColor&);
void sigOnScreenResolutionChanged(qreal scaleX, qreal scaleY);
void sigOpacityChanged(qreal);
void sigSavingWorkspace(KisWorkspaceResource* workspace);
void sigLoadingWorkspace(KisWorkspaceResource* workspace);
void mirrorModeChanged();
+ void moveMirrorVerticalCenter();
+ void moveMirrorHorizontalCenter();
+
private:
KisViewManager * m_view;
KoCanvasResourceManager *m_resourceManager;
bool m_fGChanged;
QList > m_perspectiveGrids;
// This is a flag to handle a bug:
// If pop up palette is visible and a new colour is selected, the new colour
// will be added when the user clicks on the canvas to hide the palette
// In general, we want to be able to store recent color if the pop up palette
// is not visible
bool m_enablefGChange;
};
#endif
diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc
index ecdf9be771..dde6d49266 100644
--- a/libs/ui/kis_config.cc
+++ b/libs/ui/kis_config.cc
@@ -1,1684 +1,1694 @@
/*
* Copyright (c) 2002 Patrick Julien
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_canvas_resource_provider.h"
#include "kis_config_notifier.h"
#include "kis_snap_config.h"
#include
#include
KisConfig::KisConfig()
: m_cfg( KSharedConfig::openConfig()->group(""))
{
}
KisConfig::~KisConfig()
{
if (qApp->thread() != QThread::currentThread()) {
//dbgKrita << "WARNING: KisConfig: requested config synchronization from nonGUI thread! Skipping...";
return;
}
m_cfg.sync();
}
bool KisConfig::disableTouchOnCanvas(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("disableTouchOnCanvas", false));
}
void KisConfig::setDisableTouchOnCanvas(bool value) const
{
m_cfg.writeEntry("disableTouchOnCanvas", value);
}
bool KisConfig::useProjections(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useProjections", true));
}
void KisConfig::setUseProjections(bool useProj) const
{
m_cfg.writeEntry("useProjections", useProj);
}
bool KisConfig::undoEnabled(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("undoEnabled", true));
}
void KisConfig::setUndoEnabled(bool undo) const
{
m_cfg.writeEntry("undoEnabled", undo);
}
int KisConfig::undoStackLimit(bool defaultValue) const
{
return (defaultValue ? 30 : m_cfg.readEntry("undoStackLimit", 30));
}
void KisConfig::setUndoStackLimit(int limit) const
{
m_cfg.writeEntry("undoStackLimit", limit);
}
bool KisConfig::useCumulativeUndoRedo(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useCumulativeUndoRedo",false));
}
void KisConfig::setCumulativeUndoRedo(bool value)
{
m_cfg.writeEntry("useCumulativeUndoRedo", value);
}
qreal KisConfig::stackT1(bool defaultValue) const
{
return (defaultValue ? 5 : m_cfg.readEntry("stackT1",5));
}
void KisConfig::setStackT1(int T1)
{
m_cfg.writeEntry("stackT1", T1);
}
qreal KisConfig::stackT2(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("stackT2",1));
}
void KisConfig::setStackT2(int T2)
{
m_cfg.writeEntry("stackT2", T2);
}
int KisConfig::stackN(bool defaultValue) const
{
return (defaultValue ? 5 : m_cfg.readEntry("stackN",5));
}
void KisConfig::setStackN(int N)
{
m_cfg.writeEntry("stackN", N);
}
qint32 KisConfig::defImageWidth(bool defaultValue) const
{
return (defaultValue ? 1600 : m_cfg.readEntry("imageWidthDef", 1600));
}
qint32 KisConfig::defImageHeight(bool defaultValue) const
{
return (defaultValue ? 1200 : m_cfg.readEntry("imageHeightDef", 1200));
}
qreal KisConfig::defImageResolution(bool defaultValue) const
{
return (defaultValue ? 100.0 : m_cfg.readEntry("imageResolutionDef", 100.0)) / 72.0;
}
QString KisConfig::defColorModel(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->colorModelId().id()
: m_cfg.readEntry("colorModelDef", KoColorSpaceRegistry::instance()->rgb8()->colorModelId().id()));
}
void KisConfig::defColorModel(const QString & model) const
{
m_cfg.writeEntry("colorModelDef", model);
}
QString KisConfig::defaultColorDepth(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->colorDepthId().id()
: m_cfg.readEntry("colorDepthDef", KoColorSpaceRegistry::instance()->rgb8()->colorDepthId().id()));
}
void KisConfig::setDefaultColorDepth(const QString & depth) const
{
m_cfg.writeEntry("colorDepthDef", depth);
}
QString KisConfig::defColorProfile(bool defaultValue) const
{
return (defaultValue ? KoColorSpaceRegistry::instance()->rgb8()->profile()->name() :
m_cfg.readEntry("colorProfileDef",
KoColorSpaceRegistry::instance()->rgb8()->profile()->name()));
}
void KisConfig::defColorProfile(const QString & profile) const
{
m_cfg.writeEntry("colorProfileDef", profile);
}
void KisConfig::defImageWidth(qint32 width) const
{
m_cfg.writeEntry("imageWidthDef", width);
}
void KisConfig::defImageHeight(qint32 height) const
{
m_cfg.writeEntry("imageHeightDef", height);
}
void KisConfig::defImageResolution(qreal res) const
{
m_cfg.writeEntry("imageResolutionDef", res*72.0);
}
void cleanOldCursorStyleKeys(KConfigGroup &cfg)
{
if (cfg.hasKey("newCursorStyle") &&
cfg.hasKey("newOutlineStyle")) {
cfg.deleteEntry("cursorStyleDef");
}
}
CursorStyle KisConfig::newCursorStyle(bool defaultValue) const
{
if (defaultValue) {
return CURSOR_STYLE_NO_CURSOR;
}
int style = m_cfg.readEntry("newCursorStyle", int(-1));
if (style < 0) {
// old style format
style = m_cfg.readEntry("cursorStyleDef", int(OLD_CURSOR_STYLE_OUTLINE));
switch (style) {
case OLD_CURSOR_STYLE_TOOLICON:
style = CURSOR_STYLE_TOOLICON;
break;
case OLD_CURSOR_STYLE_CROSSHAIR:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS:
style = CURSOR_STYLE_CROSSHAIR;
break;
case OLD_CURSOR_STYLE_POINTER:
style = CURSOR_STYLE_POINTER;
break;
case OLD_CURSOR_STYLE_OUTLINE:
case OLD_CURSOR_STYLE_NO_CURSOR:
style = CURSOR_STYLE_NO_CURSOR;
break;
case OLD_CURSOR_STYLE_SMALL_ROUND:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT:
style = CURSOR_STYLE_SMALL_ROUND;
break;
case OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED:
style = CURSOR_STYLE_TRIANGLE_RIGHTHANDED;
break;
case OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED:
style = CURSOR_STYLE_TRIANGLE_LEFTHANDED;
break;
default:
style = -1;
}
}
cleanOldCursorStyleKeys(m_cfg);
// compatibility with future versions
if (style < 0 || style >= N_CURSOR_STYLE_SIZE) {
style = CURSOR_STYLE_NO_CURSOR;
}
return (CursorStyle) style;
}
void KisConfig::setNewCursorStyle(CursorStyle style)
{
m_cfg.writeEntry("newCursorStyle", (int)style);
}
OutlineStyle KisConfig::newOutlineStyle(bool defaultValue) const
{
if (defaultValue) {
return OUTLINE_FULL;
}
int style = m_cfg.readEntry("newOutlineStyle", int(-1));
if (style < 0) {
// old style format
style = m_cfg.readEntry("cursorStyleDef", int(OLD_CURSOR_STYLE_OUTLINE));
switch (style) {
case OLD_CURSOR_STYLE_TOOLICON:
case OLD_CURSOR_STYLE_CROSSHAIR:
case OLD_CURSOR_STYLE_POINTER:
case OLD_CURSOR_STYLE_NO_CURSOR:
case OLD_CURSOR_STYLE_SMALL_ROUND:
case OLD_CURSOR_STYLE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_TRIANGLE_LEFTHANDED:
style = OUTLINE_NONE;
break;
case OLD_CURSOR_STYLE_OUTLINE:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_DOT:
case OLD_CURSOR_STYLE_OUTLINE_CENTER_CROSS:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_RIGHTHANDED:
case OLD_CURSOR_STYLE_OUTLINE_TRIANGLE_LEFTHANDED:
style = OUTLINE_FULL;
break;
default:
style = -1;
}
}
cleanOldCursorStyleKeys(m_cfg);
// compatibility with future versions
if (style < 0 || style >= N_OUTLINE_STYLE_SIZE) {
style = OUTLINE_FULL;
}
return (OutlineStyle) style;
}
void KisConfig::setNewOutlineStyle(OutlineStyle style)
{
m_cfg.writeEntry("newOutlineStyle", (int)style);
}
QRect KisConfig::colorPreviewRect() const
{
return m_cfg.readEntry("colorPreviewRect", QVariant(QRect(32, 32, 48, 48))).toRect();
}
void KisConfig::setColorPreviewRect(const QRect &rect)
{
m_cfg.writeEntry("colorPreviewRect", QVariant(rect));
}
bool KisConfig::useDirtyPresets(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useDirtyPresets",false));
}
void KisConfig::setUseDirtyPresets(bool value)
{
m_cfg.writeEntry("useDirtyPresets",value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::useEraserBrushSize(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useEraserBrushSize",false));
}
void KisConfig::setUseEraserBrushSize(bool value)
{
m_cfg.writeEntry("useEraserBrushSize",value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
QColor KisConfig::getMDIBackgroundColor(bool defaultValue) const
{
QColor col(77, 77, 77);
return (defaultValue ? col : m_cfg.readEntry("mdiBackgroundColor", col));
}
void KisConfig::setMDIBackgroundColor(const QColor &v) const
{
m_cfg.writeEntry("mdiBackgroundColor", v);
}
QString KisConfig::getMDIBackgroundImage(bool defaultValue) const
{
return (defaultValue ? "" : m_cfg.readEntry("mdiBackgroundImage", ""));
}
void KisConfig::setMDIBackgroundImage(const QString &filename) const
{
m_cfg.writeEntry("mdiBackgroundImage", filename);
}
QString KisConfig::monitorProfile(int screen) const
{
// Note: keep this in sync with the default profile for the RGB colorspaces!
QString profile = m_cfg.readEntry("monitorProfile" + QString(screen == 0 ? "": QString("_%1").arg(screen)), "sRGB-elle-V2-srgbtrc.icc");
//dbgKrita << "KisConfig::monitorProfile()" << profile;
return profile;
}
QString KisConfig::monitorForScreen(int screen, const QString &defaultMonitor, bool defaultValue) const
{
return (defaultValue ? defaultMonitor
: m_cfg.readEntry(QString("monitor_for_screen_%1").arg(screen), defaultMonitor));
}
void KisConfig::setMonitorForScreen(int screen, const QString& monitor)
{
m_cfg.writeEntry(QString("monitor_for_screen_%1").arg(screen), monitor);
}
void KisConfig::setMonitorProfile(int screen, const QString & monitorProfile, bool override) const
{
m_cfg.writeEntry("monitorProfile/OverrideX11", override);
m_cfg.writeEntry("monitorProfile" + QString(screen == 0 ? "": QString("_%1").arg(screen)), monitorProfile);
}
const KoColorProfile *KisConfig::getScreenProfile(int screen)
{
if (screen < 0) return 0;
KisConfig cfg;
QString monitorId;
if (KisColorManager::instance()->devices().size() > screen && screen > 0) {
monitorId = cfg.monitorForScreen(screen, KisColorManager::instance()->devices()[screen]);
}
//dbgKrita << "getScreenProfile(). Screen" << screen << "monitor id" << monitorId;
if (monitorId.isEmpty()) {
return 0;
}
QByteArray bytes = KisColorManager::instance()->displayProfile(monitorId);
//dbgKrita << "\tgetScreenProfile()" << bytes.size();
if (bytes.length() > 0) {
const KoColorProfile *profile = KoColorSpaceRegistry::instance()->createColorProfile(RGBAColorModelID.id(), Integer8BitsColorDepthID.id(), bytes);
//dbgKrita << "\tKisConfig::getScreenProfile for screen" << screen << profile->name();
return profile;
}
else {
//dbgKrita << "\tCould not get a system monitor profile";
return 0;
}
}
const KoColorProfile *KisConfig::displayProfile(int screen) const
{
if (screen < 0) return 0;
// if the user plays with the settings, they can override the display profile, in which case
// we don't want the system setting.
bool override = useSystemMonitorProfile();
//dbgKrita << "KisConfig::displayProfile(). Override X11:" << override;
const KoColorProfile *profile = 0;
if (override) {
//dbgKrita << "\tGoing to get the screen profile";
profile = KisConfig::getScreenProfile(screen);
}
// if it fails. check the configuration
if (!profile || !profile->isSuitableForDisplay()) {
//dbgKrita << "\tGoing to get the monitor profile";
QString monitorProfileName = monitorProfile(screen);
//dbgKrita << "\t\tmonitorProfileName:" << monitorProfileName;
if (!monitorProfileName.isEmpty()) {
profile = KoColorSpaceRegistry::instance()->profileByName(monitorProfileName);
}
if (profile) {
//dbgKrita << "\t\tsuitable for display" << profile->isSuitableForDisplay();
}
else {
//dbgKrita << "\t\tstill no profile";
}
}
// if we still don't have a profile, or the profile isn't suitable for display,
// we need to get a last-resort profile. the built-in sRGB is a good choice then.
if (!profile || !profile->isSuitableForDisplay()) {
//dbgKrita << "\tnothing worked, going to get sRGB built-in";
profile = KoColorSpaceRegistry::instance()->profileByName("sRGB Built-in");
}
if (profile) {
//dbgKrita << "\tKisConfig::displayProfile for screen" << screen << "is" << profile->name();
}
else {
//dbgKrita << "\tCouldn't get a display profile at all";
}
return profile;
}
QString KisConfig::workingColorSpace(bool defaultValue) const
{
return (defaultValue ? "RGBA" : m_cfg.readEntry("workingColorSpace", "RGBA"));
}
void KisConfig::setWorkingColorSpace(const QString & workingColorSpace) const
{
m_cfg.writeEntry("workingColorSpace", workingColorSpace);
}
QString KisConfig::printerColorSpace(bool /*defaultValue*/) const
{
//TODO currently only rgb8 is supported
//return (defaultValue ? "RGBA" : m_cfg.readEntry("printerColorSpace", "RGBA"));
return QString("RGBA");
}
void KisConfig::setPrinterColorSpace(const QString & printerColorSpace) const
{
m_cfg.writeEntry("printerColorSpace", printerColorSpace);
}
QString KisConfig::printerProfile(bool defaultValue) const
{
return (defaultValue ? "" : m_cfg.readEntry("printerProfile", ""));
}
void KisConfig::setPrinterProfile(const QString & printerProfile) const
{
m_cfg.writeEntry("printerProfile", printerProfile);
}
bool KisConfig::useBlackPointCompensation(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useBlackPointCompensation", true));
}
void KisConfig::setUseBlackPointCompensation(bool useBlackPointCompensation) const
{
m_cfg.writeEntry("useBlackPointCompensation", useBlackPointCompensation);
}
bool KisConfig::allowLCMSOptimization(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("allowLCMSOptimization", true));
}
void KisConfig::setAllowLCMSOptimization(bool allowLCMSOptimization)
{
m_cfg.writeEntry("allowLCMSOptimization", allowLCMSOptimization);
}
bool KisConfig::showRulers(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showrulers", false));
}
void KisConfig::setShowRulers(bool rulers) const
{
m_cfg.writeEntry("showrulers", rulers);
}
bool KisConfig::rulersTrackMouse(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("rulersTrackMouse", true));
}
void KisConfig::setRulersTrackMouse(bool value) const
{
m_cfg.writeEntry("rulersTrackMouse", value);
}
qint32 KisConfig::pasteBehaviour(bool defaultValue) const
{
return (defaultValue ? 2 : m_cfg.readEntry("pasteBehaviour", 2));
}
void KisConfig::setPasteBehaviour(qint32 renderIntent) const
{
m_cfg.writeEntry("pasteBehaviour", renderIntent);
}
qint32 KisConfig::monitorRenderIntent(bool defaultValue) const
{
qint32 intent = m_cfg.readEntry("renderIntent", INTENT_PERCEPTUAL);
if (intent > 3) intent = 3;
if (intent < 0) intent = 0;
return (defaultValue ? INTENT_PERCEPTUAL : intent);
}
void KisConfig::setRenderIntent(qint32 renderIntent) const
{
if (renderIntent > 3) renderIntent = 3;
if (renderIntent < 0) renderIntent = 0;
m_cfg.writeEntry("renderIntent", renderIntent);
}
bool KisConfig::useOpenGL(bool defaultValue) const
{
if (defaultValue) {
return true;
}
//dbgKrita << "use opengl" << m_cfg.readEntry("useOpenGL", true) << "success" << m_cfg.readEntry("canvasState", "OPENGL_SUCCESS");
QString canvasState = m_cfg.readEntry("canvasState", "OPENGL_SUCCESS");
return (m_cfg.readEntry("useOpenGL", true) && (canvasState == "OPENGL_SUCCESS" || canvasState == "TRY_OPENGL"));
}
void KisConfig::setUseOpenGL(bool useOpenGL) const
{
m_cfg.writeEntry("useOpenGL", useOpenGL);
}
int KisConfig::openGLFilteringMode(bool defaultValue) const
{
return (defaultValue ? 3 : m_cfg.readEntry("OpenGLFilterMode", 3));
}
void KisConfig::setOpenGLFilteringMode(int filteringMode)
{
m_cfg.writeEntry("OpenGLFilterMode", filteringMode);
}
bool KisConfig::useOpenGLTextureBuffer(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("useOpenGLTextureBuffer", true));
}
void KisConfig::setUseOpenGLTextureBuffer(bool useBuffer)
{
m_cfg.writeEntry("useOpenGLTextureBuffer", useBuffer);
}
int KisConfig::openGLTextureSize(bool defaultValue) const
{
return (defaultValue ? 256 : m_cfg.readEntry("textureSize", 256));
}
bool KisConfig::disableVSync(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("disableVSync", true));
}
void KisConfig::setDisableVSync(bool disableVSync)
{
m_cfg.writeEntry("disableVSync", disableVSync);
}
bool KisConfig::showAdvancedOpenGLSettings(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showAdvancedOpenGLSettings", false));
}
bool KisConfig::forceOpenGLFenceWorkaround(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("forceOpenGLFenceWorkaround", false));
}
int KisConfig::numMipmapLevels(bool defaultValue) const
{
return (defaultValue ? 4 : m_cfg.readEntry("numMipmapLevels", 4));
}
int KisConfig::textureOverlapBorder() const
{
return 1 << qMax(0, numMipmapLevels());
}
qint32 KisConfig::maxNumberOfThreads(bool defaultValue) const
{
return (defaultValue ? QThread::idealThreadCount() : m_cfg.readEntry("maxthreads", QThread::idealThreadCount()));
}
void KisConfig::setMaxNumberOfThreads(qint32 maxThreads)
{
m_cfg.writeEntry("maxthreads", maxThreads);
}
quint32 KisConfig::getGridMainStyle(bool defaultValue) const
{
int v = m_cfg.readEntry("gridmainstyle", 0);
v = qBound(0, v, 2);
return (defaultValue ? 0 : v);
}
void KisConfig::setGridMainStyle(quint32 v) const
{
m_cfg.writeEntry("gridmainstyle", v);
}
quint32 KisConfig::getGridSubdivisionStyle(bool defaultValue) const
{
quint32 v = m_cfg.readEntry("gridsubdivisionstyle", 1);
if (v > 2) v = 2;
return (defaultValue ? 1 : v);
}
void KisConfig::setGridSubdivisionStyle(quint32 v) const
{
m_cfg.writeEntry("gridsubdivisionstyle", v);
}
QColor KisConfig::getGridMainColor(bool defaultValue) const
{
QColor col(99, 99, 99);
return (defaultValue ? col : m_cfg.readEntry("gridmaincolor", col));
}
void KisConfig::setGridMainColor(const QColor & v) const
{
m_cfg.writeEntry("gridmaincolor", v);
}
QColor KisConfig::getGridSubdivisionColor(bool defaultValue) const
{
QColor col(150, 150, 150);
return (defaultValue ? col : m_cfg.readEntry("gridsubdivisioncolor", col));
}
void KisConfig::setGridSubdivisionColor(const QColor & v) const
{
m_cfg.writeEntry("gridsubdivisioncolor", v);
}
quint32 KisConfig::guidesLineStyle(bool defaultValue) const
{
int v = m_cfg.readEntry("guidesLineStyle", 0);
v = qBound(0, v, 2);
return (defaultValue ? 0 : v);
}
void KisConfig::setGuidesLineStyle(quint32 v) const
{
m_cfg.writeEntry("guidesLineStyle", v);
}
QColor KisConfig::guidesColor(bool defaultValue) const
{
QColor col(99, 99, 99);
return (defaultValue ? col : m_cfg.readEntry("guidesColor", col));
}
void KisConfig::setGuidesColor(const QColor & v) const
{
m_cfg.writeEntry("guidesColor", v);
}
void KisConfig::loadSnapConfig(KisSnapConfig *config, bool defaultValue) const
{
KisSnapConfig defaultConfig(false);
if (defaultValue) {
*config = defaultConfig;
return;
}
config->setOrthogonal(m_cfg.readEntry("globalSnapOrthogonal", defaultConfig.orthogonal()));
config->setNode(m_cfg.readEntry("globalSnapNode", defaultConfig.node()));
config->setExtension(m_cfg.readEntry("globalSnapExtension", defaultConfig.extension()));
config->setIntersection(m_cfg.readEntry("globalSnapIntersection", defaultConfig.intersection()));
config->setBoundingBox(m_cfg.readEntry("globalSnapBoundingBox", defaultConfig.boundingBox()));
config->setImageBounds(m_cfg.readEntry("globalSnapImageBounds", defaultConfig.imageBounds()));
config->setImageCenter(m_cfg.readEntry("globalSnapImageCenter", defaultConfig.imageCenter()));
}
void KisConfig::saveSnapConfig(const KisSnapConfig &config)
{
m_cfg.writeEntry("globalSnapOrthogonal", config.orthogonal());
m_cfg.writeEntry("globalSnapNode", config.node());
m_cfg.writeEntry("globalSnapExtension", config.extension());
m_cfg.writeEntry("globalSnapIntersection", config.intersection());
m_cfg.writeEntry("globalSnapBoundingBox", config.boundingBox());
m_cfg.writeEntry("globalSnapImageBounds", config.imageBounds());
m_cfg.writeEntry("globalSnapImageCenter", config.imageCenter());
}
qint32 KisConfig::checkSize(bool defaultValue) const
{
return (defaultValue ? 32 : m_cfg.readEntry("checksize", 32));
}
void KisConfig::setCheckSize(qint32 checksize) const
{
m_cfg.writeEntry("checksize", checksize);
}
bool KisConfig::scrollCheckers(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("scrollingcheckers", false));
}
void KisConfig::setScrollingCheckers(bool sc) const
{
m_cfg.writeEntry("scrollingcheckers", sc);
}
QColor KisConfig::canvasBorderColor(bool defaultValue) const
{
QColor color(QColor(128,128,128));
return (defaultValue ? color : m_cfg.readEntry("canvasBorderColor", color));
}
void KisConfig::setCanvasBorderColor(const QColor& color) const
{
m_cfg.writeEntry("canvasBorderColor", color);
}
bool KisConfig::hideScrollbars(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("hideScrollbars", false));
}
void KisConfig::setHideScrollbars(bool value) const
{
m_cfg.writeEntry("hideScrollbars", value);
}
QColor KisConfig::checkersColor1(bool defaultValue) const
{
QColor col(220, 220, 220);
return (defaultValue ? col : m_cfg.readEntry("checkerscolor", col));
}
void KisConfig::setCheckersColor1(const QColor & v) const
{
m_cfg.writeEntry("checkerscolor", v);
}
QColor KisConfig::checkersColor2(bool defaultValue) const
{
return (defaultValue ? QColor(Qt::white) : m_cfg.readEntry("checkerscolor2", QColor(Qt::white)));
}
void KisConfig::setCheckersColor2(const QColor & v) const
{
m_cfg.writeEntry("checkerscolor2", v);
}
bool KisConfig::antialiasCurves(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("antialiascurves", true));
}
void KisConfig::setAntialiasCurves(bool v) const
{
m_cfg.writeEntry("antialiascurves", v);
}
QColor KisConfig::selectionOverlayMaskColor(bool defaultValue) const
{
QColor def(255, 0, 0, 220);
return (defaultValue ? def : m_cfg.readEntry("selectionOverlayMaskColor", def));
}
void KisConfig::setSelectionOverlayMaskColor(const QColor &color)
{
m_cfg.writeEntry("selectionOverlayMaskColor", color);
}
bool KisConfig::antialiasSelectionOutline(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("AntialiasSelectionOutline", false));
}
void KisConfig::setAntialiasSelectionOutline(bool v) const
{
m_cfg.writeEntry("AntialiasSelectionOutline", v);
}
bool KisConfig::showRootLayer(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ShowRootLayer", false));
}
void KisConfig::setShowRootLayer(bool showRootLayer) const
{
m_cfg.writeEntry("ShowRootLayer", showRootLayer);
}
bool KisConfig::showGlobalSelection(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ShowGlobalSelection", false));
}
void KisConfig::setShowGlobalSelection(bool showGlobalSelection) const
{
m_cfg.writeEntry("ShowGlobalSelection", showGlobalSelection);
}
bool KisConfig::showOutlineWhilePainting(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("ShowOutlineWhilePainting", true));
}
void KisConfig::setShowOutlineWhilePainting(bool showOutlineWhilePainting) const
{
m_cfg.writeEntry("ShowOutlineWhilePainting", showOutlineWhilePainting);
}
bool KisConfig::hideSplashScreen(bool defaultValue) const
{
KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen");
return (defaultValue ? true : cfg.readEntry("HideSplashAfterStartup", true));
}
void KisConfig::setHideSplashScreen(bool hideSplashScreen) const
{
KConfigGroup cfg( KSharedConfig::openConfig(), "SplashScreen");
cfg.writeEntry("HideSplashAfterStartup", hideSplashScreen);
}
qreal KisConfig::outlineSizeMinimum(bool defaultValue) const
{
return (defaultValue ? 1.0 : m_cfg.readEntry("OutlineSizeMinimum", 1.0));
}
void KisConfig::setOutlineSizeMinimum(qreal outlineSizeMinimum) const
{
m_cfg.writeEntry("OutlineSizeMinimum", outlineSizeMinimum);
}
int KisConfig::autoSaveInterval(bool defaultValue) const
{
return (defaultValue ? KisDocument::defaultAutoSave() : m_cfg.readEntry("AutoSaveInterval", KisDocument::defaultAutoSave()));
}
void KisConfig::setAutoSaveInterval(int seconds) const
{
return m_cfg.writeEntry("AutoSaveInterval", seconds);
}
bool KisConfig::backupFile(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("CreateBackupFile", true));
}
void KisConfig::setBackupFile(bool backupFile) const
{
m_cfg.writeEntry("CreateBackupFile", backupFile);
}
bool KisConfig::showFilterGallery(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showFilterGallery", false));
}
void KisConfig::setShowFilterGallery(bool showFilterGallery) const
{
m_cfg.writeEntry("showFilterGallery", showFilterGallery);
}
bool KisConfig::showFilterGalleryLayerMaskDialog(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showFilterGalleryLayerMaskDialog", true));
}
void KisConfig::setShowFilterGalleryLayerMaskDialog(bool showFilterGallery) const
{
m_cfg.writeEntry("setShowFilterGalleryLayerMaskDialog", showFilterGallery);
}
QString KisConfig::canvasState(bool defaultValue) const
{
return (defaultValue ? "OPENGL_NOT_TRIED" : m_cfg.readEntry("canvasState", "OPENGL_NOT_TRIED"));
}
void KisConfig::setCanvasState(const QString& state) const
{
static QStringList acceptableStates;
if (acceptableStates.isEmpty()) {
acceptableStates << "OPENGL_SUCCESS" << "TRY_OPENGL" << "OPENGL_NOT_TRIED" << "OPENGL_FAILED";
}
if (acceptableStates.contains(state)) {
m_cfg.writeEntry("canvasState", state);
m_cfg.sync();
}
}
bool KisConfig::toolOptionsPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ToolOptionsPopupDetached", false));
}
void KisConfig::setToolOptionsPopupDetached(bool detached) const
{
m_cfg.writeEntry("ToolOptionsPopupDetached", detached);
}
bool KisConfig::paintopPopupDetached(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("PaintopPopupDetached", false));
}
void KisConfig::setPaintopPopupDetached(bool detached) const
{
m_cfg.writeEntry("PaintopPopupDetached", detached);
}
QString KisConfig::pressureTabletCurve(bool defaultValue) const
{
return (defaultValue ? "0,0;1,1" : m_cfg.readEntry("tabletPressureCurve","0,0;1,1;"));
}
void KisConfig::setPressureTabletCurve(const QString& curveString) const
{
m_cfg.writeEntry("tabletPressureCurve", curveString);
}
qreal KisConfig::vastScrolling(bool defaultValue) const
{
return (defaultValue ? 0.9 : m_cfg.readEntry("vastScrolling", 0.9));
}
void KisConfig::setVastScrolling(const qreal factor) const
{
m_cfg.writeEntry("vastScrolling", factor);
}
int KisConfig::presetChooserViewMode(bool defaultValue) const
{
return (defaultValue ? 0 : m_cfg.readEntry("presetChooserViewMode", 0));
}
void KisConfig::setPresetChooserViewMode(const int mode) const
{
m_cfg.writeEntry("presetChooserViewMode", mode);
}
bool KisConfig::firstRun(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("firstRun", true));
}
void KisConfig::setFirstRun(const bool first) const
{
m_cfg.writeEntry("firstRun", first);
}
int KisConfig::horizontalSplitLines(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("horizontalSplitLines", 1));
}
void KisConfig::setHorizontalSplitLines(const int numberLines) const
{
m_cfg.writeEntry("horizontalSplitLines", numberLines);
}
int KisConfig::verticalSplitLines(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("verticalSplitLines", 1));
}
void KisConfig::setVerticalSplitLines(const int numberLines) const
{
m_cfg.writeEntry("verticalSplitLines", numberLines);
}
bool KisConfig::clicklessSpacePan(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("clicklessSpacePan", true));
}
void KisConfig::setClicklessSpacePan(const bool toggle) const
{
m_cfg.writeEntry("clicklessSpacePan", toggle);
}
bool KisConfig::hideDockersFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideDockersFullScreen", true));
}
void KisConfig::setHideDockersFullscreen(const bool value) const
{
m_cfg.writeEntry("hideDockersFullScreen", value);
}
bool KisConfig::showDockerTitleBars(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showDockerTitleBars", true));
}
void KisConfig::setShowDockerTitleBars(const bool value) const
{
m_cfg.writeEntry("showDockerTitleBars", value);
}
bool KisConfig::showStatusBar(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showStatusBar", true));
}
void KisConfig::setShowStatusBar(const bool value) const
{
m_cfg.writeEntry("showStatusBar", value);
}
bool KisConfig::hideMenuFullscreen(bool defaultValue) const
{
return (defaultValue ? true: m_cfg.readEntry("hideMenuFullScreen", true));
}
void KisConfig::setHideMenuFullscreen(const bool value) const
{
m_cfg.writeEntry("hideMenuFullScreen", value);
}
bool KisConfig::hideScrollbarsFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideScrollbarsFullScreen", true));
}
void KisConfig::setHideScrollbarsFullscreen(const bool value) const
{
m_cfg.writeEntry("hideScrollbarsFullScreen", value);
}
bool KisConfig::hideStatusbarFullscreen(bool defaultValue) const
{
return (defaultValue ? true: m_cfg.readEntry("hideStatusbarFullScreen", true));
}
void KisConfig::setHideStatusbarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideStatusbarFullScreen", value);
}
bool KisConfig::hideTitlebarFullscreen(bool defaultValue) const
{
#ifdef Q_OS_WIN
return false;
#else
return (defaultValue ? true : m_cfg.readEntry("hideTitleBarFullscreen", true));
#endif
}
void KisConfig::setHideTitlebarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideTitleBarFullscreen", value);
}
bool KisConfig::hideToolbarFullscreen(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("hideToolbarFullscreen", true));
}
void KisConfig::setHideToolbarFullscreen(const bool value) const
{
m_cfg.writeEntry("hideToolbarFullscreen", value);
}
bool KisConfig::fullscreenMode(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("fullscreenMode", true));
}
void KisConfig::setFullscreenMode(const bool value) const
{
m_cfg.writeEntry("fullscreenMode", value);
}
QStringList KisConfig::favoriteCompositeOps(bool defaultValue) const
{
return (defaultValue ? QStringList() : m_cfg.readEntry("favoriteCompositeOps", QStringList()));
}
void KisConfig::setFavoriteCompositeOps(const QStringList& compositeOps) const
{
m_cfg.writeEntry("favoriteCompositeOps", compositeOps);
}
QString KisConfig::exportConfiguration(const QString &filterId, bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("ExportConfiguration-" + filterId, QString()));
}
void KisConfig::setExportConfiguration(const QString &filterId, const KisPropertiesConfiguration &properties) const
{
QString exportConfig = properties.toXML();
m_cfg.writeEntry("ExportConfiguration-" + filterId, exportConfig);
}
bool KisConfig::useOcio(bool defaultValue) const
{
#ifdef HAVE_OCIO
return (defaultValue ? false : m_cfg.readEntry("Krita/Ocio/UseOcio", false));
#else
Q_UNUSED(defaultValue);
return false;
#endif
}
void KisConfig::setUseOcio(bool useOCIO) const
{
m_cfg.writeEntry("Krita/Ocio/UseOcio", useOCIO);
}
int KisConfig::favoritePresets(bool defaultValue) const
{
return (defaultValue ? 10 : m_cfg.readEntry("numFavoritePresets", 10));
}
void KisConfig::setFavoritePresets(const int value)
{
m_cfg.writeEntry("numFavoritePresets", value);
}
bool KisConfig::levelOfDetailEnabled(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("levelOfDetailEnabled", false));
}
void KisConfig::setLevelOfDetailEnabled(bool value)
{
m_cfg.writeEntry("levelOfDetailEnabled", value);
}
KisConfig::OcioColorManagementMode
KisConfig::ocioColorManagementMode(bool defaultValue) const
{
return (OcioColorManagementMode)(defaultValue ? INTERNAL
: m_cfg.readEntry("Krita/Ocio/OcioColorManagementMode", (int) INTERNAL));
}
void KisConfig::setOcioColorManagementMode(OcioColorManagementMode mode) const
{
m_cfg.writeEntry("Krita/Ocio/OcioColorManagementMode", (int) mode);
}
QString KisConfig::ocioConfigurationPath(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("Krita/Ocio/OcioConfigPath", QString()));
}
void KisConfig::setOcioConfigurationPath(const QString &path) const
{
m_cfg.writeEntry("Krita/Ocio/OcioConfigPath", path);
}
QString KisConfig::ocioLutPath(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("Krita/Ocio/OcioLutPath", QString()));
}
void KisConfig::setOcioLutPath(const QString &path) const
{
m_cfg.writeEntry("Krita/Ocio/OcioLutPath", path);
}
int KisConfig::ocioLutEdgeSize(bool defaultValue) const
{
return (defaultValue ? 64 : m_cfg.readEntry("Krita/Ocio/LutEdgeSize", 64));
}
void KisConfig::setOcioLutEdgeSize(int value)
{
m_cfg.writeEntry("Krita/Ocio/LutEdgeSize", value);
}
bool KisConfig::ocioLockColorVisualRepresentation(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("Krita/Ocio/OcioLockColorVisualRepresentation", false));
}
void KisConfig::setOcioLockColorVisualRepresentation(bool value)
{
m_cfg.writeEntry("Krita/Ocio/OcioLockColorVisualRepresentation", value);
}
QString KisConfig::defaultPalette(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("defaultPalette", QString()));
}
void KisConfig::setDefaultPalette(const QString& name) const
{
m_cfg.writeEntry("defaultPalette", name);
}
QString KisConfig::toolbarSlider(int sliderNumber, bool defaultValue) const
{
QString def = "flow";
if (sliderNumber == 1) {
def = "opacity";
}
if (sliderNumber == 2) {
def = "size";
}
return (defaultValue ? def : m_cfg.readEntry(QString("toolbarslider_%1").arg(sliderNumber), def));
}
void KisConfig::setToolbarSlider(int sliderNumber, const QString &slider)
{
m_cfg.writeEntry(QString("toolbarslider_%1").arg(sliderNumber), slider);
}
bool KisConfig::sliderLabels(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("sliderLabels", true));
}
void KisConfig::setSliderLabels(bool enabled)
{
m_cfg.writeEntry("sliderLabels", enabled);
}
QString KisConfig::currentInputProfile(bool defaultValue) const
{
return (defaultValue ? QString() : m_cfg.readEntry("currentInputProfile", QString()));
}
void KisConfig::setCurrentInputProfile(const QString& name)
{
m_cfg.writeEntry("currentInputProfile", name);
}
bool KisConfig::useSystemMonitorProfile(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("ColorManagement/UseSystemMonitorProfile", false));
}
void KisConfig::setUseSystemMonitorProfile(bool _useSystemMonitorProfile) const
{
m_cfg.writeEntry("ColorManagement/UseSystemMonitorProfile", _useSystemMonitorProfile);
}
bool KisConfig::presetStripVisible(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("presetStripVisible", true));
}
void KisConfig::setPresetStripVisible(bool visible)
{
m_cfg.writeEntry("presetStripVisible", visible);
}
bool KisConfig::scratchpadVisible(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("scratchpadVisible", true));
}
void KisConfig::setScratchpadVisible(bool visible)
{
m_cfg.writeEntry("scratchpadVisible", visible);
}
bool KisConfig::showSingleChannelAsColor(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("showSingleChannelAsColor", false));
}
void KisConfig::setShowSingleChannelAsColor(bool asColor)
{
m_cfg.writeEntry("showSingleChannelAsColor", asColor);
}
bool KisConfig::hidePopups(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("hidePopups", false));
}
void KisConfig::setHidePopups(bool hidepopups)
{
m_cfg.writeEntry("hidePopups", hidepopups);
}
int KisConfig::numDefaultLayers(bool defaultValue) const
{
return (defaultValue ? 2 : m_cfg.readEntry("NumberOfLayersForNewImage", 2));
}
void KisConfig::setNumDefaultLayers(int num)
{
m_cfg.writeEntry("NumberOfLayersForNewImage", num);
}
quint8 KisConfig::defaultBackgroundOpacity(bool defaultValue) const
{
return (defaultValue ? (int)OPACITY_OPAQUE_U8 : m_cfg.readEntry("BackgroundOpacityForNewImage", (int)OPACITY_OPAQUE_U8));
}
void KisConfig::setDefaultBackgroundOpacity(quint8 value)
{
m_cfg.writeEntry("BackgroundOpacityForNewImage", (int)value);
}
QColor KisConfig::defaultBackgroundColor(bool defaultValue) const
{
return (defaultValue ? QColor(Qt::white) : m_cfg.readEntry("BackgroundColorForNewImage", QColor(Qt::white)));
}
void KisConfig::setDefaultBackgroundColor(QColor value)
{
m_cfg.writeEntry("BackgroundColorForNewImage", value);
}
KisConfig::BackgroundStyle KisConfig::defaultBackgroundStyle(bool defaultValue) const
{
return (KisConfig::BackgroundStyle)(defaultValue ? LAYER : m_cfg.readEntry("BackgroundStyleForNewImage", (int)LAYER));
}
void KisConfig::setDefaultBackgroundStyle(KisConfig::BackgroundStyle value)
{
m_cfg.writeEntry("BackgroundStyleForNewImage", (int)value);
}
int KisConfig::lineSmoothingType(bool defaultValue) const
{
return (defaultValue ? 1 : m_cfg.readEntry("LineSmoothingType", 1));
}
void KisConfig::setLineSmoothingType(int value)
{
m_cfg.writeEntry("LineSmoothingType", value);
}
qreal KisConfig::lineSmoothingDistance(bool defaultValue) const
{
return (defaultValue ? 50.0 : m_cfg.readEntry("LineSmoothingDistance", 50.0));
}
void KisConfig::setLineSmoothingDistance(qreal value)
{
m_cfg.writeEntry("LineSmoothingDistance", value);
}
qreal KisConfig::lineSmoothingTailAggressiveness(bool defaultValue) const
{
return (defaultValue ? 0.15 : m_cfg.readEntry("LineSmoothingTailAggressiveness", 0.15));
}
void KisConfig::setLineSmoothingTailAggressiveness(qreal value)
{
m_cfg.writeEntry("LineSmoothingTailAggressiveness", value);
}
bool KisConfig::lineSmoothingSmoothPressure(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("LineSmoothingSmoothPressure", false));
}
void KisConfig::setLineSmoothingSmoothPressure(bool value)
{
m_cfg.writeEntry("LineSmoothingSmoothPressure", value);
}
bool KisConfig::lineSmoothingScalableDistance(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingScalableDistance", true));
}
void KisConfig::setLineSmoothingScalableDistance(bool value)
{
m_cfg.writeEntry("LineSmoothingScalableDistance", value);
}
qreal KisConfig::lineSmoothingDelayDistance(bool defaultValue) const
{
return (defaultValue ? 50.0 : m_cfg.readEntry("LineSmoothingDelayDistance", 50.0));
}
void KisConfig::setLineSmoothingDelayDistance(qreal value)
{
m_cfg.writeEntry("LineSmoothingDelayDistance", value);
}
bool KisConfig::lineSmoothingUseDelayDistance(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingUseDelayDistance", true));
}
void KisConfig::setLineSmoothingUseDelayDistance(bool value)
{
m_cfg.writeEntry("LineSmoothingUseDelayDistance", value);
}
bool KisConfig::lineSmoothingFinishStabilizedCurve(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingFinishStabilizedCurve", true));
}
void KisConfig::setLineSmoothingFinishStabilizedCurve(bool value)
{
m_cfg.writeEntry("LineSmoothingFinishStabilizedCurve", value);
}
bool KisConfig::lineSmoothingStabilizeSensors(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("LineSmoothingStabilizeSensors", true));
}
void KisConfig::setLineSmoothingStabilizeSensors(bool value)
{
m_cfg.writeEntry("LineSmoothingStabilizeSensors", value);
}
int KisConfig::paletteDockerPaletteViewSectionSize(bool defaultValue) const
{
return (defaultValue ? 12 : m_cfg.readEntry("paletteDockerPaletteViewSectionSize", 12));
}
void KisConfig::setPaletteDockerPaletteViewSectionSize(int value) const
{
m_cfg.writeEntry("paletteDockerPaletteViewSectionSize", value);
}
int KisConfig::tabletEventsDelay(bool defaultValue) const
{
return (defaultValue ? 10 : m_cfg.readEntry("tabletEventsDelay", 10));
}
void KisConfig::setTabletEventsDelay(int value)
{
m_cfg.writeEntry("tabletEventsDelay", value);
}
bool KisConfig::testingAcceptCompressedTabletEvents(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("testingAcceptCompressedTabletEvents", false));
}
void KisConfig::setTestingAcceptCompressedTabletEvents(bool value)
{
m_cfg.writeEntry("testingAcceptCompressedTabletEvents", value);
}
bool KisConfig::shouldEatDriverShortcuts(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("shouldEatDriverShortcuts", false));
}
bool KisConfig::testingCompressBrushEvents(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("testingCompressBrushEvents", false));
}
void KisConfig::setTestingCompressBrushEvents(bool value)
{
m_cfg.writeEntry("testingCompressBrushEvents", value);
}
bool KisConfig::useVerboseOpenGLDebugOutput(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("useVerboseOpenGLDebugOutput", false));
}
int KisConfig::workaroundX11SmoothPressureSteps(bool defaultValue) const
{
return (defaultValue ? 0 : m_cfg.readEntry("workaroundX11SmoothPressureSteps", 0));
}
bool KisConfig::showCanvasMessages(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("showOnCanvasMessages", true));
}
void KisConfig::setShowCanvasMessages(bool show)
{
m_cfg.writeEntry("showOnCanvasMessages", show);
}
bool KisConfig::compressKra(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("compressLayersInKra", false));
}
void KisConfig::setCompressKra(bool compress)
{
m_cfg.writeEntry("compressLayersInKra", compress);
}
bool KisConfig::toolOptionsInDocker(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("ToolOptionsInDocker", true));
}
void KisConfig::setToolOptionsInDocker(bool inDocker)
{
m_cfg.writeEntry("ToolOptionsInDocker", inDocker);
}
const KoColorSpace* KisConfig::customColorSelectorColorSpace(bool defaultValue) const
{
const KoColorSpace *cs = 0;
KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
if (defaultValue || cfg.readEntry("useCustomColorSpace", true)) {
KoColorSpaceRegistry* csr = KoColorSpaceRegistry::instance();
QString modelID = cfg.readEntry("customColorSpaceModel", "RGBA");
QString depthID = cfg.readEntry("customColorSpaceDepthID", "U8");
QString profile = cfg.readEntry("customColorSpaceProfile", "sRGB built-in - (lcms internal)");
if (profile == "default") {
// qDebug() << "Falling back to default color profile.";
profile = "sRGB built-in - (lcms internal)";
}
cs = csr->colorSpace(modelID, depthID, profile);
}
return cs;
}
void KisConfig::setCustomColorSelectorColorSpace(const KoColorSpace *cs)
{
KConfigGroup cfg = KSharedConfig::openConfig()->group("advancedColorSelector");
cfg.writeEntry("useCustomColorSpace", bool(cs));
if(cs) {
cfg.writeEntry("customColorSpaceModel", cs->colorModelId().id());
cfg.writeEntry("customColorSpaceDepthID", cs->colorDepthId().id());
cfg.writeEntry("customColorSpaceProfile", cs->profile()->name());
}
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::enableOpenGLDebugging(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("enableOpenGLDebugging", false));
}
void KisConfig::setEnableOpenGLDebugging(bool value) const
{
m_cfg.writeEntry("enableOpenGLDebugging", value);
}
void KisConfig::setEnableAmdVectorizationWorkaround(bool value)
{
m_cfg.writeEntry("amdDisableVectorWorkaround", value);
}
bool KisConfig::enableAmdVectorizationWorkaround(bool defaultValue) const
{
return (defaultValue ? false : m_cfg.readEntry("amdDisableVectorWorkaround", false));
}
void KisConfig::setAnimationDropFrames(bool value)
{
bool oldValue = animationDropFrames();
if (value == oldValue) return;
m_cfg.writeEntry("animationDropFrames", value);
KisConfigNotifier::instance()->notifyDropFramesModeChanged();
}
bool KisConfig::animationDropFrames(bool defaultValue) const
{
return (defaultValue ? true : m_cfg.readEntry("animationDropFrames", true));
}
int KisConfig::scribbingUpdatesDelay(bool defaultValue) const
{
return (defaultValue ? 30 : m_cfg.readEntry("scribbingUpdatesDelay", 30));
}
void KisConfig::setScribbingUpdatesDelay(int value)
{
m_cfg.writeEntry("scribbingUpdatesDelay", value);
}
bool KisConfig::switchSelectionCtrlAlt(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("switchSelectionCtrlAlt", false);
}
void KisConfig::setSwitchSelectionCtrlAlt(bool value)
{
m_cfg.writeEntry("switchSelectionCtrlAlt", value);
KisConfigNotifier::instance()->notifyConfigChanged();
}
bool KisConfig::convertToImageColorspaceOnImport(bool defaultValue) const
{
return defaultValue ? false : m_cfg.readEntry("ConvertToImageColorSpaceOnImport", false);
}
void KisConfig::setConvertToImageColorspaceOnImport(bool value)
{
m_cfg.writeEntry("ConvertToImageColorSpaceOnImport", value);
}
int KisConfig::stabilizerSampleSize(bool defaultValue) const
{
#ifdef Q_OS_WIN
const int defaultSampleSize = 50;
#else
const int defaultSampleSize = 15;
#endif
return defaultValue ?
defaultSampleSize : m_cfg.readEntry("stabilizerSampleSize", defaultSampleSize);
}
void KisConfig::setStabilizerSampleSize(int value)
{
m_cfg.writeEntry("stabilizerSampleSize", value);
}
+
+QString KisConfig::customFFMpegPath(bool defaultValue) const
+{
+ return defaultValue ? QString() : m_cfg.readEntry("ffmpegExecutablePath", QString());
+}
+
+void KisConfig::setCustomFFMpegPath(const QString &value) const
+{
+ m_cfg.writeEntry("ffmpegExecutablePath", value);
+}
diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h
index fc02b3146a..51810c6b96 100644
--- a/libs/ui/kis_config.h
+++ b/libs/ui/kis_config.h
@@ -1,513 +1,516 @@
/*
* Copyright (c) 2002 Patrick Julien
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_CONFIG_H_
#define KIS_CONFIG_H_
#include
#include
#include