* demo/shared/icons/Symbols-Delete-icon.png,
* demo/shared/icons/accept-icon.png,
* demo/shared/icons/close.gif,
* demo/shared/icons/crop-icon.png,
* demo/shared/icons/image-add-icon.png,
* demo/shared/icons/image-edit-icon.png,
* demo/shared/icons/image-multi-icon.png,
* demo/shared/icons/image-next-icon.png,
* demo/shared/icons/image-remove-icon.png,
* demo/shared/icons/next-icon.png,
* demo/shared/icons/page-down-icon.png,
* demo/shared/icons/page-search-icon.png,
* demo/shared/icons/rotate_ccw.png,
* demo/shared/icons/rotate_cw.png,
* demo/shared/icons/search-add-icon.png,
* demo/shared/icons/search-remove-icon.png,
* demo/shared/shared.qrc,
* demo/shared/src/bak/crop_item.cc,
* demo/shared/src/bak/crop_item.hh,
* demo/shared/src/bak/image_viewer.cc,
* demo/shared/src/bak/image_viewer.hh,
* demo/shared/src/bak/types.hh,
* demo/shared/src/browse_widget.cc,
* demo/shared/src/browse_widget.hh,
* demo/shared/src/crop_item.cc,
* demo/shared/src/crop_item.hh,
* demo/shared/src/image_viewer.cc,
* demo/shared/src/image_viewer.hh,
* demo/shared/src/internal.bak/interactive_scene.cc,
* demo/shared/src/internal.bak/interactive_scene.hh,
* demo/shared/src/internal.bak/selection_rectangle.cc,
* demo/shared/src/internal.bak/selection_rectangle.hh,
* demo/shared/src/internal/interactive_scene.cc,
* demo/shared/src/internal/interactive_scene.hh,
* demo/shared/src/internal/selection_rectangle.cc,
* demo/shared/src/internal/selection_rectangle.hh,
* demo/shared/src/to_mln_image.hh,
* demo/shared/src/types.hh,
* demo/shared/ui/browse_widget.ui,
* demo/shared/ui/crop_widget.ui,
* demo/shared/ui/image_viewer.ui,
* demo/shared/ui/interactive_scene.cc,
* demo/shared/ui/interactive_scene.hh,
* demo/shared/ui/rotate_widget.ui,
* demo/wizard/images/dematerialization.png,
* demo/wizard/src/crop_page.cc,
* demo/wizard/src/crop_page.hh,
* demo/wizard/src/crop_widget.cc,
* demo/wizard/src/crop_widget.hh,
* demo/wizard/src/doc_type.hh,
* demo/wizard/src/doc_type_page.cc,
* demo/wizard/src/doc_type_page.hh,
* demo/wizard/src/doc_type_widget.cc,
* demo/wizard/src/doc_type_widget.hh,
* demo/wizard/src/load_page.cc,
* demo/wizard/src/load_page.hh,
* demo/wizard/src/load_widget.cc,
* demo/wizard/src/load_widget.hh,
* demo/wizard/src/main.cc,
* demo/wizard/src/main_window.cc,
* demo/wizard/src/main_window.hh,
* demo/wizard/src/mln_widgets.cc,
* demo/wizard/src/preprocessing_page.cc,
* demo/wizard/src/preprocessing_page.hh,
* demo/wizard/src/preprocessing_task.hh,
* demo/wizard/src/preprocessing_widget.cc,
* demo/wizard/src/preprocessing_widget.hh,
* demo/wizard/src/process_page.cc,
* demo/wizard/src/process_page.hh,
* demo/wizard/src/process_widget.cc,
* demo/wizard/src/process_widget.hh,
* demo/wizard/src/rotate_page.cc,
* demo/wizard/src/rotate_page.hh,
* demo/wizard/src/rotate_widget.cc,
* demo/wizard/src/rotate_widget.hh,
* demo/wizard/src/runner.cc,
* demo/wizard/src/runner.hh,
* demo/wizard/src/test.cc,
* demo/wizard/ui/doc_type_widget.ui,
* demo/wizard/ui/load_widget.ui,
* demo/wizard/ui/main_window.ui,
* demo/wizard/ui/preprocessing_widget.ui,
* demo/wizard/wizard.pro,
* demo/wizard/wizard.qrc: New.
---
scribo/ChangeLog | 89 +++++
scribo/demo/shared/icons/Symbols-Delete-icon.png | Bin 0 -> 3704 bytes
scribo/demo/shared/icons/accept-icon.png | Bin 0 -> 4858 bytes
scribo/demo/shared/icons/close.gif | Bin 0 -> 340 bytes
scribo/demo/shared/icons/crop-icon.png | Bin 0 -> 228 bytes
scribo/demo/shared/icons/image-add-icon.png | Bin 0 -> 2917 bytes
scribo/demo/shared/icons/image-edit-icon.png | Bin 0 -> 2305 bytes
scribo/demo/shared/icons/image-multi-icon.png | Bin 0 -> 2033 bytes
scribo/demo/shared/icons/image-next-icon.png | Bin 0 -> 3008 bytes
scribo/demo/shared/icons/image-remove-icon.png | Bin 0 -> 3127 bytes
scribo/demo/shared/icons/next-icon.png | Bin 0 -> 4611 bytes
scribo/demo/shared/icons/page-down-icon.png | Bin 0 -> 3450 bytes
scribo/demo/shared/icons/page-search-icon.png | Bin 0 -> 3101 bytes
scribo/demo/shared/icons/rotate_ccw.png | Bin 0 -> 4200 bytes
scribo/demo/shared/icons/rotate_cw.png | Bin 0 -> 4161 bytes
scribo/demo/shared/icons/search-add-icon.png | Bin 0 -> 4274 bytes
scribo/demo/shared/icons/search-remove-icon.png | Bin 0 -> 4196 bytes
scribo/demo/shared/shared.qrc | 20 ++
scribo/demo/shared/src/bak/crop_item.cc | 332 +++++++++++++++++++
scribo/demo/shared/src/bak/crop_item.hh | 100 ++++++
scribo/demo/shared/src/bak/image_viewer.cc | 242 ++++++++++++++
scribo/demo/shared/src/bak/image_viewer.hh | 116 +++++++
scribo/demo/shared/src/bak/types.hh | 50 +++
scribo/demo/shared/src/browse_widget.cc | 72 ++++
scribo/demo/shared/src/browse_widget.hh | 78 +++++
scribo/demo/shared/src/crop_item.cc | 313 ++++++++++++++++++
scribo/demo/shared/src/crop_item.hh | 103 ++++++
scribo/demo/shared/src/image_viewer.cc | 344 ++++++++++++++++++++
scribo/demo/shared/src/image_viewer.hh | 135 ++++++++
.../shared/src/internal.bak/interactive_scene.cc | 286 ++++++++++++++++
.../shared/src/internal.bak/interactive_scene.hh | 108 ++++++
.../shared/src/internal.bak/selection_rectangle.cc | 241 ++++++++++++++
.../shared/src/internal.bak/selection_rectangle.hh | 91 +++++
.../demo/shared/src/internal/interactive_scene.cc | 87 +++++
.../demo/shared/src/internal/interactive_scene.hh | 84 +++++
.../shared/src/internal/selection_rectangle.cc | 241 ++++++++++++++
.../shared/src/internal/selection_rectangle.hh | 91 +++++
scribo/demo/shared/src/to_mln_image.hh | 77 +++++
scribo/demo/shared/src/types.hh | 50 +++
scribo/demo/shared/ui/browse_widget.ui | 106 ++++++
scribo/demo/shared/ui/crop_widget.ui | 34 ++
scribo/demo/shared/ui/image_viewer.ui | 284 ++++++++++++++++
scribo/demo/shared/ui/interactive_scene.cc | 143 ++++++++
scribo/demo/shared/ui/interactive_scene.hh | 87 +++++
scribo/demo/shared/ui/rotate_widget.ui | 34 ++
scribo/demo/wizard/images/dematerialization.png | Bin 0 -> 76309 bytes
scribo/demo/wizard/src/crop_page.cc | 48 +++
scribo/demo/wizard/src/crop_page.hh | 60 ++++
scribo/demo/wizard/src/crop_widget.cc | 37 ++
scribo/demo/wizard/src/crop_widget.hh | 62 ++++
scribo/demo/wizard/src/doc_type.hh | 51 +++
scribo/demo/wizard/src/doc_type_page.cc | 48 +++
scribo/demo/wizard/src/doc_type_page.hh | 61 ++++
scribo/demo/wizard/src/doc_type_widget.cc | 38 +++
scribo/demo/wizard/src/doc_type_widget.hh | 64 ++++
scribo/demo/wizard/src/load_page.cc | 70 ++++
scribo/demo/wizard/src/load_page.hh | 67 ++++
scribo/demo/wizard/src/load_widget.cc | 56 ++++
scribo/demo/wizard/src/load_widget.hh | 64 ++++
scribo/demo/wizard/src/main.cc | 15 +
scribo/demo/wizard/src/main_window.cc | 129 ++++++++
scribo/demo/wizard/src/main_window.hh | 70 ++++
scribo/demo/wizard/src/mln_widgets.cc | 7 +
scribo/demo/wizard/src/preprocessing_page.cc | 61 ++++
scribo/demo/wizard/src/preprocessing_page.hh | 66 ++++
scribo/demo/wizard/src/preprocessing_task.hh | 61 ++++
scribo/demo/wizard/src/preprocessing_widget.cc | 87 +++++
scribo/demo/wizard/src/preprocessing_widget.hh | 65 ++++
scribo/demo/wizard/src/process_page.cc | 73 ++++
scribo/demo/wizard/src/process_page.hh | 64 ++++
scribo/demo/wizard/src/process_widget.cc | 80 +++++
scribo/demo/wizard/src/process_widget.hh | 71 ++++
scribo/demo/wizard/src/rotate_page.cc | 45 +++
scribo/demo/wizard/src/rotate_page.hh | 60 ++++
scribo/demo/wizard/src/rotate_widget.cc | 38 +++
scribo/demo/wizard/src/rotate_widget.hh | 62 ++++
scribo/demo/wizard/src/runner.cc | 279 ++++++++++++++++
scribo/demo/wizard/src/runner.hh | 84 +++++
scribo/demo/wizard/src/test.cc | 16 +
scribo/demo/wizard/ui/doc_type_widget.ui | 115 +++++++
scribo/demo/wizard/ui/load_widget.ui | 110 +++++++
scribo/demo/wizard/ui/main_window.ui | 216 ++++++++++++
scribo/demo/wizard/ui/preprocessing_widget.ui | 223 +++++++++++++
scribo/demo/wizard/wizard.pro | 67 ++++
scribo/demo/wizard/wizard.qrc | 5 +
85 files changed, 6933 insertions(+), 0 deletions(-)
create mode 100644 scribo/demo/shared/icons/Symbols-Delete-icon.png
create mode 100644 scribo/demo/shared/icons/accept-icon.png
create mode 100644 scribo/demo/shared/icons/close.gif
create mode 100644 scribo/demo/shared/icons/crop-icon.png
create mode 100644 scribo/demo/shared/icons/image-add-icon.png
create mode 100644 scribo/demo/shared/icons/image-edit-icon.png
create mode 100644 scribo/demo/shared/icons/image-multi-icon.png
create mode 100644 scribo/demo/shared/icons/image-next-icon.png
create mode 100644 scribo/demo/shared/icons/image-remove-icon.png
create mode 100644 scribo/demo/shared/icons/next-icon.png
create mode 100644 scribo/demo/shared/icons/page-down-icon.png
create mode 100644 scribo/demo/shared/icons/page-search-icon.png
create mode 100644 scribo/demo/shared/icons/rotate_ccw.png
create mode 100644 scribo/demo/shared/icons/rotate_cw.png
create mode 100644 scribo/demo/shared/icons/search-add-icon.png
create mode 100644 scribo/demo/shared/icons/search-remove-icon.png
create mode 100644 scribo/demo/shared/shared.qrc
create mode 100644 scribo/demo/shared/src/bak/crop_item.cc
create mode 100644 scribo/demo/shared/src/bak/crop_item.hh
create mode 100644 scribo/demo/shared/src/bak/image_viewer.cc
create mode 100644 scribo/demo/shared/src/bak/image_viewer.hh
create mode 100644 scribo/demo/shared/src/bak/types.hh
create mode 100644 scribo/demo/shared/src/browse_widget.cc
create mode 100644 scribo/demo/shared/src/browse_widget.hh
create mode 100644 scribo/demo/shared/src/crop_item.cc
create mode 100644 scribo/demo/shared/src/crop_item.hh
create mode 100644 scribo/demo/shared/src/image_viewer.cc
create mode 100644 scribo/demo/shared/src/image_viewer.hh
create mode 100644 scribo/demo/shared/src/internal.bak/interactive_scene.cc
create mode 100644 scribo/demo/shared/src/internal.bak/interactive_scene.hh
create mode 100644 scribo/demo/shared/src/internal.bak/selection_rectangle.cc
create mode 100644 scribo/demo/shared/src/internal.bak/selection_rectangle.hh
create mode 100644 scribo/demo/shared/src/internal/interactive_scene.cc
create mode 100644 scribo/demo/shared/src/internal/interactive_scene.hh
create mode 100644 scribo/demo/shared/src/internal/selection_rectangle.cc
create mode 100644 scribo/demo/shared/src/internal/selection_rectangle.hh
create mode 100644 scribo/demo/shared/src/to_mln_image.hh
create mode 100644 scribo/demo/shared/src/types.hh
create mode 100644 scribo/demo/shared/ui/browse_widget.ui
create mode 100644 scribo/demo/shared/ui/crop_widget.ui
create mode 100644 scribo/demo/shared/ui/image_viewer.ui
create mode 100644 scribo/demo/shared/ui/interactive_scene.cc
create mode 100644 scribo/demo/shared/ui/interactive_scene.hh
create mode 100644 scribo/demo/shared/ui/rotate_widget.ui
create mode 100644 scribo/demo/wizard/images/dematerialization.png
create mode 100644 scribo/demo/wizard/src/crop_page.cc
create mode 100644 scribo/demo/wizard/src/crop_page.hh
create mode 100644 scribo/demo/wizard/src/crop_widget.cc
create mode 100644 scribo/demo/wizard/src/crop_widget.hh
create mode 100644 scribo/demo/wizard/src/doc_type.hh
create mode 100644 scribo/demo/wizard/src/doc_type_page.cc
create mode 100644 scribo/demo/wizard/src/doc_type_page.hh
create mode 100644 scribo/demo/wizard/src/doc_type_widget.cc
create mode 100644 scribo/demo/wizard/src/doc_type_widget.hh
create mode 100644 scribo/demo/wizard/src/load_page.cc
create mode 100644 scribo/demo/wizard/src/load_page.hh
create mode 100644 scribo/demo/wizard/src/load_widget.cc
create mode 100644 scribo/demo/wizard/src/load_widget.hh
create mode 100644 scribo/demo/wizard/src/main.cc
create mode 100644 scribo/demo/wizard/src/main_window.cc
create mode 100644 scribo/demo/wizard/src/main_window.hh
create mode 100644 scribo/demo/wizard/src/mln_widgets.cc
create mode 100644 scribo/demo/wizard/src/preprocessing_page.cc
create mode 100644 scribo/demo/wizard/src/preprocessing_page.hh
create mode 100644 scribo/demo/wizard/src/preprocessing_task.hh
create mode 100644 scribo/demo/wizard/src/preprocessing_widget.cc
create mode 100644 scribo/demo/wizard/src/preprocessing_widget.hh
create mode 100644 scribo/demo/wizard/src/process_page.cc
create mode 100644 scribo/demo/wizard/src/process_page.hh
create mode 100644 scribo/demo/wizard/src/process_widget.cc
create mode 100644 scribo/demo/wizard/src/process_widget.hh
create mode 100644 scribo/demo/wizard/src/rotate_page.cc
create mode 100644 scribo/demo/wizard/src/rotate_page.hh
create mode 100644 scribo/demo/wizard/src/rotate_widget.cc
create mode 100644 scribo/demo/wizard/src/rotate_widget.hh
create mode 100644 scribo/demo/wizard/src/runner.cc
create mode 100644 scribo/demo/wizard/src/runner.hh
create mode 100644 scribo/demo/wizard/src/test.cc
create mode 100644 scribo/demo/wizard/ui/doc_type_widget.ui
create mode 100644 scribo/demo/wizard/ui/load_widget.ui
create mode 100644 scribo/demo/wizard/ui/main_window.ui
create mode 100644 scribo/demo/wizard/ui/preprocessing_widget.ui
create mode 100644 scribo/demo/wizard/wizard.pro
create mode 100644 scribo/demo/wizard/wizard.qrc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 87985ff..49df10a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,94 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ First draft of the dematerialization wizard.
+
+ * demo/shared/icons/Symbols-Delete-icon.png,
+ * demo/shared/icons/accept-icon.png,
+ * demo/shared/icons/close.gif,
+ * demo/shared/icons/crop-icon.png,
+ * demo/shared/icons/image-add-icon.png,
+ * demo/shared/icons/image-edit-icon.png,
+ * demo/shared/icons/image-multi-icon.png,
+ * demo/shared/icons/image-next-icon.png,
+ * demo/shared/icons/image-remove-icon.png,
+ * demo/shared/icons/next-icon.png,
+ * demo/shared/icons/page-down-icon.png,
+ * demo/shared/icons/page-search-icon.png,
+ * demo/shared/icons/rotate_ccw.png,
+ * demo/shared/icons/rotate_cw.png,
+ * demo/shared/icons/search-add-icon.png,
+ * demo/shared/icons/search-remove-icon.png,
+ * demo/shared/shared.qrc,
+ * demo/shared/src/bak/crop_item.cc,
+ * demo/shared/src/bak/crop_item.hh,
+ * demo/shared/src/bak/image_viewer.cc,
+ * demo/shared/src/bak/image_viewer.hh,
+ * demo/shared/src/bak/types.hh,
+ * demo/shared/src/browse_widget.cc,
+ * demo/shared/src/browse_widget.hh,
+ * demo/shared/src/crop_item.cc,
+ * demo/shared/src/crop_item.hh,
+ * demo/shared/src/image_viewer.cc,
+ * demo/shared/src/image_viewer.hh,
+ * demo/shared/src/internal.bak/interactive_scene.cc,
+ * demo/shared/src/internal.bak/interactive_scene.hh,
+ * demo/shared/src/internal.bak/selection_rectangle.cc,
+ * demo/shared/src/internal.bak/selection_rectangle.hh,
+ * demo/shared/src/internal/interactive_scene.cc,
+ * demo/shared/src/internal/interactive_scene.hh,
+ * demo/shared/src/internal/selection_rectangle.cc,
+ * demo/shared/src/internal/selection_rectangle.hh,
+ * demo/shared/src/to_mln_image.hh,
+ * demo/shared/src/types.hh,
+ * demo/shared/ui/browse_widget.ui,
+ * demo/shared/ui/crop_widget.ui,
+ * demo/shared/ui/image_viewer.ui,
+ * demo/shared/ui/interactive_scene.cc,
+ * demo/shared/ui/interactive_scene.hh,
+ * demo/shared/ui/rotate_widget.ui,
+ * demo/wizard/images/dematerialization.png,
+ * demo/wizard/src/crop_page.cc,
+ * demo/wizard/src/crop_page.hh,
+ * demo/wizard/src/crop_widget.cc,
+ * demo/wizard/src/crop_widget.hh,
+ * demo/wizard/src/doc_type.hh,
+ * demo/wizard/src/doc_type_page.cc,
+ * demo/wizard/src/doc_type_page.hh,
+ * demo/wizard/src/doc_type_widget.cc,
+ * demo/wizard/src/doc_type_widget.hh,
+ * demo/wizard/src/load_page.cc,
+ * demo/wizard/src/load_page.hh,
+ * demo/wizard/src/load_widget.cc,
+ * demo/wizard/src/load_widget.hh,
+ * demo/wizard/src/main.cc,
+ * demo/wizard/src/main_window.cc,
+ * demo/wizard/src/main_window.hh,
+ * demo/wizard/src/mln_widgets.cc,
+ * demo/wizard/src/preprocessing_page.cc,
+ * demo/wizard/src/preprocessing_page.hh,
+ * demo/wizard/src/preprocessing_task.hh,
+ * demo/wizard/src/preprocessing_widget.cc,
+ * demo/wizard/src/preprocessing_widget.hh,
+ * demo/wizard/src/process_page.cc,
+ * demo/wizard/src/process_page.hh,
+ * demo/wizard/src/process_widget.cc,
+ * demo/wizard/src/process_widget.hh,
+ * demo/wizard/src/rotate_page.cc,
+ * demo/wizard/src/rotate_page.hh,
+ * demo/wizard/src/rotate_widget.cc,
+ * demo/wizard/src/rotate_widget.hh,
+ * demo/wizard/src/runner.cc,
+ * demo/wizard/src/runner.hh,
+ * demo/wizard/src/test.cc,
+ * demo/wizard/ui/doc_type_widget.ui,
+ * demo/wizard/ui/load_widget.ui,
+ * demo/wizard/ui/main_window.ui,
+ * demo/wizard/ui/preprocessing_widget.ui,
+ * demo/wizard/wizard.pro,
+ * demo/wizard/wizard.qrc: New.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update examples.
* src/text_in_photo_ppm_fast.cc,
diff --git a/scribo/demo/shared/icons/Symbols-Delete-icon.png
b/scribo/demo/shared/icons/Symbols-Delete-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f374398c89a8bd9aaec5b75c0491aced878158e
GIT binary patch
literal 3704
zcmV-;4u|oHP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm000g@Nkl<Zc-qZb
z36xaTnf~s3wJ%-W)zu44FCa?;jRGQ0kbP-2f|_9roES}JqMkWPX5yK1lAL7XBxe$0
zlF`hVWfTaANd{LWAYfeaXcTiis0SUkC^n6BH@#I=cdf79a_7JG>Q%q$MY|bHa^con
z>eYS!_b=c7|F;?b%EmWp9kR?A`*D}5jpupxmloI>|5ELk!(e>dE3xGyzf0#vR0sRO
zB}+#Quy;84yPCmI-qWS=zbXLN2f>_-t)Ay&Pp+z}3C*aAaF@>w?vPkg&GFvE0D4nN
zb~={OPp5J_`wi)9zwOmB9|_=FlieP0<0j7eGTku3vLv<3l6;W9I(&DBqFhV>OT1Xr
z8f1q)?Ft1V0Y6*;FHJXGem8uc93<#@F*)h|!26xpbvFJ$r^^2M^%U1f1@I5m&UrOV
zdwgMS)yx@@O73$y5lv^<>Ha7`6^(bN4eWPF(!&mhS2uT#&rio1E4`R;RRAxqPRX?q
zhYL=ho4EoW?g@DjsrN8hM&4b>r5GubYlPw#N8VTO>(XX*X=ob(U`0@xyCTS5*fe)`
zbyFzB$nQAU4bWtUZg3^1u=aS2pNhqCVlee5Nb=Vu;NTC3`Q>=V8Xsy~e0ZTXiIy4#
zoJkC_+nEQ@IKKwopffMD9RMA$>sUMc?&;J`Sp$1|bo!mO;B*(<pYmh>*XGS^om~|n
z56TM;LlZ|G4m|^j=_o9S-i(5S?dSEjjP|26XWzfSM^h)D`Ld~A?Ekca<x^5NHPUg)
zqI#514%#%!O4R(&J8ihDEwfP}0C59)@vBN1&383;j@`C!fs_|qXkF8}5Z-BIm;{5<
zLgF81g+(>PU<cc~`D@YCE{(}w-qx!nKTi0yK6o14`1MK+8=I4P4U%?ESE-#{#U{;)
z<kemfo14Ou#>g866czUzIX!T1H^0Wka3srN<iGZjL}fCrzk6C}--hOyTxgwy&jXN+
z9GsFyPcU;`Rxq0hUEJg^clP1Mo`ILrkZ&ds-D3%VgC7o;1NXEt+&O<htVC-u6F|5j
zgoXu^gmG;`o9C?Xp2tpph@YQHKJsP;|4P^GMKPR!<d(4J?nckEH#g5>hN=qy(CO%P
zYM@{$TC=#cwQ}L~t=>2ecJ`kb;PQ=Id$spQXx<MgAmQt)o%r#UF_1-vhA-^JC7)`b
zkQ%znnEjm$FMrsJ?Wg;WKM}__Nt{E(9+~3TbVGP|%io9b<Q+{7Gp2fdAP`JfHSYH_
zI2=W7<c~s4mId+}Gm)@U@g(1SuDiQKlm70ZKK-yI%+>z<`Zr(e!LP51L2?**0rQ%7
z`<-n1(k3oDWmp!r0yqCo8YiL&w&g@e_s%H3r*iD2n?)-#+evjq#vQju*mu^4Ydm$b
zD-Xculi>|G3JbGgF2o7|%vX!^E(-45XS$N76n=-!@%W%>Af{n8f!Mb)2ESXk1O$_v
z62D||6C)73sE)jXPz2MJ%3|BGvzh<y<##6xJVG`)L->u+061us76Nh0rV4zi)fWsm
z!wpanhbIN#^f*dM!Fmg`yOwz}psM&?`+4<fTK&%drum_30(fRc9Fa0x))2JWv~V)~
z<USa_Ug157oQ54I&Z_r!Yg^B$*h<2mB*{y1&+tU%q1o(axNbuTx36_Or!L4j1u|CI
z5aOOP_mB%&TDLKU-5Ltzjf3a9@uy@azI+hnmCBIYh#%Fp)UZ%pkh6kSht^~H^;BZG
zhu=GAZ0XGIc_)kiBH`a8;YU;fqm>dA(`ckG)~pHO_H|x%#T5yOd5KZOjTNk{I>>EW
zD!#B74_1VW>`&4j|DcyS&n1g)BLGA$38QLi*m6f30A}(feH>^%&$gdSy!v7iKP2H_
zCE-V<=&_19K?l_|mtN+<7d8ZO?cWT*S(yXMCY7PGu>w{g4`&PewG}IUZ85~o#q%Lq
zRvRR~uLc|TjA;n-{I%{VcAkx%dMu9b(&h8?v)CANeq=Q&zALA>u+D*v8_Th2Ng8F1
zX>eb;7uC}uL?_Zv(3#n-BmfHuFMpowOF_$Oth_$NC8=;f?|!W4hT{Lp!6e_&)-4$4
z`#EA9x_6!z*l3~vtl^{C;+L@gv*oyLsfNjO5=6Ze)b%rK;B?8b(W=b?%%)unpY54Z
zEY_3FVMkj>YHJ_=kGPIqbgPZq80SI(h~c6+h5TymH9_3b>cqU30Rll((ljl?LqShb
zqs*cxHl)=;7Pl~&_t{Wx5f(@i+x@n^L%+XAe}EY0SM;tE!x`uQ13(OsX=-UMoA1S~
zf9uE9%>z^#5U)4YSD?NsU}pTH&=vq@OHM_%v4de$Ci5pc&SP7*@+2|Nf0FQTlknN`
z2sP1;Ogvvfb5Xq$8#jfpae4{?5520sDu}t0LwR=^Eig?0Mfxqej=1-1Zy(=rKKa_m
zG0w#RU=2Ub7OHJ-ytM-VI6Hwba+E8|JbX!07#>+Fb(>){S%`}~t5UJfe%^jo{aG*m
zi5}XWG7z1pMlWbk`R&RWSaN$M9-BUZh^~T>A-JD{d;PR3=5@%n{J@Hd3Psi`f?;nC
z4)Xo|@#F7i*=PQc<nRAk0L*v8e`NsAw`8!`oi<BD;k2TwSxzxAv%)v3>)5aDY;-D}
z!qffH&VF6G{#X6_Tc0R^)zp;KxbVnTIzCgL02hK207iL^d)*GKn_9&jGUHZ-fs$NN
zEJe&*QOF<Svr|#n!DwId!yIm*_UWnZQR8D<)d>Sw;e(^viTjoTUuhg9x8Wv$tPs^9
z@nwyb2)Z025?N8?;Y?-KPz9sJb&Vg0_T^4y^l#G5Up^Q$E=nHAk5+0*yb`{#%7GuX
z#KBZk@O*_uJsU2o3nT1vq1fzvY?(2<0yUpW8#<ni_Zvr2Dp4x?Hd$iKd@ybR<Ti{t
z=r64I;6c$*5q%&hs!p<iN~<(hhgc-wv6`J?Gh(vP$V6tVUTqc{>Nhkxyfhf&N7LEe
zF`eDEGioF*7=Y-gk_OgZM@`An7(5=`OpzowqYjCeSNKs?9vGRhEHUYRuaZMoEX^9q
zeLU=QTjJUP*y|&64bl<+V{#C$CX<H;b?K&^G2{FN0a)w9!Yh4vW);z8NHZl9Q|t!0
z{T_rP!D6jrPh1v~e)52)vr%{x9OcAVv#Ud>FY}hT&Inhst#eFC;ZS1Wy^fr8{r|*`
zQxgKP*n_5JLA<hJ01Z{@&=!ao4!4tqszRf?O(9qnZm>N{R3jI7X^|hzmvS^zQXMrV
z<YO}{gIr?68=9e>g4q(_SvAWKCSvE`NTKzGBtJGT08727oae`(H7Q(HpD~k;1weL4
zD66VqRL_mhFeHfBw0R~M!}hqg_h>d>T~@CO;EOBWxH3W{Q0sQ_%c{%slxqn()ZvwG
z7>M=GsI<sH?Cn1!vE;a7)=FanSmA|#suxeSDp)-uRr;h@IanDY5ORqNl)3?MSWDnH
zN#*bhN&J8=U*~3Ne$^ZgZlNY=UA1VExQqq074V9+#&AJ<8NN5!&wtXZF6&V7+L!>=
z1emkl$$zs#$EKEqsaFmw=}@^)UPfi8)5hhN0}QdraU;zi&8FXfG>(6R*;Pdg?+ekq
zyw-uwQh)KeDQSc%vy5L#aZ%xMl~_Qq*N}D1WcXYr&VJCNd_Ha9(LTMfGiM*ymNA*?
zoXu<eo^LId{9H>b&@wru=QJ*M>%0L!cY54*1(ociiO&w6V^3&_o*iaawFe`+Dq)E^
z)FiFj5W;OOI_fJ)QL`$7Y%)=?y|1>vM_7JerXT;_qirAp**|FC8x>=DfJqYgmu?Ds
zwq6&mm5fY|t0@I)T47p7;j-jlE{}&7O>N&%DERCEbnM{+>1|Q`G)g@RJ@>&FU6s`&
zt+|?-q{S}G52e6nIlX*(C{R+xTFp-nSMg9Pc5X{QZgevoRroLqP@}SVW7zTH=cZ2c
zI&%hcsVvlFHh<)F?R2<ofnbjb^GHwO_tK!YC1z}ISFweJJ8qcu-B?2eQ4P%{lbu+%
z+>ceWWYka7T+$W(ARLlZTt7oPIH1P#2l|bleyHL;TDPl2j7wZ_FY)8|cg~)+veD~9
zE~zjzmE}1CKvrN(W!#>iES<B$wW#Y~awPeK32on78Qfdg#~DvoCDtsXIi2PLYLr$I
zQ>~oml<F>({RlA`eN?Ett*5o!1IAOtX7@U1ZAwSE5&#hyv+t_+ynE}MIWqaYa2wMC
zi7d216}C_<H9+Cy4LOa6mE7ykC9s)<e`O+FmCYI!kjn|kvISl&49N&~Yv_A3jaSGe
z_tDyK(AtTT*B7?eZ`eE~xc7#}DO^)jQ1G%`O5wS97DiStHXkJxC<N|FM;4Fk+4mlg
z<9l@dT!C>ebO<0~J7<b;44B=Y*cTEz-e+j0hno*Bmf!kbx4GW?)QxowTvs$`*&I_v
z5XY$2)Q1{yI{*>OowCY*C#CxyB*sxp#_9T~eVhpb5kV(5Wknnbml;6@*7mwY_1V0y
zMsVQsk(#<1=0E`ijHC|RU!qFJApPoqE1BLB#l3=Y$h>U^pkD;x$35(>Jc*LaS8oa9
z&P6Vtzd?5}zd{|6D)t#=>yK>3KfGlmj_2J;eOsK5mvKIE0AiDVu9smw(dpH5y_hvy
zV&O(bVvXF(d|WQnLY()?8V<WM`mRB~`-FmDPJnSfIRJ$re6EgWvzTESm(C+5xZI28
z>0I`?xrDf+^JBWv^YkG0b!m8n7C6Eu&N!bK0PCLEVh_@sL~|Nxcuutgv#6c)^=jy%
z=0=pWZ_pIAd3yY>`||*>50MH*;UjkADht4bw)<!fVjO#ye`x^2pS5W8V$kG88UF_@
WXc3Fm>%r#$0000<MNUMnLSTX@gB?=<
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/accept-icon.png
b/scribo/demo/shared/icons/accept-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d929648067dcd98708664950e394aa11dae289bd
GIT binary patch
literal 4858
zcmV<W5(VvvP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm000ufNkl<Zc-p;M
z36xV+n*Q(0d&$dMSt==NUn!QND0T)^Kmqp+MWg{a(jIMT9kI1_#<AT7nLg7_&yiMI
z9mk_*rd>gxRkRUMK&L?vlzpo`m0D7jN~lzlm%Qc9e_txaQdKBw_pOu4eaU<G{ont8
z|8`#p`~;(+sllkI$|yN0*KoX{Qc1}pK%-8M<Ls1D&@?Ry97GI)a6(m-le|$lz#I5u
z!^<jCKla|_2Mg_Q6qBjsL^Y`_G784I7PGm)B#NTZXas}7Ku~zLIA!<H5CqjUDk};}
zC6hEENm4u>Z^7%ga3cQ}UbAmxX{Gdc0Z`jq&nFYod>#xd91h16o6SZ{CKD6-ob%#J
z0z!#yeeN;4!NQySzhhQW6a^BA1Vnp!=;@x*dt|DvHd@7XW6DP<e-i-pEsY#1ZWga`
z&%533F?PEh1VKRUYH+H%k?!>GCtvsvz}M}EX+xxgBo$4UHFFOW&(Tt64w*D;3|v-N
zLuV9DAj91y_$2{cm!6J9AQTE6P8rk(MYDN(RoO`GCj)Sz@svwV$gA8=*D|NeWnzNI
z<T(APZU=ew+l{cd?Ii7$rOaB?z;T2LMhMXXFpc9MRW*%dY+w`2WO8mL+&%7QxW0TA
zweTWg772BANufyh>zqY+eEf*9;U5j)$jPJSCWG-^U$%FG#cE|j!Mc;1Vbx#XfP=vX
zTtOEU940H+jTW#7A_xWnc;*9y>l0T4Mbki5Wr)iXL{o9-Nyc<4;XfGbD}~3W-3jwY
zTm`DCLL?l9j?UnINlo59xn@$`4+e0w_V{!wFTR&EY*;>X&ZeFK-2Io8bZgVM>^dq6
zMv`rDg3Iin0>|rXQPeksl;+PMbDEwjs!GCA4|K&NAjv6aA~L6B9K3q<6ST;lM|yjE
zp*0W)^eTx3lgCc{>qP@NhQixT*7aVW&&TsT`M7=uEZ_PZv_wNxz+<1)MLlLGLAtP2
z&Io!w0CGlXLeB-mEP%8^XOGZeEKD#;L4nOfUz+;}xwdR3#A7kq+SVFGYuz#w2r`85
z<yNC*M@~*o9tsbCI`#qla_jFQrli1bvOu9D2c6QGzM7o161mW-kap?J`+2V<uI-O@
zKr|T#D{q1|vmb^#M&H0dKub$YYp)WYIeF|rIt{p0oxk42DP&7tUfx6|{Qn;NfG*qo
zTV1JMq)VRNOPP;Srghy@&uCi5pj#tt0>TImX-}p)<C)gebLg{%krOb{r75MU8npIy
z($089zx4I19;0`Rx>2W7v%h(tBG9?#JN7vM{Ov7VA{u`&FE{UAi^W1VA#E0Z`~;1w
zGRd)dV3^Gfgd=@|Q;Il<0ap<4Zakag8U}I(4D<m=&zLI{qT(kC^8w0~z`=^Ki$Ua!
z^to@}BnfnI2BtmQO*(o*m^%de&b2GawWTvybfW&&mY2mW>-}ek*mD4!YO1}$Wy#v)
za=T5<(N>tT_8#!ZLg2HxnCA6p!*LXtyP9<Eq3}3of^&Up=h9XfU|OvY4zq?v)34b@
zv*3Z6JMmf$J_~#ePw#sbVkrr;Higz`Cj@)LP+;}I7YqIi@+~>csgvk0*G(Kf{<8r9
zQ2RW_`u+I@1=Uyv(5p8tCtCvFf?c%Ga%aBotR_6$j2bqg>Un%e?duj`TGxZ74kGQK
z`og5o0`v@p(!x_(=^9BMoAPTg^P+AYX0(H$Q}F1n)wEOUAy_{_T_ixGQk=}m9|xP~
zy+pD6AdL+Thlov>Fs3Y>vHJnkHq<TjdAx61G1jlE+e~lY{4^1G0}OW+(k#J5EKKXD
zUM4t?(xMg8063;~Mkh!EfIi<yFRmlVxGoB>`-8*iq>oR1ig?Xl$j~dpx)b3>`t;s4
zq#hl*S5DGX5kHY-72dt-X?kn<l_c2F0qxzvpG~M9|4u)EwqTo>N+dte&o7u7R}*mQ
z`k%wWa3d5UZAz_J$MjJ}NCUtm1v-sb1Z5ULw}3w3```8d{i4(UfWr|1?izDH)MQT_
zDuTo2=3TII&kMLX56!V|4BeeD)>R5$-ufCC6b|a^>%J1~;^iYtD%0t|IpDv<Zn5pm
z%F5#2KD7xJZ+nJ1jV3a|T?`fjhm--50f2|-uuSueLTTFIOLu6luYAblflM_@;f$g$
zE4UJFDqqyE@$)Uv9`B}CtY1MyE(W<)D~+le`KG%Gt&yT{&VGt4thfdOEiGCk8J#h<
za?Jnf7d13AtiiCk+`t>il^^{A_6HBpa$63`x44+2rU4kz&Wn`MDP+(ogzm>28@Rs6
z!{#Wjj(}t$et+`HvlWrMsvick!7?ZSMN?tnU!I`{JNJ<Z*)EVZLNP}Ze=H2Oy&ZJ2
zuZC>B;T5c4qqM2H>7{Ws<L)CJ9qmS}KaS+&3@bl%x}MD5xD2Mcd#FN26A?{lL`@3@
z<a{4(cm_ZhoTK`GCUj=r7hls(oc3MPX8{9epeQ`avlXAC@eBZV;R^@W!?Sx{rdJnw
z^_7wOG^G)eP!(({j?vv=2l-;&>riSbps4gZLFB7QTU%?5XcBihva-ZKomdB}_WTYO
zln_Wl8FVBBo$pNh0^W}mXsC7l#p&;c^qlFP=s^0sm-O?V>7IQztMGc5o;P<$-tTTd
z3fF)52wY#}0GpA=;*TN#0x68Y!^|=mXalTm)ZmG!kHXRsw*r<)QbJBlBmU;*r5=yx
z4eX}ip)Y<z_O*WkHx=2b+2|ohA{Jc&frU*jEi6xXq!7<E+(#i!50sjw5?M=uqNb>d
z_QT>?=M95X;3$V*jDLcf3?ez7^K68q9y)i!L&PUWpxSN6B&QO+deuNr_+wmHy-MBm
z&&^RXCHES5e#T0Qi48isf_I_?+E!tM@-J96&}%o&BNna^uE@`!X2C+bl03A=%?JQ>
zofaPJpi(+1=TfqzaU*6{nWV7ulCU>WX{xV$AZKM_29hT~ulZ*vb5`{WeLjGH+_9Q|
z-n@<6RFaDcPsOzmfL?;DG|wy%uc%=8ouHouI*3GzF(+)G(P)%l^!zvC_xs<=&CQ+9
z)|>M7G^lY&Fgd3H>B8&cv`ZF@0A~G|0a!F@Ip&5cI37L*Zyo**6h7KVrwoNywkG|d
zbPCeun(`$uRE4*#Wk1}u>7U@9(Zj)pwU<H_Cb<4?;}ei;PUtjDq95#T55S?Y3HC4E
z1rjzt^^NuGNOM!umc0D@IY~{Tv)0ZeQ?gSqHoF+RDuaGUq#_MUZq$ewiX9cOv}%R!
zuuO}mA}7fDV{5QU3HOCm<{M`$U^lwxUE}|in0ebdTF=Zo6A`%l{S{DV?WQB0c49L*
zk&XuJ+*Gu99JwE%8C}S#M!)H7CVRUC`11DclqejjtF7HiuvFcR7MR)|5765_nx_L8
z?J3pc`k5lkK%z=6+&ug~D9ak9-#jBkpw|!YAA5nu<*sx{#jiLW0S9wRme6Y7WdmrF
zjyi<=YUc~^X~QPCvB;?l&FUqa=%!X4h|}1Kp+W7x2A!H7>S`iihj@7Zh7B~E_maB0
zx~~W(h27Y3O$jDiVbLcy!vvQMBR!=93_i>@2Cl7G31ko|oK8hx!-*HMmT!T+ya2iO
za=3B$19;32k!|<Fou57lOUtt{FMv)P86Dq1x?z}A1*_mV=X`_$heM5UpqqzxuG;_}
z-isNzeh-U6TXOUAbPC=4!3<KBCBrCpiQbrJw3Sq%<Qf#d%ymh>CePPsG}S}4HU1BT
z;wLdm3FNBs<tRwSppJ_@F`e@6J!Fzcfohi(>49-eOJSkc0z9<q{YI9U2O{t2zlKrh
zP^gI<@8RLYn|4x8HKZwo7GOQ^ZA_+lA5J4h7741{1(>`9Jpn1IM7!gSq$q0|%p0{D
zYjpdd0N6Y($KebAI~419a!KLh{)lw;IgCBO+5H;b-0)|zba+0nZJDIfNoA!0&x`e+
z$6=0fTS_R8p_eU?RAhQE6d)~eBYbevZYoI<X>4p*i<!7%mD}Zdj58SEm)mXysy0Hk
z$BXFA`ffsZq6tz;TsNcFHVKwgzl`S18Zsd<fl`_TqQNrg_XoP_;L43F;L)*pSe}Qm
z{%=C<4!(P0<SpPf7wfwlF>H1YggU`sD1=w$Y=9WHn(e{1-;zL}WvSckd4ugbtp4UH
zaxnNQn$<)dCKrjNx{%kw{(6Ru9NQGSpz3+zFlG-*j|<INf|~cy<Dkkr=nP*ByE6$c
zbPYSSn|#D-%*Mw5G(8fIlW{p$!GjZ?q2X{CI$0v?2zJz%Me{D~1H>)O8^~Kn{{R*C
z1oc_HBowO$Rg(wQEk64svao6m%`$l|3c%Xh?d0JdPr{w$9hjBrpw;O4a|8O5+foLB
z-Y(kEYa~lXuYfCyZ=vmNZRt{?v$NBPb-)o%c6NE7w-KJ*^#IuUR>-vo5Ko1Mq>9Tj
z3Kmzt22PU~zR!rt38;B%Da`a9hjQD+?c<6<HnhZKh^an!YWj<qABv!<si{sdVKK)}
zXle1U!D@6l^ZtL|^K0x!_fwD1hV>5}v~tWiakjOZ+&20}@R;*1XaTl6{RBGhN42kz
zTZ$rj2RBqdFd$!`2S^$R-KiW};Fv%joBDf*#}m}=Z+>a?=&JkDO+>KmQk%uT!(y>;
zyIZ%yn@9gZ9fo>hHl*}rh62Fe-DrsgRj<%&bMBA;PK5n%*}8k^($WS@Q0kCM8EmfM
zQB)BjrWMg8RS%Nsd2;{*j~0`nGb&0e(+y3iyGu+Z<<EUS-_#_wl>fQ+Q8=AAh6x7a
zGWqUJV!K!Zi>luMuQ`9fcdQ^?ym=)Adp5$XoajYShs6#_<shNugVQ_`9+~nSmem3@
zH8y@F+Dw-h<(KsDC__uYztH3Iyv@q$eeK)n+GBsjI<gKM`DlMVGMEK2pE=FL$^6l4
zFnN`p^ZCx!gJjVszk;P@Em$JZL95ZBEWpa?gzCV2R06k+x}Q!OHj}XE(}hj_$jZ@Y
zntC?6LP1_msr%6iW7zSl2cCvN&mk=Ik7HLRe=mJyiDfXq>J{u|OZq>XwSEOSxg9Xc
z9lI#qvlcC`3RsF%LV=?i?j8RO$g&L0&CQ2RR$)SMe(AZ}Dr~g22d=PN?3*lBt0^o6
z$s32Bh2CU67FxB0<>hpvMTgA9Y;G2Y(c8zoP73T5u=dn;`p}NY$g+wq?C6G!^#d%x
z?vzBw<+yU{FqV*IHBW-e<fUDmoyn-wbKUUL5d$~2*a(HYxI`@RqSx!Ymp#Nd7TOCR
z*Zwz6$n``~oAoV~j8k98@oc6-GQ0eDaL1NE(s7QxWVj=Fp=5Q=F)QCw8Ws|UBCzr$
z^t$19lhN6ep*I?(t!;sqty$Ll3v-JH-&$m&qpRHoDs1t1vL~`N4+MA69nEi%gxmxP
zxe?eyrSAg3<|)kz+uJ!hH#bVow%mmPuwA>P%25%uZV?LM@}fm_T+S@QsDl;5K7*0W
zEh#J?dUN-TLpPU;Cd&?|)0xNabGUOS>~39;bxR9`6UWgKa(d6<CmgI?mZ=e(VkOv3
z1u!lDR;c#Q&>se3)@@BH(#*<=k>9<&o*98w|8%oxS?_RU`IvU<Bj3Ot1ksZW&|vH+
zQMCx=^<wk;ml6Xj)AYuXtZ~#}a1tNp6o)C7PR*ZB%AMnx@U$}+3}VlHOGVj;@Be_K
zA4Hpfx=Ap<hnC1^&wWoPJK;<Jo3tz5Ku#xHXm_F(4Uu5mi~XVY`vPE&s%Qi>V#Z8f
zPF-RF@mNaWvce@;V|jJjV8RN>inO4-tn%U?F`Z2(fj7O2ASSQ}9&FTx_rQ^^ZP1(Q
zgws+hvkFK`H!i01Z?B)dc!q50ooN&r+ZIu9qqg(GCFWvz?u9DvY#8pEqMyf}R(5rD
z?pHMV_KLE~AO4UpGlJ;YDM?<H<;YsbLagqjYJxWP93*w!yAePeO{u*kCPyHlM6iSF
zB{KE|8Wzy(9;~h8Igy%p8?o?Cun10SG+2qllm`{=e}H1gSSoO$zNLOT5|JXO!>@}L
z)8hqs#XtTrYi4v~h)t$av(V<xJF~K?jV4onhZUAuX-BM<gs}NRdeJ0;F{B@{_Vp4J
zos^=`HsZCEB4vtcj<tfgux(_lLc#UD|L#!e5Mq7MWHN0Z=F9u(9(12QLfxIbBqir#
zq+VgS+o#~o^xs9CKbQsLa*sZ@V1tet9&iqeFeo^U_Vn!0KwT}G#dRq7-{z+V1A&A@
zMUf}TDdlHIL6|F=%>|hJL>^mH(zhW1`ooU2mDpTWRia{KNhXt0LXuii$>bKnB)lyM
z{MSD3u)oibJq8=-a7LuTD2yC6JTFu#vOEHhU1%8_E9f;<jUuQp27wd!-ATbH9Khpa
gIli19{d1fD2Od*Arpnv=egFUf07*qoM6N<$f;XF01^@s6
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/close.gif b/scribo/demo/shared/icons/close.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ffcb2e60d537a5d0eb501d622f58b7039dac1bd1
GIT binary patch
literal 340
zcmZ?wbhEHb<Y(Y#xXQqAl1+RIhs0J+@vWSaTR0^*afu%?bv$J1bjaN0UV7pA#O(Xo
zrGGzu`uF+EV+N^543ZBSrMGZOKT|Y+rfT)l+W(bZ(3_CdYgNskuiyG|^UjxBcYlBU
z^yl-JCk)b07-a4<NIzAwd>fSdHYEMq=H0(<-u->+-tRjP{(SlR`{T#||Ni~||DS;}
zpaaql@(Tl7<$?YJ4;`z%6H7K7&as-`{~}pwqSvaR4zUoWMg@h-9*bHPw0lB2gS<?2
zJo@h_XDta@<(Bb|@yB0ot#Z!#I_CCv$qG%Wj&_y_91>d6;?kND6DBat;ZWCLV`7uh
lS~!Ps1tSOhN)E1-jI5hBZ`mrieaFsSbN1}r$K=Rh4FFn8eLesH
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/crop-icon.png
b/scribo/demo/shared/icons/crop-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e6b290da671ae4917167d8b14a6963d61bd1141
GIT binary patch
literal 228
zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1SD^+kpz+qoCO|{#S9GG!XV7ZFl&wkP;i>3
zi(^Q|oT-z&#SSZQxE_3bso+J|{5)T)4aXzAITBkAJyrH_Sz@TT=-%%u!VGE4wl7-6
zpk!G-e?8lRYp>kntr+6c)8=LR3QoMMDE}<zl-!Lcof@*+4~qXf7!v9tQ`D1~aQU`k
zuov4l^9SMC$^B1szXhyqwtQl`eRpB!iT#@UZ#_Qxe5d~LcP&h7SlI>sREOuU-CD6#
Y{;u1Ni+Zg;bU^O*boFyt=akR{0PwL_(f|Me
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/image-add-icon.png
b/scribo/demo/shared/icons/image-add-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e4d29c0f34aef24ccf084b23049662f8da0c2a7
GIT binary patch
literal 2917
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
P00000NkvXXu0mjf_m*)P
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/image-edit-icon.png
b/scribo/demo/shared/icons/image-edit-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..098cfaba705ab0999687bf80e6b1dc5d8ae34c38
GIT binary patch
literal 2305
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
bf4BJ`Chgj%7)mWS00000NkvXXu0mjfL@Hu6
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/image-multi-icon.png
b/scribo/demo/shared/icons/image-multi-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..60fb23f2dbd90464c953f327c6e6d0e443ad5843
GIT binary patch
literal 2033
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
P00000NkvXXu0mjf+x)}l
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/image-next-icon.png
b/scribo/demo/shared/icons/image-next-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8bc7dd4cdd7c12fd4617556d3df6809b6e86547
GIT binary patch
literal 3008
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
C;-oVG
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/image-remove-icon.png
b/scribo/demo/shared/icons/image-remove-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..9d2bd94609a92dd12b376193f5649e6f60cb2d86
GIT binary patch
literal 3127
zcmV-749N3|P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm000aANkl<Zc-qxk
z3vg8B6+Y+QyYJ0rH=Bfz#Du4yA|{<8*3Pt2L@J%pb~>Hnl$HuQzCcj1j&|w`MxaI8
zkvg_oU(-?R;ImY!)@s!$Re6N>Gw(oNyUAwXyZ7$Br{~`!yPJeCNl0Y;A(Q{#{P*AU
zo%5a7zl$|BHG4d6cPV@gN1&&t6&o5F+NMmIQbIhChxo&A^W61F_K)_=(aswi8{5(V
zDl01|B~k>9!NmDi>WIdad@EQLgr=sZ_KXEihgEuMpAY+W0)S_j=dOp_Gurv+pIKg2
zL}hvAtOW#sRtE6b1APF9{~-*W=dOp_GurtWp85IQA}Y-VASl!x)!^lW{`1X_5sjZ+
zS_mZ$(?ANfM^t+CaM#y@LN{FEr4r{L3JCz)j&}8VIk1<*ka_NUxILqtkL8)4Tr>!P
zpipNt1#cYdI^XOV(fILfFBChJffVYDYV_9e?tZPXx!_Fm-1TsKGINRNR+EfzO&2eY
z<jfJxe>AIriXEnb6!I~EcTNV*ISM&UGEH^cGH+U7GvV>BDEMO<>70Mgdgch{*U$7&
zQ7!;MA%8pt@16{tlWAopY4v2605Rlm0z^ktO}k>RGRHoCFw+Btwm}pU8v18l&pA=Z
zqDU}ra{d|9zor|c$P$K<DLCqjkY*TTrqH$1-Bf5FM4>JQ@P2)8%m5@7)MGQj43C{y
z&SC2p@lb0hL8rqB)J15a(F0gKEuXyhK@{pvq~ODb;F!%i#chXTyLm)=4HhNEk_&4z
z1Y&7=k7NjnUf{C9EUyLfEz&>=1>!0Cs40|Im)CA4mqo!4gYw5!)?KazvWZNQq_loh
z2GQ(7CkpP5rkdpE;HW<gNijJ~^5Q@SUYnVmW*Oa96L_pZ`4)K~g@Q?)>H;bzb%WEi
zrN3l`7B+WOOCcYS)>BVHqeM!_BD;l(?B=vc{0#AbbXiQJ0-*AH9rH)nB6L>TRI+v5
z7A5n10RwOi1`tXb)RiFYQ+H-F$MAFpv?_9+`HB27RcM0DO!kooI^3K=Lwhs<-E8II
zEWmG#(>xBaDN+sqWB}4YAK+pXy5h!|ec)UMTNxs%Hsp1tD3s+{!6ZvylCmuJ+9cp&
zbf6D}`z&xa&E>Agvm-klj#E@kVIOCN5a~G!P8Iof6waIbjF&BtmurFZ2|)O-0FcV&
zg^UjrSk1&#O>aFb070RMMx5@y8VZq~f>a_3m`Z{SI+wPF5D;_{0f8XSSdwT4ug3#c
zlWEBFg?0&?roj|a*#hy2wEzo_Ml1+6*&wHdNgN77^w<%Io@yaO(@?fpz%g|?*``fL
z-Qk2_G)@|t(Uj)_l;o@hY-|DZAPPkofPaDjq_rClla2N2vD?76V>>mx@f!9VJ)AD`
zWwV8Va|##+=xUNPxr_yKt6=J~<>Z`yCHewEAe)Cwc4zwBLI&V8526qkqu`qm3K1C5
z9`JGtsP5kj2i89b(e^g578HWn<pN1o(!2U=6EO^?m>LQ}qT3Ii*%!l{Uq1rz;z<xO
zOkmC{fFh=lV=#p#$^sM%V3ETNzHP74ktZKVb6!3R?<Gl=)0_G?_SZ@M2Z*_@>y+s3
zLOl_Ks`Z;muAYa%lnkYlyaO#D07MypZ=3-L+7vrv^uP8p9C_lm<R~jgv)z$ybg*wz
zU$H+Rd2uRD0}x4*Ie}^{3JG5)Rd0R*^*L2w&vTK-<s3+%Sc;%CI(7;fq;doafyzIc
z5dlf(!pm9#(xLsZXZ5XMpHu>7rw|^&J@0ZLO@rwEnzZbLOI`K{@LaVJqK)+st*-+i
zl^TgcvL^uZUU~(>Y{k;DGH7XO$x<k)u?1phw*Xf>LO_bAx-bwwK|P6D3@4kos%+-h
z{9GC&I25W}7pXX}U?nV^dJBDd{bDo{Nw60c^_JZ8zXg@6?<T|0vHADEgG9}qex>)~
zVCB0PeIF;Uyam)?57lqpfU(+I5P>%4^PzLvbhz-3&ybc%VK^MlQYgj%I?n(=Gh);p
z*^M2My=<X<5KJ~uT=O%9jO?4{3cz!#<i=lK{0hJaJL&kwN72P^DoYZ%FTVmS)~o}`
zZcm@Dg+tJ~WfLU#*JLQ<x@IvI-*g*FW^-B&)$hmp$JmJ*>R2%bhS(z2&%8+S%BiTT
z$t;Dqn&y_zNE<PfY=P#`C(si7l#8vsAT&FgG1Ivamd@S`N0u)Iqss@1#|xqqbba%3
zC|i3k$PP!AddVcTJ@zQ52lqqX)r+C<wp9bJjA9+_u<PEnP{3ey;a7ofuyTkkdt@WD
zwzcL`C`q3+zl|rl|G^pg2x)qB%(oJYO7FufYzyG<k_F_MIRg`@fXrQs%#zvX&4-dT
z_mJXrX3k87Llph&6Lc{EFqtye=Wt73-n$kHySqU)DZ~jH?M4c^{M~fX>)Y{Udq<W+
zjll!-^q!xdkrI#-g)-~m_V9f9tQW9&UniV?;BG3oWF{sx-k##NlQ#)VSgNY1`2L5|
znRhs!OR%PQ-hMNchC*oKazf|7NG9&PIX?N0)zXD;?!dZetTRKQrr-g1YWLDHN1@!Y
zwrU69n>!%*>{H;pu!8Gi)^db1F4NSAbb;Q}0haG9fRabIg6zy2^1PtU=Xb1tviied
zaZdttd4ag{P;8=D;-;#u8A>;70bk|RV8#LsJqKv(?xo{$v3379K1A(r+aUbXv*egj
zjvy2*>7>=3MkCC9w~4jPiKt-RCU9T3Y={L8J-z|uH=YKIP`k!f%XfomdMVc<+*`6c
zhU!mI(fto&;F7uFj0GBl2jLI9ZWtE}{Hl68C~v*b7T5~5nH7L$u5o%=fD!@Vbivgq
zf{O+BuG+w0hF%2d?6B?YZwK{@j{p_cjY-_u6oBF`=jSDe)V4s$rYE4YyfSNnI<~-L
z|64XL7FcuXpRn?12-@yhMb0@hP>=dps8&L5wIv&XbI~#?xb?TJb7@!~&=U#h*tCMw
zz5hl^vJWMYWLGK5_96%!tEZ`NzsEih?Z^N)5jaQ>e73x=E9&h<2hVfY!|f6CWi!^|
z64&>j;o1dcpI(kBUp;G4BeWt4%@^FXo+)I>oGGGB!?x#e_KG_}w&!J=op6vkx2(qG
z&VPXs=eN`pG!;*SL^w$oy#9BrZEMR$p(EXg==T5IIHax1o#(EH+au=ly;tIf`J15q
z#$}|P*vHtIxK^V4A1+1jof`#hGD4=K&8i#d0%H$4tFM9LH7^iHr;Ii9NC?{==B&K)
zQ(`M18dk6_zK-%AT#u(twPX|7?ye)S@V%Ae;sbe#13td`IVkyjA9UPz2cY1vmB4&i
zHB8#@JeUfL)B8lU`Qok{p;FreCZ+fOTA90;K|IaLt~WaM)SiTzRm-8GyNS_?a4bRj
zYuh1SUIC#{Fq_B{x=Jn4&T;#M#*0qKx7eul7uRF*@Ie5s41^Dus^&q-BV5bq2JTvS
z6HE^525x=(Z@dK=$y|Lc7T@zEgxlJwX6;HW^VNZ@ve8q3jzvqrvvDh>xEAvJ{cRKW
zIkCarm8z;lCk|u#>ZM!)#MlIk%uJxnsivloj>W$HVBt0Ua&Hh201VLqAu5+$1t$+S
zQdxHs%HqO81yah3vGgzRK+KUxuKav#Zf?#}Xk556XlPtA3tWkh-v$51yFl+&(@70Y
z)cae|Mg$@$Czct#KO}_K_%~;9Q3NTIT`+0$i;$XrF<3Z*i|jn0Bb%sC>e&h?E~}IO
zeUG}ftix1WG_7SWk5Cjy=_(I%!mzM_xTw&@rK{M-w3|{4MGyX&Xy&EqgRM5(z)$KY
z5`YklL2!>Ek<oYz1JC>h;=4a5J;+VG(DIo87~)2k`+PT%<GV}HbMr%>xxAc2B(&LV
zXa1_eL{KPqu+xF?3q_VeJ+u=dA3P7qL%Sf=;b)paCKV#rJf`weu+057I2W$~dD<LE
za>*@dqbSONGrtlF4QTLrDf~h#Wp3&r(!<4FH)zeriIOpt>@F}>%p!DnkZexjL&TOt
zOK;VB<}Z7kkFVRLZyeYnBJ!FPg_|$4g$0##9<1#ow~Io+w8rr)=ZLS{{2#zg#Hh_v
R?*9M)002ovPDHLkV1jt0`tAS#
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/next-icon.png
b/scribo/demo/shared/icons/next-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d97d3b48954f5296548a478a8c435e8e5e7d14b
GIT binary patch
literal 4611
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�Efcc&ws*$Ng;spdismLSehiM})0H)v^
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
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/page-down-icon.png
b/scribo/demo/shared/icons/page-down-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..5418a40dc18174d14e926ea5126ca42b7b64cf39
GIT binary patch
literal 3450
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
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/page-search-icon.png
b/scribo/demo/shared/icons/page-search-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..85e17185a6d9b8779ba72a35630ffe25108b029d
GIT binary patch
literal 3101
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
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/rotate_ccw.png
b/scribo/demo/shared/icons/rotate_ccw.png
new file mode 100644
index 0000000000000000000000000000000000000000..7adafeda3708790ee8b58f1b1518c3657452bd3d
GIT binary patch
literal 4200
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
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/rotate_cw.png
b/scribo/demo/shared/icons/rotate_cw.png
new file mode 100644
index 0000000000000000000000000000000000000000..90aee825681ece72e2efbcfb2fc4d3fc8649bf61
GIT binary patch
literal 4161
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
LNkvXXu0mjf6?w`C
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/search-add-icon.png
b/scribo/demo/shared/icons/search-add-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..06c3db2ab01bc4ab673bd663bb8d9514ad3f04fe
GIT binary patch
literal 4274
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
UDeDQ54FCWD07*qoM6N<$f_Eh*#Q*>R
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/icons/search-remove-icon.png
b/scribo/demo/shared/icons/search-remove-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e770c676a77569cc23e4f97503d6318175ad221d
GIT binary patch
literal 4196
zcmV-q5S#CbP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm000mxNkl<Zc-qBU
z33OCdn*Q&rHK{F0Wru|9D`88*4$7j@Mrm4XTk*7rw%Ri`I!6RrS(-&ed!|Q@HjR#>
zN4jYc5kyuYKq8O?0|^kaRF+Co3E2!;YDrSdtGe^wS5+ZlktMO`<viX^<yF=H{onU*
z_d(z;kFO3L59sLX&J>Hq)2udIl2jrN6^q2a4kzDBfV2=o%EV$(et<@OVL{gH?z{cm
zp&sO?{&?u*X=3i_O*ER#uZIN%J)RH~8LCn!xZb`#($i<9PN$O~An^5(Q(w89m@F1&
zbzMWVp{aF`)?f4SvkQJv{r?8w+w5F*ePi>Qw4}IKQsZNlI(;29G`E3^0{Hu>L8DRv
zvH%VT4@Q#(I*mr)2!W`PVUQ3r3Q8)fjFq*9t>M8z8=rV|j_qFx;O~16j^&-sFCTee
zT9U4&j@DgmCdu)!5H~6U{547{7KsSO17#z;pRHXkO1jM!K%;4SwVotIM?!p5Bt4pY
zwg|sw@r%D%Q2s9gfW|+F-rYGaH7V@$4@D3b5<<r&$CCh!3OJ4fui-ZW7`W~<nn}?W
z9kjK#)7euqNq*5~L$}HN)XR$&7XGXNzWDmUSbw$Z=$Pb$(42w`Fg7I#5@RC4S1!Bf
z54PIvP*Pb3r4>4uJAD$ID=uj=S$bw7h`OHzz|Q?g)cB=^bEZv7JegNWC#0p4n22yt
z`pQxD=w0uf=wV>q_FlcOfoBbD?Y`S;v(rmDJt?oMhIzB5(Ss*W|DaYXvYwv*h-p{>
ze0w~Hpw9p6sd*2-aVozM5@KU$XrPva2Wth3fDB^FYhb^jgVxl$78bPm#|~24&<u@D
zO?1|j4EW|)&idDuJhOgS0ere^UvgYjL?Lxi1&SF$gMwg0NFeygrNS+Q47&Xm2fgll
zW;nh6y4B_YJp<6v27!J`KpAy(8_k)E7Cc%%Yyh_H*z?H~S+id{nww8D$EATt#L>vG
zU_vlxnJe7_>Nj5a9gXx}y`~Fm!F=S*^Rkeg>aMmxAIhmzS4AG4F$wk`&-wEo7C*gm
zSODxg@SRrSBQL?s6UK=oBuMKo00<A#4glchz<n8<g#@Fi7l2zf>`%hleUQeMcCgv)
zw5jz+5~9^WU1M_-7Qd*+=RUv>8Nk-<Up|6?d$_2yf=oyo4Pp_;0D#s{gKLo>A7(i5
z#xc1;MsB0QZ9M+CuCLMifb|60u62SP3!cqp2fe`nqZ4AG=t{+;B~ShG{Ez{B^3Si|
znKygJs<Rg^37JQPUYCf)6!lMhFnwZmrN{)~1Q7}UPzHw%$Tn_A194Giv`g?hGoG#c
ztTtk_^Z?I0se^Zt(#k5xnlYJvzUSNJZ~glVe;G1>kG|NoCu`=^C#&ikX;N%7_BJBs
zd5R#2ua6Ab5K#m{I6|)HnH#f^TP^(noNVoMffLsza}TleJObba0M)hiFnPjgy8l?t
zXG@=d=B43a;Pj;NY16w+JrFq}6pa^ySj+)y(paw}lSr@vdt^h%O?l{g3<G$)j)qe_
zonW=vS?~%nLIxNJ)PEBsVR0-dE;;o4ujkJnGJwx^e{+6pa$*LiJ32Bf<T?Wq5n(aF
z<b*8*84w5kS%|&gqkqPMux4IoU8>FQz`%7-G@b~?JDG%d($LfbqryYz<%+74*sVS^
zWB?!U*z^6A31en<n|o+f#0ZbkB8m(Uyk3t1WI^O<cRZ2YFCmvF+fYG5l-hX*aX6fS
z1`7aK$Ld5{cqdQvhO3MLns?#S0Sw{=!vSE|oavLEuBvOGX^9B}0}KG3La#4)9IY35
z7+^undGjfCr%twJy2qq1u)(y>WP^rNhX(*-0GS}V8a+%NpGLnvlKsi+FFgBiLk6(z
zA78D;e7pfWMhvcTAeD;2lZhA*!P%VWWN0`62q$pBH1EmxjD`NSU_37{AZVXm*}Y6w
z7fZ`w&a_PIy^bzj_VROEhYaA;U3+IuO&@#wimpa9C1X6nq9%Az;*k)`m@Ec3@YVws
z1Du-yU|x5pAQy`V4+Da1c#nj5w&sOw)`e|$b!{EQjv7fXmsgEL36%^Pz@Ed|YAjqO
z*t|uG#S#)56(LAMgsx^8NicYzgak>kSKR=-rI$$v+)M~Y50ntgOe`6cR@RW<01cE?
z>GcYQZ^Ey#X1j(Afc^8qXFE18n*Zp^<7dvnoavK6rSM@vCrF6}FEiZXz?9hA3l8k_
zy>bCBEBM1<@XO_LkmAYXds)h4EU^2en2LM)`rr%>NUS6M>hSTmmc8`c`$ILpAHep#
z2cv@m{LlNTRa$0OYC<f<8Xy!VyVXj~W)qQ0r9h+{wA;IB$+b$-+S7^ZaS@G70jYs;
zG*S^t<Sr@n_V!W^nUu)nLIz{mj0JIVnU13ONn>+sQ%|2Y6H{o*umNDlhoA3Ujl=gw
zOmC2$mP&&I{fXJw&BjRTlvDD*SN6l#x?HI2Y@`yAlt@Klp{3wi!QyQ+&__k)MrXil
z>A#_|J|l_AWCE4ik1`4yo7<pLUrRH`rV{K#Uwh+szx`-9j2{HxV0Nygx&7Ly$7au*
zcBZfxCXP-74eE7IZ8ogT-3CmofeJs+$d&zr*ubODZi9~AZs@X_;knd@VcnFMf$O2r
zY3YTMifVXh#$?!i@K{-7c*v9mkIb<QI{<d<{O)ipv5_N_(vstqS`}G-b_?vT%%x$f
zK*9`Xxrmi3p^f&m)!>-{u-pkX!RD~jMpGLZr3{3f^WLGpJyL>_f)ZT~4GRu*Ubs}U
z_|+xP?)+H*u;cr@yzS{@$NcuioDJk#eE~%Kg;O7?9HSI1#at>93Yky_2DB2aka-3g
z%%m<SC09*tpb$xD?yo;4wstEtUo%qlJ~?{o^x@9-w%6DFahZPD0URkj@r#Ku<M#cv
zYPWRL`F}!OKm_>8q#!}VWe7lucT4aT6L&Mg-pr)MHoF{n+VK|~Mh3fL2>?TPD<o*b
z;PB&H;Hsew`tYUzwE{M8-VA4RPjz5;tjGGWwW6Ye-k<pc0PMYZh)Yw(7n+pz^jY7$
zN`sUEB*a$*z8s~#IM>J!gakq0tV59nR?7OvNT-JZ-X$1M`&>YJoCGX51C+NL$hyqM
z@Jj3x^h%9^?D+gsICkg&MZ<~Q*VjQf(ORVJeO+bceSzo)aI*O1gPE}zIj<DF3r8By
z(Q(=cqQXLq##5PyV%7nH36ZB45_%+$gj_-)Lja5gO#L<|Ayy}V1=saGCenwsqwvWu
z==X<Ckxd&nf(VNm))Qi}n87a~(8cqPH_;tiDs=bGL_dJyilWanq1q)`hZaMK+#gRR
z_=+jW(QuhyJkAJ2ga9}pn1yK>h<kKI;j<qeE3Sh&5d;MWpbsZrBg#f^u7wrpZ@_d&
zg;$p@1#MUa7(3dbrO^P!u1@gN24M@%ug1diK7zQX>MQ^_S$;|pr;I5quwF^|d+9oe
z(?nB~Lq>eW%y^DUIqZuF4mzAzC{98T#F`*sG(cJiC&-D_1m49{yNf3_7tX-Q0J4Kj
zHb9pvgZ_2$2C`)FVrs*;hDOGch8i6-H`If%yNmkyYaKWQtwS>3yO)>{030tr7M>oG
zQTajTC(16%en<%jN9z5_<nV{k<1*Adn~B-JC^OK3Mmaq@bM6?xP6>M_F}6%1PhaFB
zjFkhmxineRM!?kthZ}i%;#VigTPs(Tp2*Hl9TlHQf=5P!p}K;BpeAEC@kcpf<M$>y
zX3O1z5CEJlIg>hO)R-$9FKq%T&4Vbl7M&Uh&!l_+K4R7V#FlU@$zBE1gUV1!cGz3n
z1}7F4!jYVVn>MW8(8u>W-ie5fhtN@RV5lnZmy>^B5H^D-CyH{axU-xD0QpzWW~4=p
zEnHi)lBl^77^w`PJ`z8&FzG{-kh*_gh#hycJMCS+ko`8D7F15GyaNs!n(5xh^NFsa
z{LlNc_q}y=*U>-m4#(ROF>zv)6E)Q6NQ+la0a|QkT_`8l<~uPVe9^hm{N$9#(PbZ&
zzYBKT8HiA6K`vIq!laMzs=03lUOcf1rUsT_uVjalO|7u!vGb63DQEqInGdgjbNO=7
zk%I@;Vw=4N<pcxd1Slu)*9Ni~dO3RJgP#H+0LZJ!2~E+C(|u|9A5C57HxTa^OndAd
zWQ1xw>RT!VC<|5}NiYJ^qTXfhN=$?_1Z*S4<}?zkgFV5q_s`1tEyXleBPV8u6-v8+
zemeI%l3#l2`3J^lZD)Va%F5zusw)4eR4AC7NEphgzN(y}oQOwGE~H`&4odIcPENuX
zov+Q4kMxNy&^yb<?JQdjDgG+j)mML$B-kM$K2#<NAQF!41B)>8^ns1<!okJNhRmDf
zq>yTfnU{guX9oR!>S|Z9K0kAM+T4rY&&$lr<T|fiTdPzmR^3`ofxM8NT(_1}zhRYi
zWgi6uYyYsZ;6>0%>L~}dTLN(Z&PFnk@O*$}CYCI{Tkto>gP2^i2f!1FYiO$PM7^%-
zLi+Uh!OsUWGBZV8*V@-26J9xyLD@+g#In;0{J{UNs3@nm1W;6+myt4JeBo~WHYjb|
z0c!E^JcF>i#MpbJ!^%m2gVxro|Ctaq`j)%WZYJ7SDin%Mk(ix4avG4Gg4wprS`QQb
za_R?gq3$#Zl}4Z7)O7aNqGgn$mr*9}o!a}<ujeafXw5amyiHJFB;%`9gAL!h;RB
z1M307m{^4|aXUG!M-cCN<us@py<B~6YFv0)c5z3J&oTWLB;SCc>$)!htiai+hDQ4@
zAd8Zh(W`BB@5M)^zI`XgGBQw39qnt7iM3I;m(xmY0RN)X>F7=KKy_Wks!=0iHyk(o
zgA}*y2A8Xjfw(8xP+<!@076wWVNuH4&}X*g87w7_PK?gFt4WM8(Q&PP1v2q&WNZS2
zMa4pW<qdM;`L(>mzWF8qm+H^R10*B11_y;LDQMnLF17BXMr%1X5;pe~^AilXpU`la
zr6NeQ|7>_D>UWgbB$bA)vd6~7%($lk#v`XSZaF1LLL*}a$w{G7^VYt;Ww(6jb=h!Q
z79fuNTS!pY^9|-wQqc4zX|<F<kG&CnYj;0#8U%n1VjPi)gK%b!rRiY{$(Z1|V71uG
z8@o&AkBPoF;|Iuz^T_E>QSnJArzk;Ajdgm8-X~_0>CA2at3hdFK9PfJNr+$6MyXs9
zrtdxv^~PejYPyV-wG*2<tI*GhI4MXuC4?%IVWfHtBx<LDoTzQ>oh{otZ4E2OM9nnb
zkMTD!vBHy`h{Q)B$O&I_qKw`kclrQb<M|OviS|GIltE8RWzuk~(}KN?nRMG)g?%A~
zL<1UGFt*$Z9L<Q)++#e`X>Ho<B(@(?Mob;@&YJ*Y;v}x)$F?=B*eTS05{ucy_gXBQ
zBr@qccLd-)s+%wRi>PdhOeT9k2C77CpMx<d#4eYs+YaVho6TBar@dzrMobu%Vg1Hq
u{P+nRYJMr!&?iwoU->9h+b&<a$p0T424N|ApE}3@0000<MNUMnLSTXme(~S{
literal 0
HcmV?d00001
diff --git a/scribo/demo/shared/shared.qrc b/scribo/demo/shared/shared.qrc
new file mode 100644
index 0000000..051c986
--- /dev/null
+++ b/scribo/demo/shared/shared.qrc
@@ -0,0 +1,20 @@
+<RCC>
+ <qresource prefix="icons" >
+ <file>icons/close.gif</file>
+ <file>icons/image-next-icon.png</file>
+ <file>icons/page-down-icon.png</file>
+ <file>icons/page-search-icon.png</file>
+ <file>icons/crop-icon.png</file>
+ <file>icons/image-remove-icon.png</file>
+ <file>icons/search-add-icon.png</file>
+ <file>icons/search-remove-icon.png</file>
+ <file>icons/Symbols-Delete-icon.png</file>
+ <file>icons/next-icon.png</file>
+ <file>icons/accept-icon.png</file>
+ <file>icons/image-add-icon.png</file>
+ <file>icons/image-multi-icon.png</file>
+ <file>icons/image-edit-icon.png</file>
+ <file>icons/rotate_cw.png</file>
+ <file>icons/rotate_ccw.png</file>
+ </qresource>
+</RCC>
diff --git a/scribo/demo/shared/src/bak/crop_item.cc
b/scribo/demo/shared/src/bak/crop_item.cc
new file mode 100644
index 0000000..5f22878
--- /dev/null
+++ b/scribo/demo/shared/src/bak/crop_item.cc
@@ -0,0 +1,332 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#include <shared/src/crop_item.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ crop_item::crop_item(QGraphicsItem *parent)
+ : QGraphicsItem(parent)
+ {
+ _mousePress = false;
+ _cropRect = QRectF(20, 20, 100, 70);
+ setAcceptHoverEvents(true);
+
+ grabMouse();
+ }
+
+ QRectF crop_item::cropRect(void) const
+ {
+ return(_cropRect);
+ }
+
+
+ QRectF crop_item::boundingRect(void) const
+ {
+ return(parentItem()->boundingRect());
+ }
+
+ void crop_item::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ Q_UNUSED(widget);
+
+ painter->save();
+
+ QPainterPath cropPath;
+ cropPath.addRect(_cropRect);
+
+ QPainterPath windowPath;
+ windowPath.addRect(option->rect);
+ windowPath = windowPath.subtracted(cropPath);
+
+ // Draw Alpha-Black Background.
+ painter->fillPath(windowPath, QColor(0x33, 0x33, 0x33, 0xcc));
+
+ // Draw Crop Rect
+ painter->setPen(QPen(QColor(0xdd, 0xdd, 0xdd), 1));
+ painter->drawPath(cropPath);
+
+ int topRightX = _cropRect.x() + _cropRect.width();
+ int bottomY = _cropRect.y() + _cropRect.height();
+
+ // Draw Grid if mouse is Pressed
+ if (_mousePress) {
+ qreal f = 1.0f / CROP_GRID_SIZE;
+ qreal hsize = _cropRect.height() * f;
+ qreal wsize = _cropRect.width() * f;
+
+ QPainterPath gridPath;
+ for (uint i = 1; i < CROP_GRID_SIZE; ++i) {
+ qreal y = _cropRect.y() + i * hsize;
+ gridPath.moveTo(_cropRect.x(), y);
+ gridPath.lineTo(topRightX, y);
+
+ for (uint j = 1; j < CROP_GRID_SIZE; ++j) {
+ qreal x = _cropRect.x() + j * wsize;
+ gridPath.moveTo(x, _cropRect.y());
+ gridPath.lineTo(x, bottomY);
+ }
+ }
+
+ // Draw Grid Path
+ painter->setPen(QPen(QColor(0x99, 0x99, 0x99, 0x80), 1));
+ painter->drawPath(gridPath);
+ }
+
+ QPainterPath borderPath;
+// // Top-Left Corner
+// borderPath.moveTo(_cropRect.x(), _cropRect.y());
+// borderPath.lineTo(_cropRect.x() + CROP_BORDER_LINE, _cropRect.y());
+// borderPath.moveTo(_cropRect.x(), _cropRect.y());
+// borderPath.lineTo(_cropRect.x(), _cropRect.y() + CROP_BORDER_LINE);
+
+// // Top-Right Corner
+// borderPath.moveTo(topRightX - CROP_BORDER_LINE, _cropRect.y());
+// borderPath.lineTo(topRightX, _cropRect.y());
+// borderPath.moveTo(topRightX, _cropRect.y());
+// borderPath.lineTo(topRightX, _cropRect.y() + CROP_BORDER_LINE);
+
+// // Bottom-Left Corner
+// borderPath.moveTo(_cropRect.x(), bottomY);
+// borderPath.lineTo(_cropRect.x() + CROP_BORDER_LINE, bottomY);
+// borderPath.moveTo(_cropRect.x(), bottomY - CROP_BORDER_LINE);
+// borderPath.lineTo(_cropRect.x(), bottomY);
+
+// // Bottom-Left Corner
+// borderPath.moveTo(topRightX, bottomY);
+// borderPath.lineTo(topRightX - CROP_BORDER_LINE, bottomY);
+// borderPath.moveTo(topRightX, bottomY - CROP_BORDER_LINE);
+// borderPath.lineTo(topRightX, bottomY);
+
+ // Draw Border Path
+ painter->setPen(QPen(QColor(0xee, 0xee, 0xee), 3));
+ painter->drawPath(borderPath);
+
+ painter->restore();
+ }
+
+
+ void crop_item::mousePressEvent(QGraphicsSceneMouseEvent *event)
+ {
+ QGraphicsItem::mousePressEvent(event);
+
+ _mousePress = true;
+ _cropResize = CropItemResizeNone;
+ if (event->buttons() & Qt::LeftButton)
+ {
+ int lthreshold = (CROP_BORDER_LINE >> 1);
+ int rthreshold = CROP_BORDER_LINE;
+ int size = CROP_BORDER_LINE << 1;
+
+ int rightX = _cropRect.x() + _cropRect.width() - rthreshold;
+ int leftX = _cropRect.x() - lthreshold;
+
+ int bottomY = _cropRect.y() + _cropRect.height() - rthreshold;
+ int topY = _cropRect.y() - lthreshold;
+
+ QRectF bottomRightCorner(rightX, bottomY, size, size);
+ QRectF bottomLeftCorner(leftX, bottomY, size, size);
+ QRectF topRightCorner(rightX, topY, size, size);
+ QRectF topLeftCorner(leftX, topY, size, size);
+
+ int sideHeight = _cropRect.height() - 2 * size;
+ int sideWidth = _cropRect.width() - 2 * size;
+ QRectF leftSide(leftX, topY + size, size, sideHeight);
+ QRectF rightSide(rightX, topY + size, size, sideHeight);
+ QRectF topSide(leftX + size, topY, sideWidth, size);
+ QRectF bottomSide(leftX + size, bottomY, sideWidth, size);
+
+ if (bottomRightCorner.contains(event->pos()))
+ _cropResize = CropItemResizeBottomRight;
+ else if (bottomLeftCorner.contains(event->pos()))
+ _cropResize = CropItemResizeBottomLeft;
+ else if (topRightCorner.contains(event->pos()))
+ _cropResize = CropItemResizeTopRight;
+ else if (topLeftCorner.contains(event->pos()))
+ _cropResize = CropItemResizeTopLeft;
+ else if (leftSide.contains(event->pos()))
+ _cropResize = CropItemResizeLeft;
+ else if (rightSide.contains(event->pos()))
+ _cropResize = CropItemResizeRight;
+ else if (topSide.contains(event->pos()))
+ _cropResize = CropItemResizeTop;
+ else if (bottomSide.contains(event->pos()))
+ _cropResize = CropItemResizeBottom;
+ }
+
+ update();
+ }
+
+
+ void crop_item::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+ {
+ QGraphicsItem::mouseReleaseEvent(event);
+
+ _cropResize = CropItemResizeNone;
+ _mousePress = false;
+
+ update();
+ }
+
+
+ void crop_item::updateCursor(QGraphicsSceneMouseEvent *event)
+ {
+ int lthreshold = (CROP_BORDER_LINE >> 1);
+ int rthreshold = CROP_BORDER_LINE;
+ int size = CROP_BORDER_LINE << 1;
+
+ int rightX = _cropRect.x() + _cropRect.width() - rthreshold;
+ int leftX = _cropRect.x() - lthreshold;
+
+ int bottomY = _cropRect.y() + _cropRect.height() - rthreshold;
+ int topY = _cropRect.y() - lthreshold;
+
+ QRectF bottomRightCorner(rightX, bottomY, size, size);
+ QRectF bottomLeftCorner(leftX, bottomY, size, size);
+ QRectF topRightCorner(rightX, topY, size, size);
+ QRectF topLeftCorner(leftX, topY, size, size);
+
+ int sideHeight = _cropRect.height() - 2 * size;
+ int sideWidth = _cropRect.width() - 2 * size;
+ QRectF leftSide(leftX, topY + size, size, sideHeight);
+ QRectF rightSide(rightX, topY + size, size, sideHeight);
+ QRectF topSide(leftX + size, topY, sideWidth, size);
+ QRectF bottomSide(leftX + size, bottomY, sideWidth, size);
+
+ if (bottomRightCorner.contains(event->pos()))
+ setCursor(Qt::SizeFDiagCursor);
+ else if (bottomLeftCorner.contains(event->pos()))
+ setCursor(Qt::SizeBDiagCursor);
+ else if (topRightCorner.contains(event->pos()))
+ setCursor(Qt::SizeBDiagCursor);
+ else if (topLeftCorner.contains(event->pos()))
+ setCursor(Qt::SizeFDiagCursor);
+ else if (leftSide.contains(event->pos()))
+ setCursor(Qt::SizeHorCursor);
+ else if (rightSide.contains(event->pos()))
+ setCursor(Qt::SizeHorCursor);
+ else if (topSide.contains(event->pos()))
+ setCursor(Qt::SizeVerCursor);
+ else if (bottomSide.contains(event->pos()))
+ setCursor(Qt::SizeVerCursor);
+ }
+
+
+ void crop_item::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+ {
+ updateCursor(event);
+
+ QGraphicsItem::mouseMoveEvent(event);
+
+ qreal minSize = 4 + (CROP_BORDER_LINE << 1);
+
+ QPointF delta = event->pos() - event->lastPos();
+ switch (_cropResize)
+ {
+ case CropItemResizeNone:
+ if (!_cropRect.contains(event->pos()))
+ return;
+
+ setCursor(Qt::SizeAllCursor);
+
+ if (!(event->buttons() & Qt::LeftButton))
+ return;
+
+ _cropRect.translate(delta);
+ break;
+ case CropItemResizeTopLeft:
+ delta.setY(qMin(_cropRect.height() - minSize, delta.y()));
+ delta.setX(qMin(_cropRect.width() - minSize, delta.x()));
+ _cropRect.setHeight(_cropRect.height() - delta.y());
+ _cropRect.setWidth(_cropRect.width() - delta.x());
+ _cropRect.translate(delta);
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case CropItemResizeTopRight:
+ delta.setY(qMin(_cropRect.height() - minSize, delta.y()));
+ _cropRect.setWidth(_cropRect.width() + delta.x());
+ _cropRect.setHeight(_cropRect.height() - delta.y());
+ _cropRect.translate(0, delta.y());
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case CropItemResizeBottomLeft:
+ delta.setX(qMin(_cropRect.width() - minSize, delta.x()));
+ _cropRect.setHeight(_cropRect.height() + delta.y());
+ _cropRect.setWidth(_cropRect.width() - delta.x());
+ _cropRect.translate(delta.x(), 0);
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case CropItemResizeBottomRight:
+ _cropRect.setWidth(_cropRect.width() + delta.x());
+ _cropRect.setHeight(_cropRect.height() + delta.y());
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case CropItemResizeLeft:
+ delta.setX(qMin(_cropRect.width() - minSize, delta.x()));
+ _cropRect.setWidth(_cropRect.width() - delta.x());
+ _cropRect.translate(delta.x(), 0);
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case CropItemResizeRight:
+ _cropRect.setWidth(_cropRect.width() + delta.x());
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case CropItemResizeTop:
+ delta.setY(qMin(_cropRect.height() - minSize, delta.y()));
+ _cropRect.setHeight(_cropRect.height() - delta.y());
+ _cropRect.translate(0, delta.y());
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case CropItemResizeBottom:
+ _cropRect.setHeight(_cropRect.height() + delta.y());
+ setCursor(Qt::SizeVerCursor);
+ break;
+ }
+
+ if (_cropRect.width() < minSize)
+ _cropRect.setWidth(minSize);
+ if (_cropRect.height() < minSize)
+ _cropRect.setHeight(minSize);
+
+ update();
+ }
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
diff --git a/scribo/demo/shared/src/bak/crop_item.hh
b/scribo/demo/shared/src/bak/crop_item.hh
new file mode 100644
index 0000000..caf2032
--- /dev/null
+++ b/scribo/demo/shared/src/bak/crop_item.hh
@@ -0,0 +1,100 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+//
+// Based on the code located here:
+//
http://th30z.netsons.org/2010/01/qt4-image-crop-item/
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
+# define SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
+
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QGraphicsItem>
+#include <QApplication>
+#include <QPainter>
+#include <QtGui>
+
+#define CROP_BORDER_LINE 10
+#define CROP_GRID_SIZE 3
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ class crop_item : public QGraphicsItem
+ {
+ public:
+ crop_item(QGraphicsItem *parent);
+ QRectF cropRect (void) const;
+
+ public:
+ QRectF boundingRect (void) const;
+ void paint (QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget = 0);
+
+ protected:
+ void mousePressEvent (QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
+ void updateCursor(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+
+ private:
+ enum CropItemResize {
+ CropItemResizeNone,
+
+ CropItemResizeTopLeft,
+ CropItemResizeTopRight,
+ CropItemResizeBottomLeft,
+ CropItemResizeBottomRight,
+
+ CropItemResizeLeft,
+ CropItemResizeRight,
+ CropItemResizeTop,
+ CropItemResizeBottom
+ };
+
+ private:
+ CropItemResize _cropResize;
+ QRectF _cropRect;
+ bool _mousePress;
+ };
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
diff --git a/scribo/demo/shared/src/bak/image_viewer.cc
b/scribo/demo/shared/src/bak/image_viewer.cc
new file mode 100644
index 0000000..89d63d2
--- /dev/null
+++ b/scribo/demo/shared/src/bak/image_viewer.cc
@@ -0,0 +1,242 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+# include <shared/src/image_viewer.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ image_viewer::image_viewer(QWidget *parent)
+ : QWidget(parent), item_(0)
+ {
+ setupUi(this);
+
+ connect(image_->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_vertical_sliders(int)));
+ connect(image_->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_horizontal_sliders(int)));
+
+ setup_scene();
+
+ slider->setMinimum(0);
+ visible_slider(false);
+ }
+
+
+
+ image_viewer::~image_viewer()
+ {
+
+ }
+
+ unsigned image_viewer::current_slice() const
+ {
+ return slider->value();
+ }
+
+ internal::interactiveScene * image_viewer::scene()
+ {
+ return static_cast<internal::interactiveScene *>(image_->scene());
+ }
+
+ const internal::interactiveScene * image_viewer::scene() const
+ {
+ return static_cast<const internal::interactiveScene *>(image_->scene());
+ }
+
+ // Private members
+
+ void image_viewer::setup_scene()
+ {
+ QGraphicsScene *scene = new internal::interactiveScene();
+ image_->setScene(scene);
+ image_->show();
+ }
+
+ void image_viewer::draw_image(const mln::image2d<dsp_data_t>& ima)
+ {
+ QImage
+ qima = mln::convert::implementation::to_qimage_qt_rgb32_nocopy(ima);
+ QPixmap pixmap = QPixmap::fromImage(qima);
+
+ if (item_ != 0)
+ {
+ image_->scene()->removeItem(item_);
+ delete item_;
+ }
+
+ item_ = image_->scene()->addPixmap(pixmap);
+ image_->scene()->setSceneRect(item_->boundingRect());
+
+ if (pixmap.width() > image_->maximumViewportSize().width())
+ image_->fitInView(item_->boundingRect(), Qt::KeepAspectRatio);
+
+ zoomLabel->setEnabled(true);
+ zoomIn->setEnabled(true);
+ zoomOut->setEnabled(true);
+ zoomFixed->setEnabled(true);
+ zoomOriginal->setEnabled(true);
+
+ item_->translate(ima.domain().pmin().col(), ima.domain().pmin().row());
+
+ image_->setSceneRect(item_->sceneBoundingRect());
+ }
+
+
+ void image_viewer::resize_image(const QRectF& rect)
+ {
+ if (item_ != 0)
+ image_->fitInView(rect, Qt::KeepAspectRatio);
+ }
+
+ void image_viewer::resizeEvent(QResizeEvent * event)
+ {
+ if (item_ != 0)
+ resize_image(item_->boundingRect());
+ event->ignore();
+ }
+
+
+ void image_viewer::keyPressEvent(QKeyEvent *event)
+ {
+ if (event->text() == QString("+"))
+ {
+ on_zoomIn_clicked();
+ event->accept();
+ }
+ else if (event->text() == QString("-"))
+ {
+ on_zoomOut_clicked();
+ event->accept();
+ }
+ else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
+ {
+ if (event->modifiers() == Qt::ControlModifier)
+ on_zoomFixed_clicked();
+ else
+ on_zoomOriginal_clicked();
+ event->accept();
+ }
+ else
+ event->ignore();
+ }
+
+
+ // Private slots
+
+ void image_viewer::visible_slider(bool b)
+ {
+ slider->setVisible(b);
+ label_2->setVisible(b);
+ frame_nb->setVisible(b);
+ }
+
+ void image_viewer::move_vertical_sliders(int value)
+ {
+ image_->verticalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::move_horizontal_sliders(int value)
+ {
+ image_->horizontalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::on_slider_valueChanged(int sli)
+ {
+ frame_nb->setText(QString("%1/%2").arg(sli).arg(slider->maximum()));
+ emit slider_valueChanged(sli);
+ }
+
+ void image_viewer::update_image(const mln::image2d<dsp_data_t>& ima)
+ {
+ draw_image(ima);
+ }
+
+ void image_viewer::on_zoomIn_clicked()
+ {
+ image_->scale(1.2, 1.2);
+ }
+
+ void image_viewer::on_zoomOut_clicked()
+ {
+ image_->scale(1 / 1.2, 1 / 1.2);
+ }
+
+ void image_viewer::on_zoomFixed_clicked()
+ {
+ if (item_ != 0)
+ resize_image(item_->boundingRect());
+ }
+
+ void image_viewer::on_zoomOriginal_clicked()
+ {
+ if (item_ != 0)
+ resize_image(image_->viewport()->geometry());
+ }
+
+
+ void image_viewer::clear()
+ {
+ visible_slider(false);
+ if (item_ != 0 && item_->scene() == image_->scene())
+ {
+ image_->scene()->removeItem(item_);
+ delete item_;
+ item_ = 0;
+ }
+ }
+
+
+ // Public slots
+
+ void image_viewer::set_image_layer_count(unsigned nslis)
+ {
+ visible_slider(nslis > 1);
+
+ slider->setMaximum(nslis - 1);
+
+ unsigned sli = current_slice();
+ if (current_slice() >= nslis)
+ sli = 0;
+
+ slider->setSliderPosition(sli);
+ on_slider_valueChanged(sli);
+ }
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/shared/src/bak/image_viewer.hh
b/scribo/demo/shared/src/bak/image_viewer.hh
new file mode 100644
index 0000000..f18ca3b
--- /dev/null
+++ b/scribo/demo/shared/src/bak/image_viewer.hh
@@ -0,0 +1,116 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
+# define SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
+
+# include <QApplication>
+# include <QtCore>
+# include <QtGui>
+
+# include <ui_image_viewer.h>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/convert/to_qimage.hh>
+
+# include <shared/src/types.hh>
+# include <shared/src/internal/interactive_scene.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ class image_viewer
+ : public QWidget, private Ui::ImageViewer
+ {
+ Q_OBJECT;
+
+ public:
+ image_viewer(QWidget *parent = 0);
+ ~image_viewer();
+
+ unsigned current_slice() const;
+
+ internal::interactiveScene * scene();
+ const internal::interactiveScene * scene() const;
+
+ void clear();
+
+ private: // members
+ void setup_scene();
+
+ void draw_image(const mln::image2d<dsp_data_t>& ima);
+
+ void resize_image(const QRectF& rect);
+
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent * event);
+// void mouseMoveEvent(QMouseEvent *e);
+// void mousePressEvent(QMouseEvent *e);
+// void mouseReleasedEvent(QMouseEvent *e);
+
+ private slots:
+ void visible_slider(bool b);
+
+ void move_vertical_sliders(int value);
+ void move_horizontal_sliders(int value);
+
+ void on_slider_valueChanged(int sli);
+
+ void on_zoomIn_clicked();
+ void on_zoomOut_clicked();
+ void on_zoomFixed_clicked();
+ void on_zoomOriginal_clicked();
+
+
+ public slots:
+ void set_image_layer_count(unsigned nslis);
+ void update_image(const mln::image2d<dsp_data_t>& ima);
+
+
+ signals:
+ void slider_valueChanged(int sli);
+
+ private: // attributes
+ QGraphicsItem *item_;
+ bool mouse_moving_;
+ QPoint p_start_;
+ };
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
diff --git a/scribo/demo/shared/src/bak/types.hh b/scribo/demo/shared/src/bak/types.hh
new file mode 100644
index 0000000..8edb54a
--- /dev/null
+++ b/scribo/demo/shared/src/bak/types.hh
@@ -0,0 +1,50 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_TYPES_HH
+# define SCRIBO_DEMO_SHARED_SRC_TYPES_HH
+
+
+# include <mln/value/qt/rgb32.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ typedef mln::value::qt::rgb32 dsp_data_t;
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_TYPES_HH
diff --git a/scribo/demo/shared/src/browse_widget.cc
b/scribo/demo/shared/src/browse_widget.cc
new file mode 100644
index 0000000..67e553a
--- /dev/null
+++ b/scribo/demo/shared/src/browse_widget.cc
@@ -0,0 +1,72 @@
+#include <shared/src/browse_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+
+ browse_widget::browse_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+
+ QStringList filters;
+ filters << tr("Any (*.*)");
+ setDialogFilter(filters);
+
+ setDialogFileMode(QFileDialog::ExistingFile);
+ setDialogTitle(tr("Choose an existing file"));
+ setDescription(tr("Choose a file:"));
+ }
+
+ void browse_widget::setDescription(const QString& desc)
+ {
+ description_->setText(desc);
+ }
+
+ QString browse_widget::path() const
+ {
+ return path_->text();
+ }
+
+ void browse_widget::reset()
+ {
+ path_->clear();
+ }
+
+ void browse_widget::setDialogTitle(const QString& title)
+ {
+ dialog_.setLabelText(QFileDialog::LookIn, title);
+ }
+
+ void browse_widget::setDialogFileMode(const QFileDialog::FileMode& filemode)
+ {
+ dialog_.setFileMode(filemode);
+ }
+
+ void browse_widget::setDialogFilter(const QStringList& filters)
+ {
+ dialog_.setNameFilters(filters);
+ }
+
+
+ void browse_widget::on_browseBtn__clicked()
+ {
+ if (dialog_.exec())
+ {
+ path_->setText(dialog_.selectedFiles().at(0));
+ emit path_updated();
+ }
+ }
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/shared/src/browse_widget.hh
b/scribo/demo/shared/src/browse_widget.hh
new file mode 100644
index 0000000..d30213c
--- /dev/null
+++ b/scribo/demo/shared/src/browse_widget.hh
@@ -0,0 +1,78 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_BROWSE_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_BROWSE_WIDGET_HH
+
+# include <QtGui>
+# include <ui_browse_widget.h>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+
+ class browse_widget : public QWidget, protected Ui::BrowseWidget
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(QString path READ path);
+
+ public:
+ browse_widget(QWidget *parent = 0);
+
+ void setDescription(const QString& desc);
+ void setDialogTitle(const QString& title);
+ void setDialogFileMode(const QFileDialog::FileMode& filemode);
+ void setDialogFilter(const QStringList& filters);
+
+ QString path() const;
+
+ void reset();
+
+ private slots:
+ void on_browseBtn__clicked();
+
+ signals:
+ void path_updated();
+
+ private:
+ QFileDialog dialog_;
+ };
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_BROWSE_WIDGET_HH
diff --git a/scribo/demo/shared/src/crop_item.cc b/scribo/demo/shared/src/crop_item.cc
new file mode 100644
index 0000000..100ac7d
--- /dev/null
+++ b/scribo/demo/shared/src/crop_item.cc
@@ -0,0 +1,313 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#include <shared/src/crop_item.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ crop_item::crop_item(QGraphicsItem *parent)
+ : QGraphicsItem(parent)
+ {
+ mousePress_ = false;
+ setAcceptHoverEvents(true);
+
+ reset();
+
+ grabMouse();
+ }
+
+ void crop_item::reset()
+ {
+ if (parentItem())
+ cropRect_ = parentItem()->boundingRect();
+ else
+ cropRect_ = QRectF(20, 20, 100, 70);
+ }
+
+ const QRectF& crop_item::cropRect() const
+ {
+ return cropRect_;
+ }
+
+
+ QRectF crop_item::boundingRect() const
+ {
+ return parentItem()->boundingRect();
+ }
+
+ void crop_item::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ Q_UNUSED(widget);
+
+ painter->save();
+
+ QPainterPath cropPath;
+ cropPath.addRect(cropRect_);
+
+ QPainterPath windowPath;
+ windowPath.addRect(option->rect);
+ windowPath = windowPath.subtracted(cropPath);
+
+ // Draw Alpha-Black Background.
+ painter->fillPath(windowPath, QColor(0x33, 0x33, 0x33, 0xcc));
+
+ // Draw Crop Rect
+ painter->setPen(QPen(QColor(0xdd, 0xdd, 0xdd), 1));
+ painter->drawPath(cropPath);
+
+ int topRightX = cropRect_.x() + cropRect_.width();
+ int bottomY = cropRect_.y() + cropRect_.height();
+
+ QPainterPath borderPath;
+ int corner_width = cropRect_.width() / 6.f;
+ int corner_height = cropRect_.height() / 6.f;
+
+ // Top-Left Corner
+ painter->drawRect(QRectF(cropRect_.x(), cropRect_.y(),
+ corner_width, corner_height));
+
+
+ // Top-Right Corner
+ painter->drawRect(QRectF(topRightX - corner_width, cropRect_.y(),
+ corner_width, corner_height));
+
+ // Bottom-Left Corner
+ painter->drawRect(QRectF(cropRect_.x(), bottomY - corner_height,
+ corner_width, corner_height));
+
+ // Bottom-Left Corner
+ painter->drawRect(QRectF(topRightX - corner_width,
+ bottomY - corner_height,
+ corner_width, corner_height));
+
+ // Draw Border Path
+ painter->setPen(QPen(QColor(0xee, 0xee, 0xee), 3));
+ painter->drawPath(borderPath);
+
+ painter->restore();
+ }
+
+
+ void crop_item::mousePressEvent(QGraphicsSceneMouseEvent *event)
+ {
+ QGraphicsItem::mousePressEvent(event);
+
+ mousePress_ = true;
+ cropResize_ = CropItemResizeNone;
+ if (event->buttons() & Qt::LeftButton)
+ {
+ int wsize = cropRect_.width() / 6.f;
+ int hsize = cropRect_.height() / 6.f;
+
+ int rightX = cropRect_.x() + cropRect_.width() - wsize;
+ int leftX = cropRect_.x();
+
+ int bottomY = cropRect_.y() + cropRect_.height() - hsize;
+ int topY = cropRect_.y();
+
+ QRectF bottomRightCorner(rightX, bottomY, wsize, hsize);
+ QRectF bottomLeftCorner(leftX, bottomY, wsize, hsize);
+ QRectF topRightCorner(rightX, topY, wsize, hsize);
+ QRectF topLeftCorner(leftX, topY, wsize, hsize);
+
+ int sideHeight = cropRect_.height() - 2 * hsize;
+ int sideWidth = cropRect_.width() - 2 * wsize;
+ QRectF leftSide(leftX, topY + hsize, wsize, sideHeight);
+ QRectF rightSide(rightX, topY + hsize, wsize, sideHeight);
+ QRectF topSide(leftX + wsize, topY, sideWidth, hsize);
+ QRectF bottomSide(leftX + wsize, bottomY, sideWidth, hsize);
+
+ if (bottomRightCorner.contains(event->pos()))
+ cropResize_ = CropItemResizeBottomRight;
+ else if (bottomLeftCorner.contains(event->pos()))
+ cropResize_ = CropItemResizeBottomLeft;
+ else if (topRightCorner.contains(event->pos()))
+ cropResize_ = CropItemResizeTopRight;
+ else if (topLeftCorner.contains(event->pos()))
+ cropResize_ = CropItemResizeTopLeft;
+ else if (leftSide.contains(event->pos()))
+ cropResize_ = CropItemResizeLeft;
+ else if (rightSide.contains(event->pos()))
+ cropResize_ = CropItemResizeRight;
+ else if (topSide.contains(event->pos()))
+ cropResize_ = CropItemResizeTop;
+ else if (bottomSide.contains(event->pos()))
+ cropResize_ = CropItemResizeBottom;
+ }
+
+ update();
+ }
+
+
+ void crop_item::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+ {
+ QGraphicsItem::mouseReleaseEvent(event);
+
+ cropResize_ = CropItemResizeNone;
+ mousePress_ = false;
+
+ update();
+ }
+
+
+// void crop_item::updateCursor(QGraphicsSceneMouseEvent *event)
+// {
+// int lthreshold = (CROP_BORDER_LINE >> 1);
+// int rthreshold = CROP_BORDER_LINE;
+// int size = CROP_BORDER_LINE << 1;
+
+// int rightX = cropRect_.x() + cropRect_.width() - rthreshold;
+// int leftX = cropRect_.x() - lthreshold;
+
+// int bottomY = cropRect_.y() + cropRect_.height() - rthreshold;
+// int topY = cropRect_.y() - lthreshold;
+
+// QRectF bottomRightCorner(rightX, bottomY, size, size);
+// QRectF bottomLeftCorner(leftX, bottomY, size, size);
+// QRectF topRightCorner(rightX, topY, size, size);
+// QRectF topLeftCorner(leftX, topY, size, size);
+
+// int sideHeight = cropRect_.height() - 2 * size;
+// int sideWidth = cropRect_.width() - 2 * size;
+// QRectF leftSide(leftX, topY + size, size, sideHeight);
+// QRectF rightSide(rightX, topY + size, size, sideHeight);
+// QRectF topSide(leftX + size, topY, sideWidth, size);
+// QRectF bottomSide(leftX + size, bottomY, sideWidth, size);
+
+// if (bottomRightCorner.contains(event->pos()))
+// setCursor(Qt::SizeFDiagCursor);
+// else if (bottomLeftCorner.contains(event->pos()))
+// setCursor(Qt::SizeBDiagCursor);
+// else if (topRightCorner.contains(event->pos()))
+// setCursor(Qt::SizeBDiagCursor);
+// else if (topLeftCorner.contains(event->pos()))
+// setCursor(Qt::SizeFDiagCursor);
+// else if (leftSide.contains(event->pos()))
+// setCursor(Qt::SizeHorCursor);
+// else if (rightSide.contains(event->pos()))
+// setCursor(Qt::SizeHorCursor);
+// else if (topSide.contains(event->pos()))
+// setCursor(Qt::SizeVerCursor);
+// else if (bottomSide.contains(event->pos()))
+// setCursor(Qt::SizeVerCursor);
+// }
+
+
+ void crop_item::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+ {
+// updateCursor(event);
+
+ QGraphicsItem::mouseMoveEvent(event);
+
+ qreal minSize = 4 + (CROP_BORDER_LINE << 1);
+
+ QPointF delta = event->pos() - event->lastPos();
+ switch (cropResize_)
+ {
+ case CropItemResizeNone:
+ if (!cropRect_.contains(event->pos()))
+ return;
+
+ setCursor(Qt::SizeAllCursor);
+
+ if (!(event->buttons() & Qt::LeftButton))
+ return;
+
+ cropRect_.translate(delta);
+ break;
+ case CropItemResizeTopLeft:
+ delta.setY(qMin(cropRect_.height() - minSize, delta.y()));
+ delta.setX(qMin(cropRect_.width() - minSize, delta.x()));
+ cropRect_.setHeight(cropRect_.height() - delta.y());
+ cropRect_.setWidth(cropRect_.width() - delta.x());
+ cropRect_.translate(delta);
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case CropItemResizeTopRight:
+ delta.setY(qMin(cropRect_.height() - minSize, delta.y()));
+ cropRect_.setWidth(cropRect_.width() + delta.x());
+ cropRect_.setHeight(cropRect_.height() - delta.y());
+ cropRect_.translate(0, delta.y());
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case CropItemResizeBottomLeft:
+ delta.setX(qMin(cropRect_.width() - minSize, delta.x()));
+ cropRect_.setHeight(cropRect_.height() + delta.y());
+ cropRect_.setWidth(cropRect_.width() - delta.x());
+ cropRect_.translate(delta.x(), 0);
+ setCursor(Qt::SizeBDiagCursor);
+ break;
+ case CropItemResizeBottomRight:
+ cropRect_.setWidth(cropRect_.width() + delta.x());
+ cropRect_.setHeight(cropRect_.height() + delta.y());
+ setCursor(Qt::SizeFDiagCursor);
+ break;
+ case CropItemResizeLeft:
+ delta.setX(qMin(cropRect_.width() - minSize, delta.x()));
+ cropRect_.setWidth(cropRect_.width() - delta.x());
+ cropRect_.translate(delta.x(), 0);
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case CropItemResizeRight:
+ cropRect_.setWidth(cropRect_.width() + delta.x());
+ setCursor(Qt::SizeHorCursor);
+ break;
+ case CropItemResizeTop:
+ delta.setY(qMin(cropRect_.height() - minSize, delta.y()));
+ cropRect_.setHeight(cropRect_.height() - delta.y());
+ cropRect_.translate(0, delta.y());
+ setCursor(Qt::SizeVerCursor);
+ break;
+ case CropItemResizeBottom:
+ cropRect_.setHeight(cropRect_.height() + delta.y());
+ setCursor(Qt::SizeVerCursor);
+ break;
+ }
+
+ if (cropRect_.width() < minSize)
+ cropRect_.setWidth(minSize);
+ if (cropRect_.height() < minSize)
+ cropRect_.setHeight(minSize);
+
+ update();
+ }
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
diff --git a/scribo/demo/shared/src/crop_item.hh b/scribo/demo/shared/src/crop_item.hh
new file mode 100644
index 0000000..c0b1394
--- /dev/null
+++ b/scribo/demo/shared/src/crop_item.hh
@@ -0,0 +1,103 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+//
+// Based on the code located here:
+//
http://th30z.netsons.org/2010/01/qt4-image-crop-item/
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
+# define SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
+
+#include <QStyleOptionGraphicsItem>
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QGraphicsItem>
+#include <QApplication>
+#include <QPainter>
+#include <QtGui>
+
+#define CROP_BORDER_LINE 10
+#define CROP_GRID_SIZE 3
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ class crop_item : public QGraphicsItem
+ {
+ public:
+ crop_item(QGraphicsItem *parent);
+ const QRectF& cropRect() const;
+
+ QRectF boundingRect() const;
+ void paint (QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget = 0);
+
+ void reset();
+
+ protected:
+ void mousePressEvent (QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+
+// void updateCursor(QGraphicsSceneMouseEvent *event);
+
+ private:
+ enum CropItemResize
+ {
+ CropItemResizeNone,
+
+ CropItemResizeTopLeft,
+ CropItemResizeTopRight,
+ CropItemResizeBottomLeft,
+ CropItemResizeBottomRight,
+
+ CropItemResizeLeft,
+ CropItemResizeRight,
+ CropItemResizeTop,
+ CropItemResizeBottom
+ };
+
+ private:
+ CropItemResize cropResize_;
+ QRectF cropRect_;
+ bool mousePress_;
+ };
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_CROP_ITEM_HH
diff --git a/scribo/demo/shared/src/image_viewer.cc
b/scribo/demo/shared/src/image_viewer.cc
new file mode 100644
index 0000000..b61f86b
--- /dev/null
+++ b/scribo/demo/shared/src/image_viewer.cc
@@ -0,0 +1,344 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+# include <shared/src/image_viewer.hh>
+# include <shared/src/crop_item.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ image_viewer::image_viewer(QWidget *parent)
+ : QWidget(parent), image_(0), selection_(0), angle_(0)
+ {
+ setupUi(this);
+
+ connect(viewer_->verticalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_vertical_sliders(int)));
+ connect(viewer_->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+ this, SLOT(move_horizontal_sliders(int)));
+
+ setup_scene();
+
+ slider->setMinimum(0);
+ visible_slider(false);
+
+ set_selection_enabled(false);
+ set_rotation_enabled(false);
+ }
+
+
+
+ image_viewer::~image_viewer()
+ {
+
+ }
+
+ unsigned image_viewer::current_slice() const
+ {
+ return slider->value();
+ }
+
+ internal::interactiveScene * image_viewer::scene()
+ {
+ return static_cast<internal::interactiveScene *>(viewer_->scene());
+ }
+
+ const internal::interactiveScene * image_viewer::scene() const
+ {
+ return static_cast<const internal::interactiveScene *>(viewer_->scene());
+ }
+
+ // Private members
+
+ void image_viewer::setup_scene()
+ {
+ QGraphicsScene *scene = new internal::interactiveScene();
+ viewer_->setScene(scene);
+ viewer_->show();
+ }
+
+ void image_viewer::draw_image(const mln::image2d<dsp_data_t>& ima)
+ {
+ QImage
+ qima = mln::convert::to_qimage_nocopy(ima);
+ QPixmap pixmap = QPixmap::fromImage(qima);
+
+ draw_image(pixmap, QPoint(ima.domain().pmin().col(),
+ ima.domain().pmin().row()));
+ }
+
+
+ void image_viewer::draw_image(const QPixmap& pixmap)
+ {
+ draw_image(pixmap, QPoint(0, 0));
+ }
+
+
+ void image_viewer::draw_image(const QPixmap& pixmap,
+ const QPoint& origin)
+ {
+ bool restore_selection = false;
+
+ if (image_ != 0)
+ {
+ viewer_->scene()->removeItem(image_);
+ delete image_;
+
+ if (selection_)
+ {
+ selection_ = 0;
+ restore_selection = true;
+ }
+ }
+
+ image_ = viewer_->scene()->addPixmap(pixmap);
+ viewer_->scene()->setSceneRect(image_->boundingRect());
+
+ if (pixmap.width() > viewer_->maximumViewportSize().width())
+ viewer_->fitInView(image_->boundingRect(), Qt::KeepAspectRatio);
+
+ zoomLabel->setEnabled(true);
+ zoomIn->setEnabled(true);
+ zoomOut->setEnabled(true);
+ zoomFixed->setEnabled(true);
+ zoomOriginal->setEnabled(true);
+
+ image_->translate(origin.x(), origin.y());
+
+ viewer_->setSceneRect(image_->sceneBoundingRect());
+
+ // Restore selection mode if needed
+ set_selection_enabled(restore_selection);
+ }
+
+
+ void image_viewer::resize_image(const QRectF& rect)
+ {
+ if (image_ != 0)
+ viewer_->fitInView(rect, Qt::KeepAspectRatio);
+ }
+
+ void image_viewer::resizeEvent(QResizeEvent * event)
+ {
+ if (image_ != 0)
+ resize_image(image_->boundingRect());
+ event->ignore();
+ }
+
+ void image_viewer::keyPressEvent(QKeyEvent *event)
+ {
+ if (event->text() == QString("+"))
+ {
+ on_zoomIn_clicked();
+ event->accept();
+ }
+ else if (event->text() == QString("-"))
+ {
+ on_zoomOut_clicked();
+ event->accept();
+ }
+ else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
+ {
+ if (event->modifiers() == Qt::ControlModifier)
+ on_zoomFixed_clicked();
+ else
+ on_zoomOriginal_clicked();
+ event->accept();
+ }
+ else
+ event->ignore();
+ }
+
+
+ // Private slots
+
+ void image_viewer::visible_slider(bool b)
+ {
+ slider->setVisible(b);
+ label_2->setVisible(b);
+ frame_nb->setVisible(b);
+ }
+
+ void image_viewer::move_vertical_sliders(int value)
+ {
+ viewer_->verticalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::move_horizontal_sliders(int value)
+ {
+ viewer_->horizontalScrollBar()->setValue(value);
+ }
+
+
+ void image_viewer::on_slider_valueChanged(int sli)
+ {
+ frame_nb->setText(QString("%1/%2").arg(sli).arg(slider->maximum()));
+ emit slider_valueChanged(sli);
+ }
+
+ void image_viewer::update_image(const mln::image2d<dsp_data_t>& ima)
+ {
+ draw_image(ima);
+ }
+
+ void image_viewer::on_rotate_cw_btn_clicked()
+ {
+ angle_ += 90 % 360;
+ image_->rotate(90);
+ viewer_->setSceneRect(image_->sceneBoundingRect());
+ }
+
+ void image_viewer::on_rotate_ccw_btn_clicked()
+ {
+ angle_ -= 90 % 360;
+ image_->rotate(-90);
+ viewer_->setSceneRect(image_->sceneBoundingRect());
+ }
+
+ void image_viewer::on_zoomIn_clicked()
+ {
+ viewer_->scale(1.2, 1.2);
+ }
+
+ void image_viewer::on_zoomOut_clicked()
+ {
+ viewer_->scale(1 / 1.2, 1 / 1.2);
+ }
+
+ void image_viewer::on_zoomFixed_clicked()
+ {
+ if (image_ != 0)
+ resize_image(image_->boundingRect());
+ }
+
+ void image_viewer::on_zoomOriginal_clicked()
+ {
+ if (image_ != 0)
+ resize_image(viewer_->viewport()->geometry());
+ }
+
+ void image_viewer::clear()
+ {
+ visible_slider(false);
+ if (image_ != 0 && image_->scene() == viewer_->scene())
+ {
+ viewer_->scene()->removeItem(image_);
+ delete image_;
+ image_ = 0;
+ }
+ }
+
+ void image_viewer::set_selection_enabled(bool b)
+ {
+ if (b)
+ {
+ if (selection_ == 0)
+ selection_ = new crop_item(image_);
+ }
+ else
+ {
+ delete selection_;
+ selection_ = 0;
+ }
+ }
+
+
+ void image_viewer::set_rotation_enabled(bool b)
+ {
+ angle_ = 0;
+ rotate_lbl->setVisible(b);
+ rotate_cw_btn->setVisible(b);
+ rotate_ccw_btn->setVisible(b);
+ vline->setVisible(b);
+ }
+
+
+ bool image_viewer::has_selection() const
+ {
+ return selection_;
+ }
+
+
+ const QRectF& image_viewer::selection() const
+ {
+ static QRectF invalid_selection;
+ mln_assertion(has_selection());
+
+ if (selection_)
+ return selection_->cropRect();
+
+ return invalid_selection;
+ }
+
+
+ bool image_viewer::has_rotation() const
+ {
+ return rotate_lbl->isVisible();
+ }
+
+
+ qreal image_viewer::rotation() const
+ {
+ mln_assertion(has_rotation());
+
+ return angle_;
+ }
+
+
+ QPixmap image_viewer::image() const
+ {
+ return image_->pixmap();
+ }
+
+ // Public slots
+
+ void image_viewer::set_image_layer_count(unsigned nslis)
+ {
+ visible_slider(nslis > 1);
+
+ slider->setMaximum(nslis - 1);
+
+ unsigned sli = current_slice();
+ if (current_slice() >= nslis)
+ sli = 0;
+
+ slider->setSliderPosition(sli);
+ on_slider_valueChanged(sli);
+ }
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/shared/src/image_viewer.hh
b/scribo/demo/shared/src/image_viewer.hh
new file mode 100644
index 0000000..628f5d4
--- /dev/null
+++ b/scribo/demo/shared/src/image_viewer.hh
@@ -0,0 +1,135 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
+# define SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
+
+# include <QApplication>
+# include <QtCore>
+# include <QtGui>
+
+# include <ui_image_viewer.h>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/convert/to_qimage_nocopy.hh>
+
+# include <shared/src/types.hh>
+# include <shared/src/internal/interactive_scene.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ // Forward declaration.
+ class crop_item;
+
+ class image_viewer
+ : public QWidget, private Ui::ImageViewer
+ {
+ Q_OBJECT;
+
+ public:
+ image_viewer(QWidget *parent = 0);
+ ~image_viewer();
+
+ void draw_image(const mln::image2d<dsp_data_t>& ima);
+ void draw_image(const QPixmap& pixmap);
+ void draw_image(const QPixmap& pixmap, const QPoint& origin);
+
+ unsigned current_slice() const;
+
+ internal::interactiveScene * scene();
+ const internal::interactiveScene * scene() const;
+
+ void clear();
+
+ void set_selection_enabled(bool b);
+ void set_rotation_enabled(bool b);
+
+
+ bool has_selection() const;
+ const QRectF& selection() const;
+
+ bool has_rotation() const;
+ qreal rotation() const;
+
+ QPixmap image() const;
+
+ private: // members
+ void setup_scene();
+
+ void resize_image(const QRectF& rect);
+
+ void keyPressEvent(QKeyEvent *event);
+ void resizeEvent(QResizeEvent * event);
+
+ private slots:
+ void visible_slider(bool b);
+
+ void move_vertical_sliders(int value);
+ void move_horizontal_sliders(int value);
+
+ void on_slider_valueChanged(int sli);
+
+ void on_rotate_cw_btn_clicked();
+ void on_rotate_ccw_btn_clicked();
+
+ void on_zoomIn_clicked();
+ void on_zoomOut_clicked();
+ void on_zoomFixed_clicked();
+ void on_zoomOriginal_clicked();
+
+
+ public slots:
+ void set_image_layer_count(unsigned nslis);
+ void update_image(const mln::image2d<dsp_data_t>& ima);
+
+
+ signals:
+ void slider_valueChanged(int sli);
+
+ private: // attributes
+ QGraphicsPixmapItem* image_;
+ crop_item* selection_;
+ bool mouse_moving_;
+ QPoint p_start_;
+ qreal angle_;
+ };
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_IMAGE_VIEWER_HH
diff --git a/scribo/demo/shared/src/internal.bak/interactive_scene.cc
b/scribo/demo/shared/src/internal.bak/interactive_scene.cc
new file mode 100644
index 0000000..b839f6b
--- /dev/null
+++ b/scribo/demo/shared/src/internal.bak/interactive_scene.cc
@@ -0,0 +1,286 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+# include <shared/src/internal/interactive_scene.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+
+ struct test : public QGraphicsItem
+ {
+ test()
+ {
+ setZValue(0);
+ setCursor(Qt::OpenHandCursor);
+
+ }
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event)
+ {
+ setCursor(Qt::ClosedHandCursor);
+ }
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+ {
+ setCursor(Qt::OpenHandCursor);
+ }
+
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
+ {
+ setCursor(Qt::OpenHandCursor);
+ }
+
+ void paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(Qt::darkGray);
+ painter->drawEllipse(-12, -12, 30, 30);
+ painter->setPen(QPen(Qt::black, 1));
+ painter->setBrush(QBrush(Qt::red));
+ painter->drawEllipse(-15, -15, 30, 30);
+
+ painter->setBrush(QColor(0, 0, 0, 127));
+ painter->drawRect(scene()->sceneRect());
+
+ }
+
+ QRectF boundingRect() const
+ {
+ return QRectF(-15.5, -15.5, 34, 34);
+ }
+
+ };
+
+
+
+ interactiveScene::interactiveScene(QObject * parent)
+ : QGraphicsScene(parent), mode_(Drawing),
+ mouse_moved_(false), mouse_pressed_(false),
+ selectionTracking_(false)
+ {
+ rect_.setZValue(1);
+
+ QPen pen;
+ pen.setColor(QColor(Qt::black));
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidth(1);
+
+ rect_.setPen(pen);
+
+ setSceneRect(QRectF(-150, -150, 300, 300));
+
+ addItem(new test());
+ }
+
+
+ void interactiveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
+ {
+ if (mouse_pressed_)
+ {
+ // If selection is enabled.
+ if (selectionTracking_)
+ {
+ switch(mode_)
+ {
+ // Moving an existing selection.
+ case Moving:
+ {
+ QPointF p = e->scenePos() - e->lastScenePos();
+ rect_.translate(p.x(), p.y());
+ e->accept();
+ break;
+ }
+
+ // A new selection must be extended.
+ case Drawing:
+ {
+ rect_.setRect(QRectF(e->buttonDownScenePos(Qt::LeftButton),
+ e->scenePos()));
+ e->accept();
+ break;
+ }
+
+
+ // Extending an existing selection
+ case Extending:
+ {
+ rect_.update_size(rect_corner_, e->scenePos());
+ break;
+ }
+
+ default:
+ qDebug() << "interactiveScene::mouseMoveEvent - Invalid mode";
+ }
+
+ emit mouse_pressed(e->scenePos());
+ mouse_moved_ = true;
+ }
+ }
+ else
+ super_::mouseMoveEvent(e);
+
+ emit mouse_moved(e->scenePos());
+ }
+
+ void interactiveScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
+ {
+ mouse_moved_ = false;
+ mouse_pressed_ = true;
+ pressed_point_ = e->scenePos();
+
+ emit mouse_pressed(e->scenePos());
+
+ // If selection is enabled.
+ if (selectionTracking_)
+ {
+ // About to move an existing rectangle.
+ QGraphicsItem *item = itemAt(e->scenePos());
+ if (item == &rect_)
+ {
+ mode_ = Moving;
+ super_::mousePressEvent(e);
+ }
+ else if (item != 0)
+ {
+ mode_ = Extending;
+ rect_corner_ = item;
+ super_::mousePressEvent(e);
+ }
+ // Draw a new rectangle
+ else
+ {
+ mode_ = Drawing;
+ rect_.resetTransform();
+ rect_.setRect(QRectF(e->scenePos(), e->scenePos()));
+ if (rect_.scene() != this)
+ addItem(&rect_);
+ e->accept();
+ }
+ }
+ }
+
+ void interactiveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
+ {
+ mouse_pressed_ = false;
+
+ switch(mode_)
+ {
+
+ case Drawing:
+ {
+ if (selectionTracking_ && mouse_moved_)
+ emit new_selection(rect_.boundingRect());
+ else
+ {
+ // A mouse click is performed outside the selection
+ // rectangle.
+ // Clear selection if exists.
+ if (mode_ != Moving && rect_.scene() == this)
+ {
+ rect_.setRect(sceneRect());
+ removeItem(&rect_);
+ emit selection_cleared();
+ }
+ }
+ break;
+ }
+
+ case Moving:
+ {
+ if (mouse_moved_)
+ {
+ QPointF p = e->scenePos() - pressed_point_;
+
+
+ // FIXME: the bounding rectangle size is increasing by
+ // 0.5 pixels for an unknown reason...
+ rect_.setRect(rect_.boundingRect().translated(p.x(), p.y()));
+ rect_.resetTransform();
+ }
+ break;
+ }
+
+
+ case Extending:
+ {
+ break;
+ }
+
+ default:
+ qDebug() << "interactiveScene::mouseReleaseEvent - invalid mode";
+
+ }
+
+
+ if (!mouse_moved_)
+ emit mouse_click(e->scenePos());
+
+ emit mouse_released(e->scenePos());
+
+ e->accept();
+ }
+
+
+ void interactiveScene::setSelectionTracking(bool b)
+ {
+ selectionTracking_ = b;
+ }
+
+ bool interactiveScene::has_selection() const
+ {
+ return rect_.scene() == this;
+ }
+
+ QRectF interactiveScene::selection() const
+ {
+ return rect_.boundingRect();
+ }
+
+ void interactiveScene::clear_selection()
+ {
+ if (rect_.scene() == this)
+ removeItem(&rect_);
+ }
+
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/scribo/demo/shared/src/internal.bak/interactive_scene.hh
b/scribo/demo/shared/src/internal.bak/interactive_scene.hh
new file mode 100644
index 0000000..5888152
--- /dev/null
+++ b/scribo/demo/shared/src/internal.bak/interactive_scene.hh
@@ -0,0 +1,108 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+# define SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+
+# include <QtGui/QGraphicsScene>
+# include <QtGui/QGraphicsSceneMouseEvent>
+# include <QtGui/QGraphicsLineItem>
+# include <QtCore/QPoint>
+# include <QtCore/QDebug>
+
+# include <shared/src/internal/selection_rectangle.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ enum Mode
+ {
+ Moving,
+ Drawing,
+ Extending
+ };
+
+ class interactiveScene : public QGraphicsScene
+ {
+ Q_OBJECT;
+
+ typedef QGraphicsScene super_;
+
+ public:
+
+ interactiveScene(QObject * parent = 0);
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *e);
+ void mousePressEvent(QGraphicsSceneMouseEvent *e);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
+
+ void setSelectionTracking(bool b);
+
+ bool has_selection() const;
+ QRectF selection() const;
+ void clear_selection();
+
+ signals:
+ void mouse_click(const QPointF& p);
+ void mouse_moved(const QPointF& p);
+ void mouse_pressed(const QPointF& p);
+ void mouse_released(const QPointF& p);
+
+ void new_selection(const QRectF& rect);
+ void selection_cleared();
+
+ private:
+ selection_rectangle rect_;
+
+ QGraphicsItem* rect_corner_;
+
+ QPointF pressed_point_;
+
+ Mode mode_;
+
+ bool mouse_moved_;
+ bool mouse_pressed_;
+ bool selectionTracking_;
+ };
+
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
diff --git a/scribo/demo/shared/src/internal.bak/selection_rectangle.cc
b/scribo/demo/shared/src/internal.bak/selection_rectangle.cc
new file mode 100644
index 0000000..d3f82b7
--- /dev/null
+++ b/scribo/demo/shared/src/internal.bak/selection_rectangle.cc
@@ -0,0 +1,241 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <QtGui>
+#include <shared/src/internal/selection_rectangle.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ selection_rectangle::selection_rectangle()
+ {
+ QPen pen;
+ pen.setColor(QColor(Qt::red));
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidth(1);
+
+
+ rects_.resize(9);
+ for (int i = 0; i < rects_.size(); ++i)
+ {
+ rects_[i] = new QGraphicsRectItem(this);
+ rects_[i]->setZValue(1);
+ rects_[i]->setPen(pen);
+ rects_[i]->show();
+ rects_[i]->setAcceptHoverEvents(true);
+ }
+
+ rects_[1]->setCursor(Qt::SizeFDiagCursor);
+ rects_[2]->setCursor(Qt::SizeVerCursor);
+ rects_[3]->setCursor(Qt::SizeBDiagCursor);
+ rects_[4]->setCursor(Qt::SizeHorCursor);
+ rects_[5]->setCursor(Qt::SizeHorCursor);
+ rects_[6]->setCursor(Qt::SizeBDiagCursor);
+ rects_[7]->setCursor(Qt::SizeVerCursor);
+ rects_[8]->setCursor(Qt::SizeFDiagCursor);
+
+// setHandlesChildEvents(true);
+ setCursor(Qt::SizeAllCursor);
+ setAcceptHoverEvents(true);
+ }
+
+
+ selection_rectangle::~selection_rectangle()
+ {
+ foreach(QGraphicsRectItem *item, rects_)
+ delete item;
+ }
+
+
+ void selection_rectangle::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+
+ qreal border = 15;
+ qreal corner_width = qMin(qAbs(1/8.f * brect_.width()), border);
+ qreal corner_height = qMin(qAbs(1/8.f * brect_.height()), border);
+
+ painter->setBrush(QColor(255, 255, 255, 127));
+ painter->drawRect(brect_);
+
+ // Rectangle 1
+ QRectF rect1(brect_.topLeft().x(), brect_.topLeft().y(),
+ corner_width,
+ corner_height);
+ rects_[1]->setRect(rect1);
+
+ // Rectangle 2
+ QRectF rect2(rect1.topRight().x(), rect1.topRight().y(),
+ brect_.width() - 2 * corner_width,
+ corner_height);
+ rects_[2]->setRect(rect2);
+
+ // Rectangle 3
+ QRectF rect3(brect_.topRight().x() - corner_width,
+ brect_.topRight().y(),
+ corner_width,
+ corner_height);
+ rects_[3]->setRect(rect3);
+
+
+
+ // Rectangle 4
+ QRectF rect4(brect_.topLeft().x(),
+ brect_.topLeft().y() + corner_height,
+ corner_width,
+ brect_.height() - corner_height);
+ rects_[4]->setRect(rect4);
+
+ // Rectangle 5
+ QRectF rect5(brect_.topRight().x() - corner_width,
+ brect_.topRight().y() + corner_height,
+ corner_width,
+ brect_.height() - corner_height);
+ rects_[5]->setRect(rect5);
+
+
+
+ // Rectangle 6
+ QRectF rect6(brect_.bottomLeft().x(),
+ brect_.bottomLeft().y() - corner_height,
+ corner_width,
+ corner_height);
+ rects_[6]->setRect(rect6);
+
+ // Rectangle 7
+ QRectF rect7(rect6.topRight().x(), rect6.topRight().y(),
+ brect_.width() - 2 * corner_width,
+ corner_height);
+ rects_[7]->setRect(rect7);
+
+ // Rectangle 8
+ QRectF rect8(rect7.topRight().x(), rect7.topRight().y(),
+ corner_width,
+ corner_height);
+ rects_[8]->setRect(rect8);
+
+
+ painter->setPen(pen());
+ painter->drawRect(brect_);
+ }
+
+
+ QRectF selection_rectangle::boundingRect() const
+ {
+ qreal penWidth = pen().width();
+ return QRectF(brect_.x() - penWidth / 2, brect_.y() - penWidth / 2,
+ brect_.width() + penWidth / 2,
+ brect_.height() + penWidth / 2);
+ }
+
+
+ void selection_rectangle::setRect(qreal x, qreal y,
+ qreal width, qreal height)
+ {
+ prepareGeometryChange();
+ brect_ = QRectF(x, y, width, height).normalized();
+ }
+
+
+ void selection_rectangle::setRect(const QRectF & rectangle)
+ {
+ prepareGeometryChange();
+ brect_ = rectangle.normalized();
+ }
+
+
+ void selection_rectangle::update_size(QGraphicsItem *item,
+ const QPointF& p)
+ {
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+ QPointF p_ = p;
+
+ prepareGeometryChange();
+ if (rects_[1] == item)
+ brect_.setTopLeft(p_);
+ else if (rects_[2] == item)
+ brect_.setTop(p_.y());
+ else if (rects_[3] == item)
+ brect_.setTopRight(p_);
+ else if (rects_[4] == item)
+ brect_.setLeft(p_.x());
+ else if (rects_[5] == item)
+ brect_.setRight(p_.x());
+ else if (rects_[6] == item)
+ brect_.setBottomLeft(p_);
+ else if (rects_[7] == item)
+ brect_.setBottom(p_.y());
+ else if (rects_[8] == item)
+ brect_.setBottomRight(p_);
+ else
+ qDebug() << "selection_rectangle::update_size - invalid item";
+
+ brect_ = brect_.normalized();
+ }
+
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/scribo/demo/shared/src/internal.bak/selection_rectangle.hh
b/scribo/demo/shared/src/internal.bak/selection_rectangle.hh
new file mode 100644
index 0000000..b58bad2
--- /dev/null
+++ b/scribo/demo/shared/src/internal.bak/selection_rectangle.hh
@@ -0,0 +1,91 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
+# define SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
+
+# include <QtCore>
+# include <QtGui>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ class selection_rectangle : public QAbstractGraphicsShapeItem
+ {
+
+ public:
+ selection_rectangle();
+ ~selection_rectangle();
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget);
+
+ QRectF boundingRect() const;
+
+ void setRect(qreal x, qreal y, qreal width, qreal height);
+ void setRect(const QRectF & rectangle);
+
+ void update_size(QGraphicsItem *item, const QPointF& p);
+
+ private: // members
+
+
+ private: // attributes
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+ QVector<QGraphicsRectItem *> rects_;
+ QRectF brect_;
+
+ };
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
diff --git a/scribo/demo/shared/src/internal/interactive_scene.cc
b/scribo/demo/shared/src/internal/interactive_scene.cc
new file mode 100644
index 0000000..a56517b
--- /dev/null
+++ b/scribo/demo/shared/src/internal/interactive_scene.cc
@@ -0,0 +1,87 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+# include <shared/src/internal/interactive_scene.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ interactiveScene::interactiveScene(QObject * parent)
+ : QGraphicsScene(parent), mouse_moved_(false)
+ {
+ }
+
+
+ void interactiveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
+ {
+ super_::mouseMoveEvent(e);
+
+ if (e->buttons() & Qt::LeftButton)
+ {
+ emit mouse_pressed(e->scenePos());
+ mouse_moved_ = true;
+ }
+
+ emit mouse_moved(e->scenePos());
+ }
+
+ void interactiveScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
+ {
+ super_::mousePressEvent(e);
+
+ mouse_moved_ = false;
+ pressed_point_ = e->scenePos();
+
+ emit mouse_pressed(e->scenePos());
+ }
+
+ void interactiveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
+ {
+ super_::mouseReleaseEvent(e);
+
+ if (!mouse_moved_)
+ emit mouse_click(e->scenePos());
+
+ emit mouse_released(e->scenePos());
+
+ e->accept();
+ }
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/scribo/demo/shared/src/internal/interactive_scene.hh
b/scribo/demo/shared/src/internal/interactive_scene.hh
new file mode 100644
index 0000000..ba9e9e4
--- /dev/null
+++ b/scribo/demo/shared/src/internal/interactive_scene.hh
@@ -0,0 +1,84 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+# define SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+
+# include <QtGui/QGraphicsScene>
+# include <QtGui/QGraphicsSceneMouseEvent>
+# include <QtGui/QGraphicsLineItem>
+# include <QtCore/QPoint>
+# include <QtCore/QDebug>
+
+# include <shared/src/internal/selection_rectangle.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ class interactiveScene : public QGraphicsScene
+ {
+ Q_OBJECT;
+
+ typedef QGraphicsScene super_;
+
+ public:
+
+ interactiveScene(QObject * parent = 0);
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *e);
+ void mousePressEvent(QGraphicsSceneMouseEvent *e);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
+
+ signals:
+ void mouse_click(const QPointF& p);
+ void mouse_moved(const QPointF& p);
+ void mouse_pressed(const QPointF& p);
+ void mouse_released(const QPointF& p);
+
+ private:
+ QPointF pressed_point_;
+
+ bool mouse_moved_;
+ };
+
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_INTERNAL_INTERACTIVE_SCENE_HH
diff --git a/scribo/demo/shared/src/internal/selection_rectangle.cc
b/scribo/demo/shared/src/internal/selection_rectangle.cc
new file mode 100644
index 0000000..d3f82b7
--- /dev/null
+++ b/scribo/demo/shared/src/internal/selection_rectangle.cc
@@ -0,0 +1,241 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <QtGui>
+#include <shared/src/internal/selection_rectangle.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ selection_rectangle::selection_rectangle()
+ {
+ QPen pen;
+ pen.setColor(QColor(Qt::red));
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidth(1);
+
+
+ rects_.resize(9);
+ for (int i = 0; i < rects_.size(); ++i)
+ {
+ rects_[i] = new QGraphicsRectItem(this);
+ rects_[i]->setZValue(1);
+ rects_[i]->setPen(pen);
+ rects_[i]->show();
+ rects_[i]->setAcceptHoverEvents(true);
+ }
+
+ rects_[1]->setCursor(Qt::SizeFDiagCursor);
+ rects_[2]->setCursor(Qt::SizeVerCursor);
+ rects_[3]->setCursor(Qt::SizeBDiagCursor);
+ rects_[4]->setCursor(Qt::SizeHorCursor);
+ rects_[5]->setCursor(Qt::SizeHorCursor);
+ rects_[6]->setCursor(Qt::SizeBDiagCursor);
+ rects_[7]->setCursor(Qt::SizeVerCursor);
+ rects_[8]->setCursor(Qt::SizeFDiagCursor);
+
+// setHandlesChildEvents(true);
+ setCursor(Qt::SizeAllCursor);
+ setAcceptHoverEvents(true);
+ }
+
+
+ selection_rectangle::~selection_rectangle()
+ {
+ foreach(QGraphicsRectItem *item, rects_)
+ delete item;
+ }
+
+
+ void selection_rectangle::paint(QPainter *painter,
+ const QStyleOptionGraphicsItem *option,
+ QWidget *widget)
+ {
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+
+ qreal border = 15;
+ qreal corner_width = qMin(qAbs(1/8.f * brect_.width()), border);
+ qreal corner_height = qMin(qAbs(1/8.f * brect_.height()), border);
+
+ painter->setBrush(QColor(255, 255, 255, 127));
+ painter->drawRect(brect_);
+
+ // Rectangle 1
+ QRectF rect1(brect_.topLeft().x(), brect_.topLeft().y(),
+ corner_width,
+ corner_height);
+ rects_[1]->setRect(rect1);
+
+ // Rectangle 2
+ QRectF rect2(rect1.topRight().x(), rect1.topRight().y(),
+ brect_.width() - 2 * corner_width,
+ corner_height);
+ rects_[2]->setRect(rect2);
+
+ // Rectangle 3
+ QRectF rect3(brect_.topRight().x() - corner_width,
+ brect_.topRight().y(),
+ corner_width,
+ corner_height);
+ rects_[3]->setRect(rect3);
+
+
+
+ // Rectangle 4
+ QRectF rect4(brect_.topLeft().x(),
+ brect_.topLeft().y() + corner_height,
+ corner_width,
+ brect_.height() - corner_height);
+ rects_[4]->setRect(rect4);
+
+ // Rectangle 5
+ QRectF rect5(brect_.topRight().x() - corner_width,
+ brect_.topRight().y() + corner_height,
+ corner_width,
+ brect_.height() - corner_height);
+ rects_[5]->setRect(rect5);
+
+
+
+ // Rectangle 6
+ QRectF rect6(brect_.bottomLeft().x(),
+ brect_.bottomLeft().y() - corner_height,
+ corner_width,
+ corner_height);
+ rects_[6]->setRect(rect6);
+
+ // Rectangle 7
+ QRectF rect7(rect6.topRight().x(), rect6.topRight().y(),
+ brect_.width() - 2 * corner_width,
+ corner_height);
+ rects_[7]->setRect(rect7);
+
+ // Rectangle 8
+ QRectF rect8(rect7.topRight().x(), rect7.topRight().y(),
+ corner_width,
+ corner_height);
+ rects_[8]->setRect(rect8);
+
+
+ painter->setPen(pen());
+ painter->drawRect(brect_);
+ }
+
+
+ QRectF selection_rectangle::boundingRect() const
+ {
+ qreal penWidth = pen().width();
+ return QRectF(brect_.x() - penWidth / 2, brect_.y() - penWidth / 2,
+ brect_.width() + penWidth / 2,
+ brect_.height() + penWidth / 2);
+ }
+
+
+ void selection_rectangle::setRect(qreal x, qreal y,
+ qreal width, qreal height)
+ {
+ prepareGeometryChange();
+ brect_ = QRectF(x, y, width, height).normalized();
+ }
+
+
+ void selection_rectangle::setRect(const QRectF & rectangle)
+ {
+ prepareGeometryChange();
+ brect_ = rectangle.normalized();
+ }
+
+
+ void selection_rectangle::update_size(QGraphicsItem *item,
+ const QPointF& p)
+ {
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+ QPointF p_ = p;
+
+ prepareGeometryChange();
+ if (rects_[1] == item)
+ brect_.setTopLeft(p_);
+ else if (rects_[2] == item)
+ brect_.setTop(p_.y());
+ else if (rects_[3] == item)
+ brect_.setTopRight(p_);
+ else if (rects_[4] == item)
+ brect_.setLeft(p_.x());
+ else if (rects_[5] == item)
+ brect_.setRight(p_.x());
+ else if (rects_[6] == item)
+ brect_.setBottomLeft(p_);
+ else if (rects_[7] == item)
+ brect_.setBottom(p_.y());
+ else if (rects_[8] == item)
+ brect_.setBottomRight(p_);
+ else
+ qDebug() << "selection_rectangle::update_size - invalid item";
+
+ brect_ = brect_.normalized();
+ }
+
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/scribo/demo/shared/src/internal/selection_rectangle.hh
b/scribo/demo/shared/src/internal/selection_rectangle.hh
new file mode 100644
index 0000000..b58bad2
--- /dev/null
+++ b/scribo/demo/shared/src/internal/selection_rectangle.hh
@@ -0,0 +1,91 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
+# define SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
+
+# include <QtCore>
+# include <QtGui>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ namespace internal
+ {
+
+ class selection_rectangle : public QAbstractGraphicsShapeItem
+ {
+
+ public:
+ selection_rectangle();
+ ~selection_rectangle();
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget);
+
+ QRectF boundingRect() const;
+
+ void setRect(qreal x, qreal y, qreal width, qreal height);
+ void setRect(const QRectF & rectangle);
+
+ void update_size(QGraphicsItem *item, const QPointF& p);
+
+ private: // members
+
+
+ private: // attributes
+ /*
+ --------------
+ |1| 2 |3|
+ |--========--|
+ | || || |
+ | || || |
+ |4|| ||5|
+ | || || |
+ | || || |
+ |--========--|
+ |6| 7 |8|
+ --------------
+ */
+ QVector<QGraphicsRectItem *> rects_;
+ QRectF brect_;
+
+ };
+
+ } // end of namespace mln::demo::shared::internal
+
+ } // end of namespace mln::demo::shared
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_INTERNAL_SELECTION_RECTANGLE_HH
diff --git a/scribo/demo/shared/src/to_mln_image.hh
b/scribo/demo/shared/src/to_mln_image.hh
new file mode 100644
index 0000000..229f975
--- /dev/null
+++ b/scribo/demo/shared/src/to_mln_image.hh
@@ -0,0 +1,77 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_TO_MLN_IMAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_TO_MLN_IMAGE_HH
+
+# include <QImage>
+# include <QPoint>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/qt/rgb32.hh>
+# include <mln/make/box2d.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+ using namespace mln;
+
+ image2d<value::qt::rgb32>
+ to_mln_image(const QImage& ima, const QPoint& origin)
+ {
+ trace::entering("scribo::demo::shared");
+
+ mln_assertion(!ima.isNull());
+
+ image2d<value::qt::rgb32>
+ output(make::box2d(origin.y(),
+ origin.x(),
+ origin.y() + ima.height() - 1,
+ origin.x() + ima.width() - 1), 0);
+
+ memcpy(output.buffer(), ima.bits(), ima.numBytes());
+
+ mln_assertion(output.nrows() == (unsigned) ima.height());
+ mln_assertion(output.ncols() == (unsigned) ima.width());
+
+ trace::exiting("scribo::demo::shared");
+ return output;
+ }
+
+
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_TO_MLN_IMAGE_HH
diff --git a/scribo/demo/shared/src/types.hh b/scribo/demo/shared/src/types.hh
new file mode 100644
index 0000000..8edb54a
--- /dev/null
+++ b/scribo/demo/shared/src/types.hh
@@ -0,0 +1,50 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_TYPES_HH
+# define SCRIBO_DEMO_SHARED_SRC_TYPES_HH
+
+
+# include <mln/value/qt/rgb32.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace shared
+ {
+
+ typedef mln::value::qt::rgb32 dsp_data_t;
+
+ } // end of namespace scribo::demo::shared
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_TYPES_HH
diff --git a/scribo/demo/shared/ui/browse_widget.ui
b/scribo/demo/shared/ui/browse_widget.ui
new file mode 100644
index 0000000..fde675c
--- /dev/null
+++ b/scribo/demo/shared/ui/browse_widget.ui
@@ -0,0 +1,106 @@
+<ui version="4.0" >
+ <class>BrowseWidget</class>
+ <widget class="QWidget" name="BrowseWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>301</width>
+ <height>104</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2" >
+ <property name="sizeConstraint" >
+ <enum>QLayout::SetMaximumSize</enum>
+ </property>
+ <item row="0" column="1" >
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <layout class="QGridLayout" name="gridLayout" >
+ <property name="sizeConstraint" >
+ <enum>QLayout::SetMaximumSize</enum>
+ </property>
+ <item row="0" column="0" colspan="2" >
+ <widget class="QLabel" name="description_" >
+ <property name="text" >
+ <string>Description</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLineEdit" name="path_" />
+ </item>
+ <item row="1" column="1" >
+ <widget class="QPushButton" name="browseBtn_" >
+ <property name="text" >
+ <string>&Browse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="2" >
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/shared/ui/crop_widget.ui b/scribo/demo/shared/ui/crop_widget.ui
new file mode 100644
index 0000000..6b67b2b
--- /dev/null
+++ b/scribo/demo/shared/ui/crop_widget.ui
@@ -0,0 +1,34 @@
+<ui version="4.0" >
+ <class>CropWidget</class>
+ <widget class="QWidget" name="CropWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>567</width>
+ <height>481</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="scribo::demo::shared::image_viewer" native="1"
name="viewer_" />
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>scribo::demo::shared::image_viewer</class>
+ <extends>QWidget</extends>
+ <header location="global" >shared/src/image_viewer.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/shared/ui/image_viewer.ui
b/scribo/demo/shared/ui/image_viewer.ui
new file mode 100644
index 0000000..d6f80cb
--- /dev/null
+++ b/scribo/demo/shared/ui/image_viewer.ui
@@ -0,0 +1,284 @@
+<ui version="4.0" >
+ <class>ImageViewer</class>
+ <widget class="QWidget" name="ImageViewer" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>464</width>
+ <height>350</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="rotate_lbl" >
+ <property name="text" >
+ <string>Rotate:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rotate_cw_btn" >
+ <property name="toolTip" >
+ <string>Rotate clock-wise</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="../shared.qrc" >
+
<normaloff>:/icons/icons/rotate_cw.png</normaloff>:/icons/icons/rotate_cw.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rotate_ccw_btn" >
+ <property name="toolTip" >
+ <string>Rotate counter-clock-wise</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="../shared.qrc" >
+
<normaloff>:/icons/icons/rotate_ccw.png</normaloff>:/icons/icons/rotate_ccw.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="vline" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="zoomLabel" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Zoom:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomIn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="../shared.qrc" >
+
<normaloff>:/icons/icons/search-add-icon.png</normaloff>:/icons/icons/search-add-icon.png</iconset>
+ </property>
+ <property name="shortcut" >
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomOut" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="icon" >
+ <iconset resource="../shared.qrc" >
+
<normaloff>:/icons/icons/search-remove-icon.png</normaloff>:/icons/icons/search-remove-icon.png</iconset>
+ </property>
+ <property name="iconSize" >
+ <size>
+ <width>16</width>
+ <height>16</height>
+ </size>
+ </property>
+ <property name="shortcut" >
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomFixed" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>&Fit to screen</string>
+ </property>
+ <property name="shortcut" >
+ <string>F</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="zoomOriginal" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>&Original size</string>
+ </property>
+ <property name="shortcut" >
+ <string>O</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGraphicsView" name="viewer_" >
+ <property name="mouseTracking" >
+ <bool>true</bool>
+ </property>
+ <property name="acceptDrops" >
+ <bool>false</bool>
+ </property>
+ <property name="interactive" >
+ <bool>true</bool>
+ </property>
+ <property name="renderHints" >
+ <set>QPainter::Antialiasing</set>
+ </property>
+ <property name="dragMode" >
+ <enum>QGraphicsView::NoDrag</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QSlider" name="slider" >
+ <property name="focusPolicy" >
+ <enum>Qt::WheelFocus</enum>
+ </property>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition" >
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred"
>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Current Frame :</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="frame_nb" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum"
>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize" >
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>0</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../shared.qrc" />
+ </resources>
+ <connections/>
+</ui>
diff --git a/scribo/demo/shared/ui/interactive_scene.cc
b/scribo/demo/shared/ui/interactive_scene.cc
new file mode 100644
index 0000000..1ab28a3
--- /dev/null
+++ b/scribo/demo/shared/ui/interactive_scene.cc
@@ -0,0 +1,143 @@
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+# include <src/internal/interactive_scene.hh>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ namespace internal
+ {
+
+ interactiveScene::interactiveScene(QObject * parent)
+ : QGraphicsScene(parent), selectionTracking_(false)
+ {
+// line_.setZValue(1);
+ rect_.setZValue(1);
+
+ QPen pen;
+ pen.setColor(QColor(Qt::red));
+ pen.setStyle(Qt::SolidLine);
+ pen.setWidth(1);
+
+// line_.setPen(pen);
+ rect_.setPen(pen);
+ }
+
+
+ void interactiveScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
+ {
+ if (selectionTracking_ && mouse_pressed_)
+ rect_.setRect(QRectF(p_start_, e->scenePos()));
+// line_.setLine(QLineF(p_start_, e->scenePos()));
+
+ mouse_moved_ = true;
+
+ if (mouse_pressed_)
+ emit mouse_pressed(e->scenePos());
+
+ emit mouse_moved(e->scenePos());
+
+ e->accept();
+ }
+
+ void interactiveScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
+ {
+ p_start_ = e->scenePos();
+ mouse_moved_ = false;
+ mouse_pressed_ = true;
+
+ if (selectionTracking_)
+ {
+// line_.setLine(QLineF(e->scenePos(), e->scenePos()));
+// addItem(&line_);
+ rect_.setRect(QRectF(e->scenePos(), e->scenePos()));
+ if (rect_.scene() != this)
+ addItem(&rect_);
+ }
+
+ emit mouse_pressed(e->scenePos());
+
+ e->accept();
+ }
+
+ void interactiveScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
+ {
+// if (selectionTracking_ && line_.scene() == this)
+// removeItem(&line_);
+
+ mouse_pressed_ = false;
+
+ if (mouse_moved_ && selectionTracking_)
+ emit new_selection(rect_.rect());
+ else
+ {
+ if (rect_.scene() == this)
+ {
+ rect_.setRect(sceneRect());
+ removeItem(&rect_);
+ emit selection_cleared();
+ }
+
+ emit mouse_click(e->scenePos());
+ }
+
+ emit mouse_released(e->scenePos());
+
+ e->ignore();
+ }
+
+
+ void interactiveScene::setSelectionTracking(bool b)
+ {
+ selectionTracking_ = b;
+ }
+
+ bool interactiveScene::has_selection() const
+ {
+ return rect_.scene() == this;
+ }
+
+ QRectF interactiveScene::selection() const
+ {
+ return rect_.rect();
+ }
+
+ void interactiveScene::clear_selection()
+ {
+ if (rect_.scene() == this)
+ removeItem(&rect_);
+ }
+
+
+ } // end of namespace mln::demo::internal
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
diff --git a/scribo/demo/shared/ui/interactive_scene.hh
b/scribo/demo/shared/ui/interactive_scene.hh
new file mode 100644
index 0000000..b5d5595
--- /dev/null
+++ b/scribo/demo/shared/ui/interactive_scene.hh
@@ -0,0 +1,87 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+# define MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
+
+# include <QtGui/QGraphicsScene>
+# include <QtGui/QGraphicsSceneMouseEvent>
+# include <QtGui/QGraphicsLineItem>
+# include <QtCore/QPoint>
+# include <QtCore/QDebug>
+
+namespace mln
+{
+
+ namespace demo
+ {
+
+ namespace internal
+ {
+
+ class interactiveScene : public QGraphicsScene
+ {
+ Q_OBJECT
+
+ public:
+
+ interactiveScene(QObject * parent = 0);
+
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *e);
+ void mousePressEvent(QGraphicsSceneMouseEvent *e);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
+
+ void setSelectionTracking(bool b);
+
+ bool has_selection() const;
+ QRectF selection() const;
+ void clear_selection();
+
+ signals:
+ void mouse_click(const QPointF& p);
+ void mouse_moved(const QPointF& p);
+ void mouse_pressed(const QPointF& p);
+ void mouse_released(const QPointF& p);
+
+ void new_selection(const QRectF& rect);
+ void selection_cleared();
+
+ private:
+ QGraphicsRectItem rect_;
+ bool mouse_moved_;
+ bool mouse_pressed_;
+ QPointF p_start_;
+
+ bool selectionTracking_;
+ };
+
+
+ } // end of namespace mln::demo::internal
+
+ } // end of namespace mln::demo
+
+} // end of namespace mln
+
+#endif // ! MLN_DEMO_SRC_INTERNAL_INTERACTIVE_SCENE_HH
diff --git a/scribo/demo/shared/ui/rotate_widget.ui
b/scribo/demo/shared/ui/rotate_widget.ui
new file mode 100644
index 0000000..112e713
--- /dev/null
+++ b/scribo/demo/shared/ui/rotate_widget.ui
@@ -0,0 +1,34 @@
+<ui version="4.0" >
+ <class>RotateWidget</class>
+ <widget class="QWidget" name="RotateWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>567</width>
+ <height>481</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="scribo::demo::shared::image_viewer" native="1"
name="viewer_" />
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>scribo::demo::shared::image_viewer</class>
+ <extends>QWidget</extends>
+ <header location="global" >shared/src/image_viewer.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/wizard/images/dematerialization.png
b/scribo/demo/wizard/images/dematerialization.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcae3c439f77122e055fb3b14b8fd98325092393
GIT binary patch
literal 76309
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%0DmTeuj
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
M07*qoM6N<$f;Ivho&W#<
literal 0
HcmV?d00001
diff --git a/scribo/demo/wizard/src/crop_page.cc b/scribo/demo/wizard/src/crop_page.cc
new file mode 100644
index 0000000..ea3ca71
--- /dev/null
+++ b/scribo/demo/wizard/src/crop_page.cc
@@ -0,0 +1,48 @@
+#include <src/crop_page.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ crop_page::crop_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new crop_widget(this);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setTitle("Region of interest");
+ setSubTitle("Select a region of interest");
+
+ }
+
+
+ void crop_page::cleanupPage()
+ {
+ setField("load.input_dsp",
+ QPixmap(field("load.file_path").toString()));
+
+ }
+
+
+ void crop_page::initializePage()
+ {
+ widget_->load_image(field("load.input_dsp").value<QPixmap>());
+ }
+
+
+ bool crop_page::validatePage()
+ {
+ setField("load.input_dsp", widget_->image());
+ return true;
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/crop_page.hh b/scribo/demo/wizard/src/crop_page.hh
new file mode 100644
index 0000000..9891a7e
--- /dev/null
+++ b/scribo/demo/wizard/src/crop_page.hh
@@ -0,0 +1,60 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_CROP_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_CROP_PAGE_HH
+
+# include <QtGui>
+# include <src/crop_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class crop_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ public:
+ crop_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+ virtual bool validatePage();
+
+ private:
+ crop_widget *widget_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_CROP_PAGE_HH
diff --git a/scribo/demo/wizard/src/crop_widget.cc
b/scribo/demo/wizard/src/crop_widget.cc
new file mode 100644
index 0000000..37a9e80
--- /dev/null
+++ b/scribo/demo/wizard/src/crop_widget.cc
@@ -0,0 +1,37 @@
+#include <src/crop_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ crop_widget::crop_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+ }
+
+
+ void crop_widget::load_image(const QPixmap& pixmap)
+ {
+ viewer_->draw_image(pixmap);
+ viewer_->set_selection_enabled(true);
+ }
+
+
+ const QRectF& crop_widget::crop_area() const
+ {
+ return viewer_->selection();
+ }
+
+
+ QPixmap crop_widget::image() const
+ {
+ return viewer_->image().copy(crop_area().toRect());
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/crop_widget.hh
b/scribo/demo/wizard/src/crop_widget.hh
new file mode 100644
index 0000000..8d1f80b
--- /dev/null
+++ b/scribo/demo/wizard/src/crop_widget.hh
@@ -0,0 +1,62 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_CROP_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_CROP_WIDGET_HH
+
+# include <QtGui>
+# include <ui_crop_widget.h>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class crop_widget : public QWidget, private Ui::CropWidget
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(QRectF crop_area READ crop_area);
+
+ public:
+ crop_widget(QWidget *parent = 0);
+
+ void load_image(const QPixmap& pixmap);
+
+ const QRectF& crop_area() const;
+
+ QPixmap image() const;
+
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_CROP_WIDGET_HH
diff --git a/scribo/demo/wizard/src/doc_type.hh b/scribo/demo/wizard/src/doc_type.hh
new file mode 100644
index 0000000..320cd19
--- /dev/null
+++ b/scribo/demo/wizard/src/doc_type.hh
@@ -0,0 +1,51 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_HH
+# define SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_HH
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ enum Doc_Type
+ {
+ Text_Doc,
+ Picture,
+ Mixed_Doc,
+
+ Invalid_Doc
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_HH
diff --git a/scribo/demo/wizard/src/doc_type_page.cc
b/scribo/demo/wizard/src/doc_type_page.cc
new file mode 100644
index 0000000..7245569
--- /dev/null
+++ b/scribo/demo/wizard/src/doc_type_page.cc
@@ -0,0 +1,48 @@
+#include <src/doc_type_page.hh>
+#include <src/doc_type_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ doc_type_page::doc_type_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new doc_type_widget(this);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setSubTitle("Please choose the document type.");
+ setTitle("Document type");
+
+ registerField("doc_type.type_mixed_doc", widget_,
"type_mixed_doc", SIGNAL(toggled(bool)));
+ registerField("doc_type.type_picture", widget_, "type_picture",
SIGNAL(toggled(bool)));
+ registerField("doc_type.type_text_doc", widget_,
"type_text_doc", SIGNAL(toggled(bool)));
+ }
+
+
+ void doc_type_page::cleanupPage()
+ {
+ widget_->reset();
+ }
+
+
+ void doc_type_page::initializePage()
+ {
+ }
+
+
+ bool doc_type_page::isComplete()
+ {
+ return true;
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/doc_type_page.hh
b/scribo/demo/wizard/src/doc_type_page.hh
new file mode 100644
index 0000000..f0d751b
--- /dev/null
+++ b/scribo/demo/wizard/src/doc_type_page.hh
@@ -0,0 +1,61 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_PAGE_HH
+
+# include <QtGui>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ // Forward declaration.
+ class doc_type_widget;
+
+ class doc_type_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ public:
+ doc_type_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+ virtual bool isComplete();
+
+ private:
+ doc_type_widget *widget_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_PAGE_HH
diff --git a/scribo/demo/wizard/src/doc_type_widget.cc
b/scribo/demo/wizard/src/doc_type_widget.cc
new file mode 100644
index 0000000..c8453d4
--- /dev/null
+++ b/scribo/demo/wizard/src/doc_type_widget.cc
@@ -0,0 +1,38 @@
+#include <src/doc_type_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ doc_type_widget::doc_type_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+ }
+
+ void doc_type_widget::reset()
+ {
+ type_text_doc_->setChecked(true);
+ }
+
+ bool doc_type_widget::type_mixed_doc() const
+ {
+ return type_mixed_doc_->isChecked();
+ }
+
+ bool doc_type_widget::type_picture() const
+ {
+ return type_picture_->isChecked();
+ }
+
+ bool doc_type_widget::type_text_doc() const
+ {
+ return type_text_doc_->isChecked();
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/doc_type_widget.hh
b/scribo/demo/wizard/src/doc_type_widget.hh
new file mode 100644
index 0000000..ccd5324
--- /dev/null
+++ b/scribo/demo/wizard/src/doc_type_widget.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_WIDGET_HH
+
+# include <QtGui>
+# include <ui_doc_type_widget.h>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class doc_type_widget : public QWidget, private Ui::DocTypeWidget
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(bool type_mixed_doc READ type_mixed_doc);
+ Q_PROPERTY(bool type_picture READ type_picture);
+ Q_PROPERTY(bool type_text_doc READ type_text_doc);
+
+ public:
+ doc_type_widget(QWidget *parent = 0);
+
+ void reset();
+
+ bool type_mixed_doc() const;
+ bool type_picture() const;
+ bool type_text_doc() const;
+
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_DOC_TYPE_WIDGET_HH
diff --git a/scribo/demo/wizard/src/load_page.cc b/scribo/demo/wizard/src/load_page.cc
new file mode 100644
index 0000000..2d9ed43
--- /dev/null
+++ b/scribo/demo/wizard/src/load_page.cc
@@ -0,0 +1,70 @@
+#include <src/load_page.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ load_page::load_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new load_widget(this);
+
+ QStringList filters;
+ filters << tr("PNG image (*.png)")
+ << tr("JPEG image (*.jpg *.jpeg *.jpe)")
+ << tr("PNM image (*.pnm *.pbm *.pgm *.ppm)");
+ widget_->setDialogFilter(filters);
+
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setSubTitle("Choose a file to load");
+ setTitle("Image loading");
+
+ registerField("load.file_path*", widget_,
+ "path", SIGNAL(path_updated()));
+
+ registerField("load.must_crop", widget_, "must_crop");
+ registerField("load.must_rotate", widget_, "must_rotate");
+
+ registerField("load.input_dsp", this, "input_dsp");
+
+ }
+
+
+ void load_page::cleanupPage()
+ {
+ widget_->reset();
+ }
+
+
+ void load_page::initializePage()
+ {
+ }
+
+
+ bool load_page::validatePage()
+ {
+ input_dsp_ = QPixmap(widget_->path());
+ return true;
+ }
+
+
+ const QPixmap& load_page::input_dsp() const
+ {
+ return input_dsp_;
+ }
+
+ void load_page::set_input_dsp(const QPixmap& pixmap)
+ {
+ input_dsp_ = pixmap;
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/load_page.hh b/scribo/demo/wizard/src/load_page.hh
new file mode 100644
index 0000000..f3b5ec8
--- /dev/null
+++ b/scribo/demo/wizard/src/load_page.hh
@@ -0,0 +1,67 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_LOAD_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_LOAD_PAGE_HH
+
+# include <QtGui>
+# include <src/load_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class load_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(QPixmap input_dsp READ input_dsp WRITE set_input_dsp);
+
+ public:
+ load_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+ virtual bool validatePage();
+// virtual bool isComplete();
+
+ const QPixmap& input_dsp() const;
+ void set_input_dsp(const QPixmap& pixmap);
+
+ private:
+ load_widget *widget_;
+ QPixmap input_dsp_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_LOAD_PAGE_HH
diff --git a/scribo/demo/wizard/src/load_widget.cc
b/scribo/demo/wizard/src/load_widget.cc
new file mode 100644
index 0000000..1f327af
--- /dev/null
+++ b/scribo/demo/wizard/src/load_widget.cc
@@ -0,0 +1,56 @@
+#include <src/load_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ load_widget::load_widget(QWidget *parent)
+ : browse_widget(parent)
+ {
+ QGroupBox *group_box = new QGroupBox(tr("Options"), this);
+
+ QVBoxLayout *layout = new QVBoxLayout(group_box);
+ layout->setSizeConstraint(QLayout::SetMaximumSize);
+ must_crop_ = new QCheckBox(tr("Select a region of interest"),
+ group_box);
+ must_rotate_ = new QCheckBox(tr("Perform a manual rotation"),
+ group_box);
+
+ layout->addWidget(must_crop_);
+ layout->addWidget(must_rotate_);
+
+
+ QSpacerItem*
+ vspacer = new QSpacerItem(20, 40, QSizePolicy::Minimum,
+ QSizePolicy::Expanding);
+
+ gridLayout_2->addWidget(group_box, 2, 1);
+ gridLayout_2->addItem(vspacer, 3, 1, 1, 1);
+
+ gridLayout_2->setSizeConstraint(QLayout::SetMaximumSize);
+ }
+
+ void load_widget::reset()
+ {
+ browse_widget::reset();
+ must_crop_->setChecked(false);
+ must_rotate_->setChecked(false);
+ }
+
+ bool load_widget::must_crop() const
+ {
+ return must_crop_->isChecked();
+ }
+
+ bool load_widget::must_rotate() const
+ {
+ return must_rotate_->isChecked();
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/load_widget.hh
b/scribo/demo/wizard/src/load_widget.hh
new file mode 100644
index 0000000..d7cf4e5
--- /dev/null
+++ b/scribo/demo/wizard/src/load_widget.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_LOAD_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_LOAD_WIDGET_HH
+
+# include <QtGui>
+# include <shared/src/browse_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class load_widget : public shared::browse_widget
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(bool must_crop READ must_crop);
+ Q_PROPERTY(bool must_rotate READ must_rotate);
+
+ public:
+ load_widget(QWidget *parent = 0);
+ void reset();
+
+ bool must_crop() const;
+ bool must_rotate() const;
+
+ private: // attributes.
+ QCheckBox *must_crop_;
+ QCheckBox *must_rotate_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_LOAD_WIDGET_HH
diff --git a/scribo/demo/wizard/src/main.cc b/scribo/demo/wizard/src/main.cc
new file mode 100644
index 0000000..12f024a
--- /dev/null
+++ b/scribo/demo/wizard/src/main.cc
@@ -0,0 +1,15 @@
+#include <QtGui>
+#include <src/main_window.hh>
+#include <src/preprocessing_task.hh>
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+
qRegisterMetaType<preprocessing_task_set_t>("preprocessing_task_set_t");
+
+ scribo::demo::wizard::main_window win;
+ win.show();
+
+ return app.exec();
+}
diff --git a/scribo/demo/wizard/src/main_window.cc
b/scribo/demo/wizard/src/main_window.cc
new file mode 100644
index 0000000..35aa8c7
--- /dev/null
+++ b/scribo/demo/wizard/src/main_window.cc
@@ -0,0 +1,129 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#include <src/main_window.hh>
+
+#include <src/load_page.hh>
+#include <src/doc_type_page.hh>
+#include <src/crop_page.hh>
+#include <src/preprocessing_page.hh>
+#include <src/process_page.hh>
+#include <src/rotate_page.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace wizard
+ {
+
+
+ main_window::main_window()
+ {
+ setOptions(QWizard::NoBackButtonOnStartPage
+ | QWizard::DisabledBackButtonOnLastPage
+ | QWizard::NoCancelButton);
+
+ QPixmap bg_pixmap(":/images/images/dematerialization.png");
+ setPixmap(QWizard::WatermarkPixmap, bg_pixmap);
+ setPixmap(QWizard::BackgroundPixmap, bg_pixmap);
+
+
+ // Page_Load
+ load_page* page_load = new load_page(this);
+ addPage(page_load);
+
+ // Page_Task
+ doc_type_page* page_doc_type = new doc_type_page(this);
+ addPage(page_doc_type);
+
+ // Page_Crop
+ crop_page* page_crop = new crop_page(this);
+ addPage(page_crop);
+
+ // Page_Crop
+ rotate_page* page_rotate = new rotate_page(this);
+ addPage(page_rotate);
+
+ // Page_Preprocessing
+ preprocessing_page*
+ page_preprocessing = new preprocessing_page(this);
+ addPage(page_preprocessing);
+
+ // Page_Processing
+ addPage(new process_page(this));
+
+ // Page_Result
+ addPage(new QWizardPage(this));
+ }
+
+
+ int main_window::nextId() const
+ {
+ switch (currentId())
+ {
+ case Page_Load:
+ if (field("load.must_crop").toBool())
+ return Page_Crop;
+ else if (field("load.must_rotate").toBool())
+ return Page_Rotate;
+ else
+ return Page_Task;
+
+ case Page_Crop:
+ if (field("load.must_rotate").toBool())
+ return Page_Rotate;
+ else
+ return Page_Task;
+
+ case Page_Rotate:
+ return Page_Task;
+
+ case Page_Task:
+ return Page_Preprocessing;
+
+ case Page_Preprocessing:
+ return Page_Process;
+
+ case Page_Process:
+ return Page_Result;
+
+ case Page_Result:
+ return -1;
+
+ default:
+ qDebug() << "Warning: using default nextId() case.";
+ return currentId() + 1;
+ }
+ }
+
+
+ } // end of namespace scribo::demo::wizard
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/main_window.hh
b/scribo/demo/wizard/src/main_window.hh
new file mode 100644
index 0000000..af4c113
--- /dev/null
+++ b/scribo/demo/wizard/src/main_window.hh
@@ -0,0 +1,70 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_WIZARD_SRC_MAIN_WINDOW_HH
+# define SCRIBO_DEMO_WIZARD_SRC_MAIN_WINDOW_HH
+
+# include <QtGui/QWizard>
+//# include <ui_main_window.h>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace wizard
+ {
+
+
+ class main_window : public QWizard
+ {
+ Q_OBJECT;
+
+ public:
+ main_window();
+
+ virtual int nextId() const;
+
+
+ private:
+ enum { Page_Load,
+ Page_Task,
+ Page_Crop,
+ Page_Rotate,
+ Page_Preprocessing,
+ Page_Process,
+ Page_Result };
+ };
+
+
+ } // end of namespace scribo::demo::wizard
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_WIZARD_SRC_MAIN_WINDOW_HH
diff --git a/scribo/demo/wizard/src/mln_widgets.cc
b/scribo/demo/wizard/src/mln_widgets.cc
new file mode 100644
index 0000000..621cc6f
--- /dev/null
+++ b/scribo/demo/wizard/src/mln_widgets.cc
@@ -0,0 +1,7 @@
+#undef MLN_INCLUDE_ONLY
+
+// Widgets
+#include <shared/src/image_viewer.cc>
+
+// Misc
+#include <src/runner.cc>
diff --git a/scribo/demo/wizard/src/preprocessing_page.cc
b/scribo/demo/wizard/src/preprocessing_page.cc
new file mode 100644
index 0000000..f727581
--- /dev/null
+++ b/scribo/demo/wizard/src/preprocessing_page.cc
@@ -0,0 +1,61 @@
+#include <src/preprocessing_page.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ preprocessing_page::preprocessing_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new preprocessing_widget(this);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setTitle("Preprocessing tasks");
+ setSubTitle("Choose preprocessing algorithms.");
+
+ registerField("preprocessing.tasks", this, "tasks");
+ }
+
+
+ void preprocessing_page::cleanupPage()
+ {
+ widget_->reset();
+ }
+
+
+ void preprocessing_page::initializePage()
+ {
+ if (field("doc_type.type_text_doc").toBool())
+ widget_->setup_text_doc();
+ else if (field("doc_type.type_mixed_doc").toBool())
+ widget_->setup_mixed_doc();
+ else if (field("doc_type.type_picture").toBool())
+ widget_->setup_picture();
+ else
+ qDebug() << "preprocessing_page - initializePage - invalid document
type";
+ }
+
+
+ const preprocessing_task_set_t& preprocessing_page::tasks() const
+ {
+ return tasks_;
+ }
+
+
+ bool preprocessing_page::validatePage()
+ {
+ tasks_ = widget_->tasks();
+ return true;
+ }
+
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/preprocessing_page.hh
b/scribo/demo/wizard/src/preprocessing_page.hh
new file mode 100644
index 0000000..1cfbea9
--- /dev/null
+++ b/scribo/demo/wizard/src/preprocessing_page.hh
@@ -0,0 +1,66 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_PAGE_HH
+
+# include <QtGui>
+# include <src/preprocessing_widget.hh>
+# include <src/preprocessing_task.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class preprocessing_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(preprocessing_task_set_t tasks READ tasks);
+
+ public:
+ preprocessing_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+ virtual bool validatePage();
+
+ const preprocessing_task_set_t& tasks() const;
+
+ private:
+ preprocessing_widget *widget_;
+ preprocessing_task_set_t tasks_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_PAGE_HH
diff --git a/scribo/demo/wizard/src/preprocessing_task.hh
b/scribo/demo/wizard/src/preprocessing_task.hh
new file mode 100644
index 0000000..5c335b7
--- /dev/null
+++ b/scribo/demo/wizard/src/preprocessing_task.hh
@@ -0,0 +1,61 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_TASK_HH
+# define SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_TASK_HH
+
+# include <QSet>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ enum Preprocessing_Task
+ {
+ RemoveBg = 0,
+ Unskew,
+ RemoveNoise,
+ ImproveContrast,
+ ReduceSize,
+
+ BinarizationSimple,
+ BinarizationSauvola,
+ BinarizationSauvolaMs,
+
+ PREPROCESSING_TASK_COUNT // Invalid task.
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+typedef QSet<scribo::demo::Preprocessing_Task> preprocessing_task_set_t;
+Q_DECLARE_METATYPE(preprocessing_task_set_t);
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_TASK_HH
diff --git a/scribo/demo/wizard/src/preprocessing_widget.cc
b/scribo/demo/wizard/src/preprocessing_widget.cc
new file mode 100644
index 0000000..7a2c9fa
--- /dev/null
+++ b/scribo/demo/wizard/src/preprocessing_widget.cc
@@ -0,0 +1,87 @@
+#include <src/preprocessing_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ preprocessing_widget::preprocessing_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+ }
+
+ void preprocessing_widget::reset()
+ {
+ binarizationCBox->setCurrentIndex(2); // Sauvola ms
+ clear_checked();
+ }
+
+ void preprocessing_widget::setup_picture()
+ {
+ qDebug() << "setup picture";
+
+ removeBg->setChecked(true);
+ }
+
+ void preprocessing_widget::setup_mixed_doc()
+ {
+ qDebug() << "setup mixed doc";
+ }
+
+ void preprocessing_widget::setup_text_doc()
+ {
+ qDebug() << "setup text doc";
+
+ removeBg->setChecked(true);
+ unskew->setChecked(true);
+ removeNoise->setChecked(true);
+ improveContrast->setChecked(true);
+ }
+
+
+ void preprocessing_widget::clear_checked()
+ {
+ removeBg->setChecked(false);
+ unskew->setChecked(false);
+ removeNoise->setChecked(false);
+ improveContrast->setChecked(false);
+ reduceSize->setChecked(false);
+ }
+
+
+ preprocessing_task_set_t preprocessing_widget::tasks() const
+ {
+ preprocessing_task_set_t tasks;
+
+ if (removeBg->isChecked())
+ tasks.insert(RemoveBg);
+
+ if (unskew->isChecked())
+ tasks.insert(Unskew);
+
+ if (removeNoise->isChecked())
+ tasks.insert(RemoveNoise);
+
+ if (improveContrast->isChecked())
+ tasks.insert(ImproveContrast);
+
+ if (reduceSize->isChecked())
+ tasks.insert(ReduceSize);
+
+ if (binarizationCBox->currentIndex() == 0)
+ tasks.insert(BinarizationSimple);
+ else if (binarizationCBox->currentIndex() == 1)
+ tasks.insert(BinarizationSauvola);
+ else if (binarizationCBox->currentIndex() == 2)
+ tasks.insert(BinarizationSauvolaMs);
+
+ return tasks;
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/preprocessing_widget.hh
b/scribo/demo/wizard/src/preprocessing_widget.hh
new file mode 100644
index 0000000..fff268d
--- /dev/null
+++ b/scribo/demo/wizard/src/preprocessing_widget.hh
@@ -0,0 +1,65 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_WIDGET_HH
+
+# include <QtGui>
+# include <ui_preprocessing_widget.h>
+# include <src/preprocessing_task.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class preprocessing_widget : public QWidget,
+ private Ui::PreprocessingWidget
+ {
+ Q_OBJECT;
+
+ public:
+ preprocessing_widget(QWidget *parent = 0);
+ void reset();
+
+ void setup_picture();
+ void setup_mixed_doc();
+ void setup_text_doc();
+
+ preprocessing_task_set_t tasks() const;
+
+ private: // members
+ void clear_checked();
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_PREPROCESSING_WIDGET_HH
diff --git a/scribo/demo/wizard/src/process_page.cc
b/scribo/demo/wizard/src/process_page.cc
new file mode 100644
index 0000000..bbba0e3
--- /dev/null
+++ b/scribo/demo/wizard/src/process_page.cc
@@ -0,0 +1,73 @@
+#include <src/process_page.hh>
+#include <src/process_widget.hh>
+#include <src/preprocessing_task.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ process_page::process_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new process_widget(this);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setSubTitle("Processing...");
+ setTitle("Please wait while computing results.");
+
+
+ void progress(unsigned i);
+
+ void progress(unsigned i);
+
+ connect(&runner_, SIGNAL(new_intermediate_result(const QImage&)),
+ widget_, SLOT(update_pixmap(const QImage&)));
+
+ connect(&runner_, SIGNAL(new_progress_max_value(unsigned)),
+ widget_, SLOT(set_progress_max_value(unsigned)));
+
+ connect(&runner_, SIGNAL(new_progress_label(const QString&)),
+ widget_, SLOT(update_progress_label(const QString&)));
+
+ connect(&runner_, SIGNAL(progress(unsigned)),
+ widget_, SLOT(progress(unsigned)));
+ }
+
+
+ void process_page::cleanupPage()
+ {
+ widget_->reset();
+ runner_.stop();
+ }
+
+
+ void process_page::initializePage()
+ {
+ runner_.start(field("load.input_dsp").value<QPixmap>().toImage(),
+ get_doc_type(),
+ field("preprocessing.tasks").value<preprocessing_task_set_t>());
+ }
+
+
+ Doc_Type process_page::get_doc_type()
+ {
+ if (field("doc_type.type_text_doc").toBool())
+ return Text_Doc;
+ else if (field("doc_type.type_picture").toBool())
+ return Picture;
+ else if (field("doc_type.type_mixed_doc").toBool())
+ return Mixed_Doc;
+
+ return Invalid_Doc;
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/process_page.hh
b/scribo/demo/wizard/src/process_page.hh
new file mode 100644
index 0000000..6425a53
--- /dev/null
+++ b/scribo/demo/wizard/src/process_page.hh
@@ -0,0 +1,64 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_PROCESS_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_PROCESS_PAGE_HH
+
+# include <QtGui>
+# include <src/process_widget.hh>
+# include <src/runner.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class process_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ public:
+ process_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+
+ private: // members
+ Doc_Type get_doc_type();
+
+ private: // attributes
+ process_widget* widget_;
+ runner runner_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_PROCESS_PAGE_HH
diff --git a/scribo/demo/wizard/src/process_widget.cc
b/scribo/demo/wizard/src/process_widget.cc
new file mode 100644
index 0000000..c0d652f
--- /dev/null
+++ b/scribo/demo/wizard/src/process_widget.cc
@@ -0,0 +1,80 @@
+#include <src/process_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ process_widget::process_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ view_ = new QGraphicsView(this);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(view_);
+ setLayout(layout);
+
+ QVBoxLayout *progress_layout = new QVBoxLayout;
+ progress_bar_ = new QProgressBar(this);
+ progress_bar_->setMinimum(0);
+ progress_label_ = new QLabel("Processing...");
+ progress_layout->addWidget(progress_bar_);
+ progress_layout->addWidget(progress_label_);
+
+ progress_dialog_ = new QWidget();
+ progress_dialog_->setLayout(progress_layout);
+
+ view_->setScene(new QGraphicsScene());
+ progress_ = view_->scene()->addWidget(progress_dialog_);
+ progress_->setZValue(1);
+
+ image_ = view_->scene()->addPixmap(QPixmap());
+ }
+
+ void process_widget::reset()
+ {
+ progress_bar_->show();
+ progress_bar_->setValue(0);
+ progress_bar_->setMaximum(0);
+ image_->setPixmap(QPixmap());
+ }
+
+ void process_widget::set_progress_max_value(unsigned max)
+ {
+ progress_bar_->setMaximum(max);
+ }
+
+ void process_widget::update_pixmap(const QImage& image)
+ {
+ image_->setPixmap(QPixmap::fromImage(image));
+ }
+
+ void process_widget::progress(unsigned i)
+ {
+ progress_bar_->setValue(progress_bar_->value() + i);
+
+ if (progress_bar_->value() == progress_bar_->maximum())
+ progress_->hide();
+ }
+
+ void process_widget::update_progress_label(const QString& msg)
+ {
+ progress_label_->setText(msg);
+ }
+
+ void process_widget::resizeEvent(QResizeEvent* event)
+ {
+ QPoint tmp(view_->geometry().center().x()
+ - progress_->boundingRect().width() / 2,
+ view_->geometry().center().y()
+ - progress_->boundingRect().height() / 2);
+
+ progress_->setPos(view_->mapToScene(tmp));
+
+ event->ignore();
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/process_widget.hh
b/scribo/demo/wizard/src/process_widget.hh
new file mode 100644
index 0000000..8c0ed88
--- /dev/null
+++ b/scribo/demo/wizard/src/process_widget.hh
@@ -0,0 +1,71 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_PROCESS_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_PROCESS_WIDGET_HH
+
+# include <QtGui>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class process_widget : public QWidget
+ {
+ Q_OBJECT;
+
+ public:
+ process_widget(QWidget *parent = 0);
+ void reset();
+
+ public slots:
+ void set_progress_max_value(unsigned max);
+ void update_pixmap(const QImage& image);
+ void progress(unsigned i);
+ void update_progress_label(const QString& msg);
+
+ virtual void resizeEvent(QResizeEvent* event);
+
+ private:
+ QGraphicsView *view_;
+ QGraphicsPixmapItem *image_;
+
+ QLabel *progress_label_;
+ QProgressBar* progress_bar_;
+ QWidget* progress_dialog_;
+
+ QGraphicsProxyWidget* progress_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_PROCESS_WIDGET_HH
diff --git a/scribo/demo/wizard/src/rotate_page.cc
b/scribo/demo/wizard/src/rotate_page.cc
new file mode 100644
index 0000000..9b17a5d
--- /dev/null
+++ b/scribo/demo/wizard/src/rotate_page.cc
@@ -0,0 +1,45 @@
+#include <src/rotate_page.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ rotate_page::rotate_page(QWidget *parent)
+ : QWizardPage(parent)
+ {
+ widget_ = new rotate_widget(this);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(widget_);
+ setLayout(layout);
+
+ setTitle("Rotation.");
+ setSubTitle("Rotate the input image using the buttons above.");
+
+ }
+
+
+ void rotate_page::cleanupPage()
+ {
+ }
+
+
+ void rotate_page::initializePage()
+ {
+ widget_->load_image(field("load.input_dsp").value<QPixmap>());
+ }
+
+
+ bool rotate_page::isComplete()
+ {
+ setField("load.input_dsp", widget_->image());
+ return true;
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/rotate_page.hh
b/scribo/demo/wizard/src/rotate_page.hh
new file mode 100644
index 0000000..21c2074
--- /dev/null
+++ b/scribo/demo/wizard/src/rotate_page.hh
@@ -0,0 +1,60 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_ROTATE_PAGE_HH
+# define SCRIBO_DEMO_SHARED_SRC_ROTATE_PAGE_HH
+
+# include <QtGui>
+# include <src/rotate_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class rotate_page : public QWizardPage
+ {
+ Q_OBJECT;
+
+ public:
+ rotate_page(QWidget *parent = 0);
+
+ virtual void cleanupPage();
+ virtual void initializePage();
+ virtual bool isComplete();
+
+ private:
+ rotate_widget *widget_;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_ROTATE_PAGE_HH
diff --git a/scribo/demo/wizard/src/rotate_widget.cc
b/scribo/demo/wizard/src/rotate_widget.cc
new file mode 100644
index 0000000..41de670
--- /dev/null
+++ b/scribo/demo/wizard/src/rotate_widget.cc
@@ -0,0 +1,38 @@
+#include <src/rotate_widget.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ rotate_widget::rotate_widget(QWidget *parent)
+ : QWidget(parent)
+ {
+ setupUi(this);
+ }
+
+
+ void rotate_widget::load_image(const QPixmap& pixmap)
+ {
+ viewer_->draw_image(pixmap);
+ viewer_->set_rotation_enabled(true);
+ }
+
+
+ const QRectF& rotate_widget::rotate_area() const
+ {
+ return viewer_->selection();
+ }
+
+
+ QPixmap rotate_widget::image() const
+ {
+ return viewer_->image();
+ }
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/rotate_widget.hh
b/scribo/demo/wizard/src/rotate_widget.hh
new file mode 100644
index 0000000..8465f98
--- /dev/null
+++ b/scribo/demo/wizard/src/rotate_widget.hh
@@ -0,0 +1,62 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_ROTATE_WIDGET_HH
+# define SCRIBO_DEMO_SHARED_SRC_ROTATE_WIDGET_HH
+
+# include <QtGui>
+# include <ui_rotate_widget.h>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class rotate_widget : public QWidget, private Ui::RotateWidget
+ {
+ Q_OBJECT;
+
+ Q_PROPERTY(QRectF rotate_area READ rotate_area);
+
+ public:
+ rotate_widget(QWidget *parent = 0);
+
+ void load_image(const QPixmap& pixmap);
+
+ const QRectF& rotate_area() const;
+
+ QPixmap image() const;
+
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_ROTATE_WIDGET_HH
diff --git a/scribo/demo/wizard/src/runner.cc b/scribo/demo/wizard/src/runner.cc
new file mode 100644
index 0000000..162f1cb
--- /dev/null
+++ b/scribo/demo/wizard/src/runner.cc
@@ -0,0 +1,279 @@
+#include <src/runner.hh>
+
+#include <shared/src/to_mln_image.hh>
+#include <src/preprocessing_task.hh>
+#include <src/doc_type.hh>
+
+#include <mln/convert/to_qimage.hh>
+#include <mln/convert/to_qimage_nocopy.hh>
+#include <mln/fun/v2v/rgb_to_int_u.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/convert.hh>
+#include <mln/io/pbm/save.hh>
+
+#include <scribo/preprocessing/split_bg_fg.hh>
+#include <scribo/preprocessing/denoise.hh>
+#include <scribo/preprocessing/homogeneous_contrast.hh>
+#include <scribo/preprocessing/unskew.hh>
+#include <scribo/binarization/sauvola.hh>
+#include <scribo/binarization/sauvola_ms.hh>
+#include <scribo/binarization/simple.hh>
+
+#include <mln/logical/not.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ QString basedir_ = "/home/lazzara/build/scribo/src";
+
+ runner::runner(QObject *parent)
+ : QThread(parent)
+ {
+ process_.moveToThread(this);
+ }
+
+
+ void runner::start(const QImage& input,
+ const Doc_Type& doc_type,
+ const preprocessing_task_set_t& tasks)
+ {
+ input_ = input;
+ doc_type_ = doc_type;
+ tasks_ = tasks;
+
+ QThread::start();
+ }
+
+
+ void runner::run()
+ {
+ // Notification of the number of tasks.
+ emit new_progress_max_value(tasks_.size() + 2);
+
+ image2d<value::qt::rgb32> ima = load();
+
+ preprocess(ima);
+
+ process();
+ }
+
+
+ image2d<value::qt::rgb32> runner::load()
+ {
+ emit new_progress_label("Loading image");
+
+ // FIXME: specify the right top left corner.
+ // This is relevant when the image is cropped...
+ image2d<value::qt::rgb32>
+ output = shared::to_mln_image(input_, QPoint(0, 0));
+
+ QImage q_ima = convert::to_qimage_nocopy(output);
+ q_ima.save("/tmp/tmp.ppm");
+
+// io::magick::load(output, filename_.toStdString());
+
+ emit progress(1);
+ emit new_intermediate_result(input_);
+
+ return output;
+ }
+
+
+ void runner::preprocess(const image2d<value::qt::rgb32>& ima)
+ {
+
+ image2d<value::rgb8> tmp_color;
+ io::ppm::load(tmp_color, "/tmp/tmp.ppm");
+
+ image2d<bool> out_bool;
+
+
+ //==================
+ // Remove background
+ //==================
+ if (tasks_.contains(RemoveBg))
+ {
+ std::cout << "Foreground extraction" << std::endl;
+ emit new_progress_label("Foreground Extraction");
+
+ QStringList args;
+ args << "/tmp/tmp.ppm" << "10000" <<
"32"
+ << "/tmp/tmp.ppm" << "/dev/null";
+ if (process_.execute(basedir_ + "/preprocessing/split_bg_fg", args))
+ {
+ qDebug() << "Error running split_bg_fg";
+ return;
+ }
+
+ emit progress(1);
+ emit new_intermediate_result(mln::convert::to_qimage(tmp_color));
+ }
+
+
+ //=============================================
+ // Convert to grayscale image (always happens).
+ //=============================================
+ emit new_progress_label("Convert to gray-scale image");
+ image2d<value::int_u8>
+ intensity_ima = data::transform(tmp_color,
+ mln::fun::v2v::rgb_to_int_u<8>());
+ emit progress(1);
+
+
+ //=============================
+ // Improve contrast homogeneity
+ //=============================
+ if (tasks_.contains(ImproveContrast))
+ {
+ std::cout << "Improve contrast homogeneity" << std::endl;
+ emit new_progress_label("Improve contrast homogeneity");
+
+ intensity_ima = preprocessing::homogeneous_contrast(intensity_ima, 75);
+
+ image2d<value::qt::rgb32>
+ tmp_color32 = data::convert(value::qt::rgb32(), out_bool);
+ emit new_intermediate_result(convert::to_qimage(tmp_color32));
+ emit progress(1);
+ }
+
+
+ //==============================
+ // Binarization (always happens)
+ //==============================
+ emit new_progress_label("Binarization");
+
+ if (tasks_.contains(BinarizationSauvola))
+ {
+ // FIXME: sauvola should not negate the image.
+ std::cout << "Binarization Sauvola" << std::endl;
+ out_bool = logical::not_(binarization::sauvola(intensity_ima));
+ }
+ else if (tasks_.contains(BinarizationSauvolaMs))
+ {
+ // FIXME: sauvola should not negate the image.
+ std::cout << "Binarization Sauvola_ms" << std::endl;
+ out_bool = logical::not_(binarization::sauvola_ms(intensity_ima,
+ 51, 2, 67));
+ }
+ else if (tasks_.contains(BinarizationSimple))
+ {
+ std::cout << "Binarization Simple" << std::endl;
+ out_bool = scribo::binarization::simple(intensity_ima);
+ }
+ else
+ {
+ std::cout << "Binary image conversion" << std::endl;
+ out_bool = data::convert(bool(), intensity_ima);
+ }
+
+ image2d<value::qt::rgb32>
+ tmp_color32 = data::convert(value::qt::rgb32(), out_bool);
+ emit new_intermediate_result(convert::to_qimage(tmp_color32));
+ emit progress(1);
+
+
+ //========
+ // Denoise
+ //========
+ if (tasks_.contains(RemoveNoise))
+ {
+ std::cout << "Remove noise" << std::endl;
+ emit new_progress_label("Remove noise");
+
+ out_bool = preprocessing::denoise(out_bool, c8(), 2, 2);
+
+ image2d<value::qt::rgb32>
+ tmp_color32 = data::convert(value::qt::rgb32(), out_bool);
+ emit new_intermediate_result(convert::to_qimage(tmp_color32));
+ emit progress(1);
+ }
+
+
+ //=======
+ // Unskew
+ //=======
+ if (tasks_.contains(Unskew))
+ {
+ std::cout << "Unskew" << std::endl;
+ emit new_progress_label("Unskew");
+
+ out_bool = scribo::preprocessing::unskew(out_bool).first();
+
+ image2d<value::qt::rgb32>
+ tmp_color32 = data::convert(value::qt::rgb32(), out_bool);
+ emit new_intermediate_result(convert::to_qimage(tmp_color32));
+ emit progress(1);
+ }
+
+
+ //=========================
+ // Save preprocessed image.
+ //=========================
+ io::pbm::save(out_bool, "/tmp/tmp.pbm");
+ }
+
+
+ void runner::process()
+ {
+ QStringList args;
+
+
+ // FIXME: require binaries to ask for a filename for bboxes
+ // output files.
+ switch(doc_type_)
+ {
+ case Text_Doc:
+ qDebug() << "Running text_in_article_pbm";
+ args << "/tmp/tmp.pbm" << "/tmp/out.ppm";
+ if (process_.execute(basedir_ + "/text_in_article_pbm", args))
+ {
+ qDebug() << "Error while running text_in_article_pbm.";
+ return;
+ }
+ break;
+
+ case Picture:
+ qDebug() << "Running text_in_photo_pbm_fast";
+ args << "/tmp/tmp.pbm" << "/tmp/out.ppm" <<
"1" << "1" << "1";
+ if (process_.execute(basedir_ + "/text_in_photo_pbm_fast", args))
+ {
+ qDebug() << "Error while running text_in_photo_pbm_fast.";
+ return;
+ }
+ break;
+
+ case Mixed_Doc:
+ qDebug() << "Running pbm_text_in_mixed_doc";
+ if (process_.execute(basedir_ + "/pbm_text_in_mixed_doc", args))
+ {
+ qDebug() << "Error while running pbm_text_in_mixed_doc.";
+ return;
+ }
+ break;
+
+ default:
+ case Invalid_Doc:
+ qDebug() << "runner - Invalid doc type...";
+ return;
+ }
+
+ process_.waitForFinished(-1);
+
+ emit progress(1);
+ emit new_intermediate_result(QImage("/tmp/out.ppm"));
+ qDebug() << "Done";
+ }
+
+
+ void runner::stop()
+ {
+ process_.kill();
+ terminate();
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/wizard/src/runner.hh b/scribo/demo/wizard/src/runner.hh
new file mode 100644
index 0000000..4dcedc0
--- /dev/null
+++ b/scribo/demo/wizard/src/runner.hh
@@ -0,0 +1,84 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena 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, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
+# define SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
+
+# include <QtGui>
+# include <QProcess>
+
+# include <src/preprocessing_task.hh>
+# include <src/doc_type.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/qt/rgb32.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class runner : public QThread
+ {
+ Q_OBJECT;
+
+ public:
+ runner(QObject *parent = 0);
+
+ void start(const QImage& input,
+ const Doc_Type& doc_type,
+ const preprocessing_task_set_t& tasks);
+
+ void stop();
+
+ signals:
+ void new_intermediate_result(const QImage& ima);
+ void new_progress_max_value(unsigned i);
+ void new_progress_label(const QString& msg);
+ void progress(unsigned i);
+
+ private: // members
+ mln::image2d<mln::value::qt::rgb32> load();
+ void preprocess(const mln::image2d<mln::value::qt::rgb32>& ima);
+ void process();
+ virtual void run();
+
+ private: // attributes
+ QProcess process_;
+ Doc_Type doc_type_;
+ QSet<Preprocessing_Task> tasks_;
+ QImage input_;
+ };
+
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
diff --git a/scribo/demo/wizard/src/test.cc b/scribo/demo/wizard/src/test.cc
new file mode 100644
index 0000000..3d95db6
--- /dev/null
+++ b/scribo/demo/wizard/src/test.cc
@@ -0,0 +1,16 @@
+#include <QtGui>
+#include <shared/src/image_viewer.hh>
+#include <shared/src/crop_item.hh>
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+ scribo::demo::shared::image_viewer win;
+ win.show();
+ win.draw_image(QPixmap("image.jpg"), QPoint(0,0));
+
+ win.setSelectionEnabled(true);
+
+ return app.exec();
+}
diff --git a/scribo/demo/wizard/ui/doc_type_widget.ui
b/scribo/demo/wizard/ui/doc_type_widget.ui
new file mode 100644
index 0000000..39c8422
--- /dev/null
+++ b/scribo/demo/wizard/ui/doc_type_widget.ui
@@ -0,0 +1,115 @@
+<ui version="4.0" >
+ <class>DocTypeWidget</class>
+ <widget class="QWidget" name="DocTypeWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>166</width>
+ <height>140</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="1" >
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Document type</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <item>
+ <widget class="QRadioButton" name="type_text_doc_" >
+ <property name="text" >
+ <string>Text Document </string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="type_picture_" >
+ <property name="text" >
+ <string>Picture</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="type_mixed_doc_" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Mixed document</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer name="horizontalSpacer_3" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/wizard/ui/load_widget.ui b/scribo/demo/wizard/ui/load_widget.ui
new file mode 100644
index 0000000..db0dbc4
--- /dev/null
+++ b/scribo/demo/wizard/ui/load_widget.ui
@@ -0,0 +1,110 @@
+<ui version="4.0" >
+ <class>Form</class>
+ <widget class="QWidget" name="Form" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="1" >
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>76</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>83</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="scribo::demo::shared::browse_widget"
native="1" name="widget" />
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Options</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QCheckBox" name="checkBox" >
+ <property name="text" >
+ <string>Select a region of interest</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBox_2" >
+ <property name="text" >
+ <string>Perform a manual rotation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="3" >
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>83</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>76</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>scribo::demo::shared::browse_widget</class>
+ <extends>QWidget</extends>
+ <header location="global" >shared/src/browse_widget.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/wizard/ui/main_window.ui b/scribo/demo/wizard/ui/main_window.ui
new file mode 100644
index 0000000..0facd09
--- /dev/null
+++ b/scribo/demo/wizard/ui/main_window.ui
@@ -0,0 +1,216 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>507</width>
+ <height>476</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="page_3" >
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="scribo::demo::shared::wizard_title_widget"
native="1" name="title_0" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred"
>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="scribo::demo::shared::browse_widget"
native="1" name="widget_1" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Preferred"
>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page" >
+ <layout class="QVBoxLayout" name="verticalLayout_4" >
+ <item>
+ <widget class="scribo::demo::shared::wizard_title_widget"
native="1" name="title_2" />
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="1" >
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string/>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3"
>
+ <item>
+ <widget class="QRadioButton" name="radioButton_4"
>
+ <property name="text" >
+ <string>Extract all (Text, tables, images...)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButton"
>
+ <property name="text" >
+ <string>Find text</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButton_2"
>
+ <property name="text" >
+ <string>Extract tables</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButton_3"
>
+ <property name="text" >
+ <string>Detect text</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <spacer name="horizontalSpacer_3" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="page_2" />
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="prevBtn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>&Previous</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="nextBtn" >
+ <property name="text" >
+ <string>&Next</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>507</width>
+ <height>31</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>scribo::demo::shared::wizard_title_widget</class>
+ <extends>QWidget</extends>
+ <header location="global"
>shared/src/wizard_title_widget.hh</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>scribo::demo::shared::browse_widget</class>
+ <extends>QWidget</extends>
+ <header location="global" >shared/src/browse_widget.hh</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/wizard/ui/preprocessing_widget.ui
b/scribo/demo/wizard/ui/preprocessing_widget.ui
new file mode 100644
index 0000000..17225a8
--- /dev/null
+++ b/scribo/demo/wizard/ui/preprocessing_widget.ui
@@ -0,0 +1,223 @@
+<ui version="4.0" >
+ <class>PreprocessingWidget</class>
+ <widget class="QWidget" name="PreprocessingWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>398</width>
+ <height>318</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" >
+ <item row="0" column="1" >
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <spacer name="horizontalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>1</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="1" >
+ <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Preprocessing</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <item>
+ <widget class="QCheckBox" name="removeBg" >
+ <property name="text" >
+ <string>Remove background (slow)</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="unskew" >
+ <property name="text" >
+ <string>Unskew</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="removeNoise" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Remove noise</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="improveContrast" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>Improve brightness/contrast</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2"
>
+ <item>
+ <widget class="QCheckBox" name="reduceSize" >
+ <property name="text" >
+ <string>Reduce size by</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBox" >
+ <property name="minimum" >
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="title" >
+ <string>Advanced options</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <widget class="QLabel" name="binarizeLbl" >
+ <property name="text" >
+ <string>Binarization method:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QComboBox" name="binarizationCBox" >
+ <property name="currentIndex" >
+ <number>2</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Simple</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Sauvola</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Sauvola multi-scale</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="2" >
+ <spacer name="horizontalSpacer_3" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>1</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="1" >
+ <spacer name="verticalSpacer_3" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>2</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/scribo/demo/wizard/wizard.pro b/scribo/demo/wizard/wizard.pro
new file mode 100644
index 0000000..c7ab290
--- /dev/null
+++ b/scribo/demo/wizard/wizard.pro
@@ -0,0 +1,67 @@
+# -*- c++ -*-
+######################################################################
+# Automatically generated by qmake (2.01a) Tue Feb 9 12:02:10 2010
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += . src
+INCLUDEPATH += . ../ ../shared $(OLN)/milena $(OLN)
+
+DEFINES += NDEBUG MLN_INCLUDE_ONLY
+
+# Input
+HEADERS += \
+ ../shared/src/image_viewer.hh \
+ ../shared/src/internal/interactive_scene.hh \
+ ../shared/src/crop_item.hh \
+ ../shared/src/browse_widget.hh \
+ src/load_page.hh \
+ src/load_widget.hh \
+ src/doc_type_widget.hh \
+ src/doc_type_page.hh \
+ src/crop_widget.hh \
+ src/crop_page.hh \
+ src/rotate_widget.hh \
+ src/rotate_page.hh \
+ src/preprocessing_widget.hh \
+ src/preprocessing_page.hh \
+ src/process_page.hh \
+ src/process_widget.hh \
+ src/runner.hh \
+ src/preprocessing_task.hh \
+ src/doc_type.hh \
+ src/main_window.hh
+
+
+SOURCES += \
+ ../shared/src/crop_item.cc \
+ ../shared/src/internal/interactive_scene.cc \
+ ../shared/src/browse_widget.cc \
+ src/main.cc \
+ src/main_window.cc \
+ src/doc_type_widget.cc \
+ src/doc_type_page.cc \
+ src/load_page.cc \
+ src/load_widget.cc \
+ src/crop_widget.cc \
+ src/crop_page.cc \
+ src/rotate_widget.cc \
+ src/rotate_page.cc \
+ src/preprocessing_widget.cc \
+ src/preprocessing_page.cc \
+ src/process_page.cc \
+ src/process_widget.cc \
+ src/mln_widgets.cc
+
+FORMS += \
+ ../shared/ui/browse_widget.ui \
+ ../shared/ui/crop_widget.ui \
+ ../shared/ui/rotate_widget.ui \
+ ../shared/ui/image_viewer.ui \
+ ui/preprocessing_widget.ui \
+ ui/doc_type_widget.ui \
+ ui/main_window.ui
+
+
+RESOURCES += ../shared/shared.qrc wizard.qrc
diff --git a/scribo/demo/wizard/wizard.qrc b/scribo/demo/wizard/wizard.qrc
new file mode 100644
index 0000000..bd6b146
--- /dev/null
+++ b/scribo/demo/wizard/wizard.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="images" >
+ <file>images/dematerialization.png</file>
+ </qresource>
+</RCC>
--
1.5.6.5