From ce599e4f9f94b4eb00c1b5edb85bce5431ab3df2 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeedu@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kwordquiz/AUTHORS | 1 + kwordquiz/COPYING | 340 ++++++ kwordquiz/ChangeLog | 0 kwordquiz/INSTALL | 167 +++ kwordquiz/Makefile.am | 32 + kwordquiz/README | 1 + kwordquiz/TODO | 1 + kwordquiz/src/Makefile.am | 70 ++ kwordquiz/src/dlglanguage.cpp | 79 ++ kwordquiz/src/dlglanguage.h | 45 + kwordquiz/src/dlglanguagebase.ui | 244 ++++ kwordquiz/src/dlgrc.cpp | 65 + kwordquiz/src/dlgrc.h | 46 + kwordquiz/src/dlgrcbase.ui | 182 +++ kwordquiz/src/dlgsort.cpp | 60 + kwordquiz/src/dlgsort.h | 44 + kwordquiz/src/dlgsortbase.ui | 143 +++ kwordquiz/src/dlgspecchar.cpp | 82 ++ kwordquiz/src/dlgspecchar.h | 63 + kwordquiz/src/eventsrc | 283 +++++ kwordquiz/src/examples/Makefile.am | 3 + kwordquiz/src/examples/example.kvtml | 45 + kwordquiz/src/examples/fill_in_the_blank.kvtml | 69 ++ kwordquiz/src/examples/french_verbs.kvtml | 149 +++ .../src/examples/us_states_and_capitals.kvtml | 209 ++++ kwordquiz/src/flashview.cpp | 248 ++++ kwordquiz/src/flashview.h | 78 ++ kwordquiz/src/flashviewbase.ui | 552 +++++++++ kwordquiz/src/keduvocdata.cpp | 163 +++ kwordquiz/src/keduvocdata.h | 59 + kwordquiz/src/kvtmlwriter.cpp | 93 ++ kwordquiz/src/kvtmlwriter.h | 40 + kwordquiz/src/kwordquiz.cpp | 1258 ++++++++++++++++++++ kwordquiz/src/kwordquiz.desktop | 131 ++ kwordquiz/src/kwordquiz.h | 322 +++++ kwordquiz/src/kwordquiz.kcfg | 118 ++ kwordquiz/src/kwordquizdoc.cpp | 490 ++++++++ kwordquiz/src/kwordquizdoc.h | 95 ++ kwordquiz/src/kwordquizprefs.cpp | 203 ++++ kwordquiz/src/kwordquizprefs.h | 63 + kwordquiz/src/kwordquizrc | 2 + kwordquiz/src/kwordquizui.rc | 198 +++ kwordquiz/src/kwordquizview.cpp | 1083 +++++++++++++++++ kwordquiz/src/kwordquizview.h | 123 ++ kwordquiz/src/kwqnewstuff.cpp | 96 ++ kwordquiz/src/kwqnewstuff.h | 66 + kwordquiz/src/main.cpp | 102 ++ kwordquiz/src/multipleview.cpp | 290 +++++ kwordquiz/src/multipleview.h | 60 + kwordquiz/src/multipleviewbase.ui | 976 +++++++++++++++ kwordquiz/src/paukerreader.cpp | 106 ++ kwordquiz/src/paukerreader.h | 57 + kwordquiz/src/pics/Makefile.am | 5 + kwordquiz/src/pics/cr128-mime-kwordquiz_doc.png | Bin 0 -> 9361 bytes kwordquiz/src/pics/cr16-action-answer.png | Bin 0 -> 357 bytes kwordquiz/src/pics/cr16-action-check.png | Bin 0 -> 578 bytes .../src/pics/cr16-action-delete_table_row.png | Bin 0 -> 232 bytes kwordquiz/src/pics/cr16-action-dontknow.png | Bin 0 -> 910 bytes kwordquiz/src/pics/cr16-action-editor.png | Bin 0 -> 629 bytes kwordquiz/src/pics/cr16-action-flash.png | Bin 0 -> 495 bytes kwordquiz/src/pics/cr16-action-hint.png | Bin 0 -> 641 bytes .../src/pics/cr16-action-insert_table_row.png | Bin 0 -> 210 bytes kwordquiz/src/pics/cr16-action-know.png | Bin 0 -> 622 bytes kwordquiz/src/pics/cr16-action-languages.png | Bin 0 -> 416 bytes kwordquiz/src/pics/cr16-action-markasblank.png | Bin 0 -> 599 bytes kwordquiz/src/pics/cr16-action-mode1.png | Bin 0 -> 533 bytes kwordquiz/src/pics/cr16-action-mode2.png | Bin 0 -> 534 bytes kwordquiz/src/pics/cr16-action-mode3.png | Bin 0 -> 537 bytes kwordquiz/src/pics/cr16-action-mode4.png | Bin 0 -> 531 bytes kwordquiz/src/pics/cr16-action-mode5.png | Bin 0 -> 644 bytes kwordquiz/src/pics/cr16-action-multiple.png | Bin 0 -> 619 bytes kwordquiz/src/pics/cr16-action-qa.png | Bin 0 -> 695 bytes kwordquiz/src/pics/cr16-action-question.png | Bin 0 -> 354 bytes kwordquiz/src/pics/cr16-action-repeat.png | Bin 0 -> 1069 bytes kwordquiz/src/pics/cr16-action-restart.png | Bin 0 -> 644 bytes kwordquiz/src/pics/cr16-action-rowcol.png | Bin 0 -> 354 bytes kwordquiz/src/pics/cr16-action-shuffle.png | Bin 0 -> 280 bytes kwordquiz/src/pics/cr16-action-sort_incr.png | Bin 0 -> 285 bytes kwordquiz/src/pics/cr16-action-unmarkasblank.png | Bin 0 -> 823 bytes kwordquiz/src/pics/cr16-mime-kwordquiz_doc.png | Bin 0 -> 785 bytes kwordquiz/src/pics/cr22-action-answer.png | Bin 0 -> 530 bytes kwordquiz/src/pics/cr22-action-check.png | Bin 0 -> 649 bytes .../src/pics/cr22-action-delete_table_row.png | Bin 0 -> 519 bytes kwordquiz/src/pics/cr22-action-dontknow.png | Bin 0 -> 1288 bytes kwordquiz/src/pics/cr22-action-editor.png | Bin 0 -> 833 bytes kwordquiz/src/pics/cr22-action-flash.png | Bin 0 -> 664 bytes kwordquiz/src/pics/cr22-action-hint.png | Bin 0 -> 918 bytes .../src/pics/cr22-action-insert_table_row.png | Bin 0 -> 542 bytes kwordquiz/src/pics/cr22-action-know.png | Bin 0 -> 1052 bytes kwordquiz/src/pics/cr22-action-languages.png | Bin 0 -> 607 bytes kwordquiz/src/pics/cr22-action-markasblank.png | Bin 0 -> 731 bytes kwordquiz/src/pics/cr22-action-mode1.png | Bin 0 -> 729 bytes kwordquiz/src/pics/cr22-action-mode2.png | Bin 0 -> 728 bytes kwordquiz/src/pics/cr22-action-mode3.png | Bin 0 -> 732 bytes kwordquiz/src/pics/cr22-action-mode4.png | Bin 0 -> 728 bytes kwordquiz/src/pics/cr22-action-mode5.png | Bin 0 -> 960 bytes kwordquiz/src/pics/cr22-action-multiple.png | Bin 0 -> 883 bytes kwordquiz/src/pics/cr22-action-qa.png | Bin 0 -> 944 bytes kwordquiz/src/pics/cr22-action-question.png | Bin 0 -> 521 bytes kwordquiz/src/pics/cr22-action-repeat.png | Bin 0 -> 1506 bytes kwordquiz/src/pics/cr22-action-restart.png | Bin 0 -> 1085 bytes kwordquiz/src/pics/cr22-action-rowcol.png | Bin 0 -> 521 bytes kwordquiz/src/pics/cr22-action-shuffle.png | Bin 0 -> 794 bytes kwordquiz/src/pics/cr22-action-sort_incr.png | Bin 0 -> 585 bytes kwordquiz/src/pics/cr22-action-unmarkasblank.png | Bin 0 -> 1216 bytes kwordquiz/src/pics/cr22-mime-kwordquiz_doc.png | Bin 0 -> 1087 bytes kwordquiz/src/pics/cr32-action-answer.png | Bin 0 -> 648 bytes kwordquiz/src/pics/cr32-action-check.png | Bin 0 -> 1133 bytes .../src/pics/cr32-action-delete_table_row.png | Bin 0 -> 1213 bytes kwordquiz/src/pics/cr32-action-dontknow.png | Bin 0 -> 2045 bytes kwordquiz/src/pics/cr32-action-editor.png | Bin 0 -> 1262 bytes kwordquiz/src/pics/cr32-action-error.png | Bin 0 -> 1322 bytes kwordquiz/src/pics/cr32-action-flash.png | Bin 0 -> 798 bytes kwordquiz/src/pics/cr32-action-hint.png | Bin 0 -> 1252 bytes .../src/pics/cr32-action-insert_table_row.png | Bin 0 -> 1272 bytes kwordquiz/src/pics/cr32-action-know.png | Bin 0 -> 1476 bytes kwordquiz/src/pics/cr32-action-languages.png | Bin 0 -> 765 bytes kwordquiz/src/pics/cr32-action-markasblank.png | Bin 0 -> 925 bytes kwordquiz/src/pics/cr32-action-mode1.png | Bin 0 -> 996 bytes kwordquiz/src/pics/cr32-action-mode2.png | Bin 0 -> 998 bytes kwordquiz/src/pics/cr32-action-mode3.png | Bin 0 -> 993 bytes kwordquiz/src/pics/cr32-action-mode4.png | Bin 0 -> 992 bytes kwordquiz/src/pics/cr32-action-mode5.png | Bin 0 -> 1402 bytes kwordquiz/src/pics/cr32-action-multiple.png | Bin 0 -> 1316 bytes kwordquiz/src/pics/cr32-action-qa.png | Bin 0 -> 1532 bytes kwordquiz/src/pics/cr32-action-question.png | Bin 0 -> 670 bytes kwordquiz/src/pics/cr32-action-question_mark.png | Bin 0 -> 1392 bytes kwordquiz/src/pics/cr32-action-repeat.png | Bin 0 -> 2896 bytes kwordquiz/src/pics/cr32-action-restart.png | Bin 0 -> 1527 bytes kwordquiz/src/pics/cr32-action-rowcol.png | Bin 0 -> 670 bytes kwordquiz/src/pics/cr32-action-shuffle.png | Bin 0 -> 1565 bytes kwordquiz/src/pics/cr32-action-sort_incr.png | Bin 0 -> 1101 bytes kwordquiz/src/pics/cr32-action-unmarkasblank.png | Bin 0 -> 2167 bytes kwordquiz/src/pics/cr32-mime-kwordquiz_doc.png | Bin 0 -> 1749 bytes kwordquiz/src/pics/cr48-mime-kwordquiz_doc.png | Bin 0 -> 2712 bytes kwordquiz/src/pics/crsc-mime-kwordquiz_doc.svg | 324 +++++ kwordquiz/src/pics/hi128-app-kwordquiz.png | Bin 0 -> 8172 bytes kwordquiz/src/pics/hi16-app-kwordquiz.png | Bin 0 -> 702 bytes kwordquiz/src/pics/hi22-app-kwordquiz.png | Bin 0 -> 986 bytes kwordquiz/src/pics/hi32-app-kwordquiz.png | Bin 0 -> 1587 bytes kwordquiz/src/pics/hi48-app-kwordquiz.png | Bin 0 -> 2555 bytes kwordquiz/src/pics/hisc-app-kwordquiz.svg | 91 ++ kwordquiz/src/prefcardappearance.cpp | 95 ++ kwordquiz/src/prefcardappearance.h | 36 + kwordquiz/src/prefcardappearancebase.ui | 553 +++++++++ kwordquiz/src/prefcharacter.cpp | 31 + kwordquiz/src/prefcharacter.h | 36 + kwordquiz/src/prefcharacterbase.ui | 409 +++++++ kwordquiz/src/prefeditor.cpp | 32 + kwordquiz/src/prefeditor.h | 37 + kwordquiz/src/prefeditorbase.ui | 126 ++ kwordquiz/src/prefquiz.cpp | 41 + kwordquiz/src/prefquiz.h | 36 + kwordquiz/src/prefquizbase.ui | 295 +++++ kwordquiz/src/prefs.kcfgc | 5 + kwordquiz/src/qaview.cpp | 329 +++++ kwordquiz/src/qaview.h | 69 ++ kwordquiz/src/qaviewbase.ui | 869 ++++++++++++++ kwordquiz/src/version.h | 1 + kwordquiz/src/wqlistitem.cpp | 54 + kwordquiz/src/wqlistitem.h | 53 + kwordquiz/src/wqlreader.cpp | 199 ++++ kwordquiz/src/wqlreader.h | 75 ++ kwordquiz/src/wqlwriter.cpp | 93 ++ kwordquiz/src/wqlwriter.h | 42 + kwordquiz/src/wqprintdialogpage.cpp | 83 ++ kwordquiz/src/wqprintdialogpage.h | 49 + kwordquiz/src/wqquiz.cpp | 586 +++++++++ kwordquiz/src/wqquiz.h | 87 ++ kwordquiz/src/wqscore.cpp | 141 +++ kwordquiz/src/wqscore.h | 50 + kwordquiz/src/wqundo.cpp | 18 + kwordquiz/src/wqundo.h | 67 ++ kwordquiz/src/x-kwordquiz.desktop | 62 + 174 files changed, 14574 insertions(+) create mode 100644 kwordquiz/AUTHORS create mode 100644 kwordquiz/COPYING create mode 100644 kwordquiz/ChangeLog create mode 100644 kwordquiz/INSTALL create mode 100644 kwordquiz/Makefile.am create mode 100644 kwordquiz/README create mode 100644 kwordquiz/TODO create mode 100644 kwordquiz/src/Makefile.am create mode 100644 kwordquiz/src/dlglanguage.cpp create mode 100644 kwordquiz/src/dlglanguage.h create mode 100644 kwordquiz/src/dlglanguagebase.ui create mode 100644 kwordquiz/src/dlgrc.cpp create mode 100644 kwordquiz/src/dlgrc.h create mode 100644 kwordquiz/src/dlgrcbase.ui create mode 100644 kwordquiz/src/dlgsort.cpp create mode 100644 kwordquiz/src/dlgsort.h create mode 100644 kwordquiz/src/dlgsortbase.ui create mode 100644 kwordquiz/src/dlgspecchar.cpp create mode 100644 kwordquiz/src/dlgspecchar.h create mode 100644 kwordquiz/src/eventsrc create mode 100644 kwordquiz/src/examples/Makefile.am create mode 100644 kwordquiz/src/examples/example.kvtml create mode 100644 kwordquiz/src/examples/fill_in_the_blank.kvtml create mode 100644 kwordquiz/src/examples/french_verbs.kvtml create mode 100644 kwordquiz/src/examples/us_states_and_capitals.kvtml create mode 100644 kwordquiz/src/flashview.cpp create mode 100644 kwordquiz/src/flashview.h create mode 100644 kwordquiz/src/flashviewbase.ui create mode 100644 kwordquiz/src/keduvocdata.cpp create mode 100644 kwordquiz/src/keduvocdata.h create mode 100644 kwordquiz/src/kvtmlwriter.cpp create mode 100644 kwordquiz/src/kvtmlwriter.h create mode 100644 kwordquiz/src/kwordquiz.cpp create mode 100644 kwordquiz/src/kwordquiz.desktop create mode 100644 kwordquiz/src/kwordquiz.h create mode 100644 kwordquiz/src/kwordquiz.kcfg create mode 100644 kwordquiz/src/kwordquizdoc.cpp create mode 100644 kwordquiz/src/kwordquizdoc.h create mode 100644 kwordquiz/src/kwordquizprefs.cpp create mode 100644 kwordquiz/src/kwordquizprefs.h create mode 100644 kwordquiz/src/kwordquizrc create mode 100644 kwordquiz/src/kwordquizui.rc create mode 100644 kwordquiz/src/kwordquizview.cpp create mode 100644 kwordquiz/src/kwordquizview.h create mode 100644 kwordquiz/src/kwqnewstuff.cpp create mode 100644 kwordquiz/src/kwqnewstuff.h create mode 100644 kwordquiz/src/main.cpp create mode 100644 kwordquiz/src/multipleview.cpp create mode 100644 kwordquiz/src/multipleview.h create mode 100644 kwordquiz/src/multipleviewbase.ui create mode 100644 kwordquiz/src/paukerreader.cpp create mode 100644 kwordquiz/src/paukerreader.h create mode 100644 kwordquiz/src/pics/Makefile.am create mode 100644 kwordquiz/src/pics/cr128-mime-kwordquiz_doc.png create mode 100644 kwordquiz/src/pics/cr16-action-answer.png create mode 100644 kwordquiz/src/pics/cr16-action-check.png create mode 100644 kwordquiz/src/pics/cr16-action-delete_table_row.png create mode 100644 kwordquiz/src/pics/cr16-action-dontknow.png create mode 100644 kwordquiz/src/pics/cr16-action-editor.png create mode 100644 kwordquiz/src/pics/cr16-action-flash.png create mode 100644 kwordquiz/src/pics/cr16-action-hint.png create mode 100644 kwordquiz/src/pics/cr16-action-insert_table_row.png create mode 100644 kwordquiz/src/pics/cr16-action-know.png create mode 100644 kwordquiz/src/pics/cr16-action-languages.png create mode 100644 kwordquiz/src/pics/cr16-action-markasblank.png create mode 100644 kwordquiz/src/pics/cr16-action-mode1.png create mode 100644 kwordquiz/src/pics/cr16-action-mode2.png create mode 100644 kwordquiz/src/pics/cr16-action-mode3.png create mode 100644 kwordquiz/src/pics/cr16-action-mode4.png create mode 100644 kwordquiz/src/pics/cr16-action-mode5.png create mode 100644 kwordquiz/src/pics/cr16-action-multiple.png create mode 100644 kwordquiz/src/pics/cr16-action-qa.png create mode 100644 kwordquiz/src/pics/cr16-action-question.png create mode 100644 kwordquiz/src/pics/cr16-action-repeat.png create mode 100644 kwordquiz/src/pics/cr16-action-restart.png create mode 100644 kwordquiz/src/pics/cr16-action-rowcol.png create mode 100644 kwordquiz/src/pics/cr16-action-shuffle.png create mode 100644 kwordquiz/src/pics/cr16-action-sort_incr.png create mode 100644 kwordquiz/src/pics/cr16-action-unmarkasblank.png create mode 100644 kwordquiz/src/pics/cr16-mime-kwordquiz_doc.png create mode 100644 kwordquiz/src/pics/cr22-action-answer.png create mode 100644 kwordquiz/src/pics/cr22-action-check.png create mode 100644 kwordquiz/src/pics/cr22-action-delete_table_row.png create mode 100644 kwordquiz/src/pics/cr22-action-dontknow.png create mode 100644 kwordquiz/src/pics/cr22-action-editor.png create mode 100644 kwordquiz/src/pics/cr22-action-flash.png create mode 100644 kwordquiz/src/pics/cr22-action-hint.png create mode 100644 kwordquiz/src/pics/cr22-action-insert_table_row.png create mode 100644 kwordquiz/src/pics/cr22-action-know.png create mode 100644 kwordquiz/src/pics/cr22-action-languages.png create mode 100644 kwordquiz/src/pics/cr22-action-markasblank.png create mode 100644 kwordquiz/src/pics/cr22-action-mode1.png create mode 100644 kwordquiz/src/pics/cr22-action-mode2.png create mode 100644 kwordquiz/src/pics/cr22-action-mode3.png create mode 100644 kwordquiz/src/pics/cr22-action-mode4.png create mode 100644 kwordquiz/src/pics/cr22-action-mode5.png create mode 100644 kwordquiz/src/pics/cr22-action-multiple.png create mode 100644 kwordquiz/src/pics/cr22-action-qa.png create mode 100644 kwordquiz/src/pics/cr22-action-question.png create mode 100644 kwordquiz/src/pics/cr22-action-repeat.png create mode 100644 kwordquiz/src/pics/cr22-action-restart.png create mode 100644 kwordquiz/src/pics/cr22-action-rowcol.png create mode 100644 kwordquiz/src/pics/cr22-action-shuffle.png create mode 100644 kwordquiz/src/pics/cr22-action-sort_incr.png create mode 100644 kwordquiz/src/pics/cr22-action-unmarkasblank.png create mode 100644 kwordquiz/src/pics/cr22-mime-kwordquiz_doc.png create mode 100644 kwordquiz/src/pics/cr32-action-answer.png create mode 100644 kwordquiz/src/pics/cr32-action-check.png create mode 100644 kwordquiz/src/pics/cr32-action-delete_table_row.png create mode 100644 kwordquiz/src/pics/cr32-action-dontknow.png create mode 100644 kwordquiz/src/pics/cr32-action-editor.png create mode 100644 kwordquiz/src/pics/cr32-action-error.png create mode 100644 kwordquiz/src/pics/cr32-action-flash.png create mode 100644 kwordquiz/src/pics/cr32-action-hint.png create mode 100644 kwordquiz/src/pics/cr32-action-insert_table_row.png create mode 100644 kwordquiz/src/pics/cr32-action-know.png create mode 100644 kwordquiz/src/pics/cr32-action-languages.png create mode 100644 kwordquiz/src/pics/cr32-action-markasblank.png create mode 100644 kwordquiz/src/pics/cr32-action-mode1.png create mode 100644 kwordquiz/src/pics/cr32-action-mode2.png create mode 100644 kwordquiz/src/pics/cr32-action-mode3.png create mode 100644 kwordquiz/src/pics/cr32-action-mode4.png create mode 100644 kwordquiz/src/pics/cr32-action-mode5.png create mode 100644 kwordquiz/src/pics/cr32-action-multiple.png create mode 100644 kwordquiz/src/pics/cr32-action-qa.png create mode 100644 kwordquiz/src/pics/cr32-action-question.png create mode 100644 kwordquiz/src/pics/cr32-action-question_mark.png create mode 100644 kwordquiz/src/pics/cr32-action-repeat.png create mode 100644 kwordquiz/src/pics/cr32-action-restart.png create mode 100644 kwordquiz/src/pics/cr32-action-rowcol.png create mode 100644 kwordquiz/src/pics/cr32-action-shuffle.png create mode 100644 kwordquiz/src/pics/cr32-action-sort_incr.png create mode 100644 kwordquiz/src/pics/cr32-action-unmarkasblank.png create mode 100644 kwordquiz/src/pics/cr32-mime-kwordquiz_doc.png create mode 100644 kwordquiz/src/pics/cr48-mime-kwordquiz_doc.png create mode 100644 kwordquiz/src/pics/crsc-mime-kwordquiz_doc.svg create mode 100644 kwordquiz/src/pics/hi128-app-kwordquiz.png create mode 100644 kwordquiz/src/pics/hi16-app-kwordquiz.png create mode 100644 kwordquiz/src/pics/hi22-app-kwordquiz.png create mode 100644 kwordquiz/src/pics/hi32-app-kwordquiz.png create mode 100644 kwordquiz/src/pics/hi48-app-kwordquiz.png create mode 100644 kwordquiz/src/pics/hisc-app-kwordquiz.svg create mode 100644 kwordquiz/src/prefcardappearance.cpp create mode 100644 kwordquiz/src/prefcardappearance.h create mode 100644 kwordquiz/src/prefcardappearancebase.ui create mode 100644 kwordquiz/src/prefcharacter.cpp create mode 100644 kwordquiz/src/prefcharacter.h create mode 100644 kwordquiz/src/prefcharacterbase.ui create mode 100644 kwordquiz/src/prefeditor.cpp create mode 100644 kwordquiz/src/prefeditor.h create mode 100644 kwordquiz/src/prefeditorbase.ui create mode 100644 kwordquiz/src/prefquiz.cpp create mode 100644 kwordquiz/src/prefquiz.h create mode 100644 kwordquiz/src/prefquizbase.ui create mode 100644 kwordquiz/src/prefs.kcfgc create mode 100644 kwordquiz/src/qaview.cpp create mode 100644 kwordquiz/src/qaview.h create mode 100644 kwordquiz/src/qaviewbase.ui create mode 100644 kwordquiz/src/version.h create mode 100644 kwordquiz/src/wqlistitem.cpp create mode 100644 kwordquiz/src/wqlistitem.h create mode 100644 kwordquiz/src/wqlreader.cpp create mode 100644 kwordquiz/src/wqlreader.h create mode 100644 kwordquiz/src/wqlwriter.cpp create mode 100644 kwordquiz/src/wqlwriter.h create mode 100644 kwordquiz/src/wqprintdialogpage.cpp create mode 100644 kwordquiz/src/wqprintdialogpage.h create mode 100644 kwordquiz/src/wqquiz.cpp create mode 100644 kwordquiz/src/wqquiz.h create mode 100644 kwordquiz/src/wqscore.cpp create mode 100644 kwordquiz/src/wqscore.h create mode 100644 kwordquiz/src/wqundo.cpp create mode 100644 kwordquiz/src/wqundo.h create mode 100644 kwordquiz/src/x-kwordquiz.desktop (limited to 'kwordquiz') diff --git a/kwordquiz/AUTHORS b/kwordquiz/AUTHORS new file mode 100644 index 00000000..b2c3f6b7 --- /dev/null +++ b/kwordquiz/AUTHORS @@ -0,0 +1 @@ +Peter Hedlund diff --git a/kwordquiz/COPYING b/kwordquiz/COPYING new file mode 100644 index 00000000..c13faf0d --- /dev/null +++ b/kwordquiz/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/kwordquiz/ChangeLog b/kwordquiz/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/kwordquiz/INSTALL b/kwordquiz/INSTALL new file mode 100644 index 00000000..02a4a074 --- /dev/null +++ b/kwordquiz/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/kwordquiz/Makefile.am b/kwordquiz/Makefile.am new file mode 100644 index 00000000..85c32be2 --- /dev/null +++ b/kwordquiz/Makefile.am @@ -0,0 +1,32 @@ +####### kdevelop will overwrite this part!!! (begin)########## + +SUBDIRS = src + +EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO + +####### kdevelop will overwrite this part!!! (end)############ +# not a GNU package. You can remove this line, if +# have all needed files, that a GNU package needs +AUTOMAKE_OPTIONS = foreign + +$(top_srcdir)/configure.in: $(top_srcdir)/subdirs + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ; + +$(top_srcdir)/subdirs: + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs + +$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in + @cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4 + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files + +package-messages: + $(MAKE) -f admin/Makefile.common package-messages + $(MAKE) -C po merge + +dist-hook: + cd $(top_distdir) && perl admin/am_edit -padmin + cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs + + +include ../admin/Doxyfile.am diff --git a/kwordquiz/README b/kwordquiz/README new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/kwordquiz/README @@ -0,0 +1 @@ + diff --git a/kwordquiz/TODO b/kwordquiz/TODO new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/kwordquiz/TODO @@ -0,0 +1 @@ + diff --git a/kwordquiz/src/Makefile.am b/kwordquiz/src/Makefile.am new file mode 100644 index 00000000..deb60c2c --- /dev/null +++ b/kwordquiz/src/Makefile.am @@ -0,0 +1,70 @@ +####### kdevelop will overwrite this part!!! (begin)########## +bin_PROGRAMS = kwordquiz + +## INCLUDES were found outside kdevelop specific part + +kwordquiz_SOURCES = kwordquizprefs.cpp kwordquizview.cpp kwordquizdoc.cpp \ + kwordquiz.cpp main.cpp dlglanguagebase.ui flashviewbase.ui multipleviewbase.ui \ + qaviewbase.ui qaview.cpp flashview.cpp multipleview.cpp wqquiz.cpp wqlistitem.cpp \ + wqscore.cpp keduvocdata.cpp prefeditorbase.ui prefquizbase.ui prefeditor.cpp \ + prefquiz.cpp dlgsortbase.ui dlgsort.cpp dlgrcbase.ui dlgrc.cpp dlgspecchar.cpp \ + kvtmlwriter.cpp dlglanguage.cpp wqprintdialogpage.cpp prefcharacter.cpp \ + prefcharacterbase.ui paukerreader.cpp wqlreader.cpp wqlwriter.cpp wqundo.cpp prefs.kcfgc \ + prefcardappearance.cpp prefcardappearancebase.ui kwqnewstuff.cpp kwqnewstuff.h +kwordquiz_LDADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KFILE) \ + $(LIBSOCKET) $(LIB_KDEPRINT) -lknewstuff + + +EXTRA_DIST = main.cpp kwordquiz.cpp kwordquiz.h kwordquizdoc.cpp kwordquizdoc.h kwordquizview.cpp kwordquizview.h kwordquizui.rc kwordquizprefs.cpp kwordquizprefs.h + +kde_kcfg_DATA = kwordquiz.kcfg +kde_conf_DATA = kwordquizrc +mime_DATA = x-kwordquiz.desktop +mimedir = $(kde_mimedir)/application + +####### kdevelop will overwrite this part!!! (end)############ +# These paths are KDE specific. Use them: +# kde_appsdir Where your application's menu entry (.desktop) should go to. +# kde_icondir Where your icon should go to - better use KDE_ICON. +# kde_sounddir Where your sounds should go to. +# kde_htmldir Where your docs should go to. (contains lang subdirs) +# kde_datadir Where you install application data. (Use a subdir) +# kde_locale Where translation files should go to. (contains lang subdirs) +# kde_cgidir Where cgi-bin executables should go to. +# kde_confdir Where config files should go to (system-wide ones with default values). +# kde_mimedir Where mimetypes .desktop files should go to. +# kde_servicesdir Where services .desktop files should go to. +# kde_servicetypesdir Where servicetypes .desktop files should go to. +# kde_toolbardir Where general toolbar icons should go to (deprecated, use KDE_ICON). +# kde_wallpaperdir Where general wallpapers should go to. +# kde_templatesdir Where templates for the "New" menu (Konqueror/KDesktop) should go to. +# kde_bindir Where executables should go to. Use bin_PROGRAMS or bin_SCRIPTS. +# kde_libdir Where shared libraries should go to. Use lib_LTLIBRARIES. +# kde_moduledir Where modules (e.g. parts) should go to. Use kde_module_LTLIBRARIES. +# kde_styledir Where Qt/KDE widget styles should go to (new in KDE 3). +# kde_designerdir Where Qt Designer plugins should go to (new in KDE 3). + +# set the include path for X, qt and KDE +INCLUDES = -I$(top_srcdir)/kwordquiz/icons $(all_includes) +SUBDIRS = . pics examples +METASOURCES = AUTO + +# the library search path. +kwordquiz_LDFLAGS = $(all_libraries) $(KDE_RPATH) + +rcdir = $(kde_datadir)/kwordquiz +rc_DATA = kwordquizui.rc eventsrc + +xdg_apps_DATA = kwordquiz.desktop + +messages: rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + $(XGETTEXT) $$LIST -o $(podir)/kwordquiz.pot; \ + fi + + +noinst_HEADERS = qaview.h flashview.h multipleview.h wqquiz.h wqlistitem.h \ + wqscore.h prefeditor.h prefquiz.h dlgsort.h dlgrc.h dlgspecchar.h kvtmlwriter.h \ + dlglanguage.h dlglanguage.h wqprintdialogpage.h prefcharacter.h wqlreader.h \ + wqlwriter.h wqundo.h prefcardappearance.h diff --git a/kwordquiz/src/dlglanguage.cpp b/kwordquiz/src/dlglanguage.cpp new file mode 100644 index 00000000..97a8e6c1 --- /dev/null +++ b/kwordquiz/src/dlglanguage.cpp @@ -0,0 +1,79 @@ +/*************************************************************************** + dlglanguage.cpp - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include + +#include + +#include "prefs.h" +#include "dlglanguage.h" + +DlgLanguage::DlgLanguage(QWidget *parent, const char *name, bool modal): KDialogBase(Swallow, i18n("Column Titles"), Ok|Cancel, Ok, parent, name, modal, true) +{ + dlgBase = new DlgLanguageBase( this, "Dlg" ); + setMainWidget(dlgBase); + dlgBase -> picLanguage1 -> setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + dlgBase -> picLanguage2 -> setPixmap(KGlobal::iconLoader()->loadIcon("answer", KIcon::Panel)); + + completion1 = new KCompletion(); + completion1->setItems(Prefs::columnTitles1()); + dlgBase -> txtLanguage1->setCompletionObject(completion1); + + completion2 = new KCompletion(); + completion2->setItems(Prefs::columnTitles2()); + dlgBase -> txtLanguage2->setCompletionObject(completion2); + + dlgBase->txtLanguage1->setFocus(); +} + + +DlgLanguage::~DlgLanguage() +{ + delete completion1; + delete completion2; +} + + +void DlgLanguage::setLanguage(int index, const QString &lang) { + if (index == 1) { + dlgBase->txtLanguage1 -> setText(lang); + } + else + { + dlgBase->txtLanguage2 -> setText(lang); + } +} + + +QString DlgLanguage::Language(int index){ + if (index == 1) { + completion1->addItem(dlgBase->txtLanguage1 -> text()); + Prefs::setColumnTitles1(completion1->items()); + return dlgBase->txtLanguage1 -> text(); + } + else + { + completion2->addItem(dlgBase->txtLanguage2 -> text()); + Prefs::setColumnTitles2(completion2->items()); + return dlgBase->txtLanguage2 -> text(); + } +} + + + +#include "dlglanguage.moc" diff --git a/kwordquiz/src/dlglanguage.h b/kwordquiz/src/dlglanguage.h new file mode 100644 index 00000000..8dfba91d --- /dev/null +++ b/kwordquiz/src/dlglanguage.h @@ -0,0 +1,45 @@ +/*************************************************************************** + dlglanguage.h - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DLGLANGUAGE_H +#define DLGLANGUAGE_H + +#include + +#include "dlglanguagebase.h" + +class KCompletion; + +/** +@author Peter Hedlund +*/ +class DlgLanguage : public KDialogBase { + Q_OBJECT + public: + DlgLanguage(QWidget *parent = 0, const char *name = 0, bool modal=true); + ~DlgLanguage(); + + void setLanguage(int index, const QString &lang); + QString Language(int index); + + private: + DlgLanguageBase *dlgBase; + KCompletion * completion1; + KCompletion * completion2; + +}; + +#endif diff --git a/kwordquiz/src/dlglanguagebase.ui b/kwordquiz/src/dlglanguagebase.ui new file mode 100644 index 00000000..0db87f5e --- /dev/null +++ b/kwordquiz/src/dlglanguagebase.ui @@ -0,0 +1,244 @@ + +DlgLanguageBase + + + DlgLanguageBase + + + + 0 + 1 + 250 + 120 + + + + + 5 + 0 + 0 + 0 + + + + + 250 + 120 + + + + + unnamed + + + 0 + + + + layout2 + + + + unnamed + + + + picLanguage1 + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Title for the left column + + + Enter a title (identifier) for the left column + + + + + txtLanguage1 + + + + 5 + 0 + 0 + 0 + + + + LineEditPanel + + + Sunken + + + AlignAuto + + + Title for the left column + + + Enter a title (identifier) for the left column + + + + + lblLanguage1 + + + &Column 1: + + + txtLanguage1 + + + Title for the left column + + + Enter a title (identifier) for the left column + + + + + spacer13 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + layout2_2 + + + + unnamed + + + + picLanguage2 + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Title for the right column + + + Enter a title (identifier) for the right column + + + + + txtLanguage2 + + + + 5 + 0 + 0 + 0 + + + + AlignAuto + + + Title for the right column + + + Enter a title (identifier) for the right column + + + + + lblLanguage2 + + + C&olumn 2: + + + txtLanguage2 + + + Title for the right column + + + Enter a title (identifier) for the right column + + + + + spacer13_2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + + + 789cdd9c5b532bb992a8dff7afe8d87adb31a1c1601b3b4e9c0783c10603b6b9c3c43ce85a36b631e03b13e7bf9f943253948d59cdea5e3dd3319b702f3eaa4a522a2fca94cafbdffff5db7de7fcb77ffdfb3f265335ed9bdf4c4fbdfdf62f3b1b8d56fff19ffff7bffef1cfc2cece6fe153aa947fdbfde7bffde39f62f99bf94decc4ff45ae26ae045653e6025e5f1017f17e2513e3fd1366ba7f4e5ca1fb8f13e3fd7bcc78bf3d4f8cd7793c069ff72f89e3754dfd1768fcb64e4ce3d327912b69bcb3c4d8fe1133f6efde1363fba7c43c7e9118afdf31d3f31789f1fa0b318ddf5e24c6fee7cc345f156496c71d24c6f60e99b17db12226f904c957a0f1ea2131f56f7460688dfa736d64ee2f1b33e3753320e6f6f97e6a5f7488a97d5547de657bf2c4f47ccf12d3f32e8ebf50e1fbd53d31ddef9b89515e47ccfa50c4d47f16e77b37f5a70bc43c1f2362ba5f64c87b3cde77627ade548859defdc855be3f9b27467d5e11b3bd9d1373ff07c4d4bff3c8456acfc4fbf70a7cbf1a10b3feee13637fd7c8fcbce825c6eb6fc4341e3b4a1caffb2366d2f79298fab7515f7b697cba45ccf36312a37e2e98c99ea7c43c7fddc438be0531ebc3248ed73394af5a2ad17862fc2816f8793721e6f9dc4f8cf25d30e378b4412eb1bd9d258ef79b17661a7f8d98fa77d5c4f1fe9e24aed2f89f12c7eb5621972dcd6f8c7745552ad1785e89e97eb360a6eb15e4728138f65fda2d59f47f7fc2bc5b8de39b22970bd4de09333dbf434cfd672a31de7fc7bc8bf26a6292cff3f396e6b71859b1bd0b4b4cface9e91cb85bd42ec7f9798e64f1d3253fcaf11d37c8832335ef77bc4dcff03333d7f9818e3e58019e551288fdaa7f9300789f1fe1a33de9f758959ffa3c4d87f8f199fb7515fe55df61777835caeeea17e14318dcf1d33d37c779871befc5be2f87cd640e6f1ab62626c6fc68cedd923621a9fdf65c6eb3d474cfa7565665a5f1433dd6f8869fc59d4775925ffed27c6f11499c9fece90d378de99d17e7d8d19e5b737c4341ef7c88cf78b0362d2bf1689f1fe2133cdc77d62ec6f8a5ca1f95337cca4ffa89ffd3d66bb4c1c9f57cc349ffe3e315e7f20a6f1660b66942f8bf6baafd99e8c424ef79f3193ff3c13b33dbf26c6fbb17f5d2579b23b661a9f4b1cefd77d66b2b7d87e656f9ffc4f3d31533cd4c434dfaa815c617faa12933cba8e9cfa7b63c6fec49098e64bbf33e375d727a6f9502d661aaf4f8cf2e378358fcfe278358fcf0f89697c599999aedf25467dec13737c6e3293bf4f99c95e70fcba4afa106fcc38be9e42566c3f17cc64efcdc4689fa7c4ec1f7566b29f7ee278dd9602c3f24ae3f30b66b2df4962ec7f9798fd859fa7f1eb5be6928aedcd98cbb17e702fc86c6fb6cd8cfde93d6496372b31d3784f88491ef39018fb77cc45b4ff15b1a2e787ccc538be8cef77d89fb965c6fb8564c6f60ccd87dea5f86798c95fca89317e3f3393fd92fcba4cf9c93c31fa0fc9a715b57f9f18f573c94cf617e349d5b07ff7047295ecd7b59869bd386426fd30737ef1c48cf78b0131d9835789513f381f86e7d78c8969fecc9c19e74ff591613e707ecf98f17a56481cc76769fc3c5f3d9f18ed6fc14cf9c90d338e57de31637fca30537f9ab984f5ed0931cdbfda498cfa7966c6fee469e2785d72ff8afcf32171ec5fce881db62f6b89f1f91533b57f9018fb7f6746f9cc5562948fe435649f729c18db1f3053fbf3c4389f9298e65b1c27c6f5fd9199e2fb1131cd8f8dd75591d73b3121a678944d99697eae89d99e9ac464cfe21c19127ab4873133c6137d8fac77517fbe414cfab667cca86f9bae937d09667c3e5b12933e759199fc87db637d3e3053fb6f89b1fd7d666cdfec1093be6d8199fc799c18d78f1633f56f13637ce931e37ccaabc4e87f65661c9f4bedd3f8d2f3383ebb8b9cece73d31da4fc64cf6534f8cd74f98c9ffda89713c7d668a87cf89713e69bc6c7fd226c6f60533f5af13e3f523665a4f1689713d34cc940f5412e37a4bf361c8ffe579626c7fc24cfda7fb495f5d66ea8fc74bf1c0f37cb0ff9f25c6e76f98c91fe37aa80ce7431ee73f748ff1e09298fcc10c89693c42103bbc6eabc86c1fee9c19edc39f25c6f511c76b589ffa8331de8c9929be1698c9de4462b4b73e33f903c9c3fad4978951be3233c583d3c4b8de3798c9febb89713ce97e5abfd3fd349e0e33d9ff1d31e9dbb03cacef97c4980f5e3053bef49e18ed798f99f2f171628c8f57cc383eb99318c73763c6f1a97d62b21fbb9718ede59a99e2f35d62b4df0a33e98fe79fe287b9488cf118e3b9b1e4ffd63393bd1f31537e10f5ab8b9c6f9b4b64b657fb424cf3632c33cd4f62ca176b89d11e9969bc593531fac73e32afff2e2366fdbc22b33d6434bee4af57cc643f3566b29fb7c4713cbacc4cebcf3c318ef78198e65f6b66f2a7476692ff3a31f63f62a6f16689b17d816cd91f3bccb4be7613a37ccce43f16e5b59c8f659298c73f60c6f9d73d621a9fbd64a6eb536443eb89bf41b6ec6f31df3625cecffd71e2785d1c22737cc9f69929bf4f4ccf3f3163ff66454cf2a92133f9db8819edcb1788d91f7789c9bffc6d62ccbf2533e98bc66f69bd543e31fa478798f3d54b66f2cf2233ce574f13933d8958ff18cbf2bb2633d9e36b629cdf6762b26fcdf797717ed401f3fe5e9cdf2231fb9f4f8cfd9d32533c7f60a6e75f13eb383fe7c41c8fee9829bf1925c67874cb4cf1fb3e31eabfc74cfe963163ffa281ccf32f0a89b1fd4366da6f9089717c27cc141fca89317e5f33d3fec25162bc3e25e67ca59918fb5f32d3fab1488cf6f1ce4cf9fc1333daa7dc27e67c649418dbe7fb697d12b789b1fd1e33c5e7c7c4387eb22f4bf62e1e1263feb0c34ced937e1ccd6f16d7275b4af1f09c19f5638ac49c5f4c12a3bf5f32a3fde80e72d24f8399f6af1e99291e9e3053fede62a6fe0f13c7f6cd1931e947779929ff2825c6f5ea8099e2f52c31c623c54cf6719518e3c92b338d779719f5ab6e1363bc3d67a6f14e8959ffcf8951ff4366b22f9718aff37c90fef53c31ea9fe79bfc5fb513a37c4b668a37c7ccb83ee807669287e793f35b93388ea7cbf2707dab12e378b97dae6fdb89315fe0f9a778e15e1363bce2f975b4bf41f23bae671a89b13fcf4ce3e927c6eb4566ca27687e1dd7c737cc145fea89d13fd01e1cdb83b7cc149f2789e378dd8019edd9d599d19e5d2171b48f2c5dafe0f52762ae577712a33e2f98297f3a488cf6f0c84cfb352f89713eaf99697de7f152fc7715661c8ff1c4a4efec28319e8765cca45fee9fd783cbc4986f707f144f6c9119f56d4acc688fd92a31daeb0d338d17edd5b13d985d66b287d7c4680f17cc148f2a89d1dfaf9969fca93dd27f6a8ffc69c48ce3975566f2a766628c0f7bccb4fef1755e5fde1263fde498a97e1a3393ff2c1363be6499c93eaf98291f3c25e6fac733533e19e3992b27fdec2446fd08661cbf5d25467bee30933da7f6aa268ebf85ccf3e7e689b17dc74cfabf4d8cf94f8f19fb57a5c4680f6fccd8bfa813f37ed21333d56b85c4987f9d32533d9e98e4ab3063fbbe9a385eb78698d7ef6766b2af3d66aaafae13e3f832665a6f3b89717c9299f235969feb8d1533d517717d71ce703cc5eb8ef5e10f985531de3f4276bb2a5ecf7688393f3862a67a7bc14cf3a113e37cbd1173fd639829bec4facc97395e76a752fc551fa9d67ed7e193d8484b9f5fd257b4adbf4c92dff9b024f6d7b4f70bf46273f3fb33a3b37f3fbd6c93647394e1df5f35e2bf542fbf2bdd97f705ff711ffef33faf976f48f3f57dead749f2d7e8a5fb850ffdc80affbe7af949e9fe667a913efe9bc1a727fbc04f72107c81d694644d72087ff7f019c5fb07c0bdbf975ee4b31cc3e8b2f8fb531ca100895ee42b48865264f0f70c7eefc1dff0f77e9422fb75baff157a916f7202a31bc3ef93a01f906a1cad27483895b3a40f9426e8692e17f059ca157c7e9934bfcc5fde499249f7c337de41aaf06f2de88c22f0813c9475f8f7481e477db1b5fd3df462e3881b2049187553d672d7344950877fc3e84f401fa7b205bc8cf786e7cefe56ebfe398ce83c5ad710467e01236ec9b6ecc8aebc9457f25adec85b7927efe5837c943bb2007fdf957bb208f77a78aef4b7cac71ab22cf741925759915518e9a390420825b430c20a277cfc7122133dd1174f62208662249ec518ee1f8a975f23c937f5f2d53af0b1468cc08b5bb22b5ec59b9888298c7a26e662113f0bb14c3f8bf8b7b9588977511307e2109ea9831ec10a49c77f62bdf9865ea07571049fe3d81bd5201051df055896688a13b914a7a225cec4b9b810ed385efe597ef1b320a93aa20bfabb1457e21ae25a13dabb81d817e21c4407710b3ef524ee7e9d5ec25c897b71241ec4a3d841494401e2d29bac895d99893d5114255116fba212475fa59fed52d0552595883c176da594564659880e4d39863e7ac1974012ad9c14caff6abd8034c71b7fafc985ca544ff5d5931a901c4b58e27f24c987a4511efa5bb4399067a846b2aa9e21c6853c2244795869d5f3aff517d0c9b178483e029605bd2dd458bda857f5066321bb49a3fbd14f554dd4544d493b3325d43c3ebd520bb594776aa5de6155653f8cbaf9657a818f785cf3f67dd0494bd5d4813a54f5a00f18ddd1b7e4d8ae1f904c1d470feaa806b864531e515f13ca80be55b77e6f7d011b6649cad2a81379a14e554b9db187f03c7fe1f15bac2ed922cb328d770469ced5856aab0e4497719466f4dddcfa67d697d08aea424b2d90e4525dc551a3657df6908d79cf4704b02a815a041b93f1e9656a01a29bba5637ea569c82df8c5557dd7d773fe1a7d67d6cc9c92ef4754f92a007e0983ecbb1ce7949513b22d74a2e5eab2bf5a01ec529f41956e15fa897b89e044d3fab1dd04941edc21abe483d2f29ba92ad241d6cae26acc563b5b7666dc71bfac4c8d65145555265d150fb30f231c74e5805c49fd24b584f2cc4ae9aaa8075dda024a489bc7682241335c9594b55556141aa5316d3d1f2432a904992ce3017f8b056fc4ba685565ac38a8c33fa8c151fac6b7f228ec1a0438d31910ea2f0255817dbcd5a9ccd6963a1aa30af57daa862783b437b657426ce744ff7f5931e88773d8c630ff391a233fb4fa2851ee967d5830c47c55a35dbac41377de75b7aa9c15c8ce5428fc5103d3ecdfd7a4c8a72e81798d157fda6277a2a5a6aac67b2ade77a0159ca1ee4cd5dbdd42bfdae6bfa4085f95feac3a0d10d6f8a57c45c1fe8ba3e8af91a57dba1a25bf75ff3337ad1c790393addd04d6d3806873ef5893e4149a09b53d4876ee9337d2eaff4856eeb8e7ad65d7d09f973a8d0c6a1b681d834d057fa5adf80be6e216f9e518b47fa2e274fb23b68ef5e3f40bd730855dc7194e6e58feb25aef3bbfa51bde81d584f72512748425a89feaa0b7a57c3dceba22e41ef43b08a67a82d3f624f19227aa875ac5cc2dabeabcb7a5f5770b54dfeb74c5eb8040d2fc3571e20da54e4819190af85aaee625d920f69be938f858cc508a362af148df2b1c7e8208931c6aa82713233dea44f9468147339aaa031af83d5f7c0f44cdf3c09a95b66c0313145c565eaa76d8672cf8c623d7a0075a9a6b3834f113ae9656bcca63b67e6d98cd535e5e9eb768d51b96a5eccab7933d24ce2fd50ff834e50922154070f297f08f57d2d4a86fff6cccccccd4261ce508dfa11498ee839666956fadabc83242e561b5f783fe96573059a446f1fc949b00add3535f5847d7dac886a167a0a3ad1d21c9843358679d39b3d40ef022439377588454f513763f8d4a22787dda7913932c7a6619a20cd32facc7a061167cb9c9853d33267716f67b231d60d7fd996190449a4870ce2192aad92395f8b5e791bab286d56e6c2b421428ce28e44b2006aeb1cd6ee71c8504d07ee299aaeb93457e65a1e74a7e606fe36d073736bee82377eca50638fe6de3c9847b363a6a600d270dbb88bf8298e6d6606618fcbec823453b952a1d2aa444baef2eaf8517b983d53d4637d15ade7431f79ddf8e073308aa6ac87b7ebccbea998aa7c901df08166ccec07166eb14accc5664683b20cac5605d071668dd94927216add23d6fc85e7318b1174640ae15fd386ea773f579d2c28178c2b80b5d68967b0ae41da59f29f62ff4436ac87bf1fd8ccf620b10c7b011d5db37dfb04d2bc8963b8766207766847719d5d7efa59887dfbac1b20cd4b58ff7fbceeaf9dfc3c7de43c52e9b11d07ade00a927c3efaaa1ed917fb0a92d450276091bc139bcf041b7206f3af55d3bed90948829e3db3533b338f760ecf9c419e756a17ba4f99dea78c4e55edd2ae62eefc65ccddaa97b07b3dc18ccebe8b5763a25672d105d76968bf665fed01659e0d90e4637f381f3143ae7b20eaa08743a88617316fdb130b5bb747f2c1cce44a3cc0b34dfb2e1fe18e799226c902f3b8b0c7b62177ed1c2c3fe688bfab17d4c5906a39a8ef4cc93643f457722d8b3c8a73756d4feca96dc50861d0c369377c4d2f100b05e8e40c74d20e966acfd554dfd90bf8fddeb66d07fc26cc1ef467bbf6529d7f96255a77c75ea99a3c8c96ffc957d6d7fd9c957155ba5215f16cafd76331b40cd970885ff6c6deca4c75ed5dac311a3133ef51be142428f3ec80ee1eec7dc85762865f4d2b53b0b44358ffe7200db4a19c7db08f49331b3e0356b6630b1cc368cc5fe4c9492f7df2e42164758f621abd3d9f2be1ef993e8798efedee9a4e794d6ed8bd58837aa96d112429814e3eea938fea07565fd33465b10795f7be9cd8b2dd17595a29f39a99db8a69e86e5c63dee32a9c93ea533e96f40277865a5be89990b1e5cd1a31645fafb6aa4b90a97c3ea77f97fb4eca1246023d77c229d189f9c1346a784135d931c9e39d7606f22c68432fd4a37e8558365fd74ab48b4c7bc8c74cca29e2783fac6dab5e9e409a303a50b9103193cd6985f2f30e64f517b05ef82d156cc349e7c07f208ad8a229839f743e2a2dca1de72926423eecbccb541667f3c2f520afab6fca12fb9cb9be7b42bde4c7fba55ec2d503b0b2f0bb961da152afec2bd3188ff7dd40b7e5d0649f6b71bb07d612f6fd57622cafdc3066d74bf0f50ffb9ca79dc11043ea6ee49ec1a7c2e8408ff60daaa46d7a9943a5d98816f6bc9ebd6cd74bd45a5891a25e6457e8f5ac38ca125a357aaa3b21275ecbeae913a3f3ca94dcd8bd400db9998d522e4cffadea27fbe05e61d584100715f1917b7393cd5c1c23a79bca4b5b60bd7c1dc7727ad1f235daba06cf375bf402fdbb999bbb45981ff0c6cdf5246425076ee9c610a3861fa3a21c283fd30bb7720a3cff5a2fe4b1087dcee4b1aa294d7a495eeadea306175055c85817fd60dd5fd34ba8afa771f7e84ad88df989b2e8175783eab71be209ccd370a352e863de65db411277c092e42a131a254872e884aa88c7986bf8b827aaa19a7b43bbdcf0d2853a7775d0dff067f4029f19fc5e7747b9dd2392258ea20215ae82ea37647ac34fad9ec88e29839fcca224dbcf2e62d5e38e21c635e4aa8b15b48d35e7d0f45d33643a1f15265927e44cf2c19d44bd64f1acfad3fa928f075137c3384763092b97f01bd10433b18e3b956d58e38335854aeb3c663d0d5ce365d509885d2bc13b636bbb983196cd43eeeb5aee2cf85cdc91005b804a6d126b9b96bc83c8b74c5979925fdd9ba26975b12eaa6fadf7795d0927a4fcbb8d91f97e8b2c31f228036b35546ae2184660696f71164efaec813b57c53816cea6f33b97f05f0711cdb55dc7ee9b47f9eebae2d15dca41771a33d449b05077055139e9efe3c7ad20133aa0b1ba6dfb30b91a10d7151f77d6b2303fb41bb66ee7b0bae90cbc15b246f28fb168baebb85f5385de4a6ef5a90ac9af5093e87137ee56d5dc5d8c83e3a893a6bb8f33d8326592654333e05f0fb2dd455faeaf4bb2a9972e9f1484753f6430f7e02f9f6559424f67e23aec5cc75385b00317768dea02f4e51ee339df3cae279feb449446461b9b99a2b3f210ea977dd0ef4d9046d6c46d58fbb7cb02337be676a22724bd7c11c738bfc57727825e1ec4fb3659445bf7e41ef45c0ef956acdb9b908936210a4fd06b697f683d766db6b252455780356c27ae47e1ac32ccc891dbd5ab64a36bb2e811d4b0a817f53beb3ee7c7b1b604b94fd48be86d89420b2d755f5eca5af0f4601d50b3d76d16d69390ad802413cc56482b1ff6f5b1d66056d67133f562baf1c415779b2012e886dbd3bcd7bc66db6a60dff42cc52ffb398e7dd2cb285acd4a2ecc9b2b26efcdc7d3857e925db8ef1cee1bc0480650e7f45d89b2faf5dde5f52a31c5d890f902b5ddb1bc852aac089e3fc57c415eba72ccd8d253bc0feff65d45174356f9bbf918eb2554541aaad1035970d5cf356b388fd303bd04cb6a80ad8fe0031924f8498724c99fc66ca97863b54d11117e9faba5975e885b9a49a50a7a27d6b19bb2406e0eb37b22b3cd68fcb55e50d3d1bbba1ef746aa187d30878a678b99b935a3b8f73596debe9bfde8271388b7391b671bd377318bcbd72e6ba702f6c86b6f42cd08ba29bbba1ead9db655e933b74b6f21220db79f8d7dd4fb1bfe12f69e56e6d13b5bc7fa85f6c379077be6bd1e530d39f099a9048bc12c3a9e76e54e95e339f152cdd662dac78a13ac69e67b50b7847d9615d43b7d5a29391395342b2bdf975d5dfaeafd8c5cbdcfefded9f8864ef834f5c23f855a8c4f2592ed40ffbae607a615f622bb5373e587d1c226246bb49de417b032c67deefc89eb5a2c09b5b2d27ea0c67ea44efd33dbc2872c61f7024672664a7ebc916d6de865631f70104f6efa216715cfa2966c378dc1bfc0680fb4f3afe05323f0fc6b37d6b5b0c742abcab1205d60ecf56ffe2dd6c81f275f6b9131ec63e82158da4497e1334a15f2878d85385113ad6861298649b7a99794a97fbc13d983cf24be7bb4eba77882951f43d47ad5cffcdcf4c23b2bea59766cc72fe219de9cf69f78c7bee29756f8957f0fb26edb95e04a135aacf9038821959caf7d686eee0ff5b53cc4f31789a7c0f54f7ae1bc46939cc1f333e9a16637f6ddd771d721d999e0f5c11ff9636f82bfc0e7d46676668fe2f972ae6684ace3d837e4a57983357e462be0b695339c1c2d7dd39fc43dd28d739110f9dcca9faa8adaa1fd314b39d9d77ac9cb697d0ba459aa82e8867ed0ced28a1ea2da4c57cc13e8700455d4523d9b47a8235b71f6298aaa7b77e8432efceecfc3d7c4409af6b60a2044f2584fe457a0b56c1fb472211f3d6456f62ef9f78ff4b2fe0d8f916f439ef4e23b601ded0f59282e4f54b0e00e7863db7721ab1ccb377f691e4dc31eaa2a595aac4f689d9ec9437fe5afddf1a777cad8cec239f4514e53496bd1eb2a6ee66ffc2dccda738a63fa4bbd6c56541c2b4ecc61f046f04f8acbd1226847595d9bb90e6f633dc0fd2559d373f09bbbb88fe2f5933b5395304350379a503b7aa1bdbfcfedc17cb6b5ed36b8506f1a72f0b882e77712d7dea2ffc679a5b3affe219e594c5916b0df2a67bb66cf09ff28e790659e8134e12ca5ec779cf73bf2ce2d630419407d3296fb90a1f4e59e2ff8dd8fda19e3dec6cfa6dec0977c3883ae4306cb3bbce1ec33bfbb28be755e5917d7e2cc435e06abdd3445fc2aed2a877876a75756ca23b10b2a6fcacc977cd9efbb67a8db17e17dd798b3ed40a61376dd8bbee2abf6d0d653cdf9f5cf8225d30799cc449c0dbfbe37f1653eb65d2f433f162da762cd9bab0ef3eb76a6326d0771ad811a53edc8a2ca4c3b9e9486dddc90c94f20030dbb7f509f78235ecd01f8dafcd38ede7689c2be585821cbbe15ebaab59344f9e95cec87d23475db3e4334db7c03b19ade355c596587194470d9c45a24beb33f044f7d0b6fd1a9b07b0ed2844c14da3b947bfac61e85d528bc79f1a53e88322827322f67be05d1a8b97ebef3937a31f64e77b3cc2e537db45157847c0b6257176a9a4758cd2e624f633a459ac47797f7d549ace54d3cdd10ba64fa59cfd7a096c6e8bee527bdc3d4cefa100b75f0f650c7e623d3d7f5cb171febba66c738dfc89ed25efdc6592faddcce1e660379073d9f440f1d8993a8a3463a01b771dfed5966ee241b66a3ec3937ff9fb413a4c9c6d94bf62adb21fac6d1f7ff9c5e606d78b685ec2d9bc4b76116b9d17ff82f9ed0cfd57936b50df908955a2beeebe8f8b6bb8ff56788412ba84fca7aae4eb399af65f3ad922cd6fedbce16e05f7d23e1799fde87d9f256dc77fcc578f9220ad9325b65ef6a90ab3ff23d7f44d3b9b0e624abf9335552b5ecc0f4e3feceb15ed8a2dc93bb90070ff47b16d6ac4a3a0d597c9221af9faaae6575d9056942b634e62c78d3d2bef59e523d3b0afbc6309f2a3ba67713319be1774af27e1462a854f7ea5c9baca1dfac537d796f1fe4bdaf674da5cd0948d149d5da3427cb57710cf20b3dc84ed408e2e2383ba59d3eb76969df8a63ad78cef22e87fa316b6567319a2e37eae0cdea2afe80ddad445bd5e1e71eb2ce4ed4447edc5fbfc79cff09963803dd9c9b0be814cf5edcdafbb1df5e5f401f257ce7283bd20df5e8665861c4ba3d9f9b6fd6599b59227b7435f72ee3276fdf9aab85b7af86aeacdad945fefb327f607d71591bdfa0323bbaa31b59c70d7521b6ff92deb85aef7b9d271be3de26f12249b34533f1cc0f32bc2cf8cc4bfe74e4e7e258770a95d685be0ce72c419aec28bbccaef4339d5d2fb6d589e84ff9357543675f672f5ffc3d444955cdaeb39bdcfefecfaf2f229ee4b910014c16562cd1d03abbcdee742bd8ffefbcc10f95bf12f49ee88fa58857b3f117511a2481787f0fb1307eef89e3d8cfea257b100dc8b1c27adeb4bbaa9b3dca10db76b282ae6eafad7e67a6d7bd9f779a16712d79a16f9dacc92166a097cc7b5980f885ebcba7b7bbbea9974fe791615e4c2bdb356533343f8ea8db24d894a58adffb81bcab9fbd668bfc9bbf51b332aec1fd6c2fec5ca4efc37cfd5edf0fb3984f92f4219e1ccb1331565956d43be6dee01abae9bb5bb29d8d484eebab3ed022737ae66cc8a1437d0355e941bcba024916ea02f2f093f056fcb631fd09bd34e33996867cf7d4ed42942e65a5ac0cb1a0c2bb16f86eac3a72ef9b6febe2fe6c7c6f96bf9b54516f7e2f937a9c85330367faaea207f1ad82397a7cf8b642667443dce2fbb49bb3fc33feb22e114683f87dbd2358870f8c5465f3a8c6d9be7b145dc87cd7ab926d5181f759e6c2f90b7b08d5ef6516fa9885730350fb557612a599c71385916dda816e403416a2f9a331fe91eff1c9b7b8af99c5ef4c424e200ae13d7f7f9555ec5b56758fb692befbb6593ba6efbea9ab9eec899e928f3d0d757c1dea9b5069851abe674047e2b5677a36e8047237f093b0731e74124ebabe1ad71ffa7e2546c566fc06ee0a2276219c27c3fa7302faa9b9b96968effa5ab829d8f9b91ea97bb7722b750fbf0ddcbe7eb54bdfb7676eaeaf55c58fc15275a8e042a5456f0365d0ee9e6af75c4f66f7fe35fa89a0b759c59f5bf7373ffa38be27abe3bb62606de6cc14ac811a72d8f3fe5cae40aaba7bd20d79a94e5d5d3e98228cfc419c99a23f035f284bb048736c5aba84ef06c0487bf1dcba194f5e076657865df7233fca6ecc28eeba0e3667f20fc7b1cf5616f69b47f13bdf427ad44bd8b732bba6907a809a076cfcd49d98963dd0ed5ea6db7a6e5aaee1c7f45e398f084f4b86b1ca0adf210fb9f038ec208691cb66fc17bfb91ddeb3ed7f8e487f5c2f5f44eb8fbfe1db37e96debb559c0b7afb7b5f5e9adc32d7b765bfbff53fef22349c2e73d274d7aa76833b26fb779948af623d7fefefbffdf187f462f5b4686dfec58d7454695537dcb7bf8fc3e26ee41e6f6b5a9d212b93d6e9ddf21def6f9febaff03bd6cfe7dcd8ae0f73ad781db6680f720d7f20aaab4481fbf4e2f5b6b85fca836e6ec2b2bfafc779450ffc8fabe691bdfd4cb57954fbea5b5f381ef49a293e56dd1d79a8e7e20d14fc7b1af3cfc47d6f7831eb75c5faf45c2bde5dcfddbfa4dedfa56aff74bf5f2390ead7be997a3c9dfbf16d5736dfe6016e09e5e0f329f3f9027ffde7dbfeaf3ddfe7ecdbafff7fcfcd5ffbf70ff9d9fff557af97fffe71fff1f2192a73f + + + + diff --git a/kwordquiz/src/dlgrc.cpp b/kwordquiz/src/dlgrc.cpp new file mode 100644 index 00000000..07694b63 --- /dev/null +++ b/kwordquiz/src/dlgrc.cpp @@ -0,0 +1,65 @@ +/*************************************************************************** + dlglrc.cpp - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include "dlgrc.h" + +DlgRC::DlgRC(QWidget *parent, const char *name, bool modal): KDialogBase(Swallow, i18n("Rows & Columns"), Ok|Cancel, Ok, parent, name, modal, true) +{ + dlgBase = new DlgRCBase( this, "Dlg" ); + setMainWidget(dlgBase); + dlgBase->txtNumRows->setFocus(); +} + + +DlgRC::~DlgRC() +{ +} + +void DlgRC::setNumRows( int r ) +{ + dlgBase->txtNumRows->setText(QString::number(r, 10)); +} + +void DlgRC::setRowHeight( int h ) +{ + dlgBase->txtRowHeight->setText(QString::number(h, 10)); +} + +void DlgRC::setColWidth( int w ) +{ + dlgBase->txtColWidth->setText(QString::number(w, 10)); +} + +int DlgRC::numRows( ) +{ + return dlgBase->txtNumRows->text().toInt(); +} + +int DlgRC::rowHeight( ) +{ + return dlgBase->txtRowHeight->text().toInt(); +} + +int DlgRC::colWidth( ) +{ + return dlgBase->txtColWidth->text().toInt(); +} + + +#include "dlgrc.moc" diff --git a/kwordquiz/src/dlgrc.h b/kwordquiz/src/dlgrc.h new file mode 100644 index 00000000..3bf3c077 --- /dev/null +++ b/kwordquiz/src/dlgrc.h @@ -0,0 +1,46 @@ +/*************************************************************************** + dlglrc.h - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DLGRC_H +#define DLGRC_H + +#include + +#include "dlgrcbase.h" + +/** +@author Peter Hedlund +*/ +class DlgRC : public KDialogBase +{ +Q_OBJECT +public: + DlgRC(QWidget *parent = 0, const char *name = 0, bool modal=true); + + ~DlgRC(); + void setNumRows(int r); + void setRowHeight(int h); + void setColWidth(int w); + int numRows(); + int rowHeight(); + int colWidth(); + +private: + DlgRCBase *dlgBase; + +}; + +#endif diff --git a/kwordquiz/src/dlgrcbase.ui b/kwordquiz/src/dlgrcbase.ui new file mode 100644 index 00000000..1ee9a6f4 --- /dev/null +++ b/kwordquiz/src/dlgrcbase.ui @@ -0,0 +1,182 @@ + +DlgRCBase + + + DlgRCBase + + + + 0 + 0 + 200 + 156 + + + + + 200 + 150 + + + + + unnamed + + + 0 + + + + layout4 + + + + unnamed + + + + txtNumRows + + + LineEditPanel + + + 5 + + + AlignAuto + + + 0123456789 + + + Number of rows + + + Enter the number of rows the vocabulary should have + + + + + lblNumRows + + + &Number of rows: + + + txtNumRows + + + Number of rows + + + Enter the number of rows the vocabulary should have + + + + + + + layout5 + + + + unnamed + + + + txtRowHeight + + + LineEditPanel + + + 4 + + + 0123456789 + + + Height of selected row + + + Enter the height (in pixels) for the selected row(s) + + + + + lblRowHeight + + + &Row height: + + + txtRowHeight + + + Height of selected row + + + Enter the height (in pixels) for the selected row(s) + + + + + + + layout3 + + + + unnamed + + + + lblColWidth + + + Column &width: + + + txtColWidth + + + Width of selected column + + + Enter the width (in pixels) for the selected column(s) + + + + + txtColWidth + + + LineEditPanel + + + 4 + + + 0123456789 + + + Width of selected column + + + Enter the width (in pixels) for the selected column(s) + + + + + + + + + + + krestrictedline.h + krestrictedline.h + krestrictedline.h + + diff --git a/kwordquiz/src/dlgsort.cpp b/kwordquiz/src/dlgsort.cpp new file mode 100644 index 00000000..cb96c945 --- /dev/null +++ b/kwordquiz/src/dlgsort.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + dlglsort.cpp - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include + +#include "dlgsort.h" + + +DlgSort::DlgSort(QWidget *parent, const char *name, bool modal): KDialogBase(Swallow, i18n("Sort"), Ok|Cancel, Ok, parent, name, modal, true) +{ + dlgBase = new DlgSortBase( this, "Dlg" ); + setMainWidget(dlgBase); + + dlgBase->optLang1->setChecked(true); + dlgBase->optAscending->setChecked(true); + dlgBase->optLang1->setFocus(); +} + +DlgSort::~DlgSort() +{ +} + +bool DlgSort::base( ) +{ + return dlgBase->optLang1->isChecked(); +} + +bool DlgSort::ascending( ) +{ + return dlgBase->optAscending->isChecked(); +} + +void DlgSort::setLanguage( int index, const QString & lang ) +{ + if (index == 1) { + dlgBase->optLang1 -> setText("&1 " + lang); + } + else + { + dlgBase->optLang2 -> setText("&2 " + lang); + } +} + + +#include "dlgsort.moc" diff --git a/kwordquiz/src/dlgsort.h b/kwordquiz/src/dlgsort.h new file mode 100644 index 00000000..8642eb62 --- /dev/null +++ b/kwordquiz/src/dlgsort.h @@ -0,0 +1,44 @@ +/*************************************************************************** + dlglsort.h - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DLGSORT_H +#define DLGSORT_H + +#include + +#include "dlgsortbase.h" + +/** +@author Peter Hedlund +*/ +class DlgSort : public KDialogBase +{ +Q_OBJECT +public: + + DlgSort(QWidget *parent = 0, const char *name = 0, bool modal=true); + ~DlgSort(); + + bool base(); + bool ascending(); + void setLanguage(int index, const QString &lang); + +private: + DlgSortBase *dlgBase; + +}; + +#endif diff --git a/kwordquiz/src/dlgsortbase.ui b/kwordquiz/src/dlgsortbase.ui new file mode 100644 index 00000000..e2e7e3f6 --- /dev/null +++ b/kwordquiz/src/dlgsortbase.ui @@ -0,0 +1,143 @@ + +DlgSortBase + + + DlgSortBase + + + + 0 + 0 + 200 + 176 + + + + + 5 + 5 + 0 + 0 + + + + + 200 + 170 + + + + + unnamed + + + 0 + + + + layout6 + + + + unnamed + + + + grpBase + + + Based On + + + Sort based on this column + + + Select the column on which you want to base the sort + + + + unnamed + + + + optLang1 + + + &1 Language 1 + + + Sort based on this column + + + Select to sort based on the left column + + + + + optLang2 + + + &2 Language 2 + + + Sort based on this column + + + Select to sort based on the right column + + + + + + + grpDirection + + + Direction + + + Sort in this direction + + + Select direction for the sort + + + + unnamed + + + + optAscending + + + &Ascending + + + Sort in this direction + + + Select to sort in ascending order + + + + + optDescending + + + &Descending + + + Sort in this direction + + + Select to sort in descending order + + + + + + + + + + diff --git a/kwordquiz/src/dlgspecchar.cpp b/kwordquiz/src/dlgspecchar.cpp new file mode 100644 index 00000000..e35fe236 --- /dev/null +++ b/kwordquiz/src/dlgspecchar.cpp @@ -0,0 +1,82 @@ +/*************************************************************************** + dlglspecchar.cpp - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "dlgspecchar.h" + +#include + +#include +#include +#include + +DlgSpecChar::DlgSpecChar( QWidget *parent, const char *name, const QString &_font, const QChar &_chr, bool _modal ) + : KDialogBase( Plain, i18n("Select Character"), User1 | Cancel, User1 , parent, name, _modal ) +{ + initDialog(_chr,_font,true); + + setButtonText( User1, i18n("&Select") ); + setButtonTip( User1, i18n("Select this character") ); + +} + +void DlgSpecChar::initDialog(const QChar &_chr, const QString &_font, bool /*_enableFont*/) +{ + QWidget *page = plainPage(); + + grid = new QGridLayout( page, 1, 1, KDialog::marginHint(), KDialog::spacingHint() ); + + int t = (_chr.unicode()/256); + + charSelect = new KCharSelect( page, "", _font, _chr, t); + connect(charSelect, SIGNAL(doubleClicked()),this, SLOT(slotDoubleClicked())); + charSelect->resize( charSelect->sizeHint() ); + charSelect->enableFontCombo( false ); + grid->addWidget( charSelect, 0, 0 ); + + grid->addColSpacing( 0, charSelect->width() ); + grid->addRowSpacing( 0, charSelect->height() ); + grid->setRowStretch( 0, 0 ); + charSelect->setFocus(); +} + +DlgSpecChar::~DlgSpecChar() +{ +} + +void DlgSpecChar::closeDialog() +{ + KDialogBase::close(); +} + +QChar DlgSpecChar::chr() +{ + return charSelect->chr(); +} + +void DlgSpecChar::slotDoubleClicked() +{ + emit insertChar(chr()); + closeDialog(); +} + +void DlgSpecChar::slotUser1( ) +{ + emit insertChar(chr()); + closeDialog(); +} + + +#include "dlgspecchar.moc" diff --git a/kwordquiz/src/dlgspecchar.h b/kwordquiz/src/dlgspecchar.h new file mode 100644 index 00000000..f2a18c8d --- /dev/null +++ b/kwordquiz/src/dlgspecchar.h @@ -0,0 +1,63 @@ +/*************************************************************************** + dlglspecchar.h - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DLGSPECCHAR_H +#define DLGSPECCHAR_H + +#include + +class QWidget; +class QGridLayout; +class QPushButton; +class KCharSelect; +class KButtonBox; + +/** +@author Peter Hedlund +*/ +class DlgSpecChar : public KDialogBase +{ +Q_OBJECT +public: + //constructor when you want to insert multi char + DlgSpecChar( QWidget *parent, const char *name, const QString &_font, + const QChar &_chr, bool _modal=true ); + ~DlgSpecChar(); + + // internal + QChar chr(); + + void closeDialog(); + +private: + void initDialog(const QChar &_chr, const QString &_font, bool _enableFont); + +private slots: + void slotUser1(); + void slotDoubleClicked(); + +protected: + // dialog objects + QGridLayout *grid; + KButtonBox *bbox; + QPushButton *bOk, *bCancel; + KCharSelect *charSelect; + + signals: + void insertChar(QChar); +}; + +#endif diff --git a/kwordquiz/src/eventsrc b/kwordquiz/src/eventsrc new file mode 100644 index 00000000..c1c9bc70 --- /dev/null +++ b/kwordquiz/src/eventsrc @@ -0,0 +1,283 @@ +[!Global!] +IconName=kwordquiz +Comment=KWordQuiz +Comment[bn]=কে-ওয়ার্ড-কুইজ +Comment[hi]=के-वर्ड-क्विज़ +Comment[mk]=К светски квиз +Comment[ne]=केडीई वर्ड क्विज +Comment[pl]=Quiz słowny +Comment[sv]=Kwordquiz +Comment[ta]=கேவார்த்தைவினாவிடை +Comment[tg]=ИмтиҳониKҲарф +Comment[vi]=Đố Từ K + +[QuizCorrect] +Name=QuizCorrect +Name[bg]=Правилен отговор +Name[bn]==কুইজ-সঠিক +Name[bs]=KvizTačno +Name[ca]=QüestionariCorrecte +Name[cs]=Správně +Name[de]=QuizKorrekt +Name[eo]=KvizKorekta +Name[fr]=Corrigé de questionnaire +Name[gl]=Resposta Correcta +Name[hi]=क्विज-करेक्ट +Name[hu]=KvízHelyes +Name[ja]=クイズ正解 +Name[km]=សំណួរ​ត្រឹមត្រូវ +Name[nb]=Rett svar +Name[ne]=प्रश्नमाला सुधार +Name[nl]=Kwiscorrectie +Name[nn]=Rett svar +Name[pl]=Poprawna odpowiedź w Quiz +Name[pt]=Resposta Correcta +Name[sr]=Квиз-тачно +Name[sr@Latn]=Kviz-tačno +Name[sv]=Prov rätt +Name[ta]= சரியான வினா விடை +Name[tg]=ИмтиҳониДурустӣ +Name[vi]=Sửa Câu đố +Name[zh_CN]=答对 +Comment=Correct answer +Comment[af]=Regte antwoord +Comment[be]=Правільны адказ +Comment[bg]=Правилен отговор +Comment[bn]=সঠিক উত্তর +Comment[br]=Eilger reizh +Comment[bs]=Tačan odgovor +Comment[ca]=Resposta correcta +Comment[cs]=Správná odpověď +Comment[csb]=Bezzmiłkòwô òdpòwiesc +Comment[cy]=Ateb cywir +Comment[da]=Rigtigt svar +Comment[de]=Richtige Antwort +Comment[el]=Σωστή απάντηση +Comment[eo]=Korekta respondo +Comment[es]=Respuesta correcta +Comment[et]=Õige vastus +Comment[eu]=Erantzun zuzena +Comment[fa]=پاسخ درست +Comment[fi]=Oikea vastaus +Comment[fr]=Bonne réponse +Comment[ga]=Freagra ceart +Comment[gl]=Resposta correcta +Comment[he]=תשובה נכונה +Comment[hi]=सही उत्तर +Comment[hr]=Ispravan odgovor +Comment[hu]=Helyes válasz +Comment[is]=Rétt svar +Comment[it]=Risposta esatta +Comment[ja]=正解 +Comment[ka]=სწორი პასუხი +Comment[km]=ចម្លើយ​ត្រឹមត្រូវ +Comment[lt]=Teisingas atsakymas +Comment[mk]=Точен одговор +Comment[ms]=Jawapan betul +Comment[nb]=Rett svar +Comment[nds]=Richtig Antwoort +Comment[ne]=सही उत्तर +Comment[nl]=Goed antwoord +Comment[nn]=Rett svar +Comment[pl]=Poprawna odpowiedź +Comment[pt]=Resposta correcta +Comment[pt_BR]=Resposta correta +Comment[ru]=Правильный ответ +Comment[sk]=Správna odpoveď +Comment[sl]=Pravilen odgovor +Comment[sr]=Тачан одговор +Comment[sr@Latn]=Tačan odgovor +Comment[sv]=Rätt svar +Comment[ta]=சரியான விடை +Comment[tg]=Ҷавоби дуруст +Comment[tr]=Doğru yanıt +Comment[uk]=Правильна відповідь +Comment[vi]=Sửa câu trả lời +Comment[zh_CN]=正确的答案 +Comment[zh_TW]=正確答案 +default_sound=KDE_Chimes_2.ogg +default_presentation=1 + +[QuizError] +Name=QuizError +Name[bg]=Грешен отговор +Name[bn]=কুইজ-বেঠিক +Name[bs]=KvizGreška +Name[ca]=QüestionariError +Name[cs]=Chyba +Name[csb]=QuizzError +Name[de]=QuizFehler +Name[eo]=KvizEraro +Name[fr]=Erreur de questionnaire +Name[gl]=Resposta Errada +Name[hi]=क्विज़-एरर +Name[hu]=KvízHiba +Name[ja]=クイズエラー +Name[km]=សំណួរ​ខុស +Name[nb]=Feil svar +Name[ne]=क्विज त्रुटि +Name[nl]=Kwisfout +Name[nn]=Feil svar +Name[pl]=Błędna odpowiedź w Quiz +Name[pt]=Resposta Errada +Name[sr]=Квиз-грешка +Name[sr@Latn]=Kviz-greška +Name[sv]=Prov fel +Name[ta]= தவறான வினா விடை +Name[tg]=ИмтиҳониХатогӣ +Name[vi]=Lỗi Câu đố +Name[zh_CN]=答错 +Comment=Wrong answer +Comment[af]=Verkeerde antwoord +Comment[be]=Няправільны адказ +Comment[bg]=Грешен отговор +Comment[bn]=ভুল উত্তর +Comment[br]=Respont fall +Comment[bs]=Pogrešan odgovor +Comment[ca]=Resposta incorrecta +Comment[cs]=Spatná odpověď +Comment[csb]=Lëchò òdpòwiesc +Comment[cy]=Ateb anghywir +Comment[da]=Forkert svar +Comment[de]=Falsche Antwort +Comment[el]=Εσφαλμένη απάντηση +Comment[eo]=Malĝusta respondo +Comment[es]=Respuesta incorrecta +Comment[et]=Vale vastus +Comment[eu]=Erantzun okerra +Comment[fa]=پاسخ نادرست +Comment[fi]=Väärä vastaus +Comment[fr]=Mauvaise réponse +Comment[ga]=Freagra mícheart +Comment[gl]=Resposta incorrecta +Comment[he]=תשובה שגויה +Comment[hi]=गलत उत्तर +Comment[hr]=Pogrešan odgovor +Comment[hu]=Hibás válasz +Comment[is]=Rangt svar +Comment[it]=Risposta sbagliata +Comment[ja]=不正解 +Comment[ka]=მცდარი პასუხი +Comment[km]=ចម្លើយ​ខុស +Comment[lt]=Neteisingas atsakymas +Comment[mk]=Погрешен одговор +Comment[ms]=Jawapan salah +Comment[nb]=Feil svar +Comment[nds]=Verkehrt Antwoort +Comment[ne]=गलत उत्तर +Comment[nl]=Fout antwoord +Comment[nn]=Feil svar +Comment[pl]=Niepoprawna odpowiedź +Comment[pt]=Resposta errada +Comment[pt_BR]=Resposta incorreta +Comment[ru]=Неправильный ответ +Comment[sk]=Nesprávna odpoveď +Comment[sl]=Napačen odgovor +Comment[sr]=Погрешан одговор +Comment[sr@Latn]=Pogrešan odgovor +Comment[sv]=Fel svar +Comment[ta]=தவறான விடை +Comment[tg]=Ҷавоби нодуруст +Comment[tr]=Yanlış cevap +Comment[uk]=Неправильна відповідь +Comment[vi]=Câu trả lời sai +Comment[zh_CN]=错误的答案 +Comment[zh_TW]=錯誤答案 +default_sound=KDE_Error_1.ogg +default_presentation=1 + +[SyntaxError] +Name=syntaxerror +Name[af]=sintaksfout +Name[bg]=Синтактична грешка +Name[bn]=ভুল-বানান +Name[bs]=sintaksnagreška +Name[ca]=error de sintaxi +Name[cs]=chyba v syntaxi +Name[da]=syntaksfejl +Name[de]=Syntaxfehler +Name[el]=σφάλμα σύνταξης +Name[eu]=sintaxi errorea +Name[fa]=خطای نحوی +Name[fr]=Erreur de syntaxe +Name[ga]=earráid chomhréire +Name[gl]=Erro na sintaxe +Name[he]=שגיאהתחבירית +Name[hi]=सिंटेक्स-त्रुटि +Name[hu]=szintaktikaihiba +Name[ja]=構文エラー +Name[km]=កំហុស​ស្លាក +Name[nb]=syntaksfeil +Name[nds]=Syntaxfehler +Name[ne]=वाक्य संरचना त्रुटि +Name[nl]=syntaxisfout +Name[nn]=syntaksfeil +Name[pl]=Błąd składni +Name[pt]=Erro de Sintaxe +Name[pt_BR]=SyntaxError +Name[sr]=синтаксна-грешка +Name[sr@Latn]=sintaksna-greška +Name[sv]=Syntaxfel +Name[ta]= இலக்கணபிழை +Name[tr]=sözdizimi hatası +Name[vi]=lỗi ngữ pháp +Name[zh_CN]=语法错误 +Name[zh_TW]=語法錯誤 +Comment=Error in syntax +Comment[af]=Fout met sintaks +Comment[be]=Сінтаксічная памылка +Comment[bg]=Синтактична грешка +Comment[bn]=বানানে ভুল রয়েছে +Comment[br]=Fazi ereadurezh +Comment[bs]=Greška u sintaksi +Comment[ca]=Error de sintaxi +Comment[cs]=Chyba v syntaxy +Comment[csb]=Fela w syntaksie +Comment[cy]=Gwall cystrawen +Comment[da]=Fejl i syntaks +Comment[de]=Fehler in der Syntax +Comment[el]=Σφάλμα στη σύνταξη +Comment[eo]=Eraro en sintakso +Comment[es]=Error en la sintaxis +Comment[et]=Viga süntaksis +Comment[eu]=Errorea sintaxian +Comment[fa]=خطا در نحو +Comment[fi]=Virhe kieliopissa +Comment[fr]=Erreur de syntaxe +Comment[ga]=Earráid sa chomhréir +Comment[gl]=Erro na sintaxe +Comment[he]=שגיאה בתחביר +Comment[hi]=सिंटेक्स में त्रुटि +Comment[hr]=Pogreška u sintaksi +Comment[hu]=Szintaktikai hiba +Comment[is]=Villa +Comment[it]=Errore di sintassi +Comment[ja]=構文上のエラー +Comment[ka]=სინტაქსური შეცდომა +Comment[km]=កំហុស​ក្នុង​ស្លាក +Comment[lt]=Sintaksės klaida +Comment[mk]=Грешка во синтаксата +Comment[ms]=Ralat dalam sintaks +Comment[nb]=Feil i syntaks +Comment[nds]=Syntaxfehler +Comment[ne]=वाक्य संरचनामा त्रुटि +Comment[nl]=Fout in syntaxis +Comment[nn]=Feil i syntaks +Comment[pl]=Błąd w składni +Comment[pt]=Erro de Sintaxe +Comment[pt_BR]=Erro de sintaxe +Comment[ru]=Ошибка синтаксиса +Comment[sk]=Chyba v syntaxi +Comment[sl]=Napaka v skladnji +Comment[sr]=Грешка у синтакси +Comment[sr@Latn]=Greška u sintaksi +Comment[sv]=Fel i syntaxen +Comment[ta]=இலக்கணத்தில் பிழை +Comment[tg]=Хатогиҳои синтаксис +Comment[tr]=Sözdiziminde hata +Comment[uk]=Помилка синтаксису +Comment[vi]=Có lỗi trong ngữ pháp +Comment[zh_CN]=语法有错 +Comment[zh_TW]=語法錯誤 +default_sound=KDE_Error_1.ogg +default_presentation=1 diff --git a/kwordquiz/src/examples/Makefile.am b/kwordquiz/src/examples/Makefile.am new file mode 100644 index 00000000..7a24b95d --- /dev/null +++ b/kwordquiz/src/examples/Makefile.am @@ -0,0 +1,3 @@ +kwqdatadir = $(kde_datadir)/kwordquiz/examples + +kwqdata_DATA = example.kvtml french_verbs.kvtml fill_in_the_blank.kvtml us_states_and_capitals.kvtml diff --git a/kwordquiz/src/examples/example.kvtml b/kwordquiz/src/examples/example.kvtml new file mode 100644 index 00000000..36179b42 --- /dev/null +++ b/kwordquiz/src/examples/example.kvtml @@ -0,0 +1,45 @@ + + + + + + one + ein + + + two + zwei + + + three + drei + + + four + vier + + + five + fünf + + + six + sechs + + + seven + sieben + + + eight + acht + + + nine + neun + + diff --git a/kwordquiz/src/examples/fill_in_the_blank.kvtml b/kwordquiz/src/examples/fill_in_the_blank.kvtml new file mode 100644 index 00000000..5081033b --- /dev/null +++ b/kwordquiz/src/examples/fill_in_the_blank.kvtml @@ -0,0 +1,69 @@ + + + + + + the lawyer reads the newspaper + der Rechtsanwalt liest [die Zeitung] + + + kids like ice-cream + Kinder mögen [Eis] + + + they have bought a Porsche + sie haben [einen Porsche] gekauft + + + they have many secrets + sie haben viele [Geheimnisse] + + + these exercises help the students + diese Übungen helfen [den Schülern] + + + it only takes a word + es bedarf nur [eines Wortes] + + + there is only one exit + es gibt nur [einen Ausweg] + + + there are many women here + es sind viele [Frauen] hier + + + the tires on the bus are new + die Reifen [des Busses] sind neu + + + she is a doctor + sie ist [Ärztin] + + + I will buy a TV + ich werde mir [einen Fernseher] kaufen + + + Earth is a planet + die Erde ist [ein Planet] + + + the rooms have three beds + die Zimmer haben [drei Betten] + + + we travel through Turkey + wir reisen durch [die Türkei] + + + we own a computer + wir besitzen [einen Computer] + + diff --git a/kwordquiz/src/examples/french_verbs.kvtml b/kwordquiz/src/examples/french_verbs.kvtml new file mode 100644 index 00000000..d47d3d64 --- /dev/null +++ b/kwordquiz/src/examples/french_verbs.kvtml @@ -0,0 +1,149 @@ + + + + + + je suis + I am + + + tu es + you are (fam) + + + il est + he is + + + elle est + she is + + + nous sommes + we are + + + vous êtes + you are (formal) + + + ils sont + they are (m) + + + elles sont + they are (f) + + + + + + + je étais + I was + + + tu étais + you were (fam) + + + il était + he was + + + elle était + she was + + + nous étions + we were + + + vous étiez + you were (form) + + + ils étaient + they were (m) + + + elles étaient + they were (f) + + + + + + + je serai + I will be + + + tu seras + you will be (fam) + + + il sera + he will be + + + elle sera + she will be + + + nous serons + we will be + + + vous serez + you will be (form) + + + ils seront + they will be (m) + + + elles seront + they will be (f) + + + + + + + je serais + I would be + + + tu serais + you would be (fam) + + + il serait + he would be + + + elle serait + she would be + + + nous serions + we would be + + + vous seriez + you would be (form) + + + ils seraient + they would be (m) + + + elles seraient + they would be (f) + + diff --git a/kwordquiz/src/examples/us_states_and_capitals.kvtml b/kwordquiz/src/examples/us_states_and_capitals.kvtml new file mode 100644 index 00000000..71068e3f --- /dev/null +++ b/kwordquiz/src/examples/us_states_and_capitals.kvtml @@ -0,0 +1,209 @@ + + + + + + Alabama + Montgomery + + + Alaska + Juneau + + + Arizona + Phoenix + + + Arkansas + Little Rock + + + California + Sacramento + + + Colorado + Denver + + + Connecticut + Hartford + + + Delaware + Dover + + + Florida + Tallahassee + + + Georgia + Atlanta + + + Hawaii + Honolulu + + + Idaho + Boise + + + Illinois + Springfield + + + Indiana + Indianapolis + + + Iowa + Des Moines + + + Kansas + Topeka + + + Kentucky + Frankfort + + + Louisiana + Baton Rouge + + + Maine + Augusta + + + Maryland + Annapolis + + + Massachusetts + Boston + + + Michigan + Lansing + + + Minnesota + St. Paul + + + Mississippi + Jackson + + + Missouri + Jefferson City + + + Montana + Helena + + + Nebraska + Lincoln + + + Nevada + Carson City + + + New Hampshire + Concord + + + New Jersey + Trenton + + + New Mexico + Santa Fe + + + New York + Albany + + + North Carolina + Raleigh + + + North Dakota + Bismarck + + + Ohio + Columbus + + + Oklahoma + Oklahoma City + + + Oregon + Salem + + + Pennsylvania + Harrisburg + + + Rhode Island + Providence + + + South Carolina + Columbia + + + South Dakota + Pierre + + + Tennessee + Nashville + + + Texas + Austin + + + Utah + Salt Lake City + + + Vermont + Montpelier + + + Virginia + Richmond + + + Washington + Olympia + + + West Virginia + Charleston + + + Wisconsin + Madison + + + Wyoming + Cheyenne + + diff --git a/kwordquiz/src/flashview.cpp b/kwordquiz/src/flashview.cpp new file mode 100644 index 00000000..df6a39ae --- /dev/null +++ b/kwordquiz/src/flashview.cpp @@ -0,0 +1,248 @@ +/*************************************************************************** + flashview.cpp - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include +#include +#include + +#include "kwordquiz.h" +#include "flashview.h" +#include "prefs.h" + + +FlashView::FlashView(QWidget *parent, const char *name, WFlags f) + : FlashViewBase(parent, name, f) +{ + m_score = new WQScore(); + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimer())); +} + + +FlashView::~FlashView() +{ +} + + +void FlashView::setQuiz(WQQuiz *quiz) +{ + m_quiz = quiz; +} + +void FlashView::init() +{ + m_score ->setQuestionCount(m_quiz->questionCount()); + m_score ->setAsPercent(Prefs::percent()); + + m_question = 0; + m_error = 0; + picAnswered->clear(); + picCorrect->clear(); + picError->clear(); + + updateScore(); + + KWordQuizApp *win=(KWordQuizApp *) parent(); + win->actionCollection()->action("quiz_check")->setEnabled(true); + win->actionCollection()->action("flash_know")->setEnabled(true); + win->actionCollection()->action("flash_dont_know")->setEnabled(true); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled(false); + + m_showFirst = true; + slotFlip(); +} + +void FlashView::showFront(int i) +{ + lblLanguageQuestion -> setText(m_quiz ->langQuestion(i)); + lblQuestion -> setText(m_quiz -> question(i)); +} + +void FlashView::showBack(int i) +{ + lblLanguageQuestion -> setText(m_quiz->langAnswer(i)); + lblQuestion -> setText(m_quiz->answer(i)); +} + + +void FlashView::keepDiscardCard(bool keep) +{ + if (!keep) + { + m_score->countIncrement(WQScore::cdCorrect); + updateScore(); + KNotifyClient::event(winId(), "QuizCorrect", i18n("Your answer was correct!")); + } + else + { + m_error++; + m_quiz->checkAnswer(m_question, ""); + m_score->countIncrement(WQScore::cdError); + updateScore(); + KNotifyClient::event(winId(), "QuizError", i18n("Your answer was incorrect.")); + } + + m_showFirst = true; + + if (++m_question < m_quiz->questionCount()) + { + slotFlip(); + } + else + { + m_quiz->finish(); + KWordQuizApp *win=(KWordQuizApp *) parent(); + win->actionCollection()->action("quiz_check")->setEnabled(false); + win->actionCollection()->action("flash_know")->setEnabled(false); + win->actionCollection()->action("flash_dont_know")->setEnabled(false); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled((m_error > 0)); + } +} + +void FlashView::slotFlip() +{ + if (m_showFirst) + { + lblLanguageQuestion->setPaletteBackgroundColor(Prefs::frontCardColor()); + lblQuestion->setFont(Prefs::frontFont()); + lblQuestion->setPaletteForegroundColor(Prefs::frontTextColor()); + lblQuestion->setPaletteBackgroundColor(Prefs::frontCardColor()); + fraCard->setPaletteBackgroundColor(Prefs::frontCardColor()); + fraCard->setPaletteForegroundColor(Prefs::frontFrameColor()); + linFlash->setPaletteForegroundColor(Prefs::frontFrameColor()); + linFlash->setPaletteBackgroundColor(Prefs::frontCardColor()); + //linFlash->setPaletteForegroundColor(QColor(255, 0, 0)); + showFront(m_question); + m_showFirst = false; + } + else + { + lblLanguageQuestion->setPaletteBackgroundColor(Prefs::backCardColor()); + lblQuestion->setFont(Prefs::backFont()); + lblQuestion->setPaletteForegroundColor(Prefs::backTextColor()); + lblQuestion->setPaletteBackgroundColor(Prefs::backCardColor()); + fraCard->setPaletteBackgroundColor(Prefs::backCardColor()); + fraCard->setPaletteForegroundColor(Prefs::backFrameColor()); + linFlash->setPaletteForegroundColor(Prefs::backFrameColor()); + linFlash->setPaletteBackgroundColor(Prefs::backCardColor()); + //linFlash->setPaletteForegroundColor(QColor(0, 0, 255)); + showBack(m_question); + m_showFirst = true; + } + + if (Prefs::autoFlip()) + m_timer->start(Prefs::flipDelay() * 1000, true); + else + m_timer->stop(); +} + +void FlashView::slotKnow() +{ + keepDiscardCard(false); +} + +void FlashView::slotDontKnow() +{ + keepDiscardCard(true); +} + +void FlashView::slotRestart() +{ + m_quiz->activateBaseList(); + init(); +} + +void FlashView::slotRepeat() +{ + m_quiz->activateErrorList(); + init(); +} + +/*! + \fn FlashView::updateScore + */ +void FlashView::updateScore() +{ + QString s; + s = s.setNum(m_quiz->questionCount(), 10); + lblScoreCount->setText(s); + picCount->setPixmap(KGlobal::iconLoader()->loadIcon("kwordquiz", KIcon::Panel)); + + s = m_score->answerText(); + lblScoreAnswered->setText(s); + if (!s.isEmpty()) + picAnswered->setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + + s = m_score->correctText(); + lblScoreCorrect->setText(s); + if (!s.isEmpty()) + picCorrect->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + + s = m_score->errorText(); + lblScoreError->setText(s); + if (!s.isEmpty()) + picError->setPixmap(KGlobal::iconLoader()->loadIcon("error", KIcon::Panel)); +} + +void FlashView::slotTimer( ) +{ + + if (!m_showFirst) + slotFlip(); + else + if (Prefs::keepDiscard()) + slotDontKnow(); + else + slotKnow(); +} + +void FlashView::slotApplySettings( ) +{ + if (!m_showFirst) + { + lblLanguageQuestion->setPaletteBackgroundColor(Prefs::frontCardColor()); + lblQuestion->setFont(Prefs::frontFont()); + lblQuestion->setPaletteForegroundColor(Prefs::frontTextColor()); + lblQuestion->setPaletteBackgroundColor(Prefs::frontCardColor()); + fraCard->setPaletteBackgroundColor(Prefs::frontCardColor()); + fraCard->setPaletteForegroundColor(Prefs::frontFrameColor()); + linFlash->setPaletteForegroundColor(Prefs::frontFrameColor()); + linFlash->setPaletteBackgroundColor(Prefs::frontCardColor()); + } + else + { + lblLanguageQuestion->setPaletteBackgroundColor(Prefs::backCardColor()); + lblQuestion->setFont(Prefs::backFont()); + lblQuestion->setPaletteForegroundColor(Prefs::backTextColor()); + lblQuestion->setPaletteBackgroundColor(Prefs::backCardColor()); + fraCard->setPaletteBackgroundColor(Prefs::backCardColor()); + fraCard->setPaletteForegroundColor(Prefs::backFrameColor()); + linFlash->setPaletteForegroundColor(Prefs::backFrameColor()); + linFlash->setPaletteBackgroundColor(Prefs::backCardColor()); + } + if (Prefs::autoFlip()) + m_timer->start(Prefs::flipDelay() * 1000, true); + else + m_timer->stop(); + + m_score ->setAsPercent(Prefs::percent()); + updateScore(); +} + + +#include "flashview.moc" diff --git a/kwordquiz/src/flashview.h b/kwordquiz/src/flashview.h new file mode 100644 index 00000000..9fa26db9 --- /dev/null +++ b/kwordquiz/src/flashview.h @@ -0,0 +1,78 @@ +/*************************************************************************** + flashview.h - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FLASHVIEW_H +#define FLASHVIEW_H + + + +#include "flashviewbase.h" + +#include "wqscore.h" + +class WQQuiz; + +/** +@author Peter Hedlund +*/ +class FlashView : public FlashViewBase +{ +Q_OBJECT +public: + FlashView(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + + ~FlashView(); + + void setQuiz(WQQuiz *quiz); + void init(); + +private slots: + void slotTimer(); + +public slots: + void slotFlip(); + void slotKnow(); + void slotDontKnow(); + void slotRepeat(); + void slotRestart(); + void slotApplySettings(); + +private: + WQQuiz *m_quiz; + WQScore *m_score; + + KAction* actFlip; + KAction* actKnow; + KAction* actDontKnow; + KAction* actRepeat; + KAction* actRestart; + + QTimer* m_timer; + + int m_question; + int m_error; + bool m_showFirst; + bool m_soundFeedBack; + bool m_flipAuto; + bool m_keepDiscard; + + void showFront(int i); + void showBack(int i); + void keepDiscardCard(bool keep); + void updateScore(); +}; + +#endif diff --git a/kwordquiz/src/flashviewbase.ui b/kwordquiz/src/flashviewbase.ui new file mode 100644 index 00000000..d1cf9e1f --- /dev/null +++ b/kwordquiz/src/flashviewbase.ui @@ -0,0 +1,552 @@ + +FlashViewBase + + + FlashViewBase + + + + 0 + 0 + 617 + 492 + + + + + unnamed + + + + spacer9_2 + + + Vertical + + + Fixed + + + + 21 + 30 + + + + + + spacer11 + + + Horizontal + + + Fixed + + + + 30 + 20 + + + + + + spacer11_2 + + + Horizontal + + + Fixed + + + + 30 + 20 + + + + + + fraCard + + + + 7 + 7 + 0 + 0 + + + + + 255 + 255 + 255 + + + + Box + + + Plain + + + The flashcard + + + + unnamed + + + + lblLanguageQuestion + + + + 7 + 0 + 0 + 0 + + + + + 255 + 255 + 255 + + + + + 1 + + + + Language 1 + + + AlignTop + + + The flashcard + + + Language or other identifier for this card + + + + + linFlash + + + + 1 + 0 + 0 + 0 + + + + + 255 + 0 + 0 + + + + + 255 + 255 + 255 + + + + HLine + + + Plain + + + Horizontal + + + The flashcard + + + + + lblQuestion + + + + 7 + 7 + 0 + 0 + + + + + 255 + 255 + 255 + + + + This is your question + + + AutoText + + + false + + + WordBreak|AlignCenter + + + The flashcard + + + The flashcard. Select Quiz -> Check to see the other side. + + + + + + + spacer9 + + + Vertical + + + Fixed + + + + 21 + 30 + + + + + + layout13 + + + + unnamed + + + + line1_2 + + + WidgetOrigin + + + HLine + + + Sunken + + + Horizontal + + + + + layout12 + + + + unnamed + + + + lblScoreCount + + + + 5 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Questions + + + The number of cards in the session + + + + + picCorrect + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Correct answers + + + The number of cards counted as correct (I know). May be shown as a percentage. + + + + + lblScoreCorrect + + + + 5 + 0 + 0 + 0 + + + + + 0 + 255 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Correct answers + + + The number of cards counted as correct (I know). May be shown as a percentage. + + + + + picError + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Incorrect answers + + + The number of cards counted as incorrect (I do not know). May be shown as a percentage. + + + + + picCount + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Questions + + + The number of cards in the session + + + + + lblScoreAnswered + + + + 5 + 0 + 0 + 0 + + + + + 0 + 0 + 255 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Answered questions + + + The number of cards already seen. May be shown as a percentage. + + + + + picAnswered + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Answered questions + + + The number of cards already seen. May be shown as a percentage. + + + + + lblScoreError + + + + 5 + 0 + 0 + 0 + + + + + 255 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Incorrect answers + + + The number of cards counted as incorrect (I do not know). May be shown as a percentage. + + + + + + + + + + + 789cdd9c59536349b2a0dffb579475bcb58dc5456841b2b17910082476891daedd87588f401202b4736dfefb7884bb878e1632c9aaec99b2694c957c9c25c2c3f73847fd1ffffae3a17dfec7bffee31fa3b11a3f9b3f4c577dfcf12f3b190c16fff95fffebbffff1cfc2cece1fe153de2bfdb1fbcffff18f7f8af91fe60fb113ff17b996b81a588d990b787c465cc2f3954c8ce78f98e9fc297195ce3f4a8ce71799f17c7b92188ff37c0c5eef7b89e3714de31768feb64e4cf3d3c791ab69be93c478ff43661cdfa5e338be3e21e6f98bc478fc9e99ae3f4e8cc7df8869fef634318e3f65a6f5aa22b33c6e9618ef77c08cf7170b62924fd0fc0b345fdd27a6f18d0e0c77a3f1dc09328f9765cc78dcbc10f3fd2f89e9fea24d4cf7570de45db6274f4cd7674562bade45fb2a54f97cf5404ce7fb7a6294d711b33e14318d9f7503efa6f1748198d763404ce78b0cb9c8f3fd24a6ebcd1e31cb8b5ce3f3b3d7c4a8cf6b62b6b773621e7f9f98c6771ab944f73367818b053e5ff588597ff78971bc1b64be5e7413e3f10f629a8fed258ec7fd9c99f43d23a6f1ad899ce6a74f89797d4c62d4cf0533d9f39898d7af9318e73723667d98c4f17846e395cb349f68ffa5025fef86c4bc9ebb8951be2633ce471be432dbdb59e278be1932d3fcebc434be2b25c6f93d12d768fe2f89e3712b90f72cad2fce4f95cb349f77623adf4c99e97815b952208ef1b0bc5bb6e8ff7e9f79b716e7f7865c29d0fd5acc74fd0e318defcb89f1fc3be65d5c6f1aaf42f2f91b624bf247ff2ec3fc8a8578ff5d625a1f75c04cf17d4e4cf28a0a33cde79e98eeefaf98e9facfc4180f7bcc385fa591f7485e534f8ce727c6f3b31631ebf739318e6f98f17a17e35d05d6a318d7db5689693eaece8cf777a7ccb83ebe9f385e9f2d9079beaa9418eff7ce4cfad827a6f9f83b669287af277db90233e50bc54ce7ef12f37a467fa82479fd8819edcb8f99511e7b454cf777b7cc78bed82726fd699118cfef32937c378971bc57e42aad87ba65a6f9477bda2b32db69e278bde2e3b43ebe93188f3f12d37cb32133e92be6a33dcdf15c58628a674621a7eb0f98c91f5e89d93edf13e3f917c835922f3b67a6f98ac4f17cfdcc4ceb1ff55d2da6f8dc404ee77f30e3f9a24f4cf2eb4f663cee1c31c9a34e99693d5462d44fb4ffaa4ef1fb3931eaf78919f59fe17c748de41789c91f769015ebef8299e43d4c8ce31f10b37dce98f1fc4c25467963fd512bf1fdb31b66f2e72362bade3c24c6eb1d7309f5bb205674fd0b7349c5f9d4881d8e676e99f17c2199f17ee60359ef92ff4a66b287a7c418ef5f9849bf6fc415ca97e3c4e83fc7c48aee7f9d18fdfd9499f415ebc99aa972beeb21b3bce69598e431136694473d23c3fc50de33663c9e7512c7f5b22d629a7f564e8cf63462a6f9f1fd2ab83ef29e19c7538619c7f315e632f63fc7c4b41e6a2731aed72b338e274f12c7e3f29699ec73c9717c49eba11dde5fd613e3f50b66baff7e621cff9319e5335789513e92d790bdc86162bc7f8f99ee3f4d8cf509ad87a1f5164789315f3c31533d7448ccf612f5ab4a55cae7ea8599ced7c414ff5513b9c6f9b94a4cf6a51f90f52eeac77f12933eed3133ead33612a3fd4866bc3e7b23267de91233e5e72633e9eb9199ee9faea7fb1799f1fee68998f46979fea44fff9218ebab13661a5f24467fb6cc684ff23a31fa579919e7e77a89717e1933cecf923cc93e3e13a37d64cc641f8dc478fc9899fceb3231cea7cb4cf1e73531ae678598ec4bdac4787fc14ce3ebc478fc9019c7d7b3c4b85e3566ca4f85c418dff788c9bfe57962bcff8899c6ef26467db599693c9687fcddb788d9bfcf12e3f537cc94df513ec3fe601532fb83cf8839dede32d3f17662bc7f8598fb872633f9f70733d547683f86edc9b598293e1e268ef6941d21b3fef565628c3f43668ab70566f29fbdc4689f5d66f21f4f4cfad75789319e5498717c719218f3719399fca59318e793cea7fc7a9418e773ce4cfe724d4cf6617698c93ede12a37e0e99697d6789d1fe8bcc540f0e13633e4ce3e1fc641a8fe63762c6f9295e4fb237fb9418f323eb87e28fb84f8cf65e6526fd65cc54ef9c2746ff217bb3142fac6326fb6b3093fc51ffbac4f6e7df99e9f89271fc5d62ee07769849bf77cc7b3ade6fc85c2dc6f3fbc88aea677bc64ce3d1f9acffec9898f4e3cf98c95eeacc642fef89a33e748599f2d35b62f4974b625a6fad99c97f9e98c91e6e12e3f803669aaf4c8cf56409d9b2ffb599a9feb8488cf29d1093bff8180fb4ad513f92e17caca2f8e38e98293fcd9969fda7c4bc7ff1c24cfed923e6fcba9718f5394636949f3cced75af6c7a86f53e6fe4d8c88a9becffacc246f8798fbaf4f62924f9c23ab32cedf0e98d17e4409d972bd502026fdba983f8de57eca6b6445fb2bea0a5957f07ea6474cf141086287c77dcc7fb6ccfd94e920f3fdec2bb2a6f5329699ec2531d9ff3471942f1b11937d650f8971fe3bc81c4f9d21e6f815edc93a8ee7be48ac70fd32c38ce3e92e31dddf5e32e3711be7eb2adc2ff945e2a86f7180ccf69cdd3153bfb5c74cd73b66bcbf9913937dab3e33c5d70133adff2d31c7df5d628aa7fe3231c6a33233adff11b2a37a4af9c4180fe97ac7fdca3933c563bc9f63f9dc0133c59bb7c4e80f7d628a5fbac58cf2ab7de65a29aedf3531db8b4f8ce31d3253fd78c34cd73f2736713d8e88793dae98a91ee926c6fc72c74cf9f82131ea5730533ccd98717cd144e6f51585c478ff0366ea1f64629c5f8399ec793731e6e31b66daeff84c8cc7c7c45cafb612e3f87366aa07668951ff0b66ead79e99d1fee41e31d7a383c478ff1766b297bbc478ff8c99f603ae13e3fcc9be1cd9b3784c8cf1688799ee4ffaf1b4be599c8f07ff20fd9c33a37e4c9198ebc54162f4e72b66b41fdd464efad967a6fdb02766ca7775668ac7e97c1a7fc9f1fee69498f4a33bcc949fca8931be2e98291f4f1263bc51cc641f1789315ebc33d37caf9851bfea2e31c6cb0633cd7744ccfa7f4d8cfaef33937db9c4789ce525fdeb6962d43faf37f9bfba4c8cf2cd9929de1c32637cd78fcc240faf27f73726719c4f67cc4cf3558971be47cce40f178931bfa5eb69bd0789315e3d3053fd41ebe9b99f6d26c6f13c33cde739311e2f3153fea3f97adeffb865a6f8729018fd23e633efa17e89f66e3e9153fd7082ccf6e22533c5ef51e278bdcb98a9de5830a3bdbbfbc4d17eb229b3c2e39e98ebadbbc4a8ef0b66aa07c689d15e9e9869bfee2d31d69be7cc54afa5f1703eaec88cf3318e98ec219b25c6f5ab3093fe1f99295f5c25c67ae29999fac9fbc4981f7798d13e4c8919ed377b4f8cc70533aeafbe4d8cebdb64a6f5ed306b1be59f309b723c7e86ccf6670acc647fef89d1fe2e9829fe5513637cb961a6f5d84d8cc74f99297f7f24467bec33e37ac81a33f9732b31d60f5d665c0f554e8cfa7d65c6f5c81cb389eb21f87e9c0f3f12637dcce773ff3e64a6fda24662acdf2c33f5c385c4988fae99a99e6f3253fd7dcc4cfabc67c6f9fbddc4f1b8d5c49c5f07cca48f2233d5ebd789d13e3d33e5c3e3c438df4366daef607d90ffd80933d95b3531d65fe41fde53fdf4c24cfeba488cfebac78cf7eb8ca5f8777da45af95d874f62232d7d7ecb58d116fe6d92fce4c392d8df73bfdfa0179b5bdf5f999dfdfbe9659b24ebb30cfffeae19ff5bf5f253e9be3c2ff88f5bfacfff7bbd7c439aafcf53bf4f927f8f5e3a5ff8d08facf0efab975f94ee6fa617e9e3bf197cbaf219f845f6822f504e49d624fbf0770f9f413cbf07dcfd7be945beca21cc2e8bbfbfc4190a90e84dbe83642845067fcfe0f72efc0d7f7f8e5264bf4ff7bf432ff2438e607643f87d14f403520da3f50409c77292f481d2043d4de50c3e73b980cf6f93e6b7f9cb274932ea2c7de313a40affd683ce2802efcb03d9807f0fe551d4175bdbdf432f36ceb809928459b7643d774c93040df837ccfe18f471224f81e7f1dc70ddd9df2aef9fc38ccea375f561e61730e3537929dbb223afe4b5bc91b7f24edecb07f9289fe48e2cc0df77655196e05c0fd795ff56f5585356e41e48f22eabb206337d125208a184164658e1848f3f4e64a22b9ec58be889be1888573184f3fbe2edf748f24dbd7c9507963962005e7c2a3be25d7c889118c3ac27622a66f13313f3f4338b7f9b8a85f81475b12f0ee09a06e811ac9074fc17f2cd37f402771787f0398aa3510f0211f5538065899638967371224ec599381717e232ce977fe65ffccc48aab6e880feaec4b5b881b8d682fbdd42ec0b710ea283b8039f7a11f7bf4f2f61adc48338148fe249eca024a20071e943d6c5aecc445194445954c49ea8c6d9d7e867bb1474544925224fc5a5524a2ba32c4487961cc218dde04b2089564e0ae57fb75e409aa3b5bfd7e54c65aaab9ed58bea911c7348f13f926429699487fe166d0ee4e9ab81aca9578871a18e08511e32ad7afdbdfe023a39128fc947c0b260b4991aaa37f5ae3e602e643769763ffaa9a9911aab316967a2849ac6ab176aa6e6f25e2dd4276455f6c3a89bdfa617f888a7156fdf039d9caabada5707aa11f401b33bfc961cdbf50392a9a3e8416dd504976cc9431a6b4415d0b7fad6efe517b06196a4228d3a9617ea449daa33f6105ee72f3c7e8bd5255b6459c6f18c20cdb9ba5097aa0dd16518a5197cb7b6fe95fc12eea23a70a75390e44a5dc759a3656d7ac8dabae723025895402d828dc978f53cdd01a29bba51b7ea4e9c80df0c5547dd7f773fe197f23edec9c90e8cf54092a007e09c36e558e5bca4a81d91bb4b2e5eab6bf5a89ec4098c19b2f06fd44bcc2741d3af6a07745250bb90c36769e4394557b295a483f56cc25a3c52c5156b3b5ad32746b6b62aa9b2aa88a6da83990f39764216107f492f219f58885d755505ebba4549481379ed0449466a94b3969aaa41426a5015d3d6722915c8244967580b2cad15ff9269a195d6909171455fb1e383bcf617e2184c3af41823e9200a5f8175b1ddacc4d99c3666aa06eb7aad8d2a69ab9df6cae84c9ce9ae7ed62fba273e753fce3dac478aceec3f89667aa05f55172a1c157bd56cbd075df79d6fe9a50e6b3194333d147df4f8b4f6ab3129caa1df6045dff5871ee9b13855433d91977aaa6750a514a16eeee8b95ee84f5dd7fb2aacff5c1f048dae79533c22a67a5f37f461acd7b8db0e1dddaaff9a5fd18b3e82cad1e9a66e69c331388ca98ff5314a02c39ca03ef4a93ed3e7f25a5fe84bdd56afbaa3afa07e0e1dda30f436109b7afa5adfe85bd0d71dd4cd13bae3a1becfc993ec0eeef7a01fa1df39802eee284af3f6e7f512f3fcae7e526f7a07f2492eea0449482bd15f7541ef6a587b5dd26518bd0f56f10abde532f65420a2875ec7ca39e4f65d5dd17bba8ad936f9df3c79e11c343c0f5f8980685395fb4642bd16baba8b554996d27ca71e0b158b1146c551291ae5638fd1411263c29b4dd0bf64c619cf9f28d120d672d441635d07d977df64a66b9e85d4a7e68563628a8af334cea5e9c9a2e9c77e741ffa524dcf0e362274d2cbd6984d674eccc0bcaa1baad357ed1aa372cd0ccd9b7937d27cc4f347a08fd7e8ade1f349b55c9020f4f7f52819fedb35633331538535432dea472439a2e7989999eb1bb300495cec36bef07ed2cb7a061a456f1fc851b00add319fea05c75a6644350923059d6869ea665f0d61ddf4fa0830ba0049cecd01c4a297a89b217cead193c3eed3c034cca139324d90661e7d66b58288ab655ae6d89c98d3b8b7335a9beb9abf6cab0c8224d24305f10a9d56d99cad44afbc8d55953673736e2e20420ce28e44b200bad739e4ee61a850cd259c53326dd33157e65aee77c6e606fed6d353736bee82376e54a87144736f1ecca3793223b303d2f0bd711771238ead5706618fcb14409ab15ca8d06955a325d7383b2e7b0fb36b8a7aa8afa3f52cf591d78d0f3e07b368c9862999b2a9983d53958fb20d3ed08a957dcfd42c9c24a662bda241595eac025f7432b3da3ca527216ad52356fc85d7318b11746076c2bfe602badfbd5c7732a35a3066006bac15af605dbdb4b3e43762ff4836ad83bfef5b6f33282cc35e405bd76d177ac913f9218ee0d8b17db62fb617f3ec7ce36726f66c5f37419ab790ff7f9cf7579efcbc2c6b1ea9f4d00e82563083249f8fbeaa07f6d5063fa9a34ec0227927365f0936e504d65fab967db3ef20097af6c47ed89179b463b8e60ceaac133bd1cf54e96d5474aa66a7fa36d6ce5fc6dcad7a09bbd723ace8ec4cbc1b13b5928b2e98a7e1fe733bb40baa3c9b20c9727f381f3143adbb2f1ab66b3fa11b9ec5baad2866b66ef7e5a3012b168f706dcbcee4139c314dd22459601d67f6c036e4ae1d83e5c71af1a77a415df4a99783fece94ec6188fe4aae54918771ad6eec916dda568c10063d9c76c357f402b150804e8e412797c152ed891aeb7b7b0abf3fd8337b0e7e13560fc6b317f6529d6fca12adbb6ddbaa2e0fa2e56ff8ca6adecf591977a50b5515afb6b31a8be1ce500d87f865af2c547caa63af638fd18c957997eaa5204185570774f7686f42bd122bfc5aca4cc1d23e21ff4f411ab88772f6d6de25cdacf98c9dda7bfbc0318ce6fc459d9cf4f24c9edc87aaee498ca3b7e76b25fc3dd3e710f39d7d5cd129e7e4a67d8a3da897daee802405d0c9b23f59763f907d4dd39445113aef3d39b2bbb628b29429f39a99da9239d29d98633e6316ce49b5518f25bdc099a1d7167a2264bcf37a8f18aaaf775bd665a854461b9deba7dcb31559c648a0a776cf56453bd607e3a8e119f56447248fb73527a1ce827be8997ad2ef10cba6ab5a897691690ff5984935459cefd2dab6eae505a409b3534ec0ff261485b953c1fabc0d55fd05e40bb7a5836dda8a53e03f1045ec8e29839fb4979d16d58ed31413a11e76da1995c5d5bc7010e6a1f25b93258e3971ce79d44b7ebe5fea251cdd072b0bbf6bd9866c3015b9ec45bd13c47b97e94bd987ea71a317b74f602d61df7f2186f2da7563753d075f5fdae734ed0c8618d270cfee057c2acc2ee8f10dbaa46d7a9942a7d98c16f6ba5abd6cd74bd45ac848512fb223f46a551c650977357aacdba1265ea9eae913a3f3c2945ccff5a1875caf46a916a6ffd6f48bbd7503c89a10e2a0233e74af6eb85e8b63e4746ff20abc9ff4f2751ccbe945cbf768eb1a3cdf6cd10b8cefdedd871b85f5016f5ccf27a12a817ce27a3674c369565403e5577ae6c6b60a9e7fa367f248843127f248d59526bd242f7531c3aa992a401f936dcffd5bf512faeb71dc3dba16766d7da22cfacd4da1fbed847802ebd45feb149eb1eeb26741129724c97526344b377673bba7aae229d61a3eee896ae8e63ed02ed7bc74a6cedd02f4d7ff15bdc06702bf37dc676ef7886489b3a84287aba0fb3550e9f537ee7a2cdba6ec62ffebbe7a7611bb1e57b77b6e5f2e3ad841dbd873f64dd71d844a67d961927542cd241f5d23ea258bcfaa37f24b3e1e44ddf4e31a0d25642ee1d7a20956626d77282f21c7076b0a9dd679ac7a9a98e3650da2f03b542bbc33b6b28b1963d934d4beeec83583cfc51d09b005e8d446b1b73995f710f9e6a92a4ff2ab075334271dec8b1a5bfb7dce2be10929ff6e63647ed8224b8c3cca40ae864e4d1cc10c2ced2d4ec2933ebb702d558a73e16a3abf7309ff75c7605d27eed416cda3fc7467e2c99dcb5e671c2bd451b05077015139e96ff903de751ce25d9ceb321b6cd14bec404dccd5226a11d68776c356ed1cb29bcec05ba16a24ff188a96bb8cfb353518ade0c61b5d483e438da2c7b55d47d5dd558c83c3a89396bb8e2b786aca24cb9a66c0bf6ee465077db9b12ac9ba5e3afca420e4fd50c13c80bf6cca328791cec44dd8b98e4f15c20e5cd8356a08d097bb8dcff9a6319f6cf689288d8c36f66e8a4ec803e85ff640bfb7411a59177721f76f970556f6ccdd454f487af9228e717d8bef4e04bd3c8acf6db2884bdd954518b912eaadd8b7b7a0126d41147e47afa5fda1d5d8b57e97852ab97bc8613b311f85679561450edd835e241b5d91450fa08745bda89fe47dae8f636f09721fab37d1dd1285665aea677925ebc1d3837540cfdeb03ee49350ad802423ac56482b4bfb5ae61aaccadaee5dbd99767ce28abb4d100974d33d6ade6b5eb16dd5b36f7a92e297dd8c631b7a1944ab59c89979774fc97bf3f174a65f6407ce3b87f37a30931ef4395db74355fdeaeef26a9798626ca87c812e5d5dde41175602cf1f63bd20af5c21566ce92ade8777bbaea84ba1aafc693dc67a091d95866e745f165c69b3670dcfe3744fcfc1b29a60eb03f84066043f699324f9a7315b3aded86d534484dfa76aeecaae22ee6825952ae89dd8c7aecb02b539ac6e03abfd7549b6eb05351dbdabe3f6623551c3e88335547cb698995bd38f7b5f43e9edcc54a29f8c20dee66c9c6d4cdfc72a2edfbbac3c15b0fbaeea6aa16704dd54dc420f569eb6d5e833b5532f2122f5b73f1b5bf6fb6bfe12f69e16e6d10b5bc7fe85f6c379077be2951e520fd9f3da0499675845c7a75db9a7caf139f15c4d5662da32e3046b9a78037d4bd86759e8a9739429b91295b42a0b6f654797bf7a3f23d7eff3bb7736bea1133e2d3df3e12d96f48c27d90e8cafebde9b93b017d9199b2b9f450b1b91acd176925f40668cfbdcf927ae2bb124f4ca4a7baf86beab4efc33dbc25296b07b0133393325ffb2566dade9656d1fb0179fdc3c879a55bc8a7ab2dd3407df83d9ee6b27c26e75d8a9bb763d5d0f7b2c94558e04e90263afeffb7eec91974fbe562263d8c7d07dbbef07ba029f41ea90973616e2441dc63ba6fa8fbb932df518f52bfc4e64173ea3f8eed1ae7fc52758f93944add7fcd0bf992cbcb3a25e65db9efbf7f80c6f4afb4fbc635ff51f90a63b7e1464ddb62bc19d26dc71ec271043aa395f5b6a6eeaa7fa461ee0f317894f811b1b7ae1ba46939cc1f333f0e80af488333fc35d87646782f3839ffb85ab057f81cf89f57664f7e3f3e55ccf085547dd7fca2b1372fc3b65c06d99333c399afbbadf8f7ba46bcf4542e473637fa0aa6a87f6c72cd5645feb252fa7f50d9066ae0aa213c6413b4b193d44b589ae9a67d0e100baa8b97a358fd0471ec5d5a728aa1edcdc1f422dfce98f9c70f72eee906d4a132279ec27f21968a5da07ad34e5937f817ee93af9f78ff4b2fa0d8f816f419df4e68fc13a2e97b2505c1ea960c16df0c60b7f0255e5507ef853f3688eeca7aa91a5c5fe84f2f4441ef8337feeea1bef94b19d85e7d087394d25ad45afabba777fe12f61d55e531cd35fea65bda3e258716cf68337827f525c8e16413bcaeac64c74781beb11ce2fcbba9e82dfb4e33e8ad72faea9aa6185a06f34a177741508569ddc1ecca6ad6db7c199fad05083c70c9edf495c798bfe1bcf2b9d1dfaabf8cc62ccb280fdd6b8da35bb76cf5fcb29549967204d789652f6374efb1be8a81a3182f4a03f19ca3da8509e65d1dffabb65ef8c716fed675d6fe04bfe1eeabf0654b0bcc31b9e7de67717c5b79e5736c48d38f3e0d390edc629e2d7685739c4b3b65e989a3c14bbb6225a32f38ffec9efb817e8db67e17dd758b3ed40a51376dd4bbee077ed67ccc03f7af36fe931a1fadbf7455f8aabe157f726beacc7b6eba5ef5fc4a9adc69e37d71de6f3b62ffb8a7d8eb9067a4cb5234b2a3317f14969d8cd0d95fc082ad0b0fb07fd89ab897753075f9b6eece86d9728ec8b85bdea8a6fc4be6ae549a2dc782ef643695afad2f64567a573a708434f4a1756d817bf07f56e0b7b91f8ce7e1f3cf523bc45077fdb0bd2844a14ee77208bfad6ee876c14debcf8521f44beea6b662027be01d1a8b5fa7ce717f562ecb5ee64d24e537fb4d657847a0b6257077a9a27c8661771a4213d451ac57797f7d471ece54d7cba2174d97433e1c76e4cd17dcb4f7a87e93253100b75f0f6d0c7e623d3d7fdcb171febcecc93acf9cf4ca7bdfab567bd94b99dfdcc8cbc87918fa3870ec471d451333d01b771dfed5566ae91d9cc653eb7fe1bda09d26459d6cd9ee56588be71f6cf7f4d2f901b5eed43f692f5e2db30b3dcec97fe3bc3aca2ceb3be6dc827e8d44ee3be8e8e6fbbfbd87f8618b480fea4a2a7ea241bf871f6fad5de59eebf97d910fcab6b245cefd3fb305bde8afb8ebf1827df44217bcbdeb30fd5cbf51ff99197d1742aac6965237fa8caaa9e8d4d37eeef1ce999dd9145b90b75b0d79fd9440fe21b8ee97d870d3f59eaa7a6ebd95476409a502d0db90a5eb7b46fbda7d4c86661df18d65365737a3711ab197ea724ef4721864af5a0ceb5c916fac35af52c1fecad7cf0b3ec5369d30229daa95b1be764f92a8e417da17b595d0d202e0eada69d3eb76e69df8a63a7f139cba7eceba76c3f3b88d174bed607af7757f107ec6e212e55037e1ea0ea6c474de4e7fdf57bccf99f50274c40370d730e83e2b317b7f27eecb7f30be8a38cef1c6533dd544fee1d3b8cd8b7e76bf3f53e6bbd4a648faee5de65dcf0f6adb55a78fbaaef0aea323bcc7f5fe64fe417971de11b54e649b775336bbaae2ec4fbbfa537ae56c75ee5d1dabcb7493c4bd26cd14c7ce607155ed6029f79cb3f1df9b538d61943a775a1afc27396204d36cb8eb313fd4acfae67dbfa44f4a77c4e5dd3d9d7d5cb177f0f5152d5b2d3ec2cb7bfffebf945c427792e4400e343c6124dad552b3bd7a7c1fe7ff2063f74fe4ad07ba23f96221ecdb22fa2344802f1fe026261fcde13c7b15fd54b76299a5063857cdeb28faa93b521e335fc71d6d1b5edbdd54f567ad5fb79a76916734997be75b2228798805e32af6401e217e6978db7bbbea9978de791615dcc497665caa6677e56ed6e4ab02e4b0dbff7e3ab99ca9eb361fecddfa8591973b08aefc4f6d3f761be7eafef8755cc8624cf59fc269b18aa2cbbd63be6debce0b86bbebba5da598be4945ff5be16bea6274e841a3af437d095a2340b9064a62ea00e3f0e6fc56f9bd35fd04b2b3ec7d250ef9eb80788d2e5ec26bb855850e55d0b7c37561dbac9fadbbab83f1bdf9be5ef2655d587bff7453d34e169af335d57d4bdf856c1143d3e7c5bc1efe9a6b8c3f769d757f957fc6555228c06f1fb7a879087f78d5415f3a886d99dbb151da87c57bb926d5181f759a6c2f9a6fd84eef7ca97e0be93f0dc00d47e9dd5a334d3f84461600fedb36e423416a2f5a339fe99eff1c98fb8af99c5ef4c424d200ae13d7f7f96dddbb7ecc1ddda52faeedb7aef98befba6aeb3c7ec29db914f597877b601fd4de8b4420f0f55a4866a32dbcd8a4127fa33f849d8390f3a094fbabe9ad79ffa7e2546c556fc06ee0222f64e789e0cf9e718f453771fe64887ff1f1be1dec0cecff5403d38e854d403fcd673bbfadd4ebdb5c7ee43dfa8aa7f014bd5a1830b9d16bd0d94c17d8b90e34b20ef45dcab9cc7151cc64eee2fe5fdf58f3e8aefc9eaf8ae18589b39353b56430fd9cfcafe482e40aa86f3ba29afd4895bc847538499df883353f487e00b15f9a486e6d09ce832be1b0033edc6e7d6adf8e4b5670a32ecba1ffa6e7666fa71d7b5b7be927f3a8e6d5a59d86f1ec4ef7c0be9512f61dfca14c2ef3402f43c60e327ae614eec425f66157da9a7e6c4edfb177aaf9c67844f4bfab1cb0adf210fb5f030ec208699cb56fc17bfb91ddeb37dde8c487f5e2f5f44ebe5dff0ed9bf4b6f5ca2ae0dbd7dbeeb5f1d6e1963dbbade3ff257ff99124e1f3999326bd53b41ed9b7db3c4a45fb912b7ffff9ff37c65fd1cb9699e1373b56759151e7d4d8f21e3ebf8f897b90b97d6deab4446e8f5be77788b77dbe9ff77fa097f5bfaf5811fcdee03e70db0af01ee44a5d419d16e9e3f7e9656baf909fd5da9a7d65459b7f4709f58facef9bb6f14dbd7cd5f9e4efb4f27ce07b92e864795bf4b5a2a31f48f4cb71ec2b0fff91f5fd60c42dc7577b91706e2577feb671d37d7d23dbfbad7ad98c43ab5efae56cf2e7af44f5dc3d7fb00a704eb60795cf9fa8937f76deeffa7c77bcdf93f7ff9e9f7ff7ff2fdcffcdcfff577af9dffff31fff075dc58bf2 + + + + diff --git a/kwordquiz/src/keduvocdata.cpp b/kwordquiz/src/keduvocdata.cpp new file mode 100644 index 00000000..4d46d7d9 --- /dev/null +++ b/kwordquiz/src/keduvocdata.cpp @@ -0,0 +1,163 @@ +/* This file is part of the KDE Edu Library + Copyright (C) 2002 Scott Wheeler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keduvocdata.h" + +#include + +#include + +//////////////////////////////////////////////////////////////////////////////// +// class KEduVocDataItem +//////////////////////////////////////////////////////////////////////////////// + +// public methods + +KEduVocDataItem::KEduVocDataItem() +{ + +} + +KEduVocDataItem::KEduVocDataItem(QDomElement &entry) +{ + domElement = entry; +} + +KEduVocDataItem::~KEduVocDataItem() +{ + +} + +QString KEduVocDataItem::originalText() const +{ + return getText("o"); +} + +QString KEduVocDataItem::translatedText() const +{ + return getText("t"); +} + +// protected methods + +QString KEduVocDataItem::getText(const QString &tagName) const +{ + if(!domElement.isNull()) { + + QDomNodeList list = domElement.elementsByTagName(tagName); + + if(list.count() > 0) { + + QDomElement element = list.item(0).toElement(); + + if(!element.isNull()) { + return element.text(); + } + else + return QString::null; + } + else + return QString::null; + } + else + return QString::null; +} + +//////////////////////////////////////////////////////////////////////////////// +// class KEduVocData +//////////////////////////////////////////////////////////////////////////////// + + +/*! + \fn KEduVocData::KEduVocData + */ +KEduVocData::KEduVocData() +{ + document = new QDomDocument(); +} + +KEduVocDataItemList KEduVocData::parse(const QString &fileName) +{ + KEduVocDataItemList list; + + //QDomDocument document; + QFile file(fileName); + document->setContent(&file); + + QDomNodeList entries = document->elementsByTagName("e"); + + // loop through the "e" (entry) tags looking for data + for(uint i = 0 ; i < entries.count() ; i++) { + + // get an entry to operate on + QDomElement entry = entries.item(i).toElement(); + + // if the "node" is in fact an element -- i.e. not null + if(!entry.isNull()) { + KEduVocDataItem item(entry); + list.append(item); + } + } + + return list; +} + + +/*! + \fn KEduVocData::colWidth(int col) + */ +int KEduVocData::colWidth(int col) +{ + if (!document->isNull()) + if (col == 0) + return document -> documentElement().namedItem("e").namedItem("o").toElement().attribute("width", "250").toInt(); + else + return document -> documentElement().namedItem("e").namedItem("t").toElement().attribute("width", "250").toInt(); + else + return 250; +} + + +/*! + \fn KEduVocData::numRows() + */ +int KEduVocData::numRows() +{ + if (!document->isNull()) + return document->documentElement().attribute("lines", "0").toInt(); + else + return 0; +} + + +/*! + \fn KEduVocData::language(int col) + */ +QString KEduVocData::language(int col) +{ + if (!document->isNull()) + if (col == 0) + return document -> documentElement().namedItem("e").namedItem("o").toElement().attribute("l"); + else + return document -> documentElement().namedItem("e").namedItem("t").toElement().attribute("l"); + else + return QString::null; + +} + + diff --git a/kwordquiz/src/keduvocdata.h b/kwordquiz/src/keduvocdata.h new file mode 100644 index 00000000..968f3243 --- /dev/null +++ b/kwordquiz/src/keduvocdata.h @@ -0,0 +1,59 @@ +#ifndef KEDUVOCDATA_H +#define KEDUVOCDATA_H + +/* This file is part of the KDE Edu Library + Copyright (C) 2002 Scott Wheeler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +class KEduVocDataItem +{ +public: + KEduVocDataItem(); + KEduVocDataItem(QDomElement &entry); + virtual ~KEduVocDataItem(); + + QString originalText() const; + QString translatedText() const; + +protected: + QString getText(const QString &tagName) const; + +private: + QDomElement domElement; +}; + +typedef QValueList KEduVocDataItemList; + +class KEduVocData +{ +public: + KEduVocData(); + KEduVocDataItemList parse(const QString &fileName); + int colWidth(int col); + int numRows(); + QString language(int col); + + +private: + QDomDocument* document; +}; + +#endif + diff --git a/kwordquiz/src/kvtmlwriter.cpp b/kwordquiz/src/kvtmlwriter.cpp new file mode 100644 index 00000000..8ad93797 --- /dev/null +++ b/kwordquiz/src/kvtmlwriter.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + kvtmlwriter.cpp - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kvtmlwriter.h" + +KVTMLWriter::KVTMLWriter(QFile *file) +{ + outputFile = file; + if(outputFile->open(IO_WriteOnly)) + { + outputStream.setDevice(outputFile); + outputStream.setEncoding(QTextStream::UnicodeUTF8); + + outputStream << "" << endl; + outputStream << "" << endl; + } +} + +/*! + \fn KVTMLWriter::addHeader(const QString &generator, int cols, int rows, const QString &title) + */ +void KVTMLWriter::addHeader(const QString &generator, int cols, int rows, const QString &title) +{ + QString s = QString("") + .arg(generator) + .arg(cols) + .arg(rows) + .arg(title); + + outputStream << s << endl << endl; +} + +/*! + \fn KVTMLWriter::addFirstItem(const QString &ll, int lwidth, const QString &left, const QString &rl, int rwidth, const QString &right) + */ +void KVTMLWriter::addFirstItem(const QString &ll, int lwidth, const QString &left, const QString &rl, int rwidth, const QString &right) +{ + outputStream << " " << endl; + QString s = QString(" ") + .arg(lwidth) + .arg(ll); + outputStream << s << escape(left) << "" << endl; + s = QString(" ") + .arg(rwidth) + .arg(rl); + outputStream << s << escape(right) << "" << endl; + outputStream << " " << endl; +} + +/*! + \fn KVTMLWriter::addItem(const QString &left, const QString &right) + */ +void KVTMLWriter::addItem(const QString &left, const QString &right) +{ + outputStream << " " << endl; + outputStream << " " << escape(left) << "" << endl; + outputStream << " " << escape(right) << "" << endl; + outputStream << " " << endl; +} + + +KVTMLWriter::~KVTMLWriter() +{ + outputStream << "" << endl; + outputFile->close(); +} + +QString KVTMLWriter::escape( const QString & s) +{ + QString result = s; + result.replace(QChar('&'), "&"); //must be done first + result.replace(QChar('<'), "<"); + result.replace(QChar('>'), ">"); + + return result; +} + + + + diff --git a/kwordquiz/src/kvtmlwriter.h b/kwordquiz/src/kvtmlwriter.h new file mode 100644 index 00000000..7ff9fa37 --- /dev/null +++ b/kwordquiz/src/kvtmlwriter.h @@ -0,0 +1,40 @@ +/*************************************************************************** + kvtmlwriter.h - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KVTMLWRITER_H +#define KVTMLWRITER_H + +#include +#include + +/** +@author Peter Hedlund +*/ +class KVTMLWriter{ +public: + KVTMLWriter(QFile *file); + + ~KVTMLWriter(); + void addFirstItem(const QString &ll, int lwidth, const QString &left, const QString &rl, int rwidth, const QString &right); + void addHeader(const QString &generator, int cols, int rows, const QString &title); + void addItem(const QString &left, const QString &right); +private: + QString escape(const QString &); + QFile *outputFile; + QTextStream outputStream; +}; + +#endif diff --git a/kwordquiz/src/kwordquiz.cpp b/kwordquiz/src/kwordquiz.cpp new file mode 100644 index 00000000..1c384d9c --- /dev/null +++ b/kwordquiz/src/kwordquiz.cpp @@ -0,0 +1,1258 @@ +/*************************************************************************** + kwordquiz.cpp - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002-2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +// +// include files for QT +#include +#include +#include + +// include files for KDE +#include +#include +#include +#include +#include +#include //locate +#include +#include +#include +#include +//#include +#include + +// application specific includes +#include "kwordquiz.h" +#include "kwordquizdoc.h" +#include "dlglanguage.h" +#include "kwordquizprefs.h" +#include "qaview.h" +#include "flashview.h" +#include "multipleview.h" +#include "wqprintdialogpage.h" +#include "prefs.h" +#include "kwqnewstuff.h" + +#define ID_STATUS_MSG 1 +#define ID_STATUS_MSG_MODE 2 +#define ID_STATUS_MSG_SCORE 3 + +#define ID_MODE_1 1 + +#define ID_MENU_QUIZ 1001 + +KWordQuizApp::KWordQuizApp(QWidget* , const char* name):KMainWindow(0, name) +{ + + /////////////////////////////////////////////////////////////////// + // call inits to invoke all other construction parts + initStatusBar(); + initActions(); + initDocument(); + + readOptions(); + + initView(); + + m_dirWatch = KDirWatch::self(); + m_quizType = WQQuiz::qtEditor; + m_quiz = 0; + m_flashView = 0; + m_multipleView = 0; + m_qaView = 0; + m_newStuff = 0; + + slotQuizEditor(); + slotUndoChange(i18n("Cannot &Undo"), false); + updateMode(Prefs::mode()); + + m_prefDialog = 0; + + editMarkBlank->setEnabled(Prefs::enableBlanks()); + editUnmarkBlank->setEnabled(Prefs::enableBlanks()); + + if (Prefs::firstRun()) + { + fileOpenRecent->addURL( locate("data", "kwordquiz/examples/example.kvtml")); + fileOpenRecent->addURL( locate("data", "kwordquiz/examples/french_verbs.kvtml")); + fileOpenRecent->addURL( locate("data", "kwordquiz/examples/fill_in_the_blank.kvtml")); + fileOpenRecent->addURL( locate("data", "kwordquiz/examples/us_states_and_capitals.kvtml")); + Prefs::setFirstRun(false); + } +} + +KWordQuizApp::~KWordQuizApp() +{ + +} + +void KWordQuizApp::initActions() +{ + KAction* configToolbar; + KAction* configNotifications; + KAction* configApp; + + fileNew = KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection()); + fileNew->setWhatsThis(i18n("Creates a new blank vocabulary document")); + fileNew->setToolTip(fileNew->whatsThis()); + + fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection()); + fileOpen->setWhatsThis(i18n("Opens an existing vocabulary document")); + fileOpen->setToolTip(fileOpen->whatsThis()); + + fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection()); + + fileGHNS = new KAction(i18n("&Get New Vocabularies..."), "knewstuff", "CTRL+G", this, SLOT(slotFileGHNS()), actionCollection(), "file_ghns"); + fileGHNS->setWhatsThis(i18n("Downloads new vocabularies")); + fileGHNS->setToolTip(fileGHNS->whatsThis()); + + fileSave = KStdAction::save(this, SLOT(slotFileSave()), actionCollection()); + fileSave->setWhatsThis(i18n("Saves the active vocabulary document")); + fileSave->setToolTip(fileSave->whatsThis()); + + fileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection()); + fileSaveAs->setWhatsThis(i18n("Saves the active vocabulary document with a different name")); + fileSaveAs->setToolTip(fileSaveAs->whatsThis()); + + fileClose = KStdAction::close(this, SLOT(slotFileClose()), actionCollection()); + fileClose->setWhatsThis(i18n("Closes the active vocabulary document")); + fileClose->setToolTip(fileClose->whatsThis()); + + filePrint = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection()); + filePrint->setWhatsThis(i18n("Prints the active vocabulary document")); + filePrint->setToolTip(filePrint->whatsThis()); + + fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection()); + fileQuit->setWhatsThis(i18n("Quits KWordQuiz")); + fileQuit->setToolTip(fileQuit->whatsThis()); + + editUndo = KStdAction::undo(this, SLOT(slotEditUndo()), actionCollection()); + editUndo->setWhatsThis(i18n("Undoes the last command")); + editUndo->setToolTip(editUndo->whatsThis()); + + editCut = KStdAction::cut(this, SLOT(slotEditCut()), actionCollection()); + editCut->setWhatsThis(i18n("Cuts the text from the selected cells and places it on the clipboard")); + editCut->setToolTip(editCut->whatsThis()); + + editCopy = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection()); + editCopy->setWhatsThis(i18n("Copies the text from the selected cells and places it on the clipboard")); + editCopy->setToolTip(editCopy->whatsThis()); + + editPaste = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection()); + editPaste->setWhatsThis(i18n("Pastes previously cut or copied text from the clipboard into the selected cells")); + editPaste->setToolTip(editPaste->whatsThis()); + + editClear = KStdAction::clear(this, SLOT(slotEditClear()), actionCollection()); + editClear->setWhatsThis(i18n("Clears the content of the selected cells")); + editClear->setToolTip(editClear->whatsThis()); + + editInsert = new KAction(i18n("&Insert Row"), "insert_table_row", "CTRL+I", this, SLOT(slotEditInsert()), actionCollection(),"edit_insert"); + editInsert->setWhatsThis(i18n("Inserts a new row above the current row")); + editInsert->setToolTip(editInsert->whatsThis()); + + editDelete = new KAction(i18n("&Delete Row"), "delete_table_row", "CTRL+K", this, SLOT(slotEditDelete()), actionCollection(),"edit_delete"); + editDelete->setWhatsThis(i18n("Deletes the selected row(s)")); + editDelete->setToolTip(editDelete->whatsThis()); + + editMarkBlank = new KAction(i18n("&Mark as Blank"), "markasblank", "CTRL+M", this, SLOT(slotEditMarkBlank()), actionCollection(),"edit_mark_blank"); + editMarkBlank->setWhatsThis(i18n("Marks the current or selected word as a blank for Fill-in-the-blank")); + editMarkBlank->setToolTip(editMarkBlank->whatsThis()); + + editUnmarkBlank = new KAction(i18n("&Unmark Blanks"), "unmarkasblank", 0, this, SLOT(slotEditUnmarkBlank()), actionCollection(),"edit_unmark_blank"); + editUnmarkBlank->setWhatsThis(i18n("Removes blanks from the current or selected word")); + editUnmarkBlank->setToolTip(editUnmarkBlank->whatsThis()); + + //@todo implement editFind = KStdAction::find(this, SLOT(slotEditFind()), actionCollection()); + + vocabLanguages = new KAction(i18n("&Column Titles..."), "languages", "CTRL+L", this, SLOT(slotVocabLanguages()), actionCollection(),"vocab_languages"); + vocabLanguages->setWhatsThis(i18n("Defines the column titles for the active vocabulary")); + vocabLanguages->setToolTip(vocabLanguages->whatsThis()); + + vocabFont = new KAction(i18n("&Font..."), "fonts", 0, this, SLOT(slotVocabFont()), actionCollection(),"vocab_font"); + vocabFont->setWhatsThis(i18n("Defines the font used by the editor")); + vocabFont->setToolTip(vocabFont->whatsThis()); + + //@todo implement vocabKeyboard = new KAction(i18n("&Keyboard..."), "kxkb", 0, this, SLOT(slotVocabKeyboard()), actionCollection(),"vocab_keyboard"); + + vocabRC = new KAction(i18n("&Rows/Columns..."), "rowcol", 0, this, SLOT(slotVocabRC()), actionCollection(),"vocab_rc"); + vocabRC->setWhatsThis(i18n("Defines the number of rows, row heights, and column widths for the active vocabulary")); + vocabRC->setToolTip(vocabRC->whatsThis()); + + vocabSort = new KAction(i18n("&Sort..."), "sort_incr", 0, this, SLOT(slotVocabSort()), actionCollection(),"vocab_sort"); + vocabSort->setWhatsThis(i18n("Sorts the vocabulary in ascending or descending order based on the left or right column")); + vocabSort->setToolTip(vocabSort->whatsThis()); + + vocabShuffle = new KAction(i18n("Sh&uffle"), "shuffle", 0, this, SLOT(slotVocabShuffle()), actionCollection(),"vocab_shuffle"); + vocabShuffle->setWhatsThis(i18n("Shuffles the entries of the active vocabulary")); + vocabShuffle->setToolTip(vocabShuffle->whatsThis()); + + mode = new KToolBarPopupAction(i18n("Change Mode"), "mode1", 0, this, SLOT(slotMode0()), actionCollection(),"mode_0"); + mode->setWhatsThis(i18n("Changes the mode used in quiz sessions")); + mode->setToolTip(mode->whatsThis()); + + KPopupMenu *popup = mode->popupMenu(); + popup->clear(); + popup->insertItem(KGlobal::iconLoader()->loadIconSet("mode1", KIcon::Toolbar), "", this, SLOT(slotMode1()), 0, 0); + popup->insertItem(KGlobal::iconLoader()->loadIconSet("mode2", KIcon::Toolbar), "", this, SLOT(slotMode2()), 0, 1); + popup->insertItem(KGlobal::iconLoader()->loadIconSet("mode3", KIcon::Toolbar), "", this, SLOT(slotMode3()), 0, 2); + popup->insertItem(KGlobal::iconLoader()->loadIconSet("mode4", KIcon::Toolbar), "", this, SLOT(slotMode4()), 0, 3); + popup->insertItem(KGlobal::iconLoader()->loadIconSet("mode5", KIcon::Toolbar), "", this, SLOT(slotMode5()), 0, 4); + + mode1 = new KToggleAction("", "mode1", 0, this, SLOT(slotMode1()), actionCollection(),"mode_1"); + mode2 = new KToggleAction("", "mode2", 0, this, SLOT(slotMode2()), actionCollection(),"mode_2"); + mode3 = new KToggleAction("", "mode3", 0, this, SLOT(slotMode3()), actionCollection(),"mode_3"); + mode4 = new KToggleAction("", "mode4", 0, this, SLOT(slotMode4()), actionCollection(),"mode_4"); + mode5 = new KToggleAction("", "mode5", 0, this, SLOT(slotMode5()), actionCollection(),"mode_5"); + mode1->setWhatsThis(i18n("Selects this mode")); + mode2->setWhatsThis(i18n("Selects this mode")); + mode3->setWhatsThis(i18n("Selects this mode")); + mode4->setWhatsThis(i18n("Selects this mode")); + mode5->setWhatsThis(i18n("Selects this mode")); + mode1->setToolTip(mode1->whatsThis()); + mode2->setToolTip(mode2->whatsThis()); + mode3->setToolTip(mode3->whatsThis()); + mode4->setToolTip(mode4->whatsThis()); + mode5->setToolTip(mode5->whatsThis()); + + quizEditor = new KAction(i18n("&Editor"), "editor", "F6", this, SLOT(slotQuizEditor()), actionCollection(),"quiz_editor"); + quizEditor->setWhatsThis(i18n("Activates the vocabulary editor")); + quizEditor->setToolTip(quizEditor->whatsThis()); + + quizFlash = new KAction(i18n("&Flashcard"), "flash", "F7", this, SLOT(slotQuizFlash()), actionCollection(),"quiz_flash"); + quizFlash->setWhatsThis(i18n("Starts a flashcard session using the active vocabulary")); + quizFlash->setToolTip(quizFlash->whatsThis()); + + quizMultiple = new KAction(i18n("&Multiple Choice"), "multiple", "F8", this, SLOT(slotQuizMultiple()), actionCollection(),"quiz_multiple"); + quizMultiple->setWhatsThis(i18n("Starts a multiple choice session using the active vocabulary")); + quizMultiple->setToolTip(quizMultiple->whatsThis()); + + quizQA = new KAction(i18n("&Question && Answer"), "qa", "F9", this, SLOT(slotQuizQA()), actionCollection(),"quiz_qa"); + quizQA->setWhatsThis(i18n("Starts a question and answer session using the active vocabulary")); + quizQA->setToolTip(quizQA->whatsThis()); + + quizCheck = new KAction(i18n("&Check"), "check", "Return", this, 0, actionCollection(),"quiz_check"); + quizCheck->setWhatsThis(i18n("Checks your answer to this question")); + quizCheck->setToolTip(quizCheck->whatsThis()); + + flashKnow = new KAction(i18n("I &Know"), "know", "K", this, 0, actionCollection(),"flash_know"); + flashKnow->setWhatsThis(i18n("Counts this card as correct and shows the next card")); + flashKnow->setToolTip(flashKnow->whatsThis()); + + flashDontKnow = new KAction(i18n("I &Do Not Know"), "dontknow", "D", this, 0, actionCollection(),"flash_dont_know"); + flashDontKnow->setWhatsThis(i18n("Counts this card as incorrect and shows the next card")); + flashDontKnow->setToolTip(flashDontKnow->whatsThis()); + + qaHint = new KAction(i18n("&Hint"), "hint", "CTRL+H", this, 0, actionCollection(),"qa_hint"); + qaHint->setWhatsThis(i18n("Gets the next correct letter of the answer")); + qaHint->setToolTip(qaHint->whatsThis()); + + quizRestart = new KAction(i18n("&Restart"), "restart.png", "CTRL+R", this, 0, actionCollection(), "quiz_restart"); + quizRestart->setWhatsThis(i18n("Restarts the quiz session from the beginning")); + quizRestart->setToolTip(quizRestart->whatsThis()); + + quizRepeatErrors = new KAction(i18n("Repeat &Errors"), "repeat", "CTRL+E", this, 0, actionCollection(),"quiz_repeat_errors"); + quizRepeatErrors->setWhatsThis(i18n("Repeats all incorrectly answered questions")); + quizRepeatErrors->setToolTip(quizRepeatErrors->whatsThis()); + + configNotifications = KStdAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection()); + configNotifications->setWhatsThis(i18n("Configures sound and other notifications for certain events")); + configNotifications->setToolTip(configNotifications->whatsThis()); + + configApp = KStdAction::preferences(this, SLOT( slotConfigure()), actionCollection()); + configApp->setWhatsThis(i18n("Specifies preferences for the vocabulary editor and quiz sessions")); + configApp->setToolTip(configApp->whatsThis()); + + charMapper = new QSignalMapper(this); + connect(charMapper, SIGNAL(mapped(int)), this, SLOT(slotInsertChar(int))); + + specialChar1 = new KAction(i18n("Special Character 1"), "", "CTRL+1", charMapper, SLOT(map()), actionCollection(), "char_1") ; + specialChar2 = new KAction(i18n("Special Character 2"), 0, "CTRL+2", charMapper, SLOT(map()), actionCollection(), "char_2") ; + specialChar3 = new KAction(i18n("Special Character 3"), 0, "CTRL+3", charMapper, SLOT(map()), actionCollection(), "char_3") ; + specialChar4 = new KAction(i18n("Special Character 4"), 0, "CTRL+4", charMapper, SLOT(map()), actionCollection(), "char_4") ; + specialChar5 = new KAction(i18n("Special Character 5"), 0, "CTRL+5", charMapper, SLOT(map()), actionCollection(), "char_5") ; + specialChar6 = new KAction(i18n("Special Character 6"), 0, "CTRL+6", charMapper, SLOT(map()), actionCollection(), "char_6") ; + specialChar7 = new KAction(i18n("Special Character 7"), 0, "CTRL+7", charMapper, SLOT(map()), actionCollection(), "char_7") ; + specialChar8 = new KAction(i18n("Special Character 8"), 0, "CTRL+8", charMapper, SLOT(map()), actionCollection(), "char_8") ; + specialChar9 = new KAction(i18n("Special Character 9"), 0, "CTRL+9", charMapper, SLOT(map()), actionCollection(), "char_9") ; + + charMapper->setMapping(specialChar1, 1); + charMapper->setMapping(specialChar2, 2); + charMapper->setMapping(specialChar3, 3); + charMapper->setMapping(specialChar4, 4); + charMapper->setMapping(specialChar5, 5); + charMapper->setMapping(specialChar6, 6); + charMapper->setMapping(specialChar7, 7); + charMapper->setMapping(specialChar8, 8); + charMapper->setMapping(specialChar9, 9); + + actionCollection()->setHighlightingEnabled(true); + connect(actionCollection(), SIGNAL(actionStatusText(const QString &)), this, SLOT(slotStatusMsg(const QString &))); + connect(actionCollection(), SIGNAL(actionHighlighted(KAction *, bool)), this, SLOT(slotActionHighlighted(KAction *, bool))); + updateSpecialCharIcons(); + + if (!initialGeometrySet()) + resize( QSize(650, 500).expandedTo(minimumSizeHint())); + setupGUI(ToolBar | Keys | StatusBar | Create); + setAutoSaveSettings(); + + configToolbar = actionCollection()->action("options_configure_toolbars"); + configToolbar->setWhatsThis(i18n("Toggles display of the toolbars")); + configToolbar->setToolTip(configToolbar->whatsThis()); +} + +void KWordQuizApp::initStatusBar() +{ + statusBar()->insertFixedItem("", ID_STATUS_MSG_MODE, true); + statusBar()->setItemFixed(ID_STATUS_MSG_MODE, 250); + statusBar()->setItemAlignment(ID_STATUS_MSG_MODE, AlignLeft|AlignVCenter); +} + +void KWordQuizApp::initDocument() +{ + doc = new KWordQuizDoc(this); + doc->newDocument(); +} + +void KWordQuizApp::initView() +{ + m_editView = new KWordQuizView(this); + doc->addView(m_editView); + setCentralWidget(m_editView); + setCaption(doc->URL().fileName(),false); + m_editView->setFont(Prefs::editorFont()); + connect(m_editView, SIGNAL(undoChange(const QString&, bool )), this, SLOT(slotUndoChange(const QString&, bool))); + connect(m_editView, SIGNAL(contextMenuRequested(int, int, const QPoint &)), this, SLOT(slotContextMenuRequested(int, int, const QPoint& ))); +} + +void KWordQuizApp::openURL(const KURL& url) +{ + if(!url.isEmpty()) { + if (m_dirWatch->contains(url.path())) + { + KMainWindow* w; + if(memberList) + { + for(w=memberList->first(); w!=0; w=memberList->next()) + { + KWordQuizApp *a =(KWordQuizApp *) w; + if(a->doc ->URL().path() == url.path()) + { + if (w->isMinimized()) + w->showNormal(); + w->setActiveWindow(); + w->raise(); + break; + } + } + } + } + else + { + if (doc->URL().fileName() == i18n("Untitled") && m_editView->gridIsEmpty()){ + // neither saved nor has content, as good as new + openDocumentFile(url); + } + else + { + KWordQuizApp *new_window= new KWordQuizApp(); + new_window->show(); + new_window->openDocumentFile(url); + } + } + } +} + +void KWordQuizApp::openDocumentFile(const KURL& url) +{ + slotStatusMsg(i18n("Opening file...")); + if (!url.isEmpty()) { + doc->openDocument( url); + m_dirWatch->addFile(url.path()); + setCaption(doc->URL().fileName(), false); + fileOpenRecent->addURL( url ); + updateMode(Prefs::mode()); + } + slotStatusMsg(i18n("Ready")); +} + + +KWordQuizDoc *KWordQuizApp::getDocument() const +{ + return doc; +} + +void KWordQuizApp::saveOptions() +{ + fileOpenRecent->saveEntries(kapp->config(), "Recent Files"); + Prefs::writeConfig(); +} + + +void KWordQuizApp::readOptions() +{ + //Prefs::readConfig(); + fileOpenRecent->loadEntries(kapp->config(), "Recent Files"); +} + +void KWordQuizApp::saveProperties(KConfig *_cfg) +{ + if(doc->URL().fileName()!=i18n("Untitled") && !doc->isModified()) + { + // saving to tempfile not necessary + + } + else + { + KURL url=doc->URL(); + _cfg->writeEntry("filename", url.url()); + _cfg->writeEntry("modified", doc->isModified()); + QString tempname = kapp->tempSaveName(url.url()); + QString tempurl= KURL::encode_string(tempname); + KURL _url(tempurl); + doc->saveDocument(_url); + } +} + + +void KWordQuizApp::readProperties(KConfig* _cfg) +{ + QString filename = _cfg->readEntry("filename", ""); + KURL url(filename); + bool modified = _cfg->readBoolEntry("modified", false); + if(modified) + { + bool canRecover; + QString tempname = kapp->checkRecoverFile(filename, canRecover); + KURL _url(tempname); + + if(canRecover) + { + doc->openDocument(_url); + doc->setModified(); + setCaption(_url.fileName(),true); + QFile::remove(tempname); + } + } + else + { + if(!filename.isEmpty()) + { + doc->openDocument(url); + setCaption(url.fileName(),false); + } + } +} + +bool KWordQuizApp::queryClose() +{ + bool f = doc->saveModified(); + if (f) + if (m_dirWatch->contains(doc->URL().path())) + m_dirWatch->removeFile(doc->URL().path()); + return f; +} + +bool KWordQuizApp::queryExit() +{ + saveOptions(); + return true; +} + +///////////////////////////////////////////////////////////////////// +// SLOT IMPLEMENTATION +///////////////////////////////////////////////////////////////////// + +void KWordQuizApp::slotFileNew() +{ + slotStatusMsg(i18n("Opening a new document window...")); + if (doc->URL().fileName() == i18n("Untitled") && m_editView->gridIsEmpty()){ + // neither saved nor has content, as good as new + } + else + { + KWordQuizApp *new_window= new KWordQuizApp(); + new_window->show(); + } + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFileOpen() +{ + slotStatusMsg(i18n("Opening file...")); + + QCheckBox * cb = new QCheckBox(i18n("&Join selected files into one list"), 0, 0); + cb -> setChecked(false); + + QString filter = i18n("*.kvtml *.wql *.xml.gz *.csv|All Supported Documents\n*.kvtml|KDE Vocabulary Document\n*.wql|KWordQuiz Document\n*.xml.gz|Pauker Lesson\n*.csv|Comma-Separated Values"); + KFileDialog *fd = new KFileDialog(QString::null, filter, this, 0, true, cb); + fd -> setOperationMode(KFileDialog::Opening); + fd -> setMode(KFile::Files | KFile::ExistingOnly); + fd -> setCaption(i18n("Open Vocabulary Document")); + + if (fd->exec() == QDialog::Accepted) + { + KURL::List l = fd -> selectedURLs(); + bool append = ((cb -> isChecked()) && (l.count() > 1)); + + if (append) + { + KWordQuizApp * w; + if (doc->URL().fileName() == i18n("Untitled") && m_editView->gridIsEmpty()){ + // neither saved nor has content, as good as new + w = this; + } + else + { + w = new KWordQuizApp(); + w->show(); + } + + KURL::List::iterator it; + int i = 0; + for(it = l.begin(); it != l.end(); ++it) + { + w->getDocument()->openDocument(*it, true, i); + i++; + } + } + else + { + KURL::List::iterator it; + for(it = l.begin(); it != l.end(); ++it) + { + openURL(*it); + } + } + } + + delete (fd); //deletes cb also + + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFileOpenRecent(const KURL& url) +{ + slotStatusMsg(i18n("Opening file...")); + fileOpenRecent->setCurrentItem(-1); + openURL(url); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFileSave() +{ + slotStatusMsg(i18n("Saving file...")); + if (doc->URL().fileName() == i18n("Untitled") ) + { + slotFileSaveAs(); + } + else + { + doc->saveDocument(doc->URL()); + } + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFileGHNS() +{ + if (!m_newStuff) + m_newStuff = new KWQNewStuff(this); + m_newStuff->download(); +} + +void KWordQuizApp::slotFileSaveAs() +{ + slotStatusMsg(i18n("Saving file with a new filename...")); + saveAsFileName(); + slotStatusMsg(i18n("Ready")); +} + +bool KWordQuizApp::saveAsFileName( ) +{ + + bool success = false; + + QString filter = i18n("*.kvtml|KDE Vocabulary Document\n*.wql|KWordQuiz Document\n*.csv|Comma-Separated Values\n*.html|Hypertext Markup Language"); + KFileDialog *fd = new KFileDialog(QString::null, filter, this, 0, true); + fd -> setOperationMode(KFileDialog::Saving); + fd -> setCaption(i18n("Save Vocabulary Document As")); + + if (fd->exec() == QDialog::Accepted) + { + KURL url = fd -> selectedURL(); + if(!url.isEmpty()){ + + //@todo check that a valid extension was really given + if (!url.fileName().contains('.')) + { + if (fd->currentFilter() == "*.wql") + url = KURL(url.path() + ".wql"); + else if (fd->currentFilter() == "*.csv") + url = KURL(url.path() + ".csv"); + else if (fd->currentFilter() == "*.html") + url = KURL(url.path() + ".html"); + else + url = KURL(url.path() + ".kvtml"); + } + + QFileInfo fileinfo(url.path()); + if (fileinfo.exists() && KMessageBox::warningContinueCancel(0, + i18n("The file
%1
already exists. Do you want to overwrite it?
") + .arg(url.path()),QString::null,i18n("Overwrite")) == KMessageBox::Cancel) + { + // do nothing + } + else + { + if (m_dirWatch ->contains(doc->URL().path())) + m_dirWatch ->removeFile(doc->URL().path()); + doc->saveDocument(url); + m_dirWatch->addFile(url.path()); + fileOpenRecent->addURL(url); + setCaption(doc->URL().fileName(), doc->isModified()); + success = true; + } + } + } + delete(fd); + return success; +} + +void KWordQuizApp::slotFileClose() +{ + slotStatusMsg(i18n("Closing file...")); + + if (memberList->count() > 1) + close(); + else + if (queryClose()) + { + if (m_quiz != 0) + { + delete(m_quiz); + m_quiz = 0; + } + doc->newDocument(); + setCaption(doc->URL().fileName(), doc->isModified()); + delete (m_editView); + initView(); + slotQuizEditor(); + slotUndoChange(i18n("Cannot &Undo"), false); + updateMode(Prefs::mode()); + m_editView ->setFocus(); + } + + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFilePrint() +{ + slotStatusMsg(i18n("Printing...")); + WQPrintDialogPage * p = new WQPrintDialogPage(this); + KPrinter printer; + printer.addDialogPage(p); + printer.setFullPage(true); + if (printer.setup(this)) + { + m_editView->print(&printer); + } + + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotFileQuit() +{ + slotStatusMsg(i18n("Exiting...")); + saveOptions(); + // close the first window, the list makes the next one the first again. + // This ensures that queryClose() is called on each window to ask for closing + KMainWindow* w; + if(memberList) + { + for(w=memberList->first(); w!=0; w=memberList->next()) + { + // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog, + // the window and the application stay open. + if(!w->close()) + break; + } + } +} + +void KWordQuizApp::slotUndoChange( const QString & text, bool enabled ) +{ + editUndo->setText(text); + editUndo->setEnabled(enabled); +} + +void KWordQuizApp::slotEditUndo() +{ + slotStatusMsg(i18n("Undoing previous command...")); + m_editView->doEditUndo(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditCut() +{ + slotStatusMsg(i18n("Cutting selection...")); + m_editView->doEditCut(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditCopy() +{ + slotStatusMsg(i18n("Copying selection to clipboard...")); + m_editView->doEditCopy(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditPaste() +{ + slotStatusMsg(i18n("Inserting clipboard contents...")); + m_editView->doEditPaste(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditClear() +{ + slotStatusMsg(i18n("Clearing the selected cells...")); + m_editView->doEditClear(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditInsert() +{ + slotStatusMsg(i18n("Inserting rows...")); + m_editView->doEditInsert(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditDelete() +{ + slotStatusMsg(i18n("Deleting selected rows...")); + m_editView->doEditDelete(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditMarkBlank() +{ + slotStatusMsg(i18n("Marking selected text as a blank...")); + m_editView->doEditMarkBlank(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditUnmarkBlank() +{ + slotStatusMsg(i18n("Removing blank markings...")); + m_editView->doEditUnmarkBlank(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotEditFind() +{ + slotStatusMsg(i18n("Searching for indicated text...")); + KMessageBox::sorry(0, i18n("Not implemented yet")); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabLanguages() +{ + slotStatusMsg(i18n("Setting the column titles of the vocabulary...")); + DlgLanguage* dlg; + dlg = new DlgLanguage(this, "dlg_lang", true); + dlg->setLanguage(1, m_editView -> horizontalHeader()->label(0)); + dlg->setLanguage(2, m_editView -> horizontalHeader()->label(1)); + dlg->disableResize(); + if (dlg->exec() == KDialogBase::Accepted) + { + m_editView -> horizontalHeader()->setLabel(0, dlg->Language(1)); + m_editView -> horizontalHeader()->setLabel(1, dlg->Language(2)); + updateMode(Prefs::mode()); + } + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabFont() +{ + slotStatusMsg(i18n("Setting the font of the vocabulary...")); + KFontDialog* dlg; + dlg = new KFontDialog(this, "dlg_font", false, true); + dlg->setFont(m_editView -> font()); + if (dlg->exec() == KFontDialog::Accepted) + { + m_editView ->setFont(dlg->font()); + Prefs::setEditorFont(dlg->font()); + doc->setModified(true); + } + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabKeyboard() +{ + slotStatusMsg(i18n("Changing the keyboard layout...")); + KMessageBox::sorry(0, i18n("Not implemented yet")); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabChar() +{ + slotStatusMsg(i18n("Inserting special character...")); + m_editView->doVocabSpecChar(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabRC() +{ + slotStatusMsg(i18n("Changing row and column properties...")); + m_editView->doVocabRC(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabSort() +{ + slotStatusMsg(i18n("Sorting the vocabulary...")); + m_editView->doVocabSort(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotVocabShuffle() +{ + slotStatusMsg(i18n("Randomizing the vocabulary...")); + m_editView->doVocabShuffle(); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode0() +{ + slotStatusMsg(i18n("Updating mode...")); + if (Prefs::mode() < 5) { + updateMode(Prefs::mode() + 1); + } + else + { + updateMode(1); + } + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode1() +{ + slotStatusMsg(i18n("Updating mode...")); + updateMode(1); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode2() +{ + slotStatusMsg(i18n("Updating mode...")); + updateMode(2); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode3() +{ + slotStatusMsg(i18n("Updating mode...")); + updateMode(3); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode4() +{ + slotStatusMsg(i18n("Updating mode...")); + updateMode(4); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotMode5() +{ + slotStatusMsg(i18n("Updating mode...")); + updateMode(5); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotQuizEditor() +{ + slotStatusMsg(i18n("Starting editor session...")); + updateSession(WQQuiz::qtEditor); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotQuizFlash() +{ + slotStatusMsg(i18n("Starting flashcard session...")); + updateSession(WQQuiz::qtFlash); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotQuizMultiple() +{ + slotStatusMsg(i18n("Starting multiple choice session...")); + updateSession(WQQuiz::qtMultiple); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotQuizQA() +{ + slotStatusMsg(i18n("Starting question & answer session...")); + updateSession(WQQuiz::qtQA); + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::updateSession(WQQuiz::QuizType qt) +{ + if (m_quiz != 0) + { + delete(m_quiz); + m_quiz = 0; + } + + switch( m_quizType ){ + case WQQuiz::qtEditor: + // + break; + case WQQuiz::qtFlash: + if (m_flashView != 0) + { + delete(m_flashView); + m_flashView = 0; + } + break; + case WQQuiz::qtMultiple: + if (m_multipleView != 0) + { + delete(m_multipleView); + m_multipleView = 0; + } + break; + case WQQuiz::qtQA: + if (m_qaView != 0) + { + delete(m_qaView); + m_qaView = 0; + } + break; + } + + m_quizType = qt; + updateActions(qt); + + switch( m_quizType ){ + case WQQuiz::qtEditor: + m_editView->show(); + setCentralWidget(m_editView); + m_editView -> setFocus(); + break; + case WQQuiz::qtFlash: + m_quiz = new WQQuiz(m_editView); + connect(m_quiz, SIGNAL(checkingAnswer(int )), m_editView, SLOT(slotCheckedAnswer(int ))); + m_quiz ->setQuizType(WQQuiz::qtFlash); + m_quiz->setQuizMode(Prefs::mode()); + if (m_quiz -> init()) + { + m_editView->saveCurrentSelection(true); + m_editView->hide(); + m_flashView = new FlashView(this); + connect(quizCheck, SIGNAL(activated()), m_flashView, SLOT(slotFlip())); + connect(flashKnow, SIGNAL(activated()), m_flashView, SLOT(slotKnow())); + connect(flashDontKnow, SIGNAL(activated()), m_flashView, SLOT(slotDontKnow())); + connect(quizRestart, SIGNAL(activated()), m_flashView, SLOT(slotRestart())); + connect(quizRepeatErrors, SIGNAL(activated()), m_flashView, SLOT(slotRepeat())); + connect(this, SIGNAL(settingsChanged()), m_flashView, SLOT(slotApplySettings())); + + setCentralWidget(m_flashView); + m_flashView -> setQuiz(m_quiz); + m_flashView ->init(); + m_flashView->show(); + } + else + { + delete(m_quiz); + m_quiz = 0; + } + break; + case WQQuiz::qtMultiple: + m_quiz = new WQQuiz(m_editView); + connect(m_quiz, SIGNAL(checkingAnswer(int )), m_editView, SLOT(slotCheckedAnswer(int ))); + m_quiz ->setQuizType(WQQuiz::qtMultiple); + m_quiz->setQuizMode(Prefs::mode()); + if (m_quiz -> init()) + { + m_editView->saveCurrentSelection(true); + m_editView->hide(); + m_multipleView = new MultipleView(this); + connect(quizCheck, SIGNAL(activated()), m_multipleView, SLOT(slotCheck())); + connect(quizRestart, SIGNAL(activated()), m_multipleView, SLOT(slotRestart())); + connect(quizRepeatErrors, SIGNAL(activated()), m_multipleView, SLOT(slotRepeat())); + connect(this, SIGNAL(settingsChanged()), m_multipleView, SLOT(slotApplySettings())); + + setCentralWidget(m_multipleView); + + m_multipleView -> setQuiz(m_quiz); + m_multipleView ->init(); + m_multipleView->show(); + } + else + { + delete(m_quiz); + m_quiz = 0; + } + break; + case WQQuiz::qtQA: + m_quiz = new WQQuiz(m_editView); + connect(m_quiz, SIGNAL(checkingAnswer(int )), m_editView, SLOT(slotCheckedAnswer(int ))); + m_quiz ->setQuizType(WQQuiz::qtQA); + m_quiz->setQuizMode(Prefs::mode()); + if (m_quiz -> init()) + { + m_editView->saveCurrentSelection(true); + m_editView->hide(); + m_qaView = new QAView(this); + connect(quizCheck, SIGNAL(activated()), m_qaView, SLOT(slotCheck())); + connect(qaHint, SIGNAL(activated()), m_qaView, SLOT(slotHint())); + connect(quizRestart, SIGNAL(activated()), m_qaView, SLOT(slotRestart())); + connect(quizRepeatErrors, SIGNAL(activated()), m_qaView, SLOT(slotRepeat())); + connect(this, SIGNAL(settingsChanged()), m_qaView, SLOT(slotApplySettings())); + + setCentralWidget(m_qaView); + + m_qaView -> setQuiz(m_quiz); + m_qaView ->init(); + m_qaView->show(); + } + else + { + delete(m_quiz); + m_quiz = 0; + } + break; + + } +} + +/** Configure notifications */ +void KWordQuizApp::slotConfigureNotifications( ) +{ + KNotifyDialog::configure(this, "Notification Configuration Dialog"); +} + +/** Configure kwordquiz */ +void KWordQuizApp::slotConfigure() +{ + if ( KWordQuizPrefs::showDialog( "settings" ) ) + return; + + //KConfigDialog didn't find an instance of this dialog, so lets create it : + KWordQuizPrefs* dialog = new KWordQuizPrefs( this, "settings", Prefs::self() ); + connect(dialog, SIGNAL(settingsChanged()), this, SLOT(slotApplyPreferences())); + dialog->show(); +} + +void KWordQuizApp::slotApplyPreferences() +{ + kdDebug() << "Prefs Update" << endl; + editMarkBlank->setEnabled(Prefs::enableBlanks()); + editUnmarkBlank->setEnabled(Prefs::enableBlanks()); + m_editView->viewport()->repaint(true); + updateSpecialCharIcons(); + emit settingsChanged(); +} + +void KWordQuizApp::updateSpecialCharIcons( ) +{ + for (int i = 0; i < 9; i++){ + KAction * act = actionCollection()->action(QString("char_" + QString::number(i + 1)).latin1()); + act->setIcon(charIcon(Prefs::specialCharacters()[i])); + act->setToolTip(i18n("Inserts the character %1").arg(Prefs::specialCharacters()[i])); + } +} + +QString KWordQuizApp::charIcon(const QChar & c) +{ + ///Create a name and path for the icon + QString s = locateLocal("icon", "char" + QString::number(c.unicode()) + ".png"); + + ///No need to redraw if it already exists + if (KStandardDirs::exists(s)) + return s; + + QRect r(4, 4, 120, 120); + + ///A font to draw the character with + QFont font("sans"); + font.setPixelSize(100); + font.setWeight(QFont::Bold); + + ///Create the pixmap + QPixmap pm(128, 128); + pm.fill(Qt::white); + QPainter p(&pm); + p.setFont(font); + p.setPen(Qt::blue); + p.drawText(r, Qt::AlignCenter, (QString) c); + + ///Create transparency mask + QBitmap bm(128, 128); + bm.fill(Qt::color0); + QPainter b(&bm); + b.setFont(font); + b.setPen(Qt::color1); + b.drawText(r, Qt::AlignCenter, (QString) c); + + ///Mask the pixmap + pm.setMask(bm); + + ///Save the icon to disk + pm.save(s, "PNG"); + + return s; +} + +void KWordQuizApp::slotStatusMsg(const QString &text) +{ + statusBar()->clear(); + statusBar()->message(text); +} + +/*! + \fn KWordQuizApp::updateMode(int m) + */ +void KWordQuizApp::updateMode(int m) +{ + if (m_quiz != 0) + if (KMessageBox::warningContinueCancel(this, i18n("This will restart your quiz. Do you wish to continue?"), QString::null, KStdGuiItem::cont(), "askModeQuiz") != KMessageBox::Continue) + { + mode1->setChecked(Prefs::mode() == 1); + mode2->setChecked(Prefs::mode() == 2); + mode3->setChecked(Prefs::mode() == 3); + mode4->setChecked(Prefs::mode() == 4); + mode5->setChecked(Prefs::mode() == 5); + return; + } + + Prefs::setMode(m); + QString s1 = m_editView -> horizontalHeader()->label(0); + QString s2 = m_editView -> horizontalHeader()->label(1); + + mode1->setText(i18n("&1 %1 -> %2 In Order").arg(s1).arg(s2)); + mode2->setText(i18n("&2 %1 -> %2 In Order").arg(s2).arg(s1)); + mode3->setText(i18n("&3 %1 -> %2 Randomly").arg(s1).arg(s2)); + mode4->setText(i18n("&4 %1 -> %2 Randomly").arg(s2).arg(s1)); + mode5->setText(i18n("&5 %1 <-> %2 Randomly").arg(s1).arg(s2)); + + mode1->setChecked(Prefs::mode() == 1); + mode2->setChecked(Prefs::mode() == 2); + mode3->setChecked(Prefs::mode() == 3); + mode4->setChecked(Prefs::mode() == 4); + mode5->setChecked(Prefs::mode() == 5); + + KPopupMenu *popup = mode->popupMenu(); + popup->setItemChecked(0, Prefs::mode() == 1); + popup->setItemChecked(1, Prefs::mode() == 2); + popup->setItemChecked(2, Prefs::mode() == 3); + popup->setItemChecked(3, Prefs::mode() == 4); + popup->setItemChecked(4, Prefs::mode() == 5); + + popup->changeItem(0, i18n("&1 %1 -> %2 In Order").arg(s1).arg(s2)); + popup->changeItem(1, i18n("&2 %1 -> %2 In Order").arg(s2).arg(s1)); + popup->changeItem(2, i18n("&3 %1 -> %2 Randomly").arg(s1).arg(s2)); + popup->changeItem(3, i18n("&4 %1 -> %2 Randomly").arg(s2).arg(s1)); + popup->changeItem(4, i18n("&5 %1 <-> %2 Randomly").arg(s1).arg(s2)); + + QString s; + mode->setIcon("mode" + s.setNum(Prefs::mode())); + + switch( Prefs::mode() ){ + case 1: + statusBar()->changeItem(i18n("%1 -> %2 In Order").arg(s1).arg(s2), ID_STATUS_MSG_MODE); + break; + case 2: + statusBar()->changeItem(i18n("%1 -> %2 In Order").arg(s2).arg(s1), ID_STATUS_MSG_MODE); + break; + case 3: + statusBar()->changeItem(i18n("%1 -> %2 Randomly").arg(s1).arg(s2), ID_STATUS_MSG_MODE); + break; + case 4: + statusBar()->changeItem(i18n("%1 -> %2 Randomly").arg(s2).arg(s1), ID_STATUS_MSG_MODE); + break; + case 5: + statusBar()->changeItem(i18n("%1 <-> %2 Randomly").arg(s1).arg(s2), ID_STATUS_MSG_MODE); + break; + } + + if (m_quiz !=0) + updateSession(m_quizType); +} + +void KWordQuizApp::slotInsertChar( int i ) +{ + if (m_qaView != 0) + m_qaView->slotSpecChar(Prefs::specialCharacters()[i - 1]); + else + if (centralWidget() == m_editView) + m_editView->slotSpecChar(Prefs::specialCharacters()[i - 1]); +} + +void KWordQuizApp::slotActionHighlighted( KAction * action, bool hl) +{ + if (!hl) + slotStatusMsg(i18n("Ready")); +} + +void KWordQuizApp::slotContextMenuRequested(int row, int col, const QPoint & pos) +{ + QWidget *w = factory()->container("editor_popup", this); + QPopupMenu *popup = static_cast(w); + popup->exec(pos); +} + +void KWordQuizApp::updateActions( WQQuiz::QuizType qt ) +{ + bool fEdit = (qt == WQQuiz::qtEditor); + + fileSave->setEnabled(fEdit); + fileSaveAs->setEnabled(fEdit); + filePrint->setEnabled(fEdit); + //editFind->setEnabled(fEdit); + editClear->setEnabled(fEdit); + editInsert->setEnabled(fEdit); + editDelete->setEnabled(fEdit); + editMarkBlank->setEnabled(fEdit && Prefs::enableBlanks()); + editUnmarkBlank->setEnabled(fEdit && Prefs::enableBlanks()); + vocabLanguages->setEnabled(fEdit); + vocabFont->setEnabled(fEdit); + //vocabKeyboard->setEnabled(fEdit); + vocabRC->setEnabled(fEdit); + vocabSort->setEnabled(fEdit); + vocabShuffle->setEnabled(fEdit); + + quizEditor->setEnabled(qt != WQQuiz::qtEditor); + quizFlash->setEnabled(qt != WQQuiz::qtFlash); + quizMultiple->setEnabled(qt != WQQuiz::qtMultiple); + quizQA->setEnabled(qt != WQQuiz::qtQA); + + quizCheck->setEnabled(qt != WQQuiz::qtEditor); + quizRestart->setEnabled(qt != WQQuiz::qtEditor); + quizRepeatErrors->setEnabled(false); + + flashKnow->setEnabled(qt == WQQuiz::qtFlash); + flashDontKnow->setEnabled(qt == WQQuiz::qtFlash); + + qaHint->setEnabled(qt == WQQuiz::qtQA); + + toolBar("quizToolBar")->setHidden(qt == WQQuiz::qtEditor); + +} + +#include "kwordquiz.moc" diff --git a/kwordquiz/src/kwordquiz.desktop b/kwordquiz/src/kwordquiz.desktop new file mode 100644 index 00000000..d66794b7 --- /dev/null +++ b/kwordquiz/src/kwordquiz.desktop @@ -0,0 +1,131 @@ +# KDE Config File +[Desktop Entry] +Type=Application +Exec=kwordquiz -caption "%c" %i %m +Icon=kwordquiz +DocPath=kwordquiz/index.html +Comment=A flashcard and vocabulary learning program +Comment[af]='n Flitskaart- en woordeskat-aanleerprogram +Comment[be]=Праграма паляпшэння слоўнікавага запасу (флэшкарткі) +Comment[bg]=Програма за запаметяване с карти +Comment[bn]=ফ্ল্যাশকার্ড ব্যবহার ও শব্দভাণ্ডার সমৃদ্ধকারী একটি প্রোগ্রাম +Comment[bs]=Program za učenje kartica i rječnika +Comment[ca]=Un programa de targetes ràpides i d'aprenentatge de vocabulari +Comment[cs]=Výukový program na procvičení slovní zásoby +Comment[csb]=Programa do wdôrzëniô ë ùczbë słów +Comment[cy]=Rhaglen cerdiau fflach ar gyfer dysgu geirfa +Comment[da]=Et kort- og ordforråds indlæringsprogram +Comment[de]=Ein Karteikarten- und Vokabel-Lernprogramm +Comment[el]=Ένα πρόγραμμα εκμάθησης λεξιλογίου +Comment[eo]=Afiŝkarda kaj vortoproviza programo +Comment[es]=Un programa de aprendizaje de fichas y vocabulario +Comment[et]=Sähvikute ja sõnavara omandamise programm +Comment[eu]=Fitxak eta hiztegiak ikasteko programa bat +Comment[fa]=برنامۀ کارت فلاش و یادگیری واژه‌ها +Comment[fi]=Opettelukortti- ja sanastoharjoitusohjelma +Comment[fr]=Un programme d'apprentissage du vocabulaire et de cartes flash +Comment[gl]=Aprendizaxe de vocabulario e xogos de tarxetas +Comment[he]=תוכנית ללימוד דקדוק +Comment[hi]=फ्लैश कार्ड तथा शब्द सीखने का प्रोग्राम +Comment[hr]=Program za učenje vokabulara +Comment[hu]=Elektronikus szótárfüzet gyakorlási lehetőséggel +Comment[is]=Hjálparkorta og orðaforða-kennslutól +Comment[it]=Un programma di supporto alla memorizzazione +Comment[ja]=フラッシュカードと語彙学習プログラム +Comment[ka]=სიტყვათა მარაგის შემოწმება ბარათებით +Comment[km]=កម្មវិធី​រៀន​វាក្យសព្ទ និង​បណ្ណ​បង្ហាញ +Comment[lt]=Žodyno mokymosi kortelių pagalba programa +Comment[mk]=Флеш картичка и програма за проширување на речникот +Comment[ms]=Program pembelajaran kad paparan dan perbendaharaan kata +Comment[nb]=Et program for gloseøving og spørsmålskort +Comment[nds]=En Naslakoort- un Vokavellehr-Programm +Comment[ne]=फ्ल्यासकार्ड र शब्द सिक्ने कार्यक्रम +Comment[nl]=Een woordenschat-lesprogramma +Comment[nn]=Eit program for gloseøving og spørsmålskort +Comment[pl]=Program do przypominania i nauki słówek +Comment[pt]=Um programa de cartões e aprendizagem de vocabulário +Comment[pt_BR]=Um programa de aprendizagem de vocabulário +Comment[ru]=Программа для заучивания слов +Comment[sk]=Výukový program pre slovíčka +Comment[sl]=Program za učenje s kartami in učenje besedišča +Comment[sr]=Програм за учење речника и помоћу брзих картица +Comment[sr@Latn]=Program za učenje rečnika i pomoću brzih kartica +Comment[sv]=Ett program med snabbkort och ordförrådsinlärning +Comment[ta]=ஒரு ஒளி அட்டை மற்றும் சொல்லாக்கம் பயிலும் நிரல் +Comment[tg]=Омӯзиши луғат +Comment[tr]=Bir fiş ve dilbilgisi öğrenme uygulaması +Comment[uk]=Програма для завчання слів по картках +Comment[vi]=Một chương trình luyện tập từ vừng bằng các thẻ +Comment[zh_CN]=Flash 卡片和词汇学习程序 +Comment[zh_TW]=閃卡與字彙學習程式 +Terminal=false +Name=KWordQuiz +Name[bn]=কে-ওয়ার্ড-কুইজ +Name[hi]=के-वर्ड-क्विज़ +Name[ne]=केडीई वर्ड क्विज +Name[sv]=Kwordquiz +Name[ta]=கேவார்த்தை வினாவிடை +Name[tg]=KҲарфИмтиҳон +Name[vi]=Đố Từ K +GenericName=Vocabulary Trainer +GenericName[af]=Woordeskat-afrigter +GenericName[ar]=مدرب الكلمات +GenericName[be]=Пашырэнне слоўнікавага запасу +GenericName[bg]=Речникови тренировки +GenericName[bn]=শব্দভাণ্ডার সমৃদ্ধকারী +GenericName[bs]=Učitelj rječnika +GenericName[ca]=Entrenador de vocabulari +GenericName[cs]=Procvičování slovní zásoby +GenericName[csb]=Trener słowiznë +GenericName[cy]=Hyfforddwr Geirfa +GenericName[da]=Ordforrådsøvelser +GenericName[de]=Vokabeltrainer +GenericName[el]=Εκπαιδευτής λεξιλογίου +GenericName[eo]=Vortara trejnado +GenericName[es]=Entrenador de vocabulario +GenericName[et]=Sõnavara treening +GenericName[eu]=Hiztegi entrenatzailea +GenericName[fa]=مربی واژه‌ها +GenericName[fi]=Sanaston harjoittaja +GenericName[fr]=Tester son vocabulaire +GenericName[gl]=Entrenador de Vocabulario +GenericName[he]=מאמן אוצר מילים +GenericName[hi]=शब्दावली प्रशिक्षक +GenericName[hr]=Vježbanje vokabulara +GenericName[hu]=Szótárfüzet +GenericName[is]=Æfir orðaforða +GenericName[it]=Apprendimento di vocaboli +GenericName[ja]=ボキャブラリの強化 +GenericName[ka]=სიტყვათა მარაგის შემოწმება +GenericName[km]=កម្មវិធី​បង្ហាត់​វាក្យសព្ទ +GenericName[lt]=Žodyno treniruoklis +GenericName[lv]=Mācību Vārdnīca +GenericName[mk]=Тренер за речник +GenericName[mn]=Эгшигийн дасгал +GenericName[ms]=Jurulatih Perbendaharaan Kata +GenericName[nb]=Glosetrening +GenericName[nds]=Vokaveln lehren +GenericName[ne]=शब्दकोश प्रशिक्षक +GenericName[nl]=Woordenschattrainer +GenericName[nn]=Glosetrening +GenericName[nso]=Morutisi wa Tsebo ya Mantsu +GenericName[pl]=Trening słownictwa +GenericName[pt]=Treinar o Vocabulário +GenericName[pt_BR]=Treinador de vocabulário +GenericName[ru]=Тренировка словарного запаса +GenericName[se]=Sátnehárjeheapmi +GenericName[sk]=Tréning slovnej zásoby +GenericName[sl]=Učitelj besednega zaklada +GenericName[sr]=Тренер речника +GenericName[sr@Latn]=Trener rečnika +GenericName[sv]=Ordförrådsträning +GenericName[ta]=சொல்லாக்க பயிற்சியாளர் +GenericName[tg]=Машқи Луғат +GenericName[uk]=Тренування словникового запасу +GenericName[ven]=Mugudisi wa ndivho +GenericName[vi]=Luyện tập Từ vựng +GenericName[xh]=Uqeqeshi Wonobumba ababekwe ngokulandelelana +GenericName[zh_CN]=单词练习 +GenericName[zh_TW]=字彙訓練師 +GenericName[zu]=Umlolongi Wokusetshenziswa kwamagama +Categories=Qt;KDE;Education;Languages; diff --git a/kwordquiz/src/kwordquiz.h b/kwordquiz/src/kwordquiz.h new file mode 100644 index 00000000..85c474b2 --- /dev/null +++ b/kwordquiz/src/kwordquiz.h @@ -0,0 +1,322 @@ +/*************************************************************************** + kwordquiz.h - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002-2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KWORDQUIZ_H +#define KWORDQUIZ_H + + +#ifdef HAVE_CONFIG_H +#include +#endif + +// include files for Qt +#include + +// include files for KDE +#include +#include +#include +#include +#include + +// forward declaration of the KWordQuiz classes +#include "wqquiz.h" +class KWordQuizDoc; +class KWordQuizView; +class KWordQuizPrefs; +class QAView; +class MultipleView; +class FlashView; +class KWQNewStuff; + +/** + * The base class for KWordQuiz application windows. It sets up the main + * window and reads the config file as well as providing a menubar, toolbar + * and statusbar. An instance of KWordQuizView creates your center view, which is connected + * to the window's Doc object. + * KWordQuizApp reimplements the methods that KMainWindow provides for main window handling and supports + * full session management as well as using KActions. + * @see KMainWindow + * @see KApplication + * @see KConfig + * + * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team. + * @version KDevelop version 1.2 code generation + */ +class KWordQuizApp : public KMainWindow +{ + Q_OBJECT + + friend class KWordQuizView; + + public: + /** construtor of KWordQuizApp, calls all init functions to create the application. + */ + KWordQuizApp(QWidget* parent=0, const char* name=0); + ~KWordQuizApp(); + /** opens a file specified by commandline option + */ + void openDocumentFile(const KURL& url=0); + /** returns a pointer to the current document connected to the KTMainWindow instance and is used by + * the View class to access the document object's methods + */ + KWordQuizDoc *getDocument() const; + + bool saveAsFileName(); + protected: + /** save general Options like all bar positions and status as well as the geometry and the recent file list to the configuration + * file + */ + void saveOptions(); + /** read general Options again and initialize all variables like the recent file list + */ + void readOptions(); + /** initializes the KActions of the application */ + + void initActions(); + /** sets up the statusbar for the main window by initialzing a statuslabel. + */ + void initStatusBar(); + /** initializes the document object of the main window that is connected to the view in initView(). + * @see initView(); + */ + void initDocument(); + /** creates the centerwidget of the KTMainWindow instance and sets it as the view + */ + void initView(); + /** queryClose is called by KTMainWindow on each closeEvent of a window. Against the + * default implementation (only returns true), this calles saveModified() on the document object to ask if the document shall + * be saved if Modified; on cancel the closeEvent is rejected. + * @see KTMainWindow#queryClose + * @see KTMainWindow#closeEvent + */ + virtual bool queryClose(); + /** queryExit is called by KTMainWindow when the last window of the application is going to be closed during the closeEvent(). + * Against the default implementation that just returns true, this calls saveOptions() to save the settings of the last window's + * properties. + * @see KTMainWindow#queryExit + * @see KTMainWindow#closeEvent + */ + virtual bool queryExit(); + /** saves the window properties for each open window during session end to the session config file, including saving the currently + * opened file by a temporary filename provided by KApplication. + * @see KTMainWindow#saveProperties + */ + virtual void saveProperties(KConfig *_cfg); + /** reads the session config file and restores the application's state including the last opened files and documents by reading the + * temporary files saved by saveProperties() + * @see KTMainWindow#readProperties + */ + virtual void readProperties(KConfig *_cfg); + + signals: + void settingsChanged(); + + public slots: + /** open a new application window by creating a new instance of KWordQuizApp */ + void slotFileNew(); + /** open a file and load it into the document*/ + void slotFileOpen(); + /** opens a file from the recent files menu */ + void slotFileOpenRecent(const KURL& url); + /** download vocabularies from the Internet */ + void slotFileGHNS(); + /** save a document */ + void slotFileSave(); + /** save a document by a new filename*/ + void slotFileSaveAs(); + /** asks for saving if the file is modified, then closes the actual file and window*/ + void slotFileClose(); + /** print the actual file */ + void slotFilePrint(); + /** closes all open windows by calling close() on each memberList item until the list is empty, then quits the application. + * If queryClose() returns false because the user canceled the saveModified() dialog, the closing breaks.*/ + void slotFileQuit(); + + /** undo the last command */ + void slotEditUndo(); + /** put the marked text/object into the clipboard and remove it from the document */ + void slotEditCut(); + /** put the marked text/object into the clipboard */ + void slotEditCopy(); + /** paste the clipboard into the document */ + void slotEditPaste(); + /** clear the grid selection */ + void slotEditClear(); + /** insert a new row */ + void slotEditInsert(); + /** delete selected row(s) */ + void slotEditDelete(); + /** mark word as blank */ + void slotEditMarkBlank(); + /** unmark word as blank */ + void slotEditUnmarkBlank(); + /** find and replace text */ + void slotEditFind(); + + /** define vocabulary languages */ + void slotVocabLanguages(); + /** define vocabulary fonts */ + void slotVocabFont(); + /** define keyboard layouts */ + void slotVocabKeyboard(); + /** define special characters */ + void slotVocabChar(); + /** define row and column properties */ + void slotVocabRC(); + /** sort vocabulary */ + void slotVocabSort(); + /** shuffle the vocabulary */ + void slotVocabShuffle(); + + void slotMode0(); + /** mode 1 */ + void slotMode1(); + /** mode 2 */ + void slotMode2(); + /** mode 3 */ + void slotMode3(); + /** mode 4 */ + void slotMode4(); + /** mode 5 */ + void slotMode5(); + + /** editor session */ + void slotQuizEditor(); + /** flashcard session */ + void slotQuizFlash(); + /** multiple choice session */ + void slotQuizMultiple(); + /** question and answer session */ + void slotQuizQA(); + + /** configure notifications */ + void slotConfigureNotifications(); + /** configure kwordquiz */ + void slotConfigure(); + + + /** changes the statusbar contents for the standard label permanently, used to indicate current actions. + * @param text the text that is displayed in the statusbar */ + void slotStatusMsg(const QString &text); + + /** applies changes from the preferences dialog */ + void slotApplyPreferences(); + + void slotUndoChange(const QString & text, bool enabled); + + void slotInsertChar(int i); + + void slotActionHighlighted(KAction *, bool); + + void slotContextMenuRequested(int, int, const QPoint &); + private: + + WQQuiz::QuizType m_quizType; + + WQQuiz *m_quiz; + + /** view is the main widget which represents your working area. The View + * class should handle all events of the view widget. It is kept empty so + * you can create your view according to your application's needs by + * changing the view class. + */ + KWordQuizView *m_editView; + FlashView *m_flashView; + MultipleView *m_multipleView; + QAView *m_qaView; + + KWordQuizPrefs *m_prefDialog; + + /** doc represents your actual document and is created only once. It keeps + * information such as filename and does the serialization of your files. + */ + KWordQuizDoc *doc; + + // KAction pointers to enable/disable actions + KAction* fileNew; + KAction* fileOpen; + KRecentFilesAction* fileOpenRecent; + KAction* fileGHNS; + KAction* fileSave; + KAction* fileSaveAs; + KAction* fileClose; + KAction* filePrint; + KAction* fileQuit; + + KAction* editUndo; + KAction* editCut; + KAction* editCopy; + KAction* editPaste; + KAction* editClear; + KAction* editInsert; + KAction* editDelete; + KAction* editMarkBlank; + KAction* editUnmarkBlank; + //KAction* editFind; + + KAction* vocabLanguages; + KAction* vocabFont; + //KAction* vocabKeyboard; + KAction* vocabRC; + KAction* vocabSort; + KAction* vocabShuffle; + + KToolBarPopupAction* mode; + KToggleAction* mode1; + KToggleAction* mode2; + KToggleAction* mode3; + KToggleAction* mode4; + KToggleAction* mode5; + + KAction* quizEditor; + KAction* quizFlash; + KAction* quizMultiple; + KAction* quizQA; + + KAction* quizCheck; + KAction* quizRestart; + KAction* quizRepeatErrors; + + KAction* flashKnow; + KAction* flashDontKnow; + + KAction* qaHint; + + QSignalMapper* charMapper; + KAction* specialChar1; + KAction* specialChar2; + KAction* specialChar3; + KAction* specialChar4; + KAction* specialChar5; + KAction* specialChar6; + KAction* specialChar7; + KAction* specialChar8; + KAction* specialChar9; + + KDirWatch * m_dirWatch; + KWQNewStuff * m_newStuff; + + void updateMode(int m); + void updateSession(WQQuiz::QuizType qt); + void updateActions(WQQuiz::QuizType qt); + void updateSpecialCharIcons(); + QString charIcon(const QChar &); + void openURL(const KURL& url); +}; + +#endif // KWORDQUIZ_H diff --git a/kwordquiz/src/kwordquiz.kcfg b/kwordquiz/src/kwordquiz.kcfg new file mode 100644 index 00000000..f4b5d6cb --- /dev/null +++ b/kwordquiz/src/kwordquiz.kcfg @@ -0,0 +1,118 @@ + + + + + + + + true + + + + + + + + + + + + + + KGlobalSettings::generalFont() + + + + false + + + + 1 + + + + abcdefghi + + + + + + false + + + + false + + + + 3 + + + + false + + + + 1 + + + + 1 + + + + false + + + + + + KGlobalSettings::generalFont() + + + + Qt::black + + + + Qt::white + + + + Qt::red + + + + KGlobalSettings::generalFont() + + + + Qt::black + + + + Qt::white + + + + Qt::blue + + + + + + "http://edu.kde.org/kvoctrain/providers.xml" + + + + kwordquiz %f + + + + Vocabularies + + + \ No newline at end of file diff --git a/kwordquiz/src/kwordquizdoc.cpp b/kwordquiz/src/kwordquizdoc.cpp new file mode 100644 index 00000000..6666bbc8 --- /dev/null +++ b/kwordquiz/src/kwordquizdoc.cpp @@ -0,0 +1,490 @@ +/*************************************************************************** + kwordquizdoc.cpp - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// include files for Qt + +// include files for KDE +#include +#include +#include +#include "keduvocdata.h" + +// application specific includes +#include "kwordquizdoc.h" +#include "kwordquiz.h" +#include "kvtmlwriter.h" +#include "version.h" +#include "paukerreader.h" +#include "wqlreader.h" +#include "wqlwriter.h" +#include "prefs.h" + +//QList *KWordQuizDoc::pViewList = 0L; +//KWordQuizView *KWordQuizDoc::m_view; + +KWordQuizDoc::KWordQuizDoc(QWidget *parent, const char *name) : QObject(parent, name) +{ + connect(KDirWatch::self(), SIGNAL(dirty(const QString& )), this, SLOT(slotModifiedOnDisk(const QString& ))); + /* if(!pViewList) + { + pViewList = new QList(); + } + + pViewList->setAutoDelete(true);*/ +} + +KWordQuizDoc::~KWordQuizDoc() +{} + +void KWordQuizDoc::addView(KWordQuizView *view) +{ + //pViewList->append(view); + m_view = view; +} + +void KWordQuizDoc::removeView(KWordQuizView *view) +{ + // m_view = Null; + // pViewList->remove(view); +} +void KWordQuizDoc::setURL(const KURL &url) +{ + doc_url=url; +} + +const KURL& KWordQuizDoc::URL() const +{ + return doc_url; +} + +void KWordQuizDoc::slotUpdateAllViews(KWordQuizView *sender) +{ + //m_view->repaint(); + /*KWordQuizView *w; + if(pViewList) + { + for(w=pViewList->first(); w!=0; w=pViewList->next()) + { + if(w!=sender) + w->repaint(); + } + }*/ + +} + +void KWordQuizDoc::setModified(bool _m) +{ + modified=_m; + if (modified) + { + // + } + else + { + // + } +} + +bool KWordQuizDoc::saveModified() +{ + bool completed=true; + + if(modified) + { + KWordQuizApp *win=(KWordQuizApp *) parent(); + int want_save = KMessageBox::warningYesNoCancel(win, + i18n("The current file has been modified.\n" + "Do you want to save it?"), + i18n("Warning"),KStdGuiItem::save(),KStdGuiItem::discard()); + switch(want_save) + { + case KMessageBox::Yes: + if (doc_url.fileName() == i18n("Untitled")) + { + completed = win->saveAsFileName(); + } + else + { + completed = saveDocument(URL()); + }; + + break; + + case KMessageBox::No: + setModified(false); + completed=true; + break; + + case KMessageBox::Cancel: + completed=false; + break; + + default: + completed=false; + break; + } + } + + return completed; +} + +void KWordQuizDoc::closeDocument() +{ + deleteContents(); +} + +bool KWordQuizDoc::newDocument() +{ + modified=false; + doc_url.setFileName(i18n("Untitled")); + return true; +} + +bool KWordQuizDoc::openDocument(const KURL& url, bool append, int index) +{ + QString tmpfile; + if (KIO::NetAccess::download( url, tmpfile, 0 )) + { + QFile file(tmpfile); + if (!file.open(IO_ReadOnly)) + { + KMessageBox::error(0, i18n("Cannot open file
%1
").arg(url.path())); + return false; + } + + if (append) + doc_url.setFileName(i18n("Untitled")); //To invoke Save As..., + else + doc_url = url; + + QTable* g = m_view; + g->setUpdatesEnabled(false); + + int i = 0; + if (append && index > 0) + i = g->numRows(); + + if (url.path().right(7) == ".xml.gz") + { + doc_url.setFileName(i18n("Untitled"));//To invoke Save As..., since we don't have save support for this format + PaukerData * paukerDoc = new PaukerData; + PaukerDataItemList dataList = paukerDoc->parse(tmpfile); + if (!dataList.isEmpty()) + { + g->setNumRows(dataList.count() + i); + QString s; + PaukerDataItemList::ConstIterator end(dataList.end()); + for(PaukerDataItemList::ConstIterator dataIt = dataList.begin(); dataIt != end; ++dataIt) + { + s = (*dataIt).frontSide(); + if (!s.isEmpty()) + g->setText(i, 0, s); //calling setText only when there actually is text helps with sorting + s = (*dataIt).backSide(); + if (!s.isEmpty()) + g->setText(i, 1, s); + i++; + } + } + } + + if (url.path().right(6) == ".kvtml") + { + KEduVocData * kvtmldoc = new KEduVocData; + KEduVocDataItemList dataList = kvtmldoc->parse(tmpfile); + if (!dataList.isEmpty()) + { + if ((uint) kvtmldoc->numRows() > dataList.count()) + g->setNumRows(kvtmldoc->numRows() + i); + else + g->setNumRows(dataList.count() + i); + + if (!append) + { + g->horizontalHeader()->setLabel(0, kvtmldoc->language(0)); + g->horizontalHeader()->setLabel(1, kvtmldoc->language(1)); + g->setColumnWidth(0, kvtmldoc->colWidth(0)); + g->setColumnWidth(1, kvtmldoc->colWidth(1)); + } + QString s; + KEduVocDataItemList::ConstIterator end(dataList.end()); + for(KEduVocDataItemList::ConstIterator dataIt = dataList.begin(); dataIt != end; ++dataIt) + { + s = (*dataIt).originalText(); + if (!s.isEmpty()) + g->setText(i, 0, s); //calling setText only when there actually is text helps with sorting + s = (*dataIt).translatedText(); + if (!s.isEmpty()) + g->setText(i, 1, s); + i++; + } + } + } + + if (url.path().right(4) == ".wql") + { + WqlReader * wqldoc = new WqlReader; + KWqlDataItemList dataList = wqldoc->parse(tmpfile); + if (!dataList.isEmpty()) + { + if ((uint) wqldoc->numRows() > dataList.count()) + g->setNumRows(wqldoc->numRows() + i); + else + g->setNumRows(dataList.count() + i); + + if (!append) + { + g->horizontalHeader()->setLabel(0, wqldoc->language(0)); + g->horizontalHeader()->setLabel(1, wqldoc->language(1)); + g->setColumnWidth(0, wqldoc->colWidth(0)); + g->setColumnWidth(1, wqldoc->colWidth(1)); + g->setFont(wqldoc->font()); + g->setCurrentCell(wqldoc->startRow(), wqldoc->startCol()); + g->selectCells(wqldoc->startRow(), wqldoc->startCol(), wqldoc->endRow(), wqldoc->endCol()); + Prefs::setSpecialCharacters(wqldoc->specialCharacters()); + } + QString s; + KWqlDataItemList::ConstIterator end(dataList.end()); + for(KWqlDataItemList::ConstIterator dataIt = dataList.begin(); dataIt != end; ++dataIt) + { + s = (*dataIt).frontText(); + if (!s.isEmpty()) + g->setText(i, 0, s); //calling setText only when there actually is text helps with sorting + s = (*dataIt).backText(); + if (!s.isEmpty()) + g->setText(i, 1, s); + g->setRowHeight(i, (*dataIt).rowHeight()); + i++; + } + } + } + + if (url.path().right(4) == ".csv") + { + QTextStream ts(&file); + ts.setEncoding(QTextStream::UnicodeUTF8); + + QString f = ts.read(); + QStringList fl = QStringList::split('\n', f, true); + g->setNumRows(fl.count() - 1 + i); + + QStringList sl = QStringList::split(",", fl[0], true); + + if (!append) + { + if (!sl[0].isEmpty()) + g->horizontalHeader()->setLabel(0, sl[0]); + if (!sl[1].isEmpty()) + g->horizontalHeader()->setLabel(1, sl[1]); + } + + for(int j = 1; j < fl.count(); j++) + { + QStringList sl = QStringList::split(",", fl[j], true); + if (!sl[0].isEmpty()) + g->setText(i + j - 1, 0, sl[0]); + if (!sl[1].isEmpty()) + g->setText(i + j - 1, 1, sl[1]); + } + } + + file.close(); + KIO::NetAccess::removeTempFile( tmpfile ); + + //Apply word wrap to cell with text + QTableItem* itm; + for (int r = 0; r <= g->numRows() -1; ++r) + { + itm = g->item(r, 0); + if (itm != 0) + itm->setWordWrap(true); + itm = g->item(r, 1); + if (itm != 0) + itm->setWordWrap(true); + } + + g->setUpdatesEnabled(true); + g->repaintContents(); + } + modified=false; + if (append) + modified = true; + + return true; +} + +bool KWordQuizDoc::saveDocument(const KURL& url, const char *format /*=0*/) +{ + + QFile file(url.path()); + if (!file.open(IO_WriteOnly)) + { + KMessageBox::error(0, i18n("Cannot write to file
%1
") + .arg(url.path())); + //if (filename == fname) + // filename = ""; + return false; + } + + QTable* g = m_view; + QString s = ""; + int w = 0; + + if (url.path().right(6) == ".kvtml") + { + file.close(); + KVTMLWriter writer(&file); + writer.addHeader(QString("kwordquiz %1").arg(KWQ_VERSION), 2, g->numRows(), url.fileName()); + writer.addFirstItem(g->horizontalHeader()->label(0), g->columnWidth(0), g->text(w, 0), g->horizontalHeader()->label(1), g->columnWidth(1), g->text(w, 1)); + w++; + int r = g->numRows(); + while (w < r) + { + writer.addItem(g->text(w, 0), g->text(w, 1)); + w++; + } + } + + if (url.path().right(4) == ".wql") + { + file.close(); + WqlWriter writer(&file); + writer.writeFont(g->font()); + writer.writeCharacters(Prefs::specialCharacters()); + writer.writeGridInfo(g->verticalHeader()->width(), g->columnWidth(0), g->columnWidth(1), g->numRows()); + if (g->numSelections() > 0) + { + QTableSelection qts = g->selection(0); + writer.writeSelection(qts.leftCol(), qts.topRow(), qts.rightCol(), qts.bottomRow()); + } + else + { + writer.writeSelection(g->currentColumn(), g->currentRow(), g->currentColumn(), g->currentRow()); + } + writer.writeFirstItem(g->horizontalHeader()->label(0), g->horizontalHeader()->label(1)); + int r = g->numRows(); + while (w < r) + { + writer.writeItem(g->text(w, 0), g->text(w, 1), g->rowHeight(w)); + w++; + } + } + + if (url.path().right(4) == ".csv") + { + QTextStream ts(&file); + ts.setEncoding(QTextStream::UnicodeUTF8); + ts << g->horizontalHeader()->label(0) << "," << g->horizontalHeader()->label(1) << endl; + + int i = 0; + int r = g->numRows(); + while (i < r) + { + ts << g->text(i, 0) << "," << g->text(i, 1) << endl; + i++; + } + } + + if (url.path().right(5) == ".html") + { + QString cw1 = "width: " + QString::number(g->columnWidth(0)) + "; "; + QString cw2 = "width: " + QString::number(g->columnWidth(1)) + "; "; + + QString fn = "font-family: '" + g->font().family() + "'; "; + QString fs = "font-size: " + QString::number(g->font().pointSize()) + "pt; "; + QString fb; + QString fi; + + if (g->font().bold()) + fb = "font-weight: bold; "; + else + fb = "font-weight: normal; "; + + if (g->font().italic()) + fi = "font-style: italic; "; + else + fi = "font-style: normal; "; + + QString hstyle0 = "style=\"text-align: right; width: " + QString::number(g->verticalHeader()->sectionSize(0)) + "; font-size: 12pt; background-color: darkgray\""; + QString hstyle1 = "style=\"" + cw1 + "font-size: 12pt; background-color: darkgray\""; + QString hstyle2 = "style=\"" + cw2 + "font-size: 12pt; background-color: darkgray\""; + + QString style1 = "style=\"" + cw1 + fn + fs + fb + fi + "background-color: white\""; + QString style2 = "style=\"" + cw2 + fn + fs + fb + fi + "background-color: white\""; + + QTextStream ts(&file); + ts.setEncoding(QTextStream::UnicodeUTF8); + + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + + ts << "" << url.fileName() << "" << endl; + ts << "" << endl; + ts << "" << endl; + + ts << "" << endl; + + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + + int i = 0; + int r = g->numRows(); + while (i < r) + { + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + i++; + } + + ts << "

" << g->horizontalHeader()->label(0) << "

" + g->horizontalHeader()->label(1) << "

" << QString::number(i + 1) << "

" << g->text(i, 0) << "

" << g->text(i, 1) << "

" << endl; + ts << "" << endl; + ts << "" << endl; + } + + if (url.path().right(5) != ".html") + { + doc_url = url; + setModified(false); + } + return true; +} + +void KWordQuizDoc::deleteContents() +{ +} + +void KWordQuizDoc::slotModifiedOnDisk( const QString & path) +{ + /*@todo this code doesn't work very well. Have to look in more detail on how Kate does it. + if (doc_url.path() == path) + { + QString str = i18n("The file %1 was changed (modified) on disc by another program!\n\n").arg(doc_url.fileName()); + int i = KMessageBox::warningYesNoCancel(0, str + i18n("Do you want to reload the modified file? Data loss may occur."),QString::null,i18n("Reload"),i18n("Do Not Reload")); + if ( i == KMessageBox::Yes) + openDocument(doc_url); + } + */ +} + +#include "kwordquizdoc.moc" diff --git a/kwordquiz/src/kwordquizdoc.h b/kwordquiz/src/kwordquizdoc.h new file mode 100644 index 00000000..28e75419 --- /dev/null +++ b/kwordquiz/src/kwordquizdoc.h @@ -0,0 +1,95 @@ +/*************************************************************************** + kwordquizdoc.h - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KWORDQUIZDOC_H +#define KWORDQUIZDOC_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +// include files for QT + +// include files for KDE +#include + +// forward declaration of the KWordQuiz classes +class KWordQuizView; + +/** KWordQuizDoc provides a document object for a document-view model. + * + * The KWordQuizDoc class provides a document object that can be used in conjunction with the classes KWordQuizApp and KWordQuizView + * to create a document-view model for standard KDE applications based on KApplication and KMainWindow. Thereby, the document object + * is created by the KWordQuizApp instance and contains the document structure with the according methods for manipulation of the document + * data by KWordQuizView objects. Also, KWordQuizDoc contains the methods for serialization of the document data from and to files. + * + * @author Source Framework Automatically Generated by KDevelop, (c) The KDevelop Team. + * @version KDevelop version 1.2 code generation + */ +class KWordQuizDoc : public QObject +{ + Q_OBJECT + public: + /** Constructor for the fileclass of the application */ + KWordQuizDoc(QWidget *parent, const char *name=0); + /** Destructor for the fileclass of the application */ + ~KWordQuizDoc(); + + /** adds a view to the document which represents the document contents. Usually this is your main view. */ + void addView(KWordQuizView *view); + /** removes a view from the list of currently connected views */ + void removeView(KWordQuizView *view); + /** sets the modified flag for the document after a modifying action on the view connected to the document.*/ + void setModified(bool _m=true); + /** returns if the document is modified or not. Use this to determine if your document needs saving by the user on closing.*/ + bool isModified(){ return modified; } + /** "save modified" - asks the user for saving if the document is modified */ + bool saveModified(); + /** deletes the document's contents */ + void deleteContents(); + /** initializes the document generally */ + bool newDocument(); + /** closes the acutal document */ + void closeDocument(); + /** loads the document by filename */ + bool openDocument(const KURL& url, bool append = false, int index = 0); + /** saves the document under filename and format.*/ + bool saveDocument(const KURL& url, const char *format=0); + /** returns the KURL of the document */ + const KURL& URL() const; + /** sets the URL of the document */ + void setURL(const KURL& url); + + public slots: + /** calls repaint() on all views connected to the document object and is called by the view by which the document has been changed. + * As this view normally repaints itself, it is excluded from the paintEvent. + */ + void slotUpdateAllViews(KWordQuizView *sender); + void slotModifiedOnDisk(const QString &); + + public: + /** the list of the views currently connected to the document */ + //static QList *pViewList; + //static KWordQuizView *m_view; + private: + /** the modified flag of the current document */ + bool modified; + KURL doc_url; + KWordQuizView *m_view; +}; + +#endif // KWORDQUIZDOC_H diff --git a/kwordquiz/src/kwordquizprefs.cpp b/kwordquiz/src/kwordquizprefs.cpp new file mode 100644 index 00000000..932868cd --- /dev/null +++ b/kwordquiz/src/kwordquizprefs.cpp @@ -0,0 +1,203 @@ +/*************************************************************************** + kwordquizprefs.cpp - description + ------------------- + begin : Sun Aug 18 2002 + copyright : (C) 2002-2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kwordquizprefs.h" +#include "prefeditor.h" +#include "prefquiz.h" +#include "prefcharacter.h" +#include "prefcardappearance.h" +#include "kwordquiz.h" +#include "dlgspecchar.h" + +KWordQuizPrefs::KWordQuizPrefs(QWidget *parent, const char *name, KConfigSkeleton *config, DialogType dialogType, int /*dialogButtons*/, ButtonCode /*defaultButton*/, bool /*modal*/) + : KConfigDialog(parent, name, config, dialogType, Default|Ok|Apply|Cancel|Help, Ok, false) +{ + m_config = config; + + m_prefEditor = new PrefEditor(0, "Editor Settings"); + addPage(m_prefEditor, i18n("Editor"), "editor", i18n("Editor Settings"), true); + + m_prefQuiz = new PrefQuiz(0, "Quiz Settings"); + addPage(m_prefQuiz, i18n("Quiz"), "qa", i18n("Quiz Settings"), true); + + m_prefCardAppearance = new PrefCardAppearance(0, "Flashcard Appearance"); + addPage(m_prefCardAppearance, i18n("Flashcard\nAppearance"), "flash", i18n("Flashcard Appearance Settings"), true); + + m_prefCharacter = new PrefCharacter(0, "Special Characters"); + addPage(m_prefCharacter, i18n("Special\nCharacters"), "kcharselect", i18n("Special Characters"), true); + + m_dlgSpecChar = 0L; + + connect(m_prefCharacter->lstCharacters, SIGNAL(selectionChanged()), this, SLOT(slotCharListSelectionChanged())); + connect(m_prefCharacter->btnCharacter, SIGNAL(clicked()), this, SLOT(slotSelectSpecChar())); + + KWordQuizApp *win=(KWordQuizApp *) parent; + int i=0; + + KConfigSkeletonItem * item = m_config->findItem("SpecialCharacters"); + QString ds = item->property().toString(); + + for ( QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + it.current()->setText(2, (QString) ds[i++] ) ; + it.current()->setText(1, win->actionCollection()->action(QString("char_" + QString::number(i)).latin1())->shortcut().toString()); + } + + m_prefCharacter->lstCharacters->setSelected(m_prefCharacter->lstCharacters->firstChild(), true); + m_prefCharacter->lstCharacters->setItemMargin(2); + + kapp->processEvents(); +} + +void KWordQuizPrefs::slotCharListSelectionChanged() +{ + m_prefCharacter->lblPreview->setText(m_prefCharacter->lstCharacters->currentItem()->text(2)); +} + +void KWordQuizPrefs::slotSelectSpecChar( ) +{ + KConfigSkeletonItem * item = m_config->findItem("EditorFont"); + QString f = item->property().toFont().family(); + QString s = m_prefCharacter->lstCharacters->currentItem()->text(2); + QChar c = s[0]; + + if (m_dlgSpecChar == 0) + { + m_dlgSpecChar = new DlgSpecChar( this, "insert special char", f, c, true ); + connect(m_dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + connect(m_dlgSpecChar, SIGNAL(finished()), this, SLOT(slotDlgSpecCharClosed())); + } + m_dlgSpecChar->show(); +} + +void KWordQuizPrefs::slotDlgSpecCharClosed() +{ + if ( m_dlgSpecChar ) + { + disconnect(m_dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + disconnect(m_dlgSpecChar, SIGNAL(finished()), this, SLOT(slotDlgSpecCharClosed())); + m_dlgSpecChar->deleteLater(); + m_dlgSpecChar = 0L; + } +} + +void KWordQuizPrefs::slotSpecChar(QChar c) +{ + m_prefCharacter->lstCharacters->currentItem()->setText(2, c); + m_prefCharacter->lblPreview->setText(m_prefCharacter->lstCharacters->currentItem()->text(2)); + updateButtons(); +} + +bool KWordQuizPrefs::hasChanged() +{ + bool result; + + QString s; + for (QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + s.append(it.current()->text(2)); + } + + KConfigSkeletonItem * item = m_config->findItem("SpecialCharacters"); + QString ds = item->property().toString(); + + if (ds == s.stripWhiteSpace()) + result = KConfigDialog::hasChanged(); + else + result = true; + + return result; +} + +bool KWordQuizPrefs::isDefault() +{ + bool bUseDefaults = m_config->useDefaults(true); + bool result; + + QString s; + for (QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + s.append(it.current()->text(2)); + } + + KConfigSkeletonItem * item = m_config->findItem("SpecialCharacters"); + QString ds = item->property().toString(); + + if (ds == s.stripWhiteSpace()) + result = KConfigDialog::isDefault(); + else + result = false; + + m_config->useDefaults(bUseDefaults); + return result; +} + +void KWordQuizPrefs::updateSettings( ) +{ + QString s; + for (QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + s.append(it.current()->text(2)); + } + + KConfigSkeletonItem * item = m_config->findItem("SpecialCharacters"); + item->setProperty(QVariant(s)); + + emit settingsChanged(); +} + +void KWordQuizPrefs::updateWidgetsDefault( ) +{ + bool bUseDefaults = m_config->useDefaults(true); + + QString s; + for (QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + s.append(it.current()->text(2)); + } + + KConfigSkeletonItem * item = m_config->findItem("SpecialCharacters"); + QString ds = item->property().toString(); + + int i=0; + for (QListViewItemIterator it = m_prefCharacter->lstCharacters; it.current(); ++it) + { + it.current()->setText(2, (QString) ds[i++] ) ; + } + m_prefCharacter->lblPreview->setText(m_prefCharacter->lstCharacters->currentItem()->text(2)); + m_config->useDefaults(bUseDefaults); +} + +#include "kwordquizprefs.moc" diff --git a/kwordquiz/src/kwordquizprefs.h b/kwordquiz/src/kwordquizprefs.h new file mode 100644 index 00000000..f53e30d8 --- /dev/null +++ b/kwordquiz/src/kwordquizprefs.h @@ -0,0 +1,63 @@ +/*************************************************************************** + kwordquizprefs.h - description + ------------------- + begin : Sun Aug 18 2002 + copyright : (C) 2002-2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KWORDQUIZPREFS_H +#define KWORDQUIZPREFS_H + +#include + +/** + *@author Peter Hedlund +*/ + +class PrefEditor; +class PrefQuiz; +class PrefCharacter; +class PrefCardAppearance; +class DlgSpecChar; + +class KWordQuizPrefs : public KConfigDialog +{ + Q_OBJECT +public: + KWordQuizPrefs(QWidget *parent=0, const char *name=0, KConfigSkeleton *config=0, DialogType dialogType=IconList, + int dialogButtons=Default|Ok|Apply|Cancel|Help, ButtonCode defaultButton=Ok, bool modal=false); + +protected slots: + void updateSettings(); + void updateWidgetsDefault(); + +private slots: + void slotCharListSelectionChanged(); + void slotDlgSpecCharClosed(); + void slotSelectSpecChar(); + void slotSpecChar(QChar); + +protected: + bool hasChanged(); + bool isDefault(); + +private: + PrefEditor *m_prefEditor; + PrefQuiz *m_prefQuiz; + PrefCharacter* m_prefCharacter; + DlgSpecChar* m_dlgSpecChar; + PrefCardAppearance* m_prefCardAppearance; + KConfigSkeleton * m_config; +}; + +#endif diff --git a/kwordquiz/src/kwordquizrc b/kwordquiz/src/kwordquizrc new file mode 100644 index 00000000..64f970aa --- /dev/null +++ b/kwordquiz/src/kwordquizrc @@ -0,0 +1,2 @@ +[KNewStuff] +ProvidersUrl=http://edu.kde.org/contrib/kvtml/providers.xml \ No newline at end of file diff --git a/kwordquiz/src/kwordquizui.rc b/kwordquiz/src/kwordquizui.rc new file mode 100644 index 00000000..f8159fcd --- /dev/null +++ b/kwordquiz/src/kwordquizui.rc @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + &Go To + + + + + + + V&ocabulary + + + + + + + + + + + + + &Mode + + + + + + + + &Quiz + + + + + + + + + + --> + + + + + + + + + + Go to + + + + + + + Quiz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kwordquiz/src/kwordquizview.cpp b/kwordquiz/src/kwordquizview.cpp new file mode 100644 index 00000000..69e2046b --- /dev/null +++ b/kwordquiz/src/kwordquizview.cpp @@ -0,0 +1,1083 @@ +/*************************************************************************** + kwordquizview.cpp - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +// include files for Qt +#include +#include +#include +#include + +// include files for KDE +#include //i18n +#include // always useful +#include +#include +#include + +// application specific includes +#include "kwordquizview.h" +#include "kwordquizdoc.h" +#include "kwordquiz.h" +#include "dlgsort.h" +#include "prefs.h" +#include "dlgrc.h" +#include "dlgspecchar.h" + +QValueList *KWordQuizView::m_undoList = 0L; + +KWQTableItem::KWQTableItem(QTable* table, EditType et, const QString & text) : QTableItem(table, et, text) +{} + +int KWQTableItem::alignment() const +{ + bool num; + bool ok1 = false; + bool ok2 = false; + (void)text().toInt(&ok1); + if (!ok1) + (void)text().toDouble(&ok2); + num = ok1 || ok2; + + return (num ? Qt::AlignRight : Qt::AlignAuto) | Qt::AlignVCenter; +} + +KWordQuizView::KWordQuizView(QWidget *parent, const char *name) : QTable(parent, name) +{ + if(!m_undoList) + m_undoList = new QValueList(); + + setNumCols(2); + setNumRows(50); + setColumnWidth(1, 250); + setColumnWidth(0, 250); + setSelectionMode(QTable::Single); + horizontalHeader()->setLabel(0, i18n("Column 1")); + horizontalHeader()->setLabel(1, i18n("Column 2")); + setMinimumSize(0, 0); //This seems to improve resizing of main window + dlgSpecChar = 0; +} + +KWordQuizView::~KWordQuizView() +{ +} + +KWordQuizDoc *KWordQuizView::getDocument() const +{ + KWordQuizApp *theApp=(KWordQuizApp *) parentWidget(); + return theApp->getDocument(); +} + +void KWordQuizView::print(KPrinter *pPrinter) +{ + QPainter painter; + + //type 0 Vocabulary list + //type 1 Vocabulary exam + //type 2 Flashcards + int type = pPrinter->option("kde-kwordquiz-type").toInt(); + + //I think working with screen resolution is enough for our purposes + int res = pPrinter->resolution(); + int pad = 2; + int marg = res; + int card_marg = res / 2; + int card_width = 5 * res; + int card_height = 3 * res; + int card_text_marg = res /5; + int card_line_top = 30; + + if (type == 2) + pPrinter->setOrientation(KPrinter::Landscape); + + painter.begin(pPrinter); + + int pageNum = 1; + + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + + + + if (type == 1) + cw3 = 50; + + int gridWidth = cw0 + cw1 + cw2 + cw3; + int lPos = marg; + int tPos = marg + horizontalHeader()->height(); + + QRect w = painter.window(); + + doNewPage(painter, res, type); + + if (type == 2) + { + tPos = card_marg; + for (int rc = 0; rc < numRows(); ++rc) + { + + //draw rectangle 2 cards wide + painter.drawRect(card_marg, tPos, 2 * card_width, card_height); + //divide into 2 cards with line + painter.drawLine(card_marg + card_width, tPos, card_marg + card_width, tPos + card_height); + //draw line inside card + painter.drawLine(card_marg + card_text_marg, tPos + card_line_top, + card_marg + card_width - card_text_marg, tPos + card_line_top); + painter.drawLine(card_marg + card_width + card_text_marg, tPos + card_line_top, + card_marg + card_width + card_width - card_text_marg, tPos + card_line_top); + //draw headers + painter.setFont(KGlobalSettings::generalFont()); + painter.drawText(card_marg + card_text_marg, tPos, card_width, card_line_top, AlignAuto | AlignVCenter, horizontalHeader()->label(0)); + painter.drawText(card_marg + card_width + card_text_marg, tPos, card_width, card_line_top, AlignAuto | AlignVCenter, horizontalHeader()->label(1)); + //draw text + painter.setFont(font()); + painter.drawText(card_marg + card_text_marg, tPos + card_line_top, card_width - (2 * card_text_marg), card_height - card_line_top, AlignHCenter | AlignVCenter | WordBreak, text(rc, 0)); + painter.drawText(card_marg + card_width + card_text_marg, tPos + card_line_top, card_width - (2 * card_text_marg), card_height - card_line_top, AlignHCenter | AlignVCenter | WordBreak, text(rc, 1)); + + tPos = tPos + card_height + card_line_top; + + if (tPos + card_height + card_line_top > w.height() - card_marg) + { + doEndOfPage(painter, tPos, pageNum++, res, type); + tPos = card_marg; + pPrinter->newPage(); + doNewPage(painter, res, type); + } + } + + } + else + { + + for (int rc = 0; rc < numRows(); ++rc) + { + painter.drawLine(lPos, tPos, lPos + gridWidth, tPos); + painter.setFont(KGlobalSettings::generalFont()); + + painter.drawText(lPos, tPos, cw0 - pad, rowHeight(rc), AlignRight | AlignVCenter, QString::number(rc + 1)); + + painter.setFont(font()); + painter.drawText(lPos + cw0 + pad, tPos, cw1, rowHeight(rc), AlignAuto | AlignVCenter | WordBreak, text(rc, 0)); + + if (type == 0) + painter.drawText(lPos + cw0 + cw1 + pad, tPos, cw2, rowHeight(rc), AlignAuto | AlignVCenter | WordBreak, text(rc, 1)); + + tPos = tPos + rowHeight(rc); + + if (tPos + rowHeight(rc + 1) > w.height() - marg) + { + doEndOfPage(painter, tPos, pageNum++, res, type); + tPos = marg + horizontalHeader()->height(); + pPrinter->newPage(); + doNewPage(painter, res, type); + } + } + } + doEndOfPage(painter, tPos, pageNum++, res, type); + painter.end(); +} + +void KWordQuizView::doNewPage( QPainter & painter, int res, int type ) +{ + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + int marg = res; + int card_marg = res / 2; + int pad = 2; + + if (type == 1) + cw3 = 50; + + QRect w = painter.window(); + + painter.setFont(KGlobalSettings::generalFont()); + + if (type == 2) + { + painter.drawText(card_marg, card_marg - 20, i18n("KWordQuiz - %1").arg(getDocument()->URL().fileName())); + return; + } + painter.drawLine(marg, marg, marg + cw0 + cw1 + cw2 + cw3, marg); + + painter.drawText(marg, marg - 20, i18n("KWordQuiz - %1").arg(getDocument()->URL().fileName())); + + if (type == 1) + { + QString score = i18n("Name:_____________________________ Date:__________"); + QRect r = painter.boundingRect(0, 0, 0, 0, AlignAuto, score); + painter.drawText(w.width() - r.width() - marg, marg - 20, score); + } + + painter.drawText(marg, marg, cw0, horizontalHeader()->height(), AlignRight | AlignVCenter, ""); + + painter.drawText(marg + cw0 + pad, marg, cw1, horizontalHeader()->height(), AlignAuto | AlignVCenter, horizontalHeader()->label(0)); + painter.drawText(marg + cw0 + cw1 + pad, marg, cw2, horizontalHeader()->height(), AlignAuto | AlignVCenter, horizontalHeader()->label(1)); + + if (type == 1) + painter.drawText(marg + cw0 + cw1 + cw2 + pad, marg, cw3, horizontalHeader()->height(), AlignAuto | AlignVCenter, i18n("Score")); + +} + +void KWordQuizView::doEndOfPage( QPainter & painter, int vPos, int pageNum, int res, int type ) +{ + int marg = res; + painter.setFont(KGlobalSettings::generalFont()); + QRect w = painter.window(); + QRect r = painter.boundingRect(0, 0, 0, 0, AlignAuto, QString::number(pageNum)); + painter.drawText((w.width()/2) - (r.width()/2), w.height() - marg + 20, QString::number(pageNum)); + + if (type == 2) + return; + + int cw0 = verticalHeader()->width(); + int cw1 = columnWidth(0); + int cw2 = columnWidth(1); + int cw3 = 0; + + if (type == 1) + cw3 = 50; + + //Last horizontal line + painter.drawLine(marg, vPos, marg + cw0 + cw1 + cw2 + cw3, vPos); + //Four vertical lines + painter.drawLine(marg, marg, marg, vPos); + painter.drawLine(marg + cw0, marg, marg + cw0, vPos); + painter.drawLine(marg + cw0 + cw1, marg, marg + cw0 + cw1, vPos); + painter.drawLine(marg + cw0 + cw1 + cw2, marg, marg + cw0 + cw1 + cw2, vPos); + + if (type == 1) + painter.drawLine(marg + cw0 + cw1 + cw2 + cw3, marg, marg + cw0 + cw1 + cw2 + cw3, vPos); + +} + + + +/*! + \fn KWordQuizView::gridIsEmpty() + */ +bool KWordQuizView::gridIsEmpty() +{ + for(int i = 0; i < numRows(); i++){ + for(int j = 0; j < 2; j++){ + if(!text(i, j).isEmpty()){ + return false; + } + } + } + return true; +} + +QWidget * KWordQuizView::beginEdit( int row, int col, bool replace ) +{ + m_currentText = text(row, col); + cellEditor = QTable::beginEdit(row, col, replace); + if (cellEditor) + cellEditor->installEventFilter(this); + return cellEditor; +} + +void KWordQuizView::endEdit( int row, int col, bool accept, bool replace ) +{ + // this code gets called after enter and arrow keys, now we + // only process if editing really has been done + + if (cellWidget(row, col) != 0) //if edited the cellWidget still exists + { + if (((QLineEdit *) cellWidget(row, col))->text() != m_currentText) + addUndo(i18n("&Undo Entry")); + QTable::endEdit(row, col, accept, replace); //this will destroy the cellWidget + if (!text(row, col).isEmpty()) + { + QTableItem* itm; + itm = item(row, col); + itm->setWordWrap(true); + adjustRow(row); + getDocument() -> setModified(true); + if (Prefs::enableBlanks()) + if (!checkForBlank(text(row, col), true)) + KNotifyClient::event(winId(), "SyntaxError", i18n("There is an error with the Fill-in-the-blank brackets")); + } + } +} + +void KWordQuizView::adjustRow( int row ) +{ + // we want to make the row high enough to display content, but + // if the user already made it even higher we keep that height + int rh = rowHeight(row); + QTable::adjustRow(row); + if (rh > rowHeight(row)) + setRowHeight(row, rh); +} + +void KWordQuizView::saveCurrentSelection(bool clear = true) +{ + + m_currentRow = currentRow(); + m_currentCol = currentColumn(); + + if (numSelections() > 0) + { + m_currentSel = selection(0); + if (clear) + clearSelection(); + } + else + { + QTableSelection* ts; + ts = new QTableSelection(m_currentRow, m_currentCol, m_currentRow, m_currentCol); + m_currentSel = *ts; + } +} + +void KWordQuizView::doEditUndo( ) +{ + if (isEditing()) + { + if (((QLineEdit *) cellWidget(currentRow(), currentColumn()))->isUndoAvailable()) + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->undo(); + } + else + { + WQUndo undo; + if (m_undoList->count() > 0) + { + setUpdatesEnabled(false); + undo = m_undoList->first(); + setFont(undo.font()); + verticalHeader()->setMinimumWidth(undo.colWidth0()); + setColumnWidth(0, undo.colWidth1()); + setColumnWidth(1, undo.colWidth2()); + setNumRows(0); + setNumRows(undo.numRows()); + setCurrentCell(undo.currentRow(), undo.currentCol()); + addSelection(undo.selection()); + + QString s; + int i = 0; + KWqlDataItemList dataList = undo.list(); + KWqlDataItemList::ConstIterator end(dataList.end()); + for(KWqlDataItemList::ConstIterator dataIt = dataList.begin(); dataIt != end; ++dataIt) + { + s = (*dataIt).frontText(); + if (!s.isEmpty()) + setText(i, 0, s); //calling setText only when there actually is text helps with sorting + s = (*dataIt).backText(); + if (!s.isEmpty()) + setText(i, 1, s); + setRowHeight(i, (*dataIt).rowHeight()); + i++; + } + + m_undoList->remove(m_undoList->begin()); + setUpdatesEnabled(true); + } + + if (m_undoList->count() > 0) + { + undo = m_undoList->first(); + emit undoChange(undo.text(), true); + } + else + emit undoChange(i18n("Cannot &Undo"), false); + } +} + +void KWordQuizView::doEditCut( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->cut(); + } + else + { + addUndo(i18n("&Undo Cut")); + doEditCopy(); + saveCurrentSelection(); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + clearCell(r, c); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditCopy( ) +{ + bool mod = getDocument()->isModified(); + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->copy(); + } + else + { + saveCurrentSelection(false); + QString s; + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + { + for (int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + s = s + text(r, c) + "\t"; + s = s + "\n"; + } + kapp->clipboard()->setText(s); + } + getDocument()->setModified(mod); +} + +void KWordQuizView::doEditPaste( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->paste(); + } + else + { + addUndo(i18n("&Undo Paste")); + saveCurrentSelection(); + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + int lc = m_currentSel.leftCol(); + int rc = m_currentSel.rightCol(); + + if (lc == rc && tr == br) //one cell selected + { + QString s = kapp->clipboard()->text(); + QStringList sl; + sl = QStringList::split("\n", s); + + uint r = numRows() - tr; + + if (sl.count() > r) //do we need to add rows? + { + setNumRows(numRows() + (sl.count() - r)); + br = numRows(); + } + else + br= br + sl.count() - 1; + + if (lc == 0) //left col? + if (sl[0].find("\t") < ((int) sl[0].length() - 1)) + rc = 1; //expand to second column; + + uint i = 0; + int ar = tr; + QStringList sr; + while(i < sl.count() && br <= numRows() ) + { + int ac = lc; + + sr = QStringList::split("\t", sl[i]); + int c = 0; + while (ac <= rc) + { + setText(ar, ac, sr[c]); + ac++; + c++; + } + ar++; + i++; + } + + + } + else + { + QString s = kapp->clipboard()->text(); + QStringList sl; + sl = QStringList::split("\n", s); + uint i = 0; + int ar = tr; + QStringList sr; + while(i < sl.count() && ar <= br ) + { + int ac = lc; + + sr = QStringList::split("\t", sl[i]); + int c = 0; + while (ac <= rc) + { + setText(ar, ac, sr[c]); + ac++; + c++; + } + ar++; + i++; + } + } + + //restore selection + addSelection(QTableSelection(tr, lc, br, rc)); + setCurrentCell(m_currentRow, m_currentCol); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditClear( ) +{ + if (isEditing()) + { + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->clear(); + } + else + { + addUndo(i18n("&Undo Clear")); + saveCurrentSelection(false); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + clearCell(r, c); + } + getDocument()->setModified(true); +} + +void KWordQuizView::doEditInsert( ) +{ + addUndo(i18n("&Undo Insert")); + setUpdatesEnabled(false); + saveCurrentSelection(); + insertRows(m_currentSel.topRow(), m_currentSel.bottomRow() - m_currentSel.topRow() + 1); + + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + setUpdatesEnabled(true); + repaintContents(); + getDocument()->setModified(true); +} + +void KWordQuizView::doEditDelete( ) +{ + addUndo(i18n("&Undo Delete")); + //retrieve current selection + saveCurrentSelection(); + + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + + if (tr == 0 && br == numRows() - 1) + br--; //leave one row if all rows are selected + + for (int r = br; r >= tr; --r) + removeRow(r); + + if (br > numRows()) + br = numRows(); //adjust for new numRows + + //restore selection as much as possible + addSelection(QTableSelection(tr, m_currentSel.leftCol(), br, m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + getDocument()->setModified(true); +} + +const char delim_start = '['; +const char delim_end = ']'; + + +bool KWordQuizView::checkForBlank( const QString & s, bool blank ) +{ + if (!blank) + return true; + + bool result = false; + int openCount = 0; + int closeCount = 0; + QMemArray openPos(0); + QMemArray closePos(0); + + for (uint i = 0; i<= s.length(); ++i) + { + if (s[i] == delim_start) + { + openCount++; + openPos.resize(openCount); + openPos[openCount] = i; + } + + if (s[i] == delim_end) + { + closeCount++; + closePos.resize(closeCount); + closePos[closeCount] = i; + } + } + + if (openCount == 0 && closeCount == 0) + return true; + + if (openCount > 0 && closeCount > 0) + if (openPos.size() == closePos.size()) + for (uint i = 0; i <= openPos.size(); ++i) + result = (openPos[i] < closePos[i]); + + return result; +} + +void KWordQuizView::doEditMarkBlank( ) +{ + if (isEditing()) + { + addUndo(i18n("&Undo Mark Blank")); + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + if (l->text().length() > 0) + { + QString s = l->text(); + int cp = l->cursorPosition(); + if (!l->hasSelectedText()) + { + if (!s[cp].isSpace() && !s[cp - 1].isSpace()) + { + l->cursorWordBackward(false); + int cp1 = l->cursorPosition(); + l->cursorWordForward(false); + if (l->cursorPosition() != (int) s.length()) + { while(l->text()[l->cursorPosition()].isSpace()) + l->cursorBackward(false, 1); + } + int cp2 = l->cursorPosition(); + if (cp2 == (int) s.length()) + l->setSelection(cp1, cp2 - cp1); + else + l->setSelection(cp1, cp2 - cp1 - 1); + + } + else + return; + } + + + if (l->hasSelectedText()) + { + QString st = l->selectedText(); + int len = st.length(); + st = st.prepend(delim_start); + st = st.append(delim_end); + int ss = l->selectionStart(); + s = s.replace(ss, len, st); + l->setText(s); + l->setSelection(ss, st.length()); + } + } + } +} + +void KWordQuizView::doEditUnmarkBlank( ) +{ + addUndo(i18n("&Undo Unmark Blank")); + QString s; + + if (isEditing()) + { + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + + if (l->hasSelectedText()) + { + QString ls = l->text(); + s = l->selectedText(); + int len = s.length(); + s.remove(delim_start); + s.remove(delim_end); + int ss = l->selectionStart(); + ls = ls.replace(ss, len, s); + l->setText(ls); + l->setSelection(ss, s.length()); + } + else + { + if (l->text().length() > 0) + { + s = l->text(); + int cs = l->cursorPosition(); + + int fr = s.findRev(delim_start, cs); + if (fr > 0) + { + s = s.replace(fr, 1, ""); + cs--; + } + int ff = s.find(delim_end, cs); + if (ff > 0) + s = s.replace(ff, 1, ""); + + l->setText(s); + l->setCursorPosition(cs); + } + } + } + else + { + saveCurrentSelection(false); + for (int r = m_currentSel.topRow(); r <= m_currentSel.bottomRow(); ++r) + for(int c = m_currentSel.leftCol(); c <= m_currentSel.rightCol(); ++c) + { + s = text(r, c); + s = s.remove(delim_start); + s = s.remove(delim_end); + setText(r, c, s); + } + } +} + +bool KWordQuizView::checkSyntax(bool all, bool blanks) +{ + int errorCount = 0; + int r1, r2, c1 ,c2; + + if (all) + { + r1 = 0; + r2 = numRows() - 1; + c1 = 0; + c2 = 1; + } + else + { + saveCurrentSelection(false); + r1 = m_currentSel.topRow(); + r2 = m_currentSel.bottomRow(); + c1 = m_currentSel.leftCol(); + c2 = m_currentSel.rightCol(); + } + + for (int r = r1; r <= r2; ++r) + for(int c = c1 ; c <= c2 ; ++c ) + { + QString s = text(r, c); + if (s.length() > 0) + for (uint i = 0; i <= s.length(); ++i) + if (s[i] == delim_start || s[i] == delim_end) + if (!checkForBlank(s, blanks)) + errorCount++; + } + return (errorCount == 0); +} + +void KWordQuizView::doVocabSort( ) +{ + saveCurrentSelection(); + DlgSort* dlg; + dlg = new DlgSort(this, "dlg_sort", true); + dlg->setLanguage(1, horizontalHeader()->label(0)); + dlg->setLanguage(2, horizontalHeader()->label(1)); + dlg->disableResize(); + if (dlg->exec() == KDialogBase::Accepted) + { + addUndo(i18n("&Undo Sort")); + if (dlg->base()) + sortColumn(0, dlg->ascending(), true); + else + sortColumn(1, dlg->ascending(), true); + getDocument()->setModified(true); + } + //restore selection + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); +} + +void KWordQuizView::doVocabShuffle( ) +{ + //@todo handle empty rows + addUndo(i18n("&Undo Shuffle")); + saveCurrentSelection(); + KRandomSequence* rs; + rs = new KRandomSequence(); + int count = numRows(); + setUpdatesEnabled(false); + while (count > 0) + { + swapRows(count-1, rs->getLong(count)); + count--; + } + //restore selection + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + setUpdatesEnabled(true); + repaintContents(); + getDocument()->setModified(true); +} + +void KWordQuizView::doVocabRC( ) +{ + saveCurrentSelection(); + DlgRC* dlg; + dlg = new DlgRC(this, "dlg_rc", true); + //dlg->setInitialSize(QSize(225, 230), true); + dlg->setNumRows(numRows()); + dlg->setRowHeight(rowHeight(m_currentRow)); + dlg->setColWidth(columnWidth(m_currentCol)); + dlg->disableResize(); + if (dlg->exec() == KDialogBase::Accepted) + { + if (dlg->numRows() < 1) + setNumRows(1); + else + setNumRows(dlg->numRows()); + for (int i = m_currentSel.topRow(); i <= m_currentSel.bottomRow(); ++i) + setRowHeight(i, dlg->rowHeight()); + for (int i = m_currentSel.leftCol(); i <= m_currentSel.rightCol(); ++i) + setColumnWidth(i, dlg->colWidth()); + getDocument()->setModified(true); + } + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); +} + +void KWordQuizView::doVocabSpecChar( ) +{ + QString f = font().family(); + QChar c=' '; + if (dlgSpecChar==0) + { + dlgSpecChar = new DlgSpecChar( this, "insert special char", f, c, false ); + connect( dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + connect( dlgSpecChar, SIGNAL( finished() ), this, SLOT( slotDlgSpecCharClosed() ) ); + } + dlgSpecChar->show(); +} + +void KWordQuizView::slotDlgSpecCharClosed( ) +{ + if ( dlgSpecChar ) + { + disconnect( dlgSpecChar, SIGNAL(insertChar(QChar)), this, SLOT(slotSpecChar(QChar))); + disconnect( dlgSpecChar, SIGNAL( finished() ), this, SLOT( slotDlgSpecCharClosed() ) ); + dlgSpecChar->deleteLater(); + dlgSpecChar = 0L; + } +} + +void KWordQuizView::slotSpecChar(const QChar & c) +{ + if (isEditing()) + { + QLineEdit * l = (QLineEdit *) cellWidget(currentRow(), currentColumn()); + if (l->hasSelectedText()) + { + QString ls = l->text(); + QString s = l->selectedText(); + int len = s.length(); + int ss = l->selectionStart(); + ls = ls.replace(ss, len, c); + l->setText(ls); + l->setSelection(ss, 1); + } + else + { + QString s = l->text(); + int i = l->cursorPosition(); + s.insert(i, c); + l->setText(s); + l->setCursorPosition(i + 1); + } + } + else + { + editCell(currentRow(), currentColumn(), true); + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->setText(c); + ((QLineEdit *) cellWidget(currentRow(), currentColumn()))->setCursorPosition(1); + } +} + +void KWordQuizView::activateNextCell( ) +{ + saveCurrentSelection(false); + int tr = m_currentSel.topRow(); + int br = m_currentSel.bottomRow(); + int lc = m_currentSel.leftCol(); + int rc = m_currentSel.rightCol(); + + if (lc == rc && tr == br) //one cell selected + { + clearSelection(); + switch(Prefs::enterMove()) + { + case 0: + if (m_currentRow == (numRows() - 1)) + setNumRows(numRows() + 1); + setCurrentCell(m_currentRow + 1, m_currentCol); + break; + case 1: + if (m_currentCol == 0) + setCurrentCell(m_currentRow, m_currentCol + 1); + else + { + if (m_currentRow == (numRows() - 1)) + setNumRows(numRows() + 1); + setCurrentCell(m_currentRow + 1, m_currentCol - 1); + } + break; + case 2: + setCurrentCell(m_currentRow, m_currentCol); + break; + } + } + else //a larger selection, move within it + { + //addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + switch(Prefs::enterMove()) + { + case 0: + if (m_currentRow == br) + { + if (m_currentCol < rc) + setCurrentCell(tr, rc); + else + setCurrentCell(tr, lc); + } + else + if (m_currentRow < br) + setCurrentCell(m_currentRow + 1, m_currentCol); + break; + case 1: + if (m_currentCol == rc) + { + if (m_currentRow < br) + setCurrentCell(m_currentRow + 1, lc); + else + setCurrentCell(tr, lc); + } + else + setCurrentCell(m_currentRow, m_currentCol + 1); + break; + case 2: + setCurrentCell(m_currentRow, m_currentCol); + break; + } + } +} + +void KWordQuizView::addUndo( const QString & caption ) +{ + while (m_undoList->count() > 10) + { + m_undoList->remove(m_undoList->begin()); + } + + WQUndo* undo = new WQUndo(); + undo->setText(caption); + undo->setFont(font()); + undo->setColWidth0(verticalHeader()->width()); + undo->setColWidth1(columnWidth(0)); + undo->setColWidth2(columnWidth(1)); + undo->setNumRows(numRows()); + undo->setCurrentRow(currentRow()); + undo->setCurrentCol(currentColumn()); + undo->setSelection(selection(0)); + + KWqlDataItemList list; + for(int i = 0; i < numRows(); i++) + { + KWqlDataItem item(text(i, 0), text(i, 1), rowHeight(i)); + list.append(item); + } + + undo->setList(list); + + m_undoList->prepend(*undo); + + getDocument()->setModified(true); + + emit undoChange(caption, true); +} + +void KWordQuizView::setFont( const QFont & font) +{ + QTable::setFont(font); + horizontalHeader()->setFont(KGlobalSettings::generalFont()); + verticalHeader()->setFont(KGlobalSettings::generalFont()); + for (int i = 0; i < numRows(); ++i) + adjustRow(i); //setRowHeight(i, fontMetrics().lineSpacing() ); +} + +void KWordQuizView::paintCell( QPainter * p, int row, int col, const QRect & cr, bool selected, const QColorGroup & cg ) +{ + QColorGroup g (cg); + + if (Prefs::enableBlanks()) + if (!checkForBlank(text(row, col), true)) + g.setColor(QColorGroup::Text, Qt::red); + + QTable::paintCell (p, row, col, cr, selected, g ); +} + +void KWordQuizView::keyPressEvent( QKeyEvent * e) +{ + /*if (isEditing()) + if (e->key() == Key_Tab) + { + endEdit(currentRow(), currentColumn(), true, true); + activateNextCell(); + return; + } + else + return; + */ + if (e->key() == Key_Tab) + { + activateNextCell(); + return; + } + QTable::keyPressEvent(e); +} + +void KWordQuizView::slotCheckedAnswer( int i ) +{ + if (i == -1) + { + clearSelection(); + addSelection(QTableSelection(m_currentSel.topRow(), m_currentSel.leftCol(), m_currentSel.bottomRow(), m_currentSel.rightCol())); + setCurrentCell(m_currentRow, m_currentCol); + } + else + { + clearSelection(); + setCurrentCell(i, 0); + selectRow(i); + } +} + +bool KWordQuizView::eventFilter( QObject * o, QEvent * e ) +{ + if (o == cellEditor) + { + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent *k = (QKeyEvent *)e; + if (k->key() == Key_Tab) + { + endEdit(currentRow(), currentColumn(), true, true); + activateNextCell(); + return true; + } + } + } + return QTable::eventFilter(o, e); +} + +void KWordQuizView::setText(int row, int col, const QString & text) +{ + QTableItem *itm = item(row, col); + if (itm) { + itm->setText(text); + itm->updateEditor(row, col); + updateCell(row, col); + } else { + KWQTableItem *i = new KWQTableItem(this, QTableItem::OnTyping, text); + setItem(row, col, i); + } +} + +#include "kwordquizview.moc" diff --git a/kwordquiz/src/kwordquizview.h b/kwordquiz/src/kwordquizview.h new file mode 100644 index 00000000..6e963064 --- /dev/null +++ b/kwordquiz/src/kwordquizview.h @@ -0,0 +1,123 @@ +/*************************************************************************** + kwordquizview.h - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KWORDQUIZVIEW_H +#define KWORDQUIZVIEW_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +// include files for Qt +#include + +#include + +#include "wqlreader.h" +#include "wqundo.h" + +#include +#include "wqundo.h" +//include + +class KWordQuizDoc; +class DlgSpecChar; + +/** +@author Peter Hedlund +*/ + +class KWQTableItem :public QTableItem +{ +public: + KWQTableItem( QTable* table, EditType et, const QString & text ); + virtual int alignment() const; +}; + +class KWordQuizView : public QTable +{ + Q_OBJECT + public: + /** Constructor for the main view */ + KWordQuizView(QWidget *parent = 0, const char *name=0); + /** Destructor for the main view */ + ~KWordQuizView(); + + /** returns a pointer to the document connected to the view instance. Mind that this method requires a KWordQuizApp instance as a parent + * widget to get to the window document pointer by calling the KWordQuizApp::getDocument() method. + * + * @see KWordQuizApp#getDocument + */ + KWordQuizDoc *getDocument() const; + + //Reimplemented from QTable + void paintCell ( QPainter * p, int row, int col, const QRect & cr, bool selected, const QColorGroup & cg ); + void setFont( const QFont &); + void setText( int row, int col, const QString &text ); + + /** contains the implementation for printing functionality */ + void print(KPrinter *pPrinter); + bool gridIsEmpty(); + void addUndo(const QString & caption); + void doEditUndo(); + void doEditCut(); + void doEditCopy(); + void doEditPaste(); + void doEditClear(); + void doEditInsert(); + void doEditDelete(); + void doEditMarkBlank(); + void doEditUnmarkBlank(); + void doVocabSort(); + void doVocabShuffle(); + void doVocabRC(); + void doVocabSpecChar(); + bool checkSyntax(bool all, bool blanks); + void saveCurrentSelection(bool clear); + protected: + QWidget * beginEdit(int row, int col, bool replace); + void endEdit ( int row, int col, bool accept, bool replace ); + void activateNextCell(); + void keyPressEvent( QKeyEvent* ); + bool eventFilter( QObject*, QEvent* ); + public slots: + void adjustRow(int row); + void slotSpecChar(const QChar &); + void slotCheckedAnswer(int ); + + private slots: + void slotDlgSpecCharClosed(); + + signals: + void undoChange(const QString & text, bool enabled); + + private: + int m_currentRow; + int m_currentCol; + QString m_currentText; + QTableSelection m_currentSel; + DlgSpecChar* dlgSpecChar; + QWidget * cellEditor; + /** the list of the undo objects */ + static QValueList *m_undoList; + + void doNewPage(QPainter & painter, int res, int type); + void doEndOfPage(QPainter & painter, int vPos, int pageNum, int res, int type); + bool checkForBlank(const QString & s, bool blank); +}; + +#endif // KWORDQUIZVIEW_H diff --git a/kwordquiz/src/kwqnewstuff.cpp b/kwordquiz/src/kwqnewstuff.cpp new file mode 100644 index 00000000..cc8310a7 --- /dev/null +++ b/kwordquiz/src/kwqnewstuff.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + Implementation of KNewStuff + ------------------- + begin : Thu Jun 02 13:12:30 PDT 2002 + copyright : (C) 2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include "kwordquiz.h" +#include "kwqnewstuff.h" +#include "prefs.h" + +KWQNewStuff::KWQNewStuff(QWidget *parent, const char *name) : QObject(), KNewStuff("kdeedu/vocabulary", parent) +{ + m_app = (KWordQuizApp *) parent; +} + + +bool KWQNewStuff::install(const QString & fileName) +{ + m_app->slotFileOpenRecent(KURL(fileName)); + return true; +} + + +bool KWQNewStuff::createUploadFile(const QString & fileName) +{ + return true; +} + + +QString KWQNewStuff::destinationPath(KNS::Entry * entry) +{ + if (entry) + { + KURL url = entry->payload(); + QString fileName = url.fileName(); + + QString path = Prefs::installPath(); //default is Vocabularies which will be created in the user's home directory + QString file; + + if (path.isEmpty()) + file = KNewStuff::downloadDestination(entry); //fall back on a temp file, should never happen + else + { + file = QDir::home().path() + "/" + path + "/"; + KStandardDirs::makeDir(file); //ensure the directory exists + file += fileName; + } + return file; + } + else + return QString::null; +} + + +QString KWQNewStuff::downloadDestination(KNS::Entry * entry) +{ + QString file = destinationPath(entry); + + if (KStandardDirs::exists(file)) + { + int result = KMessageBox::questionYesNo(parentWidget(), + i18n("The file '%1' already exists. Do you want to overwrite it?") + .arg(file), + QString::null, + i18n("Overwrite"),i18n("Do Not Overwrite")); + if (result == KMessageBox::No) + return QString::null; + } + KMessageBox::information(parentWidget(), + i18n("The selected file will now be downloaded and saved as\n'%1'.") + .arg(file), + QString::null, + "NewStuffDownloadLocation"); + return file; +} + +#include "kwqnewstuff.moc" diff --git a/kwordquiz/src/kwqnewstuff.h b/kwordquiz/src/kwqnewstuff.h new file mode 100644 index 00000000..eb91044a --- /dev/null +++ b/kwordquiz/src/kwqnewstuff.h @@ -0,0 +1,66 @@ +/*************************************************************************** + Implementation of KNewStuff + ------------------- + begin : Thu Jun 02 13:12:30 PDT 2002 + copyright : (C) 2005 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KWQNEWSTUFF_H +#define KWQNEWSTUFF_H + +#include + +class KWordQuizApp; + +/** +@author Peter Hedlund +*/ +class KWQNewStuff : public QObject, public KNewStuff +{ +Q_OBJECT +public: + KWQNewStuff(QWidget *parent = 0, const char *name = 0); + + /** + Installs a downloaded file according to the application's configuration. + + @param fileName filename of the donwloaded file + @return @c true in case of installation success, @c false otherwise + */ + bool install(const QString &fileName); + + /** + Creates a file suitable for upload. + Note that this method always fails, since using KNewStuffGeneric + means that the provided file must already be in a usable format. + + @param fileName the name of the file to upload after its creation + @return @c true in case of creation success, @c false otherwise + */ + bool createUploadFile(const QString &fileName); + + /** + Queries the preferred destination file for a download. + + @param entry a Hotstuff data entry + @return destination filename, or 0 to return directory only + */ + QString downloadDestination(KNS::Entry *entry); + +private: + QString destinationPath(KNS::Entry *entry); + + KWordQuizApp * m_app; +}; + +#endif diff --git a/kwordquiz/src/main.cpp b/kwordquiz/src/main.cpp new file mode 100644 index 00000000..57fefbfd --- /dev/null +++ b/kwordquiz/src/main.cpp @@ -0,0 +1,102 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Wed Jul 24 20:12:30 PDT 2002 + copyright : (C) 2002-2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include "kwordquiz.h" +#include "version.h" + +static const char *description = I18N_NOOP("A powerful flashcard and vocabulary learning program"); + +static KCmdLineOptions options[] = +{ + { "m", 0, 0 }, + { "mode ", I18N_NOOP("A number 1-5 corresponding to the \nentries in the Mode menu"), 0 }, + { "g", 0, 0 }, + { "goto ", I18N_NOOP("Type of session to start with: \n'flash' for flashcard, \n'mc' for multiple choice, \n'qa' for question and answer"), 0 }, + { "+[File]", I18N_NOOP("File to open"), 0 }, + { 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + KAboutData aboutData("kwordquiz", + I18N_NOOP("KWordQuiz"), + KWQ_VERSION, + description, + KAboutData::License_GPL, + "(c) 2003-2005, Peter Hedlund", + 0, + "http://edu.kde.org/kwordquiz", + "submit@bugs.kde.org"); + + aboutData.addAuthor("Peter Hedlund", 0, "peter.hedlund@kdemail.net"); + aboutData.addCredit("Anne-Marie Mahfouf", I18N_NOOP("KDE Edutainment Maintainer"), "annma@kde.org", 0); + + KCmdLineArgs::init( argc, argv, &aboutData ); + KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. + + KApplication app; + + if (app.isRestored()) + { + RESTORE(KWordQuizApp); + } + else + { + KWordQuizApp *kwordquiz = new KWordQuizApp(); + kwordquiz->show(); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if (args->count()) + { + kwordquiz->openDocumentFile(args->arg(args->count() - 1)); + QCString mode = args->getOption("mode"); + if (!mode.isEmpty()) + { + if (mode == "1") + kwordquiz->slotMode1(); + if (mode == "2") + kwordquiz->slotMode2(); + if (mode == "3") + kwordquiz->slotMode3(); + if (mode == "4") + kwordquiz->slotMode4(); + if (mode == "5") + kwordquiz->slotMode5(); + } + QCString go_to = args->getOption("goto"); + if (!go_to.isEmpty()) + { + if (go_to == "flash") + kwordquiz->slotQuizFlash(); + if (go_to == "mc") + kwordquiz->slotQuizMultiple(); + if (go_to == "qa") + kwordquiz->slotQuizQA(); + } + } + else + { + kwordquiz->openDocumentFile(); + } + args->clear(); + } + return app.exec(); +} diff --git a/kwordquiz/src/multipleview.cpp b/kwordquiz/src/multipleview.cpp new file mode 100644 index 00000000..9c050a86 --- /dev/null +++ b/kwordquiz/src/multipleview.cpp @@ -0,0 +1,290 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include +#include +#include + +#include "kwordquiz.h" +#include "multipleview.h" +#include "prefs.h" + +MultipleView::MultipleView(QWidget *parent, const char *name, WFlags f) + : MultipleViewBase(parent, name, f) +{ + m_score = new WQScore(); +} + + +MultipleView::~MultipleView() +{} + +void MultipleView::setQuiz(WQQuiz *quiz) +{ + m_quiz = quiz; +} + +void MultipleView::init() +{ + + m_score ->setQuestionCount(m_quiz->questionCount()); + m_score ->setAsPercent(Prefs::percent()); + m_question = 0; + m_error = 0; + + opt1->show(); + opt2->show(); + opt3->show(); + + lblQuestion -> setFont(Prefs::editorFont()); + lblPreviousQuestion -> setFont(Prefs::editorFont()); + lblYourAnswer -> setFont(Prefs::editorFont()); + lblCorrect -> setFont(Prefs::editorFont()); + opt1->setFont(Prefs::editorFont()); + opt2->setFont(Prefs::editorFont()); + opt3->setFont(Prefs::editorFont()); + + picAnswered->clear(); + picCorrect->clear(); + picError->clear(); + + lblPreviousQuestionHeader->clear(); + lblPreviousQuestion->clear(); + lblYourAnswerHeader->clear(); + lblYourAnswer->clear(); + lblCorrectHeader->clear(); + lblCorrect->clear(); + + picPrevious->clear(); + picYourAnswer->clear(); + picCorrectAnswer->clear(); + + KWordQuizApp *win=(KWordQuizApp *) parent(); + win->actionCollection()->action("quiz_check")->setEnabled(true); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled(false); + + updateScore(); + showQuestion(0); +} + +void MultipleView::slotCheck() +{ + KWordQuizApp *win=(KWordQuizApp *) parent(); + if (win->actionCollection()->action("quiz_check")->isEnabled()) + { + + QString ans; + bool oneIsChecked = false; + + if (opt1->isChecked()) + { + ans = opt1->text().mid(3, opt1->text().length()); + oneIsChecked = true; + } + + if (opt2->isChecked()) + { + ans = opt2->text().mid(3, opt2->text().length()); + oneIsChecked = true; + } + + if (opt3->isChecked()) + { + ans = opt3->text().mid(3, opt3->text().length()); + oneIsChecked = true; + } + + if (!oneIsChecked) + return; + + bool fIsCorrect = m_quiz->checkAnswer(m_question, ans); + + if (fIsCorrect) + { + + picYourAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + lblCorrectHeader->clear(); + picCorrectAnswer->clear(); + lblCorrect->clear(); + m_score->countIncrement(WQScore::cdCorrect); + updateScore(); + KNotifyClient::event(winId(), "QuizCorrect", i18n("Your answer was correct!")); + } + else + { + m_error++; + + picYourAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("error", KIcon::Panel)); + + lblCorrect->setText(m_quiz->answer(m_question)); + //lblCorrect->setFont(m_quiz->fontAnswer(m_question)); + picCorrectAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + lblCorrectHeader->setText(i18n("Correct Answer")); + m_score->countIncrement(WQScore::cdError); + updateScore(); + KNotifyClient::event(winId(), "QuizError", i18n("Your answer was incorrect.")); + } + + lblPreviousQuestionHeader->setText(i18n("Previous Question")); + lblPreviousQuestion->setText(m_quiz->question(m_question)); + //lblPreviousQuestion->setFont(m_quiz->fontQuestion(m_question)); + picPrevious->setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + + lblYourAnswerHeader->setText(i18n("Your Answer")); + lblYourAnswer->setText(m_quiz->yourAnswer(m_question, ans)); + //lblYourAnswer->setFont(m_quiz->fontAnswer(m_question)); + + if (++m_question < m_quiz->questionCount()) + { + showQuestion(m_question); + } + else + { + m_quiz->finish(); + win->actionCollection()->action("quiz_check")->setEnabled(false); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled((m_error > 0)); + + lblQuestionLanguage->setText(i18n("Summary")); + lblQuestion->clear(); + lblAnswerLanguage->clear(); + opt1->hide(); + opt2->hide(); + opt3->hide(); + picQuestion->setPixmap(KGlobal::iconLoader()->loadIcon("kwordquiz", KIcon::Panel)); + picAnswer->clear(); + } + } +} + +void MultipleView::slotOpt1Clicked() +{ + if (Prefs::autoCheck()) + slotCheck(); + else + { + opt2->setChecked(false); + opt3->setChecked(false); + } +} + +void MultipleView::slotOpt2Clicked() +{ + if (Prefs::autoCheck()) + slotCheck(); + else + { + opt1->setChecked(false); + opt3->setChecked(false); + } +} + +void MultipleView::slotOpt3Clicked() +{ + if (Prefs::autoCheck()) + slotCheck(); + else + { + opt1->setChecked(false); + opt2->setChecked(false); + } +} + +void MultipleView::slotRestart() +{ + m_quiz->activateBaseList(); + init(); +} + +void MultipleView::slotRepeat() +{ + m_quiz->activateErrorList(); + init(); +} + +void MultipleView::updateScore() +{ + QString s; + s = s.setNum(m_quiz->questionCount(), 10); + lblScoreCount->setText(s); + picCount->setPixmap(KGlobal::iconLoader()->loadIcon("kwordquiz", KIcon::Panel)); + + s = m_score->answerText(); + lblScoreAnswered->setText(s); + if (!s.isEmpty()) + picAnswered->setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + + s = m_score->correctText(); + lblScoreCorrect->setText(s); + if (!s.isEmpty()) + picCorrect->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + + s = m_score->errorText(); + lblScoreError->setText(s); + if (!s.isEmpty()) + picError->setPixmap(KGlobal::iconLoader()->loadIcon("error", KIcon::Panel)); +} + + +/*! + \fn MultipleView::showQuestion(int i) + */ +void MultipleView::showQuestion(int i) +{ + + lblQuestionLanguage -> setText(m_quiz ->langQuestion(i)); + lblQuestion -> setText(m_quiz ->question(i)); + //lblQuestion -> setFont(m_quiz->fontQuestion(i)); + + picQuestion->setPixmap(KGlobal::iconLoader()->loadIcon(m_quiz->quizIcon(i, WQQuiz::qiLeftCol), KIcon::Panel)); + + lblAnswerLanguage -> setText(m_quiz ->langAnswer(i)); + + //opt1->setFont(m_quiz->fontAnswer(i)); + //opt2->setFont(m_quiz->fontAnswer(i)); + //opt3->setFont(m_quiz->fontAnswer(i)); + + QStringList sl = m_quiz->multiOptions(i); + QString s[10]; + int j = 0; + for(QStringList::Iterator it = sl.begin(); it != sl.end(); ++it) + { + s[j] = *it; + j++; + } + + opt1->setText("&1 " + s[0]); + opt2->setText("&2 " + s[1]); + opt3->setText("&3 " + s[2]); + + opt1->setChecked(false); + opt2->setChecked(false); + opt3->setChecked(false); + + picAnswer->setPixmap(KGlobal::iconLoader()->loadIcon(m_quiz->quizIcon(i, WQQuiz::qiRightCol), KIcon::Panel)); +} + +void MultipleView::slotApplySettings( ) +{ + m_score ->setAsPercent(Prefs::percent()); + updateScore(); +} + +#include "multipleview.moc" diff --git a/kwordquiz/src/multipleview.h b/kwordquiz/src/multipleview.h new file mode 100644 index 00000000..c5b1cd16 --- /dev/null +++ b/kwordquiz/src/multipleview.h @@ -0,0 +1,60 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MULTIPLEVIEW_H +#define MULTIPLEVIEW_H + +#include "multipleviewbase.h" + +#include "wqscore.h" + +/** +@author Peter Hedlund +*/ +class MultipleView : public MultipleViewBase +{ +Q_OBJECT +public: + MultipleView(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + + ~MultipleView(); + + void setQuiz(WQQuiz *quiz); + void init(); + +public slots: + void slotCheck(); + void slotRepeat(); + void slotRestart(); + void slotOpt1Clicked(); + void slotOpt2Clicked(); + void slotOpt3Clicked(); + void slotApplySettings(); + +private: + WQQuiz *m_quiz; + WQScore *m_score; + + int m_question; + int m_error; + + void updateScore(); + void showQuestion(int i); +}; + +#endif diff --git a/kwordquiz/src/multipleviewbase.ui b/kwordquiz/src/multipleviewbase.ui new file mode 100644 index 00000000..5d85e7af --- /dev/null +++ b/kwordquiz/src/multipleviewbase.ui @@ -0,0 +1,976 @@ + +MultipleViewBase + + + MultipleViewBase + + + + 0 + 0 + 596 + 619 + + + + + 5 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + unnamed + + + + layout58 + + + + unnamed + + + + lblQuestionLanguage + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Language 1 + + + AlignTop + + + The question + + + Language or other identifier for the question + + + + + lblQuestion + + + + 7 + 5 + 0 + 0 + + + + This is your question + + + AutoText + + + false + + + WordBreak|AlignTop + + + The question + + + The question + + + + + picQuestion + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + The question + + + + + + + layout60 + + + + unnamed + + + + picYourAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Your previous answer + + + + + lblYourAnswerHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Your Answer + + + AlignTop + + + Your previous answer + + + Your answer to the previous question + + + + + lblYourAnswer + + + + 7 + 5 + 0 + 0 + + + + This was your answer + + + AutoText + + + false + + + WordBreak|AlignTop + + + Your previous answer + + + Your answer to the previous question + + + + + + + layout13 + + + + unnamed + + + + line1_2 + + + WidgetOrigin + + + HLine + + + Sunken + + + Horizontal + + + + + layout12 + + + + unnamed + + + + lblScoreCount + + + + 5 + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Questions + + + The number of questions in the session + + + + + picCorrect + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Correct answers + + + The number of questions answered correctly. May be shown as a percentage. + + + + + lblScoreCorrect + + + + 5 + 0 + 0 + 0 + + + + + 0 + 255 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Correct answers + + + The number of questions answered correctly. May be shown as a percentage. + + + + + picError + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Incorrect answers + + + The number of questions answered incorrectly. May be shown as a percentage. + + + + + picCount + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Questions + + + The number of questions in the session + + + + + lblScoreAnswered + + + + 5 + 0 + 0 + 0 + + + + + 0 + 0 + 255 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Answered questions + + + The number of questions already answered. May be shown as a percentage. + + + + + picAnswered + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Answered questions + + + The number of questions already answered. May be shown as a percentage. + + + + + lblScoreError + + + + 5 + 0 + 0 + 0 + + + + + 255 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Incorrect answers + + + The number of questions answered incorrectly. May be shown as a percentage. + + + + + + + + + layout61 + + + + unnamed + + + + lblCorrectHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Correct Answer + + + AlignTop + + + Previous correct answer + + + The correct answer to the previous question + + + + + lblCorrect + + + + 7 + 5 + 0 + 0 + + + + This was the correct answer + + + AutoText + + + false + + + WordBreak|AlignTop + + + Previous correct answer + + + The correct answer to the previous question + + + + + picCorrectAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Previous correct answer + + + + + + + layout63 + + + + unnamed + + + + picAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image2 + + + true + + + Your choices + + + + + opt2 + + + + 7 + 5 + 0 + 0 + + + + + 0 + 20 + + + + &2 Option + + + Your choices + + + Three choices for the answer. One is correct. + + + + + opt1 + + + + 7 + 5 + 0 + 0 + + + + + 0 + 20 + + + + &1 Option + + + Your choices + + + Three choices for the answer. One is correct. + + + + + lblAnswerLanguage + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Language 2 + + + AlignTop + + + Your choices + + + Language or other identifier for the answer + + + + + opt3 + + + + 7 + 5 + 0 + 0 + + + + + 0 + 20 + + + + &3 Option + + + Your choices + + + Three choices for the answer. One is correct. + + + + + + + layout59 + + + + unnamed + + + + lblPreviousQuestionHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Previous Question + + + AlignTop + + + Previous question + + + The previous question + + + + + lblPreviousQuestion + + + + 7 + 5 + 0 + 0 + + + + This was your question + + + AutoText + + + false + + + WordBreak|AlignTop + + + -1 + + + Previous question + + + The previous question + + + + + picPrevious + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Previous question + + + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + + + 789cdd9c5b536ac996a8dff7afa8d8f9b6a3235b1410e2c47940515054c0bb76f4435e270888cadd8ef3dfcfc81c63a413c455aeaa55dd15bd0d6af9c92433478e7bcec9fef77ffd76df39ffed5ffffe8fc9544dfbe637d3536fbffdcbce46a3d57ffce7fffdaf7ffcb3b0b3f35b78952ae5df76fff96ffff8a758fe667e133bf17f91ab892b81d594b980ef2f888b78bd9289f1fa09335d3f27aed0f5c789f1fa3d66bcde9e27c6f7793d063fef5f12c7f735cd5fa0f5db3a31ad4f9f44aea4f5ce12e3f847cc38bf7b4f8ce39f12f3fa45627cff8e993e7f9118df7f21a6f5db8bc438ff9c99f6ab82ccf2b883c438de21338e2f56c4249f20f90ab45e3d24a6f98d0e0ca3d17cae8dccf36563667cdf0c88797cbe9ec6171d621a5fd59177d99e3c317dbe6789e9f32eaebf50e1ebd53d315def9b89515e47ccfa50c4347f16f77b37cda70bc4bc1f2362ba5e64c87bbcde7762fabca910b3bcfb91ab7c7d364f8cfabc22667b3b27e6f90f88697ee7918b349e89d7ef15f87a352066fddd27c6f9ae91f9f3a29718df7f23a6f5d851e2f8be3f62267d2f89697e1bf5b597d6a75bc4bc3f2631eae78299ec794accfbd74d8ceb5b10b33e4ce2f87e86f2554b255a4f8c1fc5027fde4d88793ff713a37c17ccb81e6d904b6c6f6789e3f5e68599d65f23a6f95d3571bcbe2789abb4fea7c4f17dab90f74bb4bf31de15558958bf12d3f566c14cef5790cb05e2387f69b764d1fffd09f36e35ae6f8a5c2ed07827ccf4f91d629a3f5389f1fa3be65d945713937c9e3f6f493fcf91617d7b8538fe2e31ed8f3a64a6f85e232679459919dff77bc434be7f60a6cf1f26c6783860c6f52a5cafda2779cd4162bcbec68cd7675d62d6ef2831cedf63c6cfbb9bc065d88f3ddc6f454ceb71c7ccb47f1d66dc1fff96387e3e6b20f37a5531318e3763c6f1ec1131adc7ef32e3fb3d474cfa726566ca178a99ae37c46c4f38bfe2f8252c31c7af33e434ff3b33da9faf31a3bcf68698e6778fcc78bd382026fd6a9118af1f3293fcf78971be297285f64bdd30d3f5d17ff6f7387e65c7c8e9fd65e2389e62a6fdf4f789f1fd07625a7fb6604679b3b85ffb3ac5b37e6294a7c84cf6a990d37867cce44fcfc46cdfaf89f17a5c9fae92fcd91d33addf258ed7eb3e338d1ff375652fbdffc68cef8b2131c9afdf99f17dd727a6f5ab1633d9bb4f8ceb8dfe5bd1fb1c3f703c5d2579c41b335edf53c88af573c14cf6d54c8cf6704accf6586726fdf413e3fb717f211d51bc544fcc14ff3531c52fd520a67865aac4248fde43e6f56625669ccf9e10d37acc4362dc5fc75c44fdac88157d7ec85c54717cbedee17ce69619af179219c7331364bd4bf1c13093bd9413637c7b66267b78212e533e9e27c6fd23f9b4a2f1ef1363bcb864a6fc83fb6d787fad26e67c3024667b2933d3fb7789317fed235739ff3599f17d3b65a6f88ffb61787fcd9898f6cfcc9971ff541f19f603f7f78c19dfcf0a89a37e6c8b98f6abe713633c5830d37edc30e3fae41d33cea70c33cda7994bd8cf9d10d3feab9dc4a89f67669c4f9e268eef4b9e5f917f3d248ef3cb19b1c3f1652d317e7ec54ce31f24c6f9df99513e739518e523790dd9a71c27c6f107cc34fe3c31eea724a6fd16c78931ff3d32937f1f11d3fed8e8afaac8f6e217cc942f268971bdbbc45c1ff0e7395ede3297a33df819f3fe5ebcfe8598f2a36d33e37cfa1e59efa27e7d8398ecc19e31a33dd8f43ed99f60c6cf674b62d2b72e3253bdc2e3b1be1f9869fcb7c438fe3e338e6f7688c91e6c8199fc759c18fdb3c54cf3dbc4187f7acc688ff22a31fa679919d7e7d2f8b4bef4795c9f257d25fb7a4f8cf69531937dd513e3fb27cce49fedc4b89e3e33c5cbe7c4b89fb45eb64f6913e3f88299e6d789f1fd2366b28f4562cc678699f26f2531e653da0f43f1419e27c6f127cc347fba9ef4d565a6f978bd142f3cef07c787b3c4f8f91b66f22fb44753e5fa551053fc772d66b28f4366f22766ae1f9f98f17a3140565c0fa9c4e83f5564b62777ce8cf6e4cf1263be45f90ceb5f7f30c6833133c5eb0233d9a7488cf6d96726ffc98849fffa3231c6cf3233c9779a18e34d8399fca59b18d793aea77a205d4febe93093bfdc11937d189687ede32531e6e70b668a97ef89d1fef798a9fe1c27c67c7ac58ceb933b89717d33665c9fda27267bb37b89311e5f3353bcbf4b8cf65e6126fdf1fe53bc311789b19e7b44b6142fac6726ff386226f9e3f5bac8fd859810537ec8a6cc946faf89b91f6812b33d9f23572ddabf1d33633eb1afc8acdfec9298fdf58a99eca1c64cf6f096388eafcbcc947fe689d11f1e88693fb56626ff7864267d5f27c6f947ccb4de2c318e2f902dfb578799f6ab9b18e563267f70d11eb4e57ced717cabb8debf2476b87f6688ac499f421097f17d8dfab286f289bf41b6e43f3efab32971ff632e91793efb82ccf5b5b1ccb43f89a93ea825d6713f98c9bfb36a62946f9f98f36986ccf14a14912df9774f13937e6db40f6339ff6712d9eca2bd6503665c8fee11733d72c98cefdbd89fd812f733fe38711c4f1c22b37d66fbccd40f25a6cf3f31e3f86645ccfe3b64a6783262c6fdf40564b617b14b4cf9d8df26c6fc2499493fb47ecbf5b54f8cfedf21e6f873c94cf127d687d6b17caec94cfef79a18fdfb9998fc43f3f50ee55707cc95285f564466ffd03e31ce77ca4cf9e881993eff9a388eefcf89b95fb963a67a6e9418e3e92d33e59ffbc4a8df1e33c5978c19e7170d62da5f51488ce31f3253ff2d13e3fa4e9829fe961363feb966a6f38ba3c4f8fe9498eb9766629c7fc94cf96f9118f5ffce4cfdcd1333da9f447b768eebcf51621cff8999ece536318edf63a67ae63131ae9feccb71fff39018e3d90e338d4ffa71b4bf59ccafae6ca93ed1e7cca81f5324a6fce22789d19f2f99d17e748798f5d360a6f3ac47668aff27ccd4afb49869fec3c4e8ff67c4a41fdd65a6faa99418e3ef0133e5a759628c378a99ece32a31c68b57665aef2e33ea57dd26c678cdfbe768bd53e4a4ffe7c4a8ff2133d9974b8cefb79869fdf3c4a8ff0e33ae5fb513a37c4b668a37c7cc18dff50333c943fbc9f6244de2b89e2ecbc3fd8a4a8cebe5f1a95e35edc498ff66ccb4dfaf89315eed3253bdcff273ffd2488cf379665a4f3f31be5f64a6fcc8fb4bfe2e6e9829bed413a37fa03d38b6076f99293e4f12c7f5ba0133dab3ab33a33dbb4262b497f47eb518df7f42667dbb9dc4a8cf0b66aa070e12a33d3c32d3f9d54b62dccf6b66aa6706ccb81e5761c6f5184fcce7554789f17e58c64cfae5f9391f5c26c67a81e7e3f38b2233eadb9498d11eb355628c2f37ccb4de2e31e7e35d66b287d7c4680fbc7f1c8f2a89d1df797f285fc8341ee93f8d47fe3462c6f5cb2a33f9533331ea7b8f99f21fbfcff9e52d31d6ab8e99eab93133f9cf3231d6439699ecf38a99eab953644ff125f3ccd41fc778e6cb493f3b89513f8219d76f578951be0e33d9731a4f99b8fe1631ed9f9b27c6f11d33e9ff3631d63f3d669c5f9512a33dbc31e3fca24e4cfb639f98a9df2c24c6faeb9499fa83c4245f8519c7f7d5c4513e6b90797fcd3333d9d71e33f50bd789717d1933e5db4e625c9f64a67a8de4f7dcefaf98a99f8af9c57be85f707f6bc8dc0f78bcdeb37efc01b38ef2652362a56d64b407cfebd147ccd44f2c98697f74e2387ef646ccfdaa61c6ebbb5329feaa97546bbfebf04a6ca4a5d72f992bdad65f26c9efbc5812fb6bc6fb057ab1b9fdfd99d5d9bf9f5eb649b2b9caf0efaf5af15faa97df95eecbeb82ffb80ffff99fd7cb37a4f9fa3af5eb24f96bf4d2fdc2877e64857f5fbdfca4747f33bd481fffcde0d5937de0273908be40392559931cc2df3dbc46f1fa0170efefa517f92cc7b0ba2cfefe14572840a217f90a92a11419fc3d83df7bf037fcbd1fa5c87e9dee7f855ee49b9cc0eac6f0fb24e807a41a47eb09124ee52ce903a5097a9acb05bc967205af5f26cd2ff397779264d2fdf08d77902afc5b0b3aa3087c200f651dfe3d92c7515f6c6d7f0fbdd8b8e206481256dd94b5dc7b9a24a8c3bf61f527a08f53d9025ec66bc3e7cefe5679ff1c56741ead6b082bbf8015b7645b7664575eca2b792d6fe4adbc93f7f2413eca1d5980bfefca3d59846b3d7caef4b7aac71ab22cf741925759915558e9a390420825b430c20a277cfc7122133dd1174f62208662249ec518ae1f8a975f23c937f5f2551ef8c81123f0e296ec8a57f12626620aab9e89b958c4d7422cd3cf22fe6d2e56e25dd4c4813884cfd4418f6085a4e33f916fbea117185d1cc1eb38ce463d0844d4770196259ae2442ec5a9688933712e2e443bae977f965ffc2c48aa8ee882fe2ec595b886b8d684f16e20f6853807d141dc824f3d89bb5fa797b057e25e1c8907f1287650125180b8f4266b625766624f14454994c5bea8c4d557e967bb14f4ae924a449e8bb6524a2ba32c4487a61cc31cbde04b2089564e0ae57fb55e409ae38dbfd7e44265aaa7faea490d488e25a4f81f49f221699487fe166d0ee419aa91acaa678871a18e08511e32ad7afeb5fe023a39160fc947c0b260b6851aab17f5aade602d643769753ffaa9aa899aaa296967a6849ac74fafd4422de59d5aa977c8aaec875137bf4c2ff0128f6bdebe0f3a69a99a3a5087aa1ef401ab3bfa961cdbf50392a9e3e8411dd500976cca239a6b4215d0b7fad6efe517b06196a42c8d3a9117ea54b5d4197b08eff3171ebfc5ea922db22cd3784590e65c5da8b6ea407419476946dfadad7f26bf84515417466a812497ea2aae1a2debb3876cec7b3e22805509d422d8988c9f5ea61120baa96b75a36ec529f8cd5875d5dd77cf137e2aefe3484e7661ae7b92043d00d7f4598e75ce4b8ada11b95172f15a5da907f5284e61ce90857fa15e623e099a7e563ba09382da851cbe48332f29ba92ad241d6c6613d6e2b1da5bb3b6e30d7d6264eba8a22aa9b268a87d58f99863276401f1a7f412f28985d8555315b0ae1b94843491d74e9064a226396ba9aa2a24a43a55311d2d3fa4029924e90c6b810f6bc5bf645a68a5356464dcd167ecf820affd8938068b0e3dc6443a88c297605d6c376b7136a78d85aac2be5e69a38ada6aa7bd323a1367baa7fbfa490fc4bb1ec6b587fd48d199fd27d1428ff4b3ea4185a362af9a6df6a09bbef32dbdd4602fc672a1c762881e9ff67e3d264539f40bece8ab7ed3133d152d35d633d9d673bd802a650feae6ae5eea957ed7357da0c2fe2ff561d0e88637c577c45c1fe8ba3e8af51a77dba1a35bf75ff3337ad1c750393addd04d6d38068739f5893e4149609a53d4876ee9337d2eaff4856eeb8e7ad65d7d09f573e8d0c6a1b781d834d057fa5adf80be6ea16e9ed18847fa2e274fb23b18ef5e3f40bf73085ddc7194e6e58feb25e6f95dfda85ef40ee4935cd409929056a2bfea82ded5b0f7baa84b30fb10ace2197acb8fd85386881e7a1d2b9790db777559efeb0a66dbe47fcbe4854bd0f0327c8503a24d451e1809f55ae8ea2ed625f990e63bf558a8588c302ace4ad1281f7b8c0e921863ac2a182733e34d7a458946b196a30e1aeb3ac8be07a667fae64948dd32038e89292a2ed33c6d33947b6614fbd103e84b35dd3bf814a1935eb6c66cba72669ecd585d539dbe6ed71895abe6c5bc9a3723cd245e0ffd3fe80425194277f090ea87d0dfd7a264f86fcfccccdc2c14d60cd5a81f91e4889e639666a5afcd3b48e262b7f185f7935e3633d0247afb484e8255e8aea9a9279ceb2323aa599829e8444b73600ed518f64d6fce00b30b90e4dcd421163d45dd8ce1558b9e1c4e9f46e6c81c9b86698234cbe833eb1544dc2d73624e4dcb9cc5b39dc9c65a37fc655b651024911e2a8867e8b44ae67c2d7ae56daca2b459990bd38608318a2712c90268ac73c8dde350a19a0e5c53345d7369aeccb53ce84ecd0dfc6da0e7e6d6dc056ffc54a1c619cdbd79308f66c74c4d01a4e1b1f114f1531cdbac0cc21997d90569a672a542a75589965ce5ecf8d17b983d53d4637d15ade7431f79ddf8e073b08aa6ac9b92299b7d533155f9203be003cd58d90f2c5c6295988bcd8a06651958ad0aa0e3cc1ab393ee84a8758f58f317dec72c46d09129847f4d1bbadffd5c77b2a05a3066006bad13cf605d8374b2e43fc5fe896c580f7f3fb099ed416119ce023aba66fbf609a47913c7f0de891dd8a11dc53cbbfcf4b310fbf65937409a9790ff7f9cf7d7eefc3c7dd43c52e9b11d07ad6006493e1f7d558fec8b7d05496aa813b0483e89cd57820d3983fdd7aa69dfec042441cf9ed9a99d99473b87cf9c419d756a17ba4f95dea78a4e55edd2ae62edfc65ccddaa97707a3dc18acebe8b5763a25672d105f3348c5fb3aff6802acf0648f2713e9c8f98a1d63d1075d0c32174c38b58b7ed8985addb23f9606672251ee0b34dfb2e1fe18a799226c902fbb8b0c7b62177ed1c2c3fd688bfab17d4c5907a39e8ef4cc93643f45772ad8a3c8a7b756d4feca96dc50861d0c3e9347c4d2f100b05e8e40c74d20e966acfd554dfd90bf8fddeb66d07fc26ec1ecc67bbf6529d7f96255a77c75ea99a3c8c96ffc957d6f37ececab82b5da98a78b6d7ebb11846866a38c42f7b636f65a6baf62ef6188d5899f7a85e0a1294797740770ff63ed42bb1c2afa6cc142ced10f2ff1ca4813194b30ff6316966c367c0ca766c816318adf98b3a39e9a54f9e3c84aaee514ca3b7e76b25fc3dd3e710f3bddd5dd329e7e486dd8b3da897da16419212e8e4a33ff9e87e20fb9aa6298b3de8bcf7e5c496edbec852a6cc6b666e2ba6a1bb31c7bcc72c9c93ea533d96f40257865e5be8999071e4cd1e31545fafb6aa4b50a97cbe4fff2ef79d94258c047aee8453a213eb8369d4f0827ab26392c73bed0cd45930865ea847fd0ab16cbeae95681799f6508f995453c4f57e58db56bd3c81346175a0722162259bd30ad5e71da8ea2f205ff82d1d6cc349e7c07f208ad8a229839f743e3a2daa1de72926423decbccb541677f3c2f5a0aeab6fca12e79cb9be7b42bde4d7fba55ec2bb076065e1772d3b42a559d957a6311eefbb816ecba1c93ef7e2760fac259cfbafc4585eb961acae97e0eb1ff6394f27832186d4ddc83d834f85d5811eed1b7449dbf432874eb3112dec79bd7ad9ae97a8b59091a25e6457e8f5aa38ca1246357aaa3ba1265eabeae915a3f3ca94dcd8bd400fb9598d522d4cffadea27fbe05e216b4288838ef8c8bdb9c9662d8e91d34de5a52db05ebe8e6339bd68f91a6d5d83e79b2d7a81f9ddcccddd22ec0f78e3663e0955c9815bba31c4a8e1c7aaa806caeff4c2ad9c02cfbfd60b792cc29c3379ac6a4a935e9297baf7a8c105741532f6453fc8fb6b7a09fdf5349e1e5d09bbb13f5116fde26ad0fd76433c817d1a6e740a7dacbb6c3b48e20e58925c6742ab04490e9d5015f1186b0d1fcf443574736f68971b5eba50e7ae0efa1bfe8c5ee03583dfebee28777a44b2c45554a0c355d0fd864a6ff869d413d93165f093599464fbbd8bd8f5b86388710db9ea62076d63cf39347dd70c95ce478749d60935937c7027512f59bc57fd29bfe4e341d4cd30eed15842e6127e239a6025d671a7b20d393e5853e8b4ce63d5d3c01c2fab4e40ec5a093e195b3bc58cb16c1e6a5fd77267c1e7e28904d802746a93d8dbb4e41d44be65aaca93fceade144dab8b7d517d6bbfcf7925dc21e5df6d8cccf75b6489914719c8d5d0a989635881a5b3c559b8d3670fdcb92ac6b570359d3fb984ff3a8868aeed3a76df3cca77d7158fee520ebad358a14e8285ba2b88ca497f1f3f6e0595d001add56d3b87c9f58098577c3c59cbc2fed069d8ba9d4376d319782b548de41f63d174d7f1bca60ab395dcea531792cf5093e87137ee56d5dc5d8c83e3a893a6bb8f3bd8326592654333e05f0fb2dd455faeaf4bb2a9972edf2908793f5430f7e02f9f6559c24c67e23a9c5cc7bb0ae1042e9c1ad505e8cb3dc6fb7cf3984f3ef789288d8c3636334567e521f42ffba0df9b208dac89db90fbb7cb023b7be676a22724bd7c11c7b8bec56727825e1ec4fb3659445bf7e41ecc5c0ef556ecdb9b508936210a4fd06be97c683d766d8eb2524557801cb613f351b8571976e4c8edea55b2d13559f4087a58d48bfa9dbccff571ec2d41ee13f5227a5ba2d0424bdd9797b2163c3d5807f4ec759b857c12aa15906482d50a69e5c3be3e720d56651d37532fa61befb8e269134402dd707b9acf9ad76c5b0dec9b9ea5f8653fc7b14f7a1945ab59c9857973c5e4bdf978bad04fb20bd79dc3750358c900fa9cbe2b5155bf7ebabcde25a6181b2a5fa0b63b96b7d08515c1f3a7582fc84b578e155bfa149fc3bb7d57d1c55055fe6e3dc67a091d95866ef440165cf573cf1aeec7e9815e826535c0d647f0820a12fca44392e4efc66ce97863b74d11117e9faba5975e885bda49a50a7a27f6b19bb2406d0ebb7b22b3cd68fcb55e50d3d1bbba1ecf46aa187db0868af71633736b46f1ec6b2cbd7d37fbd14f26106f7336ce36a6ef621597ef5dd6ee0ad823afbd093d23e8a6ecea7ab476b7ad4aafb95d7a0b1169b8fdded847bfbfe12fe1ec69651ebdb375ec5fe83c9c4fb067deeb31f590039f994ab018aca2e3ddaedc5de5789f78a9666b31ed23e3046b9af91ef42de19c6505fd4e9f322557a2927665e5fbb2ab4b5f3d9f91ebf7f9d93b1b9fd009afa65ef8a7d08bf15d89643b30bfaef9816985b3c8eed45cf961b4b009c91a6d27f90564c678ce9dbfe3ba164b42afacb41fa8b11fa953ffccb6f0214b38bd80959c99921f6f545b1b7ad938071cc43b37fd50b38a67514bb69bd6e05f60b507daf957f0a91178feb51beb5a3863a1ac722c4817187bfd9b7f8b3df2c79dafb5c818ce31f4102c6da2cbf01aa50ef9c3c6429ca88956b4b014c3a4dbd44baad43f9e89ecc16b129f3ddaf553bc83955f43d47ad5cffcdcf4c2332bea59766cc72fe23dbc399d3ff1897dc52fadf02bff1e64dd762ac19d268c58f30710432a395ffbd0dcdc1fea6b7988f75f24de05ae7fd20bd7359ae40c9e9f490f3dbbb1efbe8ea70ec9ce04e7077fe48fbd09fe02af539bd9993d8af797733d23541dc7be212fcd1be4f81965c06d9933dc395afaa63f8967a41bf74542e4732b7faa2a6a87cec72cd5645feb252fa7f52d9066a90aa21be6413b4b193d44b599ae9827d0e108baa8a57a368fd047b6e2ee531455f7eed0875af8dd9f87afc98234ed6d1d4088e4b19fc867a0b56a1fb472211f3d5456f62ef9f78ff4b2fe0d8f916f439df4e23b601ded0f59282e4f54b0e00e7863db77a1aa1ccb377f691e4dc31eaa2a595aec4f284fcfe4a1bff2d7eef8d333656c67e13ef4514e53496bd1eb2a6ee66ffc2decda738a63fa4bbd6c76541c2b4ecc61f046f04f8acbd122e844595d9bb90e4f633dc0f52559d373f09bbb788ee2f5933b5395b043d0379ad03b7aa1bdbfcf9dc17cb6b5ed36b8506f1a6af098c1f327896b4fd17fe37ea5b3affe21deb398b22c60bf55ae76cd9e13fe51cea1ca3c0369c2bd94b2df71deefc83bb78c116400fdc958ee4385d2977bbee0773f7a678c7b1b3f9b7a035ff2e11e741d2a583ee10df73ef3a78be25bf72bebe25a9c79a8cb20db4d53c4afd2a9728867777a65a53c12bba0f2a6cc7cc997fdbe7b86be7d119e778d35db0e543ae1d4bde82bbe6a0f6d3df59c5fff2c58327d90c94cc4ddf0eb67135fd663dbf532f463d1722af6bcb9ee309fb73395693b88b9067a4cb5238b2a33ed78a7349ce6864a7e02156838fd83fec41bf16a0ec0d7e69f4ef4b64b14cec542862cfb56ecabd6ee24ca4ff7c57e284d53b7ed3344b3cd2710abe959c3955576984104974dec45e233fb43f0d4b7f0149d0aa7e7204da84461bc43b9a76fec51c846e1c98b2ff54194413b917939f32d8846cdf5fb3b3fa91763ef7437cbec32f5471b7d45a8b7207675a1a779846c7611671ad35da4497c76795f9dc45edec4bb1b42974c3febf91af4d218ddb7fca46798da591f62a10ede1efad87c64faba7ff9e2655dd7ec18e71bd9533aabdfb8d74b99dbd9c36c20ef60e693e8a123711275d44877c06d3c777b96993bc986d9287bceedff27ed0469b271f692bdca7688be71f5fd3fa717c80dcfb690bd6593f834cc22b7fa0fffc53bf473759e4d6d433e42a7d68ae73a3a3eedee63ff1962d00afa93b29eabd36ce66bd97cab248bb5ffb6b305f857df48f8bc4fcfc36c792aee3bfe62bc7c11856c99adb27735c8f51ff9993fa2e95c587392d5fc992aa95a7660faf17ce7582f6c51eec95da88307fa3d0b39ab92ee862c3ec990d74f55d7b2baec8234a15a1a7315bc6969df7a4ea99e1d857363d84f951dd3b38958cdf03325793f0a3154aa7b75ae4dd6d06fd6a9bebcb70ff2ded7b3a6d2e604a4e8a46e6d9a93e5ab3806f5851e64276a0471719c9dd2499fdbb4b46fc5b156bccff22e87fa316b6567319a2e37fae0cdee2afe80ddad445bd5e1e71eaace4ed4447edd5f3fc79cff09963803dd9c9b0b9814efbdb8b5e763bf9d5f401f257ce6283bd20df5e866d861c4be3d5f9b6ff6599b55227b7435f72ce3276fdf5aab85a7af86aeacdad945fefb327f20bfb8ac8d4f50991dddd18dace386ba10c77f494f5cadcfbdce938d756f937891a4d9a29978cf0f2abc2cf8cc4bfeeec8cfc5b1ee143aad0b7d19eeb30469b2a3ec32bbd2cf74ef7ab1ad4f447fcae7d40d9d7d5dbd7cf1f710255535bbce6e72e7fb3f9f5f44bc93e742043059c858a2a175769bdde956b0ffdf79821f3a7f25e839d11f4b11dfcdc65f44699004e2fd3dc4c2f8bd278e633fab97ec4134a0c60af9bc697755377b9421b6ed64055dddde5bfdce4eaf7b3f9f342d622e79a16f9dacc92166a097cc7b5980f885f9e5d3d35ddfd4cba7fb91615f4c2bdb356533343f8ea8db24d894a58adffb81baab9fbd668bfc93bf51b332e6e07eb6174e2ed2f761be7eaeef8755cc2749fa104f8ee58918ab2c2bea1d736f30876efaee966a672392537ed5075a644ecf9c0d3574e86fa02b3d88efae409285ba803afc243c15bf6d4d7f422fcd781f4b43bd7bea76214a97b25256865850e1530b7c36561db9f7cda775f17c363e37cbdf4daaa837bf97493dcec23d0367faaea207f1a982397a7cf8b642667443dce2f3b49bbbfc33feb22e114683f87dbd23c8c30746aab27954e36cdf3d8a2e54beeb5dc9b6a8c0e72c73e1fc853d84eef7320b73ccc27d0350fb557612a599c73b0a23dbb403dd80682c44f3476bfc23dfe3936ff15c338bdf99849a4014c273fefe2aabd8b7acea1e6d257df76db3774cdf7d53573dd9133d251f7b1afaf83af437a1d30a3d7ccf808ec46bcff46cd009d46ee027e1e43ce824dce9fa6a5d7fe8fb9518159bf11bb82b88d885703f19f2cf09e8a7e6e6a6a1bdeb6be1a660e7e77aa4eeddcaadd43dfc3670fbfad52e7ddf9eb9b9be56153f064bd5a1830b9d163d0d94c1b87baadd733d99ddfbd7e827829e66157f2eef6fbef4717c4e56c767c5c0dacc992958033de4b0e7fdb95c815475f7a41bf2529dbaba7c304558f9833833457f06be50966091e6d8b474099f0d8095f6e27deb66bcf33a30bb329cba1ff951766346f1d475b0b9937f388e7db6b270de3c8adff916d2a35ec2b995d935853403f43c60e3a7eec4b4ec816ef732ddd673d3720d3fa6e7ca794578b76418bbacf01df2500b8fc3096258b96cc67ff19bdbe139dbfee788f4c7f5f245b4fef81b3e7d939eb65edb057cfa7adb589f9e3adc7266b775fe3fe52f3f9224bcde73d2a4678a3623fb769b47a9e83c72edefbfffff8df167f4b26565f8cd8e755d64d439d5b73c87cfcf63e21964ee5c9b3a2d913be3d6f913e26dafefe7fd1fe865f3ef6b5604bfd7b90fdcb6037c06b9565750a745faf8757ad9da2be457b5b1675f59d1e7bfa384fa47d6f74ddbf8a65ebeea7cf223addd1ff89e243a59de167dade9e80712fd741cfbcac37f647d3f9871cbfbebbd48b8b69cbb7edbbc695cdfeaf57ea95e3ec7a1752ffd7235f9ebd7a27a6ecc1fec025cd3eb41e5f307eae4dfbbee57bdbe3bdfafc9fb7fcfd75ffdff0bf7dff9fa5fa597fff77ffef1ff0167adac06 + + + 789cdd7c576f2bb996eefbf9158dc3b7830147c1b2655cdc07cb92a39ca33c980746d90a0e0a4e83fbdfefe20a542978b777f7ee99c6b450dbfe5c55e4ca81a4fadffff5dbede9d16ffffaf77f8c2766f2e07e73f766f4dbbffc7438fcf88ffffcbffff58f7f964ba5dfd255ab547fabfcf3dffef14f35f9cdfda64af81fe2bb8ceb099b9ee032dd1f335ee3e74b19d3f30f82f9f911e33a3d6fa619d3f3e782e979dfcd98eedf3276f47e68674cf73b84cb4cbfdb64ccf4d957c475a1d7f433a6f7278279fe72c678dfbe3166fa553963babf2798de0f2e63baef1933fdfe3e639a7f2098e545fcd4851f5fcd98c67b164ce3ab2963d1c70b63a6d72ac63cbfbd491846e3f982272cf3c58660ba6f2b8c65fc43c6228f36631edf8c0957c49e2c637ebf1b19f3fb1eeda75c97e74d9b313f1fca1913bf86b1cc5f61ccf3c7ed842b793e7bc458e46118f3f3ca11ae0abdaf8cf97db7cf58e6437bac6ccaf3712f63d2e72e63b1b7066399ff89b1d8c321e135b15fd46fb52ccf1bc3989f779f19d37c7b84e57de533a6fbf78c859fab8cf17ee808267d3bc798e777c788337df69db1c8f73663d2cf8160b6e767c622bfa38c89be2163d187ce18efc712e15a8de585f6bc5696f7fd3563890fe38c89bf0dc1448fa910ae89bd6d654cfeb52198e97f63ccf38769c6f87cd730de64fa63c678dfb509d76b2cdf266253636c036379de0ae6fb1784d7cb8c2f13ae556a9efc3f54045736511e3784d7cb3cde5030bfdf66ccf3c7978ce9f90fc11592f72e63e62f76197bd60fcaaf06f455cb38fe3163968f190966fe371833bfea4630d3d3632ce347c1fc7e3d63d297164cf4aa2ae10de6d77533a6e71f05d3f3b1c358eceb2c63926f5330cb1bf3db3ac8a34af2de61ccf4f80dc1347e0882493ee128637c3f9e11167acd45c634dead60d68766ccf4c407c174bfdb65ccfa0a23c1f4bcae0be6e799be0d9127ea7f7dc6efa560b2af702598f8f14f8c79fc30144ccfab77c6ac3f739731f1772a98f97bc998e63b215c6779987dc1ac3f7c7fa32ad8d532c6f7cd2363964f0c19d3fd23c64c6fdc17ccf68cf165c3e6fb5782f9be65ccf49b6ec6f47c95f026d31f2b82d93eb632267aea82797c9447bd2af76d144cf7d53d63e6c70e05b37e8e1933fde65330db632363a217eba3ba95fca514638edfb14d7893f9538f82e9fdae236c849f6dc14c8fcd98f45b652cf6752b989e8faf1993bf21bd987e289e9d1096f9625d303fef18f3786e2b63a26f4df01ac97bc0d8d07d772978cde0f813c681e673ef82e979bd2e98c6739ab0ad707cd913ccf638c898e83d17ccfa95fbeb9c8fab19933ff0fcd6b0bf0f32267b93f90dc757cc8f9b2ee7db9031f9efb3607ebe4558e461d71933bfce08267e0dcde7807eb28f3dc1743fae678cf2f43cbff0d7bdcf98e2c39d60a6a72c98e4a72f05f37c6b8279be91e01af53bcc8fc8cb9c644cf2f482693ebd9b31c5cf73c16ccfa38c49ff82038dafdf33a6f75f05f3f81f19d3fc4f82399ee5e7d99f0e093bb6273dcc98c6ef0be6f1c719933c9b8c59deaa9131e5e373c15cff6c3166f9588c8f06ec93e4194a8c59fe3e0a26f97b9331eadb1d0aa6f7e3016396af3d15ccf151de17f95e0b66ffbacb98ec694b308def1a8c59fe7e2a98fb9fc38ca9fe7912ccf9683f63e2ef4830e95f9f664cfeb02b98f9bfc898f83f134cf4f957c2599f6f19933ebb82599f5b19d3fd1dc1ec0fed8cc95f4b82399ef43226795618b33d689f318daf04f3fc3663badf104cf3db7ec614cf3f05733c7fcc98f2c50363f6477d90318dff2c98e7bfcf98f43511ccf389fcd83f439db1f8e37ec6f4be3ccffa8f982f8dab73fde9b7098b7e83154cfa0db58c293fdc10167dd8ad8cc97f8360ce3fa782d95e5a1993bd9c0b267bb1778c591f763b638a1f5782b91edec998ec612298edf73863a2e74330fb573f63f2af9e60b6df67c6ac2f27f488be1e3326f95e0be6f8b69e31d9634930d73f2e638aef2782893e7d9b31c9ab2298e833321febdfbf654cf9ee5e30c7bbb38cc9fed60473bd5317ccf5c44bc6547fb03d78f65f772a98edf54130c737b477bbb6c9fd9a5182597e9b8cb97f32af8cb95f72f23edbabeb1016fdc53bc62cdfa804b3be9f0573fdb39931cad39e09e6783fc364ef6b8c257f9505b3fd1f0a667db632a6f99d60a6779a318dcff479f19f9660cebffd8cc93f997ecff61e51dfd68bfcdc1163965fd8632cfde6a660ae377cc6245f7ede487f3d10ccf7cb8299ff7bc28ee37db484bdf813fa9babc9fbe15c30fb472963e2ff8cb1f4672f82d9bf7705d72dde3f15bcb986f35d32667ff40f82395e5c11f6ecdf5dcf58f48ff9cc2548f59a65ccfe1e9460ce9f6b82999e1bc6ec6f665330cfdf252cf57178cf98f22fd633be26fd9d7a62ccfcc71dc16c1f8f8ca57f3b672ceb05fb844d20fadc8d609257a0f183f45f619bb0e8dfd07cc1f2f3b64a38e7e70dc6eb3c1eda6f5897fecb4d09677bba259cf37747303d6faa82599f958c1df277c498e37b57654cfc0f194b7dd3262cf1c8d3fd20f1213e11f615924f7c174cf3990dc652ff0d04d37d87f13aae4b7f15ee3246fb571f843dc7a7ae16ccfdc6b9607e7f47308fef194b7d6c0573be78104cf28af78483f427978cb9fe892e63f2af57c11cbfc68cb95e511b1993fee4bee4972898e309f11b211e50bea2fb51fc4d5d3366fefda6608ecff58ce97d799ee3a79d0a66fdbc0836c43fd11b83d8532d63b26f2d98e3f16ec6940f3e05f378cd8c71beb0ce58e4d717ccf1613f63f28f0bc15c8f5c654cf5744b30ebff3863a4c7e4f9881e95ef133d6a9bb1e8eb22639a5ff8e1f8651b19537cac0b66ffc8cf73bd722698e3cd7ac6648f420feb2fe6f9391f5c0a26fadd7dc648bf66fd05a95f5b1913fd53c15c2f4c32267b0c82391f3d644cf4950473bddccd98fc632898ed2bdfe7fc752298ebd3b260f237739031f2e3c5ded81ec363c614bff27816efeb2ae128fdd12063e2bf2798f90f19d3fd3dc1cc7f7e9ef5772498fda19931ddbf11cceb1b3163aa4f8c60ee37f3f8142fed81608effbb82d95f2682995f965f947ecc658cfc9cc9f3d28f998c89df6dc15c3f8c32267f5282d9df4e32a6fb1782b91fc9f3b1bedf0573bedc11ccf1f53063e4cf5e09267ddbfc3cebfb5630f11f447eebce23be16ec6b88d7184bbfd8cc98f817fd48fff19031dd17fad89fcd4dc664efa782593e7719d37dd11ffbb3ef644cf131d347f2d135c1ec0f6f19537cda144cf231971993bf88fc0cc9277e0af601ef8b7d458e6f228fc8fc3f654ceb3beb82d91f6a19137f7dc1bc5ef09931ddcfcf73ffd5c998f8177b8b1c0f323d240fef05933cdca360e2d789fc22dbc347c69eec5fabbfead266ee779bae8c9df67cfd92b950767f1927bf730927fed78cf70bf4e20bf2fd19eafcdf4f2fab3859a432fdfc5514ffa57af95deebe7c2ef94f98f9cfffbc5ebec1cdd7cf995fc7c95fa397b32f7ce84756f8f7d5cb4f72f737d38b8ef8b30bd7bd7e00dcd3fde40b9c53b235e1df235c037cbe0ff8feefa517a06c08573753db839f0ffa11ae7be6a20b7febc2ef8953fafd01b9e8fe3addff0abde827fd0cd40de1f7e7a41fe42c594ffaf9a247050ebbaca7b19ec035d5af70fd326e7e99bfbc3127cf6733df78036ed2cff7a4338ec01ffa536fc1cf86de467d89b5fd3df4e291e2267092a86ee9f7c23dcb1c6cc1cf44fd0ee86357ef019ee2b3e9bdfdbf55de3f008a0ed0ba7a40f92150bca7dbfa481feb137daacff4b9bed097fa4a5feb1b7dab3bf0f73b5d82e72cbc73a0cb7fab7aaca92bba8adebea66b40e98d5ed71bbaae3795564a1965f16394535e05155557ddab07d5537d78bea706bf86936feae5ab3c30cb1103f0e23d7dac86ea513da967a0fa458dd418afb19ae4cf18ff365253f5aaded4bbfa80773e418f6085ace33f916fbea117185d6dc1d5c0d9b807011dbca96d7da09aaaa5a76a47edaa3db5af0ed421d22b9fc9179f3173d55647baae8ed5893a85b8d64ae341ec4b712e4587003ed55367bf4e2f28ab2672737ec6deac2e202e3de97775a9bbaaafaed4b5ba51b7aa83d4dff167351772b7a4ca8847c07d4555d59aaa01f52d8cecf7e84b9069d53a18e9c62fd74b93f452b8def544d5d5a6d14619c37c4c80c61f7132e385f899303fc9e6aac61aa76bc6438c4b75c41b7265ccb723c377fd4535d88e933d274b507a628289a66bee8116b19bd2973c14b8310fa6677ac48de9abb219e0db5333348f10ef3ae609e2a1f821eae697e9052eb4ae99b75741277be6d9bc989141af00ea26dfe263a57e1267668ab2689b57bd6ede7483e77ae60ae85b7deb4fe597344a453bf3ae0fcd87f9345be22159ceab3d7e95d5951678e9e113899b86d9364dd382e832446e06dfadad7f26bfe02890d940271f66c7ec22d56459cbb42ec87d2e2294e153628e4af8f624df83e866f6ccbe39503be037435d3687df5d4ff869bd78882fc730579b3921ba89a6653ee67191d30973351ba510afcdae3932c76a07e64c59f817ea05f349d2f4c09c804e4ecd19e4f0719e79c2d1956d25eb60319bb016cdd49c1769074f99d72745b6b6b93097e64a6d9b6ba07c28b113b280fa537a49f9c443ec7a3737605dfbcc0969a2a01de4e4c13c14ace5163e1d880f54c5b44d67c615f050629d512d30b356fa8b3377a664ca909149a203eaf820affd8938067a493dc6b30e108577c0bac46ee6e26c411b63730b74ef9a0ac8b66ad64c2d7d4940ed990d53379b56ab57ab907690c72c3a67ff1134b6c65ab50915ceac839beb41177de75b7a7907590cf5c43a754f1e9f653f1f93900feb95b3c146dbb5f76ad704fba0dbb667fb50a594a06e86cad30eecd03eda27e018c6b2cf49a30bde74879c8eec937db123acd7a4dbc69e75ce7fddcfe8c58ea1720c7662a7a6223138cd695fed2b7352b26fa40ffb6e3fec2754fa4776cb36520eb7db20d3d4a10d536f03b1a96f9bb66577cc9add85baf985479cd8bd023fd9ee60bc7d7b00fdce277471dbc8cde31fd70be6f94b7b68a26d433e29441de464c2313549f1c81edb137d624fa1e3dac28e7800bde52cf65420a2a75e073884dc7e67cfecb9bd3092914ad9ce780ed0f04475ec25449b1bfd611b586d6e41ad36c7c98c9befd463a962b157f6da14a25131f6d81be4e4d676cc29f42fe05bf64e2ee2086b39eea0735df7a1f76cc996f53ac8be9263a244c5499ee7d05675c9ae613ffaa1a9ba2d5a58b6b2ac9795319b9f1cd99a5d377b5ca7cfdb355200b6b561eb76d3369c4ecf434e78c31ebf87d75b61ecd4dfbf2367f4f3de41c072167d678ce351053dce35f7d839e76dcba5b58280ddc617decf7a59cc40cfe8ed03f899ac62eaa2513c57ce885015c24c4927a6e3baeede04909b5d9c0166a72efa0962510f753384eb1d3d39adcd0cdc83ebb9be1b0037e433f315044acb0ddda37bc2f58101ae2b14695df097559501be15a1821840a775ed9ee7a257d1c63aaaeabc7b71238810035c91c816c0631d809e86a94275298a1cba899bba57e8273fce26ee0dfed6b73df7ee3ed01b172b549cd17dba2dd05f4357ddb6d467676c6dcb716cb132c0b52db06ffda25fcd25745a1db4e4bb9c1d73efe19aae659d6da2f5ccf451d44d4c3e0754b4f496db71bb6ecfedbb037dad8fc00748d67d90fba16ba3058f9779b1157704be185207e8a4fb98db735bf21791631723e8c06da79f6e04ddef6da13b19732d8819c01dbb13d503ebeae795a5b814fb9f75d39dc2df3f54cd9d414f9cd602daf6d19d432fb9ab9fa0378a7ac75db84b77857976b2f419ab5b776d27c0cde3d7eb69abf4822ba82253639d43ad5006c93e8ff53d3482b7ae039cbc934e9245f24a6cb1126c423468696bdedc9d2b0127e4d92faeec2a60395578671feaac5db766ea5c1f2d5574e6d6d5ec0ed6ce5fc6dc957ae9a3756145e7d6d5d092560ad185f2348cbfe13a2e70e5d9044e5ef28a6a3162a65af7437dba7357876e788c75db3978f4a6d7fada29f0a12485965bd737f0c42873338bfa6f6aec9537fa0e3827bdafd8b759d08b67bd502fd7d20db7e32d46ffd25c1549b2daf3ce7b1f304238f2705e0d9fd74b592bf3e623e824add2947cd7f4ec9ebf8711dafec1f7c06f92f4603edff703d358e605adbbed87e6597fa2e52ff9ca7cde2f589974a5afe646f5fce37c2c067d40359ce2977f72693da6ec9fb1c768f21a4a8ff5524e3d2849077477ed5f52bd8215fe5dce4cc9d2ea90ff53748631d4ba1ff971d6cc82cfb89a9ff8a9c430a6f98b3a39ebe5813db90755dd8d7a465e8ab512fdeeeca77b3a9bf8d7399d4a4e6efa37ec41a3b6fe1d38f9009dccfa9359f70394bb81db557de8bcabfad97ffa2de572a62c6a66e41bae0ffee2b1324a59b8c0d5523d96f5927620d2ef50e3aee3c88b3d62aa5982dfd6a94a29f47d3cce9baefa2676b710096ccfb7fc8ec23e14fdac443d0cf46453e6c7fa5dbf0775168c61fbe6d8068865a305ad24bb70a606f598cb3505d23bb3b6957a492bdc893ae3f7f50656b205ad707ddeb611ec7ceb6cd5ee5dd337fd01f8cf8beefb77c82725e4645cec4dd88e926ca01ef687beadea38d6a13fb2a97b5be425cdf9e28f2166a25e8af47ea9178f55df03fe6e755a211da942f6e2de09e2bd3fb1500b835e967a71b0ae2aaefbbfaabe3ef5a7986727e0eb33fb9431912f33f667fedc51b5037a7477d025add2cbc8dc418e19a05ee6aa97d57a41ada58c847a81ce6973be2a465ed2a8157b0f5578172d6a891b8cceaf10032ffc25f4908bd5a8d4c2f82f74d19b7e045dda2ecce7a1236ef82b7fbd588b53e4f437fa04bc9ff5f2751c2be8056a51b4750b9eaf57e805e6f7b7bee3efb0079f2ee5936405904ffc05c42855a0aabc1467c7bee4a1aa51a7b6afb7d519bc37d2dbe65955592fd94b3d66373334a74982ab73ff4abda4fefa05578f4e955a900ff262bdaf405d3c4df104e4d49b1f152c14eb2eff9038f1d5cc49b9301252099cacf91644fe73ac3522ae895ae8e622d9e582978e4dc3a7aaa7f7337a816b04bf6ff9f5c2ea11f3825474cc9a2941f7eba0d2eb2d8dbaa38f8093d314358093d57b17d8f5f80d887175fd7a461db4c79eb3674b7e132b9ddc61b27542cd04d1bd8e7ae972a5b5a097623c40dd908c863af891b20bd1842ab176d0ba8d1182bae003ac7a9a94e375cdb720764d95ac8ccdafeea795cc41aa7d830a062d26ad48185c6379c6de664f5faa36eb6e6e27cab45d2be534f4e9ad95fdbee495b4432abf7b8ccc572b78c1c8a3d66ceaacca8a56b129c7a47e12727cb0e642c9ca53b11ae5b5d6e0d424f8103cf4242089a63a0f51f7cf2658a13e270b0d5d535c4bcc1fb0c998e21dd21a56adc3147a40ca2bb447df4df2e1d5b0793b87ec66d6c15ba16a64ff18aa66b8c7f59a9a8ffec39796ba9062867a481e171e42cf3c873eea95ce06b4c20025b8e776cdb8305b8117fba9db28bd995ed46abd9cc94e41cafba982b9027f59e6650233eda9d3b4728dbb0a681de97df5a9d6c2102bc811e693d53b19982f6dc5dfba1664e34fe85faaaaa152ef93569d42cafdab7901c9ee59f293ac972fe298d4b733bd5cabd755bca843b3a14b307325d55bd8b7b7a0127d83285c62af251ee663d7e2285373111ef5f1d904f351daa14a1269f8773bc8363ac70bf44b2d4b1237bf93f7a53ec6de12f8de3151f91551686c3aa60ed9ed3d797ad209f4ec5baa96f209562b255e91158e66f6358b695495b5fdad896e823bae2fe87b1009ec243c99cea265e2bcc6ddd9871cbffc721c5bd2cb00ade6152ac7cdf0acc60bf4d06afd26d404037d00cff581923ee493f32055fdfceaf27c97388bb125ccc2877e435f401776089279a17a419f04da4f9fbdc5ebf0611c26f6345595bf5b8f895e52476521137ee84e982ef7ac693fce6a7d0396d5045b1fc075e876c14fdac4c9dc6ecc8a8e17bb6d8e88f0fbc83c86d7f0c6ab4f603d90dbdbd8c72ef202b5b9ddc4fcb2724769955e48d3e85dc7e11dab893b8a3ee801c88b72eeddaee1f3431dddbadb4b7e621e20de166d9c6dccee611557ec5de67605202c7d84cfd433826eae7ccd1a55dc6dbbe36be46a6a0811a9b77a6f6cd6ef2ff84b5a7b7a752a6cb94dea5f783d5c56b05f42c33acef9fdb0edf693c570155de61cc9bac17de2b436588c69b38c93ace92534a16f49eb2cafd0ef1c73a6145e4a7c4d430b2c7bc50ad8bc5eb80eb3394ba6ab65fb61077b31d99510db81f9ed63d87569f71a628f7b0d7b68610fcc2bda4ef60bc88cb8ce5ddc719d8b25a95756d5b06b42d8371fe1406c61c64b5abd004af6dc4e385ca8b616f4b2b00ed8c79d9b8754b3aa9e7acbb69b690840b77d326b6a177c6a00de0f35b17d4c6b2c9455c00a47ac0b8cbde1281c618f3c93ca5c644ceb185681a51ddb33b8645d49ac12ed0bfef606f3ede4f504ea4e56d463dcafc899485afb4d678feec2891aabc5f314a5541986d370866b633de3f591ef8573dcc31bf1fa9374299d70e10e432f5caae98a3e5e6c087704c355b88618d229f8da4c73a370635bfa93f65f34ed026f2de945ea1acb7c26cfefea083dbb73ebe196571d849b32a371e884bbf099fc05ae5d55731510473be710e94f364209aaf84dc8f1b76ab1229ae58eb4733409e550c135d2857d9114f97c2954cd8d39917551aec9bed64b914f1fd6809ba93955476831e5a2c760547bb117b60c3a1c40173535de297f11949aaabc336bda7e2dd4a0167e0beb7e3f3cfa5bac6f96b8c1483ea1e8a216ab4ade8b0d1bfa261c42bff49cfdfb477a99ff86c720d4a14e1a408eb944cd082f14971f203a41de066f1c854da82a87fa296aa75cdfd5712f6584b116fa13ced323fd1955347e63e94c99d859da872e6a2aff8e5ed7f1b7d14687bda75ab0a365bd2c7654122b76dc7df246f04f8ecb6811bca26cf69cb107d017d2fae43b44d45ef4b88e62cd6630e6264928dd4fbd637833b5180a6b30cbb6b6da06c7e6de0e740d3378712571ee14fd37f62b83eb44ec5979dd82ecf74eaa5dd704d9f7f418ec781f66487b29bbb1eb0f63173aaa4f8c20fd903abb2a54280fba14ef63a177e66a7afeb3a837f0a5d883fa6f0b2a5859e1adc839cdd5eb635f5c5bea54edc53ec8a69ff7ae310e904598dbe8edc03dea86baf44da8cdbaea330ee2d09f83c7a775c6778a0e50e9bc40b43f8c8fe1c3d5dd66ee39bffe8c8533fb149fe2334a23ceaf4d7c598fadd64b2f1caa5dbfa38a2bc1c5132f604ff1258edc05e61ae83121d61caaba1be14e695acd4ddefaac9ab8fa07fd49f85443d7556d8a5dbffb19e3ba9883312a610dfbaab99d44bdb42ff6436ea06770d710cd164f20929da5183d756d77e9d6a0de6d512f8267f67be0a969a728ad97551337a91285f13e75c9ee40d8ec607fd05b41fd5c3c8be338b1353d0a6b108d5af3fb3b3fa917e79ff5344ea1ae9b9d1e99eb2b52bd05b1eb087a9a94cd0eb9e274bc4f96f45135d4cb3bdcdd50d04d94c271b8f2258eeeab3e7286e930beda54b797d1479e8b91e9ebfee58b0b28720d5d0ba5f896d7ea17f77a29731b578feffa1266de410f1da816eaa89977c03daebb41cfeaebf1237ec6ad82fc97b503dcc446dc8e4dddce1dc1c39fd30be486819faa5a6ce169987181fa99ff8e29ab9846dcf1067a9b633ce96e308abeb3c7a618f40afdc995ed998fb81baee2de576b67857f0fe3be1ada1264dc7bb2dc39bd7cd1efffe07a5417f1201ec6b6316ad67f14679e45d391526e188f42cd5c9a67d3b4255cdfd9b67dffae4bfa0eeae05d3b8ca982ece4dd90f1120f8531cdad7d8c27fa18b849d5d2f06cf9ecc537f57246eb660aaa942b538aa77c3691aa19395352f4a331ae07a47393957806a9fac4687de547fa2adcc673557543e0a22d14e773963f8a63505f581d2f8cd3697df38957fac2a2a57d2b8eed61ddf3a67bf6305ec62b45fbf0f37df06277851fb0bba93a3463f8b4a1ea6cabce424ef9fa1c73f193ea8417e8971edd0b4895f65ec2dcf9d86fe71773a5277ce6c8d88939f6b7d46160df5eaccd17fbac556b8fd80b15ce322e79fbca5a2d9dbe5261649af1bab8c6ff07f24b883774dec8356cc34ee2ad3fb54738becf27aee6e79ec3e96cf5421c5fe658fe5db99e867b7e50e1c50ef8cc637177e4e7e2d8d9043aad43bb8d27d3811b6de25de85acb7bd7e3557d22fb5331a7ceebecebeae58bbfa72809d55229960bebfb3f9f5f14eee4e1778be027642cb56dcae62d56ec3bdaff8f4ff0a7cebfcce7447fcc05de8d8d2fa2347002f1be0ab110bff72471ec67f512d780fa13cce72dffaacbb106196f4b77e2babd5cdd5bfd8ea4e7bd5f569ac6984bb6f95b27737ca817d08b0b0dddc1f38289aea5d35ddfd4cbd27e64928b7bb265b76babcefd2e378b1c2cf27247dffb81baeb3536e37ef1e4afc2155fccc1af782676f67d98afcff5fdb88a59e4e401e2c9b6de517d558f1bb6ed3e6d85e79ef7dd55d54e698123ccaff6c9dc4105f9e0f7530d9dfa1be84aab78770a9c0ccd36d4e1782a7e154d7f422f2ddcc7b250efeefa7788d297b11e372116ccbe03836763cdc497974eebd2fa6c09d7bba84ae898fbd88b4fd6d9d43706a83a2756e3a98211797cfab6825bc395c067cefb7352fe197f99e788a2017e5faf0179e7c336cc955326747518aa235f5ae84a564505596719c16b1bae0eddef494c548ed2be816da8937881dca435838e35deba0b3b8168acd229d6af69fc23dfe3832ac2f277581ba9265017e99c7f54d0bfdc755518fa46feeedb62ef98bffb6676bba66bbb4edf74bd4e2743aad869a51efe1e729853c36ee8c6a4133b443fa1550afc16c95774fda1ef5752546ce137705f75cfd17ef254ef807e9e7dc7f54dcd1f9b3b7f0376deb0c6b47dc9974c1b7e33616c83ab85968fbe635b26ad127da6d55e73889d169d06eac25825d3ec76bb265671ad728a121c6227f7a7f2fee265c7784ed6e259315c77066e9ea087ec75efc33a72b8a5f7c0be4fcc87afe96b0794db4fb5e75aa106be70a66f4c703df7a4277436009ebfc77deb16eebcf6f1f79e6e84fd58b66bb8eada5f94e41f8e63cb56f680f5197dbb3db25e06f2bb9cbdf053b0f15d5f774f2e40973db25b1638f075d0c524e789bc2e97acf68cbe4f3e241d60f47dd72dfc49bbb3e99cedc37244fae37af9225acffe46a76ff269eb3929d0e9eb55632d9d3a5cb166b772fe3fe52f3fe2245d6f056ef299a2c5c8bedae6892bf6f4b9bffffeff1be3cfe865056596cf831775d1e5ce696bc5397c398f496b9085756deeb454618ddbea15672c8bd7f7f3fe0ff4b2f8f7392b82dfb7a40f5c250159839cab2bb8d3627dfc3abdacec158a542dc8ec2b2b5afe3b71687f647ddfb48d6feae5abcea738d2dcfec0f738b1d9f256e86b4e473fe0e8a7e3d8571efe23ebfbc18c2beecff7221eadcecde12fc70d6bdd875faa97e53834efa55f52537c7e2eaa17c6fc8114e099ee03543e7fa04efebde77ed5f5ddf97e4ddeff7b5e7ff5ff17eebff3fa5fa597fff77ffef1ff01feeab8c5 + + + 789cdd9cdb5372c992e8dff75fd1b1eb6dc7448d2820c489f380a2a0a88077999887ba2e141015b93971fef7935599592e106dbf6e7ba663b6417ffe6451555979afb5d8fffeafdf6e3ba7bffdebdfff317955aff7e637d3572fbffdcb4e47a3e57ffce7fffdaf7ffcb3b0b5f55b78952ac5dfb6fff96ffff8a758fc667e135bf17f91ab892b81d52b7301df9f1317f17a2513e3f51366ba7e465ca1eb0f13e3f53bcc78bd3d4d8ceff37a0c7ede3f258eef6b9abf40ebb775625a9f3e8a5c49eb9d26c6f10f98717ef79618c73f26e6f58bc4f8fe0d337dfe2c31beff444cebb7678971fe1933ed570599e5717b8971bc7d661c5f2c89493e41f21568bd7a484cf31b1d1846a3f95c1b99e7cb1e99f17d3320e6f1f97a1a5f7488697c5547de667bf2c4f4f93ecdbf4d9f7771fd850a5faf6e89e97adf488cf23a62d68722a6f9b371e0ed349f2e10f37e8c88e97a9121eff07adf88e9f3a642ccf2ee46aef2f5d93431eaf38298eded9498e7df23a6f99d472ed278265ebf53e0ebd58098f5779b18e7bb44e6cf8b7e627cff8598d6634789e3fbbece4cfa5e10d3fcd6464eebd32d62de1f9318f573c64cf6fc4accfbd74d8ceb9b13b33e4ce2f87e76815c2ad17a62fc2816f8f36e42ccfbb99b18e53b65c6f568835c627b3b491caf374fccb4fe1a31cdefaa89717d15e22aadff21717cdf2ae4dd2aed6f8c7745552ad17a9e89e97a3367a6f7717c552e10c7f94bdb258bfeef9bccdbd5b8be57e47281c63b62a6cf6f11d3fc99488cd7df306fa3bc9a98e4f33d624bf2477b2ac1fa760a71fc6d62da1fb5cf4cf1bd464cf28a3233beeff9f334bebf65a6cfef27c6783860c6f52a5cafda2579cd5e62bcbec68cd7671d62d6ef2831cedf67c6cfbbabc065d88f1ddc6f454ceb7187ccb47f1d66dc1fff92387e3ea3eb79bdaa9818c79b32e378f68098d6e30bccf87edf1093be5c9999f28562a6eb99793fa33f9493bc7ec98cf6e5df98511e7b454ce3bb1e335e2ff688497f5a24c6eb87cc24df6d629cef15b942fba1ae98f17a1ffd697787e3adb0c4146fb20364bede2e12c7f11533ed9fbf498cefdf11933cd98c99e48ffeb9ab53fc56c8e9fa1633f9c72331dbeb7362bc1ee7d7559237bb66a6f5b9c4f17a7dcf8ce36751ff959d144fef13e37e1799491f75e434de0b338e2786c4b41ffa8d19df77347e95e4552d66b2779f18e58bf654d1559257bc30e3fb7d89ac583f67ccb4dfcdc4681f47c46c9ffbccb41ffdc4387fb447483f141ff50e32cf9725c6ebed11318d67ee12e37e38e622ea7749ace8f343e6a28ae35b6287f3996b66bc5e48661ccf4c90f536f9b361267b2825c678f4c84cfa7b222e53fe9c25467f22f9b4a2f16f13a3ff7799293ee3f8a6c2f1fd8199f2a526a678ae1ac4e4ffa68a5ca5fdcf5e9079bfcc9898f6c3cc98713fd43d32c887fb75c28cef67bdc471bf6d8b98e4efdbc4e80f7366ca8797ccb8bff28619e7538699e653cc25eca78e88693fd55662dcaf47669c4f1e278eefcb2b66b2f7bbc4717e39257638beac25c6cf2f9969fcbdc438ff1b33ca672e12a37c24af217b93e3c438fe8099c69f25c6fd94c4b4dfe23031e69f1e33d9cb0131ed4f16f5ab8a6c3f561393fdf82172b29f2233bd7f9d18eb995d62b257d364c6f7ed2b33ee87be45d6dba84f7f484cfab727cca87fdb488cf62698f1f3d99c98f4ab8bcc541ff078acdf3b661aff25318ebfcb8ce39b2d62d2bf2d30d37e8c13a3fc2d669adf26c6f8d16746fb931789d11fcbccb83e97c6a7f5a5cfe3faec3672b2a7b7c4684f1933d9533d31be7fc44cfed84e8cebb967a678f79818f793d6cbf6286d621c5f30d3fc3a31be7fc04cf6314f8cf9c63053bedb4d8cf9cc13533c90a78971fc0933cddf4f8cfaea32d37cbc5e8a0ffe8c98e3c14962fcfc1533d97bcc17cab0fdfb3933d54793c4180fb689b9bee3cf53bed7d7ccbb3b71bc69621daf7f22a67acfb69969be2a32db973b6546fbf2adc4983f515ec3f6a0db8971bd63668ad70566b2579118edf59e99fc2923267bd0e789317e9699717e719c18f7a3c14cfed34d8ceb49d7537e4fd7d37a3acce43f37c4642f86e5617b794a8cf1f09499f6f72d31fac30e33d5a3e3c4984f2f98717d722b31ae6fca8ceb53bbc4647f762731dacb2533c5fb9bc468ff1566d21fef3fc51f739618eb338c8fc652fcb09e99fce58099eaa358dfeb6295fa9dac4a4cf9c4b598291eee33933def212bee9f1f9849ff0362ee1f5462cc17cfc8acefac4bccfe7cce4cf6516326fb78491cf75f9799293fcd12a37fdc12d3fe6acd4cfed26326fd5f26c6f947ccb45e9f18c797c896fdadc34cf54a3731cac7ef937f589cdf72ff2526c4b45f59621aef9298fba90631e94b9c22ab02eacb8e13c7f8a35f910de5234fe359f23717edd594b8fff119b2a2fa429d23eb6d1ccf0c89291e0841acf07d5144b6e4bf7d7adfb2be62bc3196fb2383e35b9ecf3e216bda2f6399495f8929bed6982b51feec8d98fc3bdb4d8cf29591397eba8c98e2998dfe6f4b1c8f7d15d994717fb307669c4ff789b9df3967c6f76dec8face3fec81f248efb2ff691d9ffb31233f557bbccf4f907661cdf2c91933d0e99299e8d9871bffc1631c563b14d4cf9d95f25c6fc289969ff0f8929de299f18e34f07d9517c72e7cc14ffa27caeccf2b92633f9fb73628cb78fc896f2976e32a3fc6a2f71942fdb26667bf18971be6366ca8777ccf4f927e66a31ca7f424cfbe16e98a9be1c25c6787ecd4cf9ef3631ea3763a6789618e7170d62da5f51488ce3ef33533f2913e3fa8e98c99ecb8931ff5d32d3f9c541627cff15d971bdda4c8cf32f9829ffce13a3fedf98a9bf7a6046fb93bbc45c8f8e12e3f87c3df747d78971fc3e33e59bbbc4b87eb22f47f62cee1263bcda62a6f1493f8ef63743f91dc7477dca8cfa314562ca4f7e9218fdf99c19ed477788593f0d663affea3153be693253ff74cc4cf3ef33e3f806ed33f99bee3253be2e25c6f8bac74cf9709a18e38d6226fbb8488cf1e29999d6bbc58cfa55d7cc148fd3fa68bdb4bf49ff8f8951ff4366b22f9718df6f31d3fa678951ff1d665cbf6a2746f916cc146f0e9931beebbbc4280fef27f72f26715c4f97e5e17a5425c6f5f2f8548f9a7662cc6fbcff142fdc73628c57dbcc548f913d38ee771a89713ecf4cebb94f8cef179929ffd1fe7af27771c54cf1a59e18fd23dab72fb33d78cb4cf1799218eb8b0133dab3ab33a33dbb0233da47b69fd8c4f71f8849df6e2b31eaf38c99f27d2d31da438f99cecf9e12c7f5f90b66aa4f78bd14ff5d25715c8ff1c4a4efac9e38ee4fdf31937e797ece07e789b15ee0f9f8bca3c88cfa36a5c4989f16cc547f5c31d37abbc49c8fb799c91e9e13a33df0fe713caa24467fbf64a6f5a7f148ff693cf2a71133ae5f5613a33f3599293e141263fea3f7d9fee44b62ac471d33d5bf6366f29f4562ac872c33d9e70533d57347c4145f321e9fec2b43fd78a89fa3bd18b42fcff5adbd464efadb4a8cd70b6694cf2e99c9dedb89d1ded3781aeb8f5a621be56d11f3f9d32c31cee798c95eae98a95eea27467d9498c97e5e12c7f5644366538af3a3bd7bde5ffbc04cfd722131d66fc7ccd43f2426f9cb89e37cbec2ace2fbd61073fe7f6426fbdc61a67ee23231ae2f63a67cdd4e8cf9fd8099f42999717d769e18d7a799717dbe48ccf5dd3333c59b6562ec1ff9f3a4efeeab147fd54baa95df75782536d2d2eb47e68abaffcb24f99d174b627f66bc1fd08bcdedefafaccefefdf4b24992f555867f7f6ac57fa95e7e57ba4faf0bfee3defde77f5e2fdf90e6f3ebd4cf49f2d7e8a5fb890f7d65857f5fbdfca2747f33bd481fffcde0d597f7c00f72107c81724ab2263984bf7b788de2f503e0fedf4b2ff2518e617559fcfd21ae5080444ff21924432932f87b06bff7e16ff8fb7d9422fb39ddff845ee48b9cc0eac6f0fb24e807a41a47eb0912beca69d2074a13f4349373782de4125e3f26cd8ff9cb1b4932e9befbc61b4815fead059d5104de93fbb20eff1ec8c3a82fb6b6bf875e6c5c71032409ab6eca5aee3d4d12d4e1dfb0fa23d0c7b16c012fe2b5e173277fabbc7f0a2b3a8dd63584959fc18a5bb22d3bb22bcfe585bc9457f25adec85b79277b724b16e0efdb724716e15a0f9f2bfdadeab1862ccb5d90e45956641556da135208a184164658e1848f3f4e64a22feec5831888a11889473186eb87e2e96724f9a65e3ecb03ef3962045edc925df12c5ec444bcc2aaa76226e6f135178bf4338f7f9b89a5781335b127f6e13375d0235821e9f84fe49b6fe805461707f03a8cb3510f0211f54d806589a638920b712c5ae2449c8a33d18eebe59fc5273f7392aa23baa0bf7371212e21ae3561bc2b887d21ce417410d7e0530fe2e6e7f412f64adc8a0371277a620b251105884b2fb226b66526764451944459ec8a4a5c7d957e364b41ef2aa944e499682ba5b432ca427468ca31ccd10fbe049268e5a450fea7f502d21caefdbd26e72a537d75af1ed480e458408aff4a927749a33cf4b7687320cf508d64553d428c0b754488f29069d5e3cffa0be8e450dc251f01cb82d9e66aac9ed4b37a81b590dda4d57df5535513f5aa5e493b5325d42c7e7aa9e66a216fd452bd4156653f8cbaf931bdc04bf456bc7d1774d25235b5a7f6553de8035677f02d3936eb07245387d1833aaa012ed9940734d7842aa06ff5addfcb2f60c32c49591a7524cfd4b16aa913f610dee74f3c7e83d5255b64595ee315419a5375a6daaa03d1651ca5197db7b6fe95fc1246515d18a905929cab8bb86ab4ac8f1eb2b6eff988005625508b6063327e7a914680e8a62ed595ba16c7e03763d55537df3d4ff8a5bc8f2339d985b96e4912f4005cd3473956392f296a47e446c9c56b75a1ee544f1cc39c210bffa05e623e099a7e545ba09382da861c3e4f332f28ba92ad241dac6713d6e2a1da59b1b6c3357d6264eba8a22aa9b268a85d58f99863276401f1a7f412f28985d8555315b0ae2b94843491d74e9064a226396ba9aa2a24a43a55311d2ddfa5029924e90c6b81776bc5bf645a68a5356464dcd147ecf820affd8938068b0e3dc6443a88c2e7605d6c372b7136a78db9aac2be5e68a38ada6aa7bd323a1327baafeff5831e88373d8c6b0ffb91a233fb4fa2b91ee947d5870a47c55e355bef41d77de75b7aa9c15e8ce55c8fc5103d3eedfd6a4c8a72e827d8d167fda227fa55b4d4584f655bcff41caa941da89bbb7aa197fa4dd7f49e0afbbfd0fb41a36bde14df1133bda7ebfa20d66bdc6d878e6ed57fcdafe8451f42e5e8744337b5e1181ce6d447fa082581698e511fbaa54ff4a9bcd067baad3bea5177f539d4cfa1431b87de0662d3405fe84b7d05faba86ba794a231ee89b9c3cc9ee60bc5b7d07fdce3e747187519aa73fae9798e7b7754f3de92dc827b9a8132421ad447fd505bdad61ef75519760f62158c523f496efb1a70c113df43a562e20b76febb2ded515ccb6c9ff16c90b17a0e145f8ca06449b8adc3312eab5d0d59dad4af22ecd77eab150b11861549c95a2513ef6181d2431263c29659ccc8c37e915251ac55a8e3a68aceb20fbee99beb9370f42ea9619704c4c517191e6699ba1dc31a3d88fee415faae9dec187089df4b23166d39553f368c6ea92eaf455bbc6a85c354fe6d9bc186926f17ae8ff412728c910ba83bb543f84febe1625c37ffb666a6666aeb066a846fd882447f41cb3304b7d69de401217bb8d4fbc9ff4b29e8126d1db477212ac42774d4d3de05cef19514dc34c41275a9a3db3afc6b06f7a7d06985d8024a7a60eb1e821ea660caf5af4e470fa343207e6d0344c13a459449f59ad20e26e9923736c5ae6249eed4cd6d6bae62f9b2a832089f450413c42a75532a72bd12b6f6315a5cdd29c99364488513c91481640639d42ee1e870ad574e09aa2e99a7373612ee55ef7d55cc1df067a66aecd4df0c60f156a9cd1dc9a3bd3335be6d514401a1e1b4f113fc4b1f5ca209c71996d90e6552e55e8b42ad192ab9c1ddf7b0fb3638a7aac2fa2f5bceb23af1b1f7c0e56d19475533265b36b2aa62aef64077ca0192bfb81854bac1233b15ed1a02c03ab5501749c5963b6d29d10b5ea112bfec2fb98c5083a3285f0af6943f7bb9beb4ee6540bc60c60ad75e211ac6b904e96fc87d83f910debe1ef7b36b37d282cc3594047d7ecbd7d00695ec421bc77640776684731cf2e3efcccc5ae7dd40d90e629e4ffaff3feca9d9f87f79a472a3db6e3a015cc20c9e7a3afea917db2cf20490d750216c927b1f94ab021a7b0ff5a35ed8b9d8024e8d953fb6aa7a66767f09913a8b38eed5cdf53a5f7a1a25355bbb0cb583b7f1a7337ea259c5e4fb0a2b36fe2d998a8955c74c13c0de3d7ecb3dda3cab30192bc9f0fe72366a875f7441df4b00fddf03cd66d3b626eebf640de99a95c8a3bf86cd3bec91e5c314bd22459601fe7f6d036e4b69d81e5c71af177f582ba18522f07fd9d29d96688fe4aae54910771af2eed913db6ad18210c7a389d86afe80562a1009d9c804edac152eda97ad537f60c7ebfb56ddb01bf09bb07f3d9ae3d57a71f6589d6ddb117aa26f7a3e57ff095d5bc9fb332ee4a97aa221eede56a2c8691a11a0ef1cb5ed96b99a9aebd893d462356e67daa97820465de1dd0dd9dbd0df54aacf0ab2933054bdb87fc3f0369600ce5ec9ded25cdacf90c58d9962d700ca3357f522727bddc93270fa1aaeb89d7e8edf95a097fcff429c47c6fb75774ca39b96177620feaa5b64590a4043a79ef4fdebb1fc8bea669ca62073aef5d39b165bb2bb29429f39a99d98a69e86ecc316f310be7a4fa508f25bdc095a1d7167a2a641c79bd470cd5d7b3adea12542a1fefd3bfc95d27650923819e39e194e8c4fae0356a784e3dd921c9e39d7606ea2c1843cf554f3f432c9bad6a25da45a63dd46326d51471bdefd6b6512f0f204d581da85c8858c9e6b442f57907aafa33c8177e4307db70d239f01f8822b668cae0279df74e8b6ac7598a89500f3bef3295c5dd3c737da8ebeaebb2c439a7eede3da05ef2ebfd542fe1dd3db0b2f0bb961da1d2acec2baf311eefba816ecba1c93ef6e27607ac259cfb2fc5585eb861acae17e0ebeff6394b27832186d4ddc83d824f85d5811eed0b74499bf432834eb3112dec71b57ad9ac97a8b59091a25e6457e8d5aa38ca124635fa5577424dbc52d5d32b46e7a529b9b17b821e72bd1aa55a98fe5bd50ff6ce3d43d68410071df1817b7193f55a1c23a77b95e7b6c07af93c8ee5f4a2e573b4750d9e6f36e805e677533773f3b03fe08debf92454257b6ee1c610a386efaba21a28bfd373b7740a3cff52cfe5a108734ee5a1aa294d7a495eeadea206e7d055c8d8177d91f757f412faebd7787a7421ecdafe4459f493ab41f7db0df104f669b8d629dc63dd65db4112b7c792e43a135a2548b2ef84aa885eac357c3c13d5d0cdbda05dae79e95c9dba3ae86ff82b7a81d7147eafbb83dce911c9125751810e5741f71b2abde187518f64c794c14fa65192cdf72e62d7e30e21c635e4b28b1db48d3de7d0dcbb66a874de3b4cb24ea899e49d3b8a7ac9e2bdea0ff9251f0fa26e86718fc6123297f06bd1042bb18e3b966dc8f1c19a42a7751aab9e06e67859750262d752f0c9d8ca29668c65b350fbba963b093e174f24c016a0539bc4dea6256f20f22d52559ee457b7a6685a5dec8bea1bfb7dce2be10e29ff6e6364bedd204b8c3cca40ae864e4d1cc20a2c9d2d4ec39d3ebbe74e5531ae85abe9fcc925fcd74144736dd7b1bba627df5c57f4dcb91c745f63853a0916ea2e202a27fdbdffb82554427bb456b7e91c26d703625ef1f1642d0bfb43a761ab760ed94d67e0ad5035927f8c45d35dc6f39a2acc5672cb0f5d483e434da2c75db96b557337310e8ea34e9aee36ee60cb94499635cd807fddc976177db9be2ac9ba5eba7ca720e4fd50c1dc82bf7c946501339d88cb70721def2a8413b8706a5417a02fd78bf7f966319f7cec13511a196d6c6a8aceca7de85f7641bf57411a5913d721f76f960576f6c46d454f487af9248e717d8bcf4e04bddc89b74db288b6eecb1d98b91ceaadd8b737a1126d42149ea0d7d2f9d06aec5a1f65a98aae00396c2be6a370af32ecc881dbd6cb64a32bb2e811f4b0a817f53b799febe3d85b82dc47ea49f43744a1b996fa5e9ecb5af0f4601dd0b3d76d16f249a856409209562ba49577fb7acf35589575dc543d996ebce38aa74d100974c3ed683e6b5eb16d35b02f7a9ae297fd18c73ee86514ad6629e7e6c51593f7e6e3e95c3fc82e5c770ad70d602503e873ee5d89aafad5d3e5d52e31c5d850f902b5dda1bc862eac089eff8af5823c77e558b1a54ff139bcdb75155d0c55e5efd663ac97d05169e846f764c1553ff6ace17e9c1ee8055856036c7d042fa820c14f3a2449fe6ecc868e3776db1411e1f7995a78e985b8a69d54aaa0b7621fbb2e0bd4e6b0bb47325b8fc69feb05351dbdabebf16ca48ad1076ba8786f3133d76614cfbec6d2db37b31bfd6402f13667e36c63fa265671f9de65e5ae803df0da9bd033826ecaaeae472b77dbaaf49ad985b71091869bef8dbdf7fb6bfe12ce9e96a6e79dad63ff42e7e17c823df55e8fa9871cf8cc5482c560151def76e5ee2ac7fbc40b355d8969ef192758d3d4f7a16f09e72c4be877ee295372252a695796fe5e7675e9b3e73372fd3e3f7b67e3133ae1d5d473ff107a31be2b916c07e6d7353f30ad7016d97d35177e182d6c42b246db497e0199319e73e7efb8aec492d02b2bed076aec47ead83fb22dbccb124e2f602527a6e4c76bd5d69a5ed6ce0107f1cecd7da859c5a3a825db4d6bf04fb0da3dedfc33f8d4083cffd28d752d9cb150563914a40b8cbdfec5bfc41ef9fdced74a640ce7187a089636d165788d5287fc6e63214ed4442b5a588a61d2adeb2555eaefcf44f6e13589cf1e6dfb57bc83955f43d47ad54ffdccf4c3332bea51766cc7cfe33dbc199d3ff1897dc52fac70d77e1964dd742ac19d268cf8e66b10432a395f7bd7dcccefe94bb98ff75f24de05ae7fd00bd7359ae40c9e9f490f3dbbb16f7e1f4f1d929d09ce0fbeee0fbc09fe02af639bd9a93d88f797733d23541d87fe509e9b17c8f153ca809b3267b873b4f00ddf8c67a46bf74542e4734b7fa42a6a8bcec72cd5649feb252fa7f5c720cd42154437cc837696327a886a535d310fa0c31174510bf5687ad047b6e2ee531455b76edfb7a0167ef327e16b9e204d7b5307102279ec27f21968a5da07ad9cca9e87cacade24fffe4a2fabdff018f933a8939e7c1baca3fd2e0bc5e5890a16dc016f6cfb0e549563f9e2bba6671a765f55c9d2627f42797a2af7fdb9bf70871f9e29633b0bf7a10f729a4a5a8b5e5771537fe9af60d71e531cd39fea65bda3e2587164f68337827f525c8e164127caead2cc74781aeb0eae2fc99a9e81df5cc77314af1fdc89aa841d82bed184ded10bedfd4dee0ce6a3ad6db6c1b97ad15083c70c9e3f495c798afe1bf72b9d7df6b7f19ec52bcb02f65be56ad7ec38e1efe40caacc139026dc4b29fb9ef3be276fdc22469001f42763b90b15cabddcf15bbef0de3b63dc5bfb59d71bf892df86faaf0e152c9ff0867b9ff9d345f1adfb957571294efc0eeccd94ef5dd34957b408883ed77a69a53c10dba0f2a6cc7cd1977cd93d42df3e0fcfbbc69a6d0b2a9d70ea5ef4bbbe62f76d3df59c9fffcc5932bde7ab998cbbe157cf263eadc736eb65e8c7a2e554ec7973dd613e6f6722537610730df4986a4b165566daf14e6938cd0d95fc042ad070fa07fd8937e2d9ec81afcd3e9ce86d96289c8b850c59f6c7b1af5ab993283fdc17fb529aa66edb478866eb4f2056d3b3864babec30d350ef36b11789cfec0fc1535fc253742a9c9e8334a11285f1f6e58ebeb207211b85272f3ed5075166326828e4d41f43346aaededff945bd187ba3bb99b78bd41fadf515a1de82d8d5859ea607d9ec2cce34a6bb4893f8ecf2ae3a8abdbc897737842e99fb2cf36fd04b6374dff0939e616a677d88853a787be863f391e9f3fee59397755db3659c3fcceed359fddabd5ecadcceee670ff206663e8a1e3a124751478d7407dcc673b74799b9a36c900db3516eff3f682748933d66e3ec49b643f48dabbfff737a81dcf0680bd973f6129f8699e756ffeebf78877ea64eb3896dc81e746aad78aea3e3d3ee3ef69f21062da13f29eb993ace5efd5b36fdecec2cf7df763603ffba37123eefd3f3301b9e8afb8ebf182f9f44219b678b6ca906b9fe233ff37b349d096b8eb237df522555cb6ae63e9eef1ceab92dca1db90d75f040bf657b90b32ae96ec8fc830c79fd54752ddb975d9026544b63ae82d72ded5bcf29d5b37a383786fd54d9013d9b88d50c3f5392f7a31043a5ba55a7da6487fac53a752f6fed9dbcf5fb5943697304527452b7f69a93e5b33806f5851e644d3582b838ce8ee8a4cfad5bdab7e2582bde67799343ddcb8eb3568ca68bb53e78bdbb8a3f607750ffa83afcdc42d5d9899ac8affbf3e798f33fa14e98826e4ecc194c8af75edccaf3b1dfce2fa08f123e7394d57543f5dc143b8cd8b7e76bf3f53e6bbd4a648faee69e65fce0ed1b6bb5f0f4d5d095553b3bcd7f5fe60fe417979de11354664b7774236bbba12ec4f19fd21357ab73aff2646ddd9b249e2769366826def3830a2feb80cf3ce5ef8efc5a1cebbe42a775a6cfc37d96204d56cfbad9b97ea47bd7f34d7d22fa533ea7aee9ecf3eae593bf8728a9aad94576993bdffff5fc22e29d3c172280c942c6120dadb3abec5ab782fdffce13fcd0f92b41cf897e2d457c377bfc244a832410ef6f2016c6ef3d711cfb55bd64b7a2013556c8e74dbbadbad91d64bcba6f673d5ddddc5bfdce4eaf7a3f9f34cd632e19d3b74e56e41053d04be6bd2c40fcc2fcf2e1e9ae6feae5c3fdc8b02fa6956d99b2199aaf23ea2609d665a9e2f77ea0eeea674fd92cffe46fd4ac8c39b89f15c2c945fa3ecce7cff57d59c57c90e41ee2c9a13c12639565db7acbdc1acca1ebbebba1da598be4945ff59e1699d55367430d1dfa1be84af7e2bb4b9064aecea00e3f0a4fc56f5ad39fd04b33dec7d250ef1ebb6d88d2a56c272b422ca8f0a9053e1bab0edcdbfad3ba783e1b9f9be5ef2655d48bdff6553dce427de0ccbdabe8417caa60861e1fbead9069dd10d7f83cedfa2eff8abfac4a84d1207e5fef00f2f09e91aa6c7a6a9c955c4f74a1f25ded4a3645053e679909e74fed3e74bfe7998471a7e1be01a8fd226b466966f18ec2c836ed4037201a0bd1fc6a8d7fe47b7cf2259e6b66f13b935013884278cedf9f6765fb92edba9eada4efbeadf78ee9bb6fea22ab64d5be94bdbe803ebe0efd4de8b4420fdf37528fc5735ff575d009d46ee027e1e43ce824dce9fa6c5d7fe8fb9518159bf11bb84b88d885703f19f2cf11e8a7e666a6a1bdbbd7c2bd829d9fea91ba754bb754b7f0dbc0edea67bbf0f7f6c4cdf4a5aaf83158aa0e1d5ce8b4e869a00cc6dd51edbe01796ffc73f413414fb38a3f97f7d75ffa303e27abe3b362606de6c414ac811e72d8b7fe442e41aaba7bd00d79ae8e5d5dde9922acfc4e9c98a26f812f942558a439342d5dc2670360a5fd78dfba19efbc0eccb60ca7ee077e945d9a513c751dacefe41f8e631fad2c9c378fe277be85f4a897706e65b64d21cd003d0fd8f8b13b322dbba7db7da7db7a665aaee1c7f45c39af08ef960c639715be431e6ae17138410c2b97cdf82f7e733b3c677bff3122fd71bd7c12addfff864fdfa4a7ad5776019fbede34d687a70e379cd96d9cff4ff9cb579284d75b4e9af44cd17a64df6cf328159d47aefcfdf7ffbf31fe8c5e36ac0cbfd9b1aa8b8c3aa7fa86e7f0f9794c3c83cc9d6b53a7257267dc3a7f42bce9f5fdbcff855ed6ffbe6245f07b9dfbc04d3bc067902b7505755aa48f9fd3cbc65e21bfaab53dfbcc8a3efe1d25d45f59df376de39b7af9acf3c98fb4727fe07b92e864791bf4b5a2a32f24fae538f699877f657d5fccb8e1fdd55e245c5bce5dbf69de34ae3feefb1fd5cbc738b4eaa59fae267ffd4a54cf8df9c52ec0357d0f95cf1fa8937fefba9f7a7d77be9fc9fb7fcfd75ffdff0bf7dff9fa5fa597fff77ffef1ff0139bda7d7 + + + + + opt1 + clicked() + MultipleViewBase + slotOpt1Clicked() + + + opt2 + clicked() + MultipleViewBase + slotOpt2Clicked() + + + opt3 + clicked() + MultipleViewBase + slotOpt3Clicked() + + + + slotOpt1Clicked() + slotOpt2Clicked() + slotOpt3Clicked() + + + diff --git a/kwordquiz/src/paukerreader.cpp b/kwordquiz/src/paukerreader.cpp new file mode 100644 index 00000000..95bcf7cc --- /dev/null +++ b/kwordquiz/src/paukerreader.cpp @@ -0,0 +1,106 @@ +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "paukerreader.h" + +#include +#include + +#include +#include + +PaukerDataItem::PaukerDataItem() +{ +} + +PaukerDataItem::PaukerDataItem(QDomElement &entry) +{ + domElement = entry; +} + +PaukerDataItem::~PaukerDataItem() +{ +} + +QString PaukerDataItem::frontSide() const +{ + return getText("FrontSide"); +} + +QString PaukerDataItem::backSide() const +{ + return getText("BackSide"); +} + +QString PaukerDataItem::getText(const QString &tagName) const +{ + if(!domElement.isNull()) { + + QDomNodeList list = domElement.elementsByTagName(tagName); + + if(list.count() > 0) { + + QDomElement element = list.item(0).toElement(); + + if(!element.isNull()) { + return element.text(); + } + else + return QString::null; + } + else + return QString::null; + } + else + return QString::null; +} + +/*! + \fn PaukerData::PaukerData + */ +PaukerData::PaukerData() +{ + document = new QDomDocument(); +} + +PaukerDataItemList PaukerData::parse(const QString &fileName) +{ + PaukerDataItemList list; + + QIODevice * file = KFilterDev::deviceForFile(fileName); + document->setContent(file); + + QDomNodeList entries = document->elementsByTagName("Card"); + + // loop through the "Card" tags looking for data + for(uint i = 0 ; i < entries.count() ; i++) { + + // get an entry to operate on + QDomElement entry = entries.item(i).toElement(); + + // if the "node" is in fact an element -- i.e. not null + if(!entry.isNull()) { + PaukerDataItem item(entry); + list.append(item); + } + } + delete file; + return list; +} + + diff --git a/kwordquiz/src/paukerreader.h b/kwordquiz/src/paukerreader.h new file mode 100644 index 00000000..95a3241c --- /dev/null +++ b/kwordquiz/src/paukerreader.h @@ -0,0 +1,57 @@ +#ifndef PAUKERITEM_H +#define PAUKERITEM_H + +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +class PaukerDataItem +{ +public: + PaukerDataItem(); + PaukerDataItem(QDomElement &entry); + virtual ~PaukerDataItem(); + + QString frontSide() const; + QString backSide() const; + +protected: + QString getText(const QString &tagName) const; + +private: + QDomElement domElement; +}; + +typedef QValueList PaukerDataItemList; + +class PaukerData +{ +public: + PaukerData(); + PaukerDataItemList parse(const QString &fileName); + int colWidth(int col); + int numRows(); + QString language(int col); + +private: + QDomDocument* document; +}; + +#endif diff --git a/kwordquiz/src/pics/Makefile.am b/kwordquiz/src/pics/Makefile.am new file mode 100644 index 00000000..6a1b4477 --- /dev/null +++ b/kwordquiz/src/pics/Makefile.am @@ -0,0 +1,5 @@ +kwordquiziconsdir = $(kde_datadir)/kwordquiz/icons + +kwordquizicons_ICON = AUTO + +KDE_ICON = kwordquiz kwordquiz_doc diff --git a/kwordquiz/src/pics/cr128-mime-kwordquiz_doc.png b/kwordquiz/src/pics/cr128-mime-kwordquiz_doc.png new file mode 100644 index 00000000..3d49add7 Binary files /dev/null and b/kwordquiz/src/pics/cr128-mime-kwordquiz_doc.png differ diff --git a/kwordquiz/src/pics/cr16-action-answer.png b/kwordquiz/src/pics/cr16-action-answer.png new file mode 100644 index 00000000..2ae98e35 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-answer.png differ diff --git a/kwordquiz/src/pics/cr16-action-check.png b/kwordquiz/src/pics/cr16-action-check.png new file mode 100644 index 00000000..29ec6cea Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-check.png differ diff --git a/kwordquiz/src/pics/cr16-action-delete_table_row.png b/kwordquiz/src/pics/cr16-action-delete_table_row.png new file mode 100644 index 00000000..490b130d Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-delete_table_row.png differ diff --git a/kwordquiz/src/pics/cr16-action-dontknow.png b/kwordquiz/src/pics/cr16-action-dontknow.png new file mode 100644 index 00000000..9ac31a0d Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-dontknow.png differ diff --git a/kwordquiz/src/pics/cr16-action-editor.png b/kwordquiz/src/pics/cr16-action-editor.png new file mode 100644 index 00000000..9a8dfbf5 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-editor.png differ diff --git a/kwordquiz/src/pics/cr16-action-flash.png b/kwordquiz/src/pics/cr16-action-flash.png new file mode 100644 index 00000000..178ab1a5 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-flash.png differ diff --git a/kwordquiz/src/pics/cr16-action-hint.png b/kwordquiz/src/pics/cr16-action-hint.png new file mode 100644 index 00000000..4904f418 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-hint.png differ diff --git a/kwordquiz/src/pics/cr16-action-insert_table_row.png b/kwordquiz/src/pics/cr16-action-insert_table_row.png new file mode 100644 index 00000000..e4859a43 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-insert_table_row.png differ diff --git a/kwordquiz/src/pics/cr16-action-know.png b/kwordquiz/src/pics/cr16-action-know.png new file mode 100644 index 00000000..a982d388 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-know.png differ diff --git a/kwordquiz/src/pics/cr16-action-languages.png b/kwordquiz/src/pics/cr16-action-languages.png new file mode 100644 index 00000000..b6194c82 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-languages.png differ diff --git a/kwordquiz/src/pics/cr16-action-markasblank.png b/kwordquiz/src/pics/cr16-action-markasblank.png new file mode 100644 index 00000000..07784dd7 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-markasblank.png differ diff --git a/kwordquiz/src/pics/cr16-action-mode1.png b/kwordquiz/src/pics/cr16-action-mode1.png new file mode 100644 index 00000000..b9ed7524 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-mode1.png differ diff --git a/kwordquiz/src/pics/cr16-action-mode2.png b/kwordquiz/src/pics/cr16-action-mode2.png new file mode 100644 index 00000000..cf1ed735 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-mode2.png differ diff --git a/kwordquiz/src/pics/cr16-action-mode3.png b/kwordquiz/src/pics/cr16-action-mode3.png new file mode 100644 index 00000000..b80cf65e Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-mode3.png differ diff --git a/kwordquiz/src/pics/cr16-action-mode4.png b/kwordquiz/src/pics/cr16-action-mode4.png new file mode 100644 index 00000000..f4e1bf87 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-mode4.png differ diff --git a/kwordquiz/src/pics/cr16-action-mode5.png b/kwordquiz/src/pics/cr16-action-mode5.png new file mode 100644 index 00000000..17d1d6d1 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-mode5.png differ diff --git a/kwordquiz/src/pics/cr16-action-multiple.png b/kwordquiz/src/pics/cr16-action-multiple.png new file mode 100644 index 00000000..3ab31256 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-multiple.png differ diff --git a/kwordquiz/src/pics/cr16-action-qa.png b/kwordquiz/src/pics/cr16-action-qa.png new file mode 100644 index 00000000..61807730 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-qa.png differ diff --git a/kwordquiz/src/pics/cr16-action-question.png b/kwordquiz/src/pics/cr16-action-question.png new file mode 100644 index 00000000..e84ef887 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-question.png differ diff --git a/kwordquiz/src/pics/cr16-action-repeat.png b/kwordquiz/src/pics/cr16-action-repeat.png new file mode 100644 index 00000000..9e5d0b93 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-repeat.png differ diff --git a/kwordquiz/src/pics/cr16-action-restart.png b/kwordquiz/src/pics/cr16-action-restart.png new file mode 100644 index 00000000..27b981a5 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-restart.png differ diff --git a/kwordquiz/src/pics/cr16-action-rowcol.png b/kwordquiz/src/pics/cr16-action-rowcol.png new file mode 100644 index 00000000..e84ef887 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-rowcol.png differ diff --git a/kwordquiz/src/pics/cr16-action-shuffle.png b/kwordquiz/src/pics/cr16-action-shuffle.png new file mode 100644 index 00000000..d4d70dfa Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-shuffle.png differ diff --git a/kwordquiz/src/pics/cr16-action-sort_incr.png b/kwordquiz/src/pics/cr16-action-sort_incr.png new file mode 100644 index 00000000..f64da9a7 Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-sort_incr.png differ diff --git a/kwordquiz/src/pics/cr16-action-unmarkasblank.png b/kwordquiz/src/pics/cr16-action-unmarkasblank.png new file mode 100644 index 00000000..c9789f1c Binary files /dev/null and b/kwordquiz/src/pics/cr16-action-unmarkasblank.png differ diff --git a/kwordquiz/src/pics/cr16-mime-kwordquiz_doc.png b/kwordquiz/src/pics/cr16-mime-kwordquiz_doc.png new file mode 100644 index 00000000..963cf134 Binary files /dev/null and b/kwordquiz/src/pics/cr16-mime-kwordquiz_doc.png differ diff --git a/kwordquiz/src/pics/cr22-action-answer.png b/kwordquiz/src/pics/cr22-action-answer.png new file mode 100644 index 00000000..f5715ca2 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-answer.png differ diff --git a/kwordquiz/src/pics/cr22-action-check.png b/kwordquiz/src/pics/cr22-action-check.png new file mode 100644 index 00000000..41744e7d Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-check.png differ diff --git a/kwordquiz/src/pics/cr22-action-delete_table_row.png b/kwordquiz/src/pics/cr22-action-delete_table_row.png new file mode 100644 index 00000000..8953710b Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-delete_table_row.png differ diff --git a/kwordquiz/src/pics/cr22-action-dontknow.png b/kwordquiz/src/pics/cr22-action-dontknow.png new file mode 100644 index 00000000..be345ca6 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-dontknow.png differ diff --git a/kwordquiz/src/pics/cr22-action-editor.png b/kwordquiz/src/pics/cr22-action-editor.png new file mode 100644 index 00000000..102641a4 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-editor.png differ diff --git a/kwordquiz/src/pics/cr22-action-flash.png b/kwordquiz/src/pics/cr22-action-flash.png new file mode 100644 index 00000000..6b292abf Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-flash.png differ diff --git a/kwordquiz/src/pics/cr22-action-hint.png b/kwordquiz/src/pics/cr22-action-hint.png new file mode 100644 index 00000000..23c73a98 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-hint.png differ diff --git a/kwordquiz/src/pics/cr22-action-insert_table_row.png b/kwordquiz/src/pics/cr22-action-insert_table_row.png new file mode 100644 index 00000000..5eff7ada Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-insert_table_row.png differ diff --git a/kwordquiz/src/pics/cr22-action-know.png b/kwordquiz/src/pics/cr22-action-know.png new file mode 100644 index 00000000..84b8370c Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-know.png differ diff --git a/kwordquiz/src/pics/cr22-action-languages.png b/kwordquiz/src/pics/cr22-action-languages.png new file mode 100644 index 00000000..f577beea Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-languages.png differ diff --git a/kwordquiz/src/pics/cr22-action-markasblank.png b/kwordquiz/src/pics/cr22-action-markasblank.png new file mode 100644 index 00000000..876b1eef Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-markasblank.png differ diff --git a/kwordquiz/src/pics/cr22-action-mode1.png b/kwordquiz/src/pics/cr22-action-mode1.png new file mode 100644 index 00000000..42528921 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-mode1.png differ diff --git a/kwordquiz/src/pics/cr22-action-mode2.png b/kwordquiz/src/pics/cr22-action-mode2.png new file mode 100644 index 00000000..0a649772 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-mode2.png differ diff --git a/kwordquiz/src/pics/cr22-action-mode3.png b/kwordquiz/src/pics/cr22-action-mode3.png new file mode 100644 index 00000000..0916782f Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-mode3.png differ diff --git a/kwordquiz/src/pics/cr22-action-mode4.png b/kwordquiz/src/pics/cr22-action-mode4.png new file mode 100644 index 00000000..e8be1691 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-mode4.png differ diff --git a/kwordquiz/src/pics/cr22-action-mode5.png b/kwordquiz/src/pics/cr22-action-mode5.png new file mode 100644 index 00000000..b7c856bc Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-mode5.png differ diff --git a/kwordquiz/src/pics/cr22-action-multiple.png b/kwordquiz/src/pics/cr22-action-multiple.png new file mode 100644 index 00000000..cfe67ce6 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-multiple.png differ diff --git a/kwordquiz/src/pics/cr22-action-qa.png b/kwordquiz/src/pics/cr22-action-qa.png new file mode 100644 index 00000000..af1f2127 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-qa.png differ diff --git a/kwordquiz/src/pics/cr22-action-question.png b/kwordquiz/src/pics/cr22-action-question.png new file mode 100644 index 00000000..b115cd3c Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-question.png differ diff --git a/kwordquiz/src/pics/cr22-action-repeat.png b/kwordquiz/src/pics/cr22-action-repeat.png new file mode 100644 index 00000000..954a2c9f Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-repeat.png differ diff --git a/kwordquiz/src/pics/cr22-action-restart.png b/kwordquiz/src/pics/cr22-action-restart.png new file mode 100644 index 00000000..a08444fd Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-restart.png differ diff --git a/kwordquiz/src/pics/cr22-action-rowcol.png b/kwordquiz/src/pics/cr22-action-rowcol.png new file mode 100644 index 00000000..b115cd3c Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-rowcol.png differ diff --git a/kwordquiz/src/pics/cr22-action-shuffle.png b/kwordquiz/src/pics/cr22-action-shuffle.png new file mode 100644 index 00000000..d62dd92c Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-shuffle.png differ diff --git a/kwordquiz/src/pics/cr22-action-sort_incr.png b/kwordquiz/src/pics/cr22-action-sort_incr.png new file mode 100644 index 00000000..80f4638f Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-sort_incr.png differ diff --git a/kwordquiz/src/pics/cr22-action-unmarkasblank.png b/kwordquiz/src/pics/cr22-action-unmarkasblank.png new file mode 100644 index 00000000..0d5bdfd6 Binary files /dev/null and b/kwordquiz/src/pics/cr22-action-unmarkasblank.png differ diff --git a/kwordquiz/src/pics/cr22-mime-kwordquiz_doc.png b/kwordquiz/src/pics/cr22-mime-kwordquiz_doc.png new file mode 100644 index 00000000..6be4c1a3 Binary files /dev/null and b/kwordquiz/src/pics/cr22-mime-kwordquiz_doc.png differ diff --git a/kwordquiz/src/pics/cr32-action-answer.png b/kwordquiz/src/pics/cr32-action-answer.png new file mode 100644 index 00000000..a74209be Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-answer.png differ diff --git a/kwordquiz/src/pics/cr32-action-check.png b/kwordquiz/src/pics/cr32-action-check.png new file mode 100644 index 00000000..3424c990 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-check.png differ diff --git a/kwordquiz/src/pics/cr32-action-delete_table_row.png b/kwordquiz/src/pics/cr32-action-delete_table_row.png new file mode 100644 index 00000000..22d4c85b Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-delete_table_row.png differ diff --git a/kwordquiz/src/pics/cr32-action-dontknow.png b/kwordquiz/src/pics/cr32-action-dontknow.png new file mode 100644 index 00000000..3f1b4bed Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-dontknow.png differ diff --git a/kwordquiz/src/pics/cr32-action-editor.png b/kwordquiz/src/pics/cr32-action-editor.png new file mode 100644 index 00000000..92c642fd Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-editor.png differ diff --git a/kwordquiz/src/pics/cr32-action-error.png b/kwordquiz/src/pics/cr32-action-error.png new file mode 100644 index 00000000..3915cd7b Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-error.png differ diff --git a/kwordquiz/src/pics/cr32-action-flash.png b/kwordquiz/src/pics/cr32-action-flash.png new file mode 100644 index 00000000..cbb4bab5 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-flash.png differ diff --git a/kwordquiz/src/pics/cr32-action-hint.png b/kwordquiz/src/pics/cr32-action-hint.png new file mode 100644 index 00000000..cc64272e Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-hint.png differ diff --git a/kwordquiz/src/pics/cr32-action-insert_table_row.png b/kwordquiz/src/pics/cr32-action-insert_table_row.png new file mode 100644 index 00000000..49ac3c4d Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-insert_table_row.png differ diff --git a/kwordquiz/src/pics/cr32-action-know.png b/kwordquiz/src/pics/cr32-action-know.png new file mode 100644 index 00000000..f04442ca Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-know.png differ diff --git a/kwordquiz/src/pics/cr32-action-languages.png b/kwordquiz/src/pics/cr32-action-languages.png new file mode 100644 index 00000000..6647bf00 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-languages.png differ diff --git a/kwordquiz/src/pics/cr32-action-markasblank.png b/kwordquiz/src/pics/cr32-action-markasblank.png new file mode 100644 index 00000000..514b083a Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-markasblank.png differ diff --git a/kwordquiz/src/pics/cr32-action-mode1.png b/kwordquiz/src/pics/cr32-action-mode1.png new file mode 100644 index 00000000..3c4f2497 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-mode1.png differ diff --git a/kwordquiz/src/pics/cr32-action-mode2.png b/kwordquiz/src/pics/cr32-action-mode2.png new file mode 100644 index 00000000..9a9e1d40 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-mode2.png differ diff --git a/kwordquiz/src/pics/cr32-action-mode3.png b/kwordquiz/src/pics/cr32-action-mode3.png new file mode 100644 index 00000000..09e6ffd9 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-mode3.png differ diff --git a/kwordquiz/src/pics/cr32-action-mode4.png b/kwordquiz/src/pics/cr32-action-mode4.png new file mode 100644 index 00000000..30c643b2 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-mode4.png differ diff --git a/kwordquiz/src/pics/cr32-action-mode5.png b/kwordquiz/src/pics/cr32-action-mode5.png new file mode 100644 index 00000000..1ed133ff Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-mode5.png differ diff --git a/kwordquiz/src/pics/cr32-action-multiple.png b/kwordquiz/src/pics/cr32-action-multiple.png new file mode 100644 index 00000000..37209f37 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-multiple.png differ diff --git a/kwordquiz/src/pics/cr32-action-qa.png b/kwordquiz/src/pics/cr32-action-qa.png new file mode 100644 index 00000000..b102c66b Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-qa.png differ diff --git a/kwordquiz/src/pics/cr32-action-question.png b/kwordquiz/src/pics/cr32-action-question.png new file mode 100644 index 00000000..a5fd2a27 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-question.png differ diff --git a/kwordquiz/src/pics/cr32-action-question_mark.png b/kwordquiz/src/pics/cr32-action-question_mark.png new file mode 100644 index 00000000..bb83d8c2 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-question_mark.png differ diff --git a/kwordquiz/src/pics/cr32-action-repeat.png b/kwordquiz/src/pics/cr32-action-repeat.png new file mode 100644 index 00000000..69c60c8d Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-repeat.png differ diff --git a/kwordquiz/src/pics/cr32-action-restart.png b/kwordquiz/src/pics/cr32-action-restart.png new file mode 100644 index 00000000..851c5c38 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-restart.png differ diff --git a/kwordquiz/src/pics/cr32-action-rowcol.png b/kwordquiz/src/pics/cr32-action-rowcol.png new file mode 100644 index 00000000..a5fd2a27 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-rowcol.png differ diff --git a/kwordquiz/src/pics/cr32-action-shuffle.png b/kwordquiz/src/pics/cr32-action-shuffle.png new file mode 100644 index 00000000..32a112ca Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-shuffle.png differ diff --git a/kwordquiz/src/pics/cr32-action-sort_incr.png b/kwordquiz/src/pics/cr32-action-sort_incr.png new file mode 100644 index 00000000..5843d08c Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-sort_incr.png differ diff --git a/kwordquiz/src/pics/cr32-action-unmarkasblank.png b/kwordquiz/src/pics/cr32-action-unmarkasblank.png new file mode 100644 index 00000000..5aafb3f9 Binary files /dev/null and b/kwordquiz/src/pics/cr32-action-unmarkasblank.png differ diff --git a/kwordquiz/src/pics/cr32-mime-kwordquiz_doc.png b/kwordquiz/src/pics/cr32-mime-kwordquiz_doc.png new file mode 100644 index 00000000..14f5cb25 Binary files /dev/null and b/kwordquiz/src/pics/cr32-mime-kwordquiz_doc.png differ diff --git a/kwordquiz/src/pics/cr48-mime-kwordquiz_doc.png b/kwordquiz/src/pics/cr48-mime-kwordquiz_doc.png new file mode 100644 index 00000000..84eeae0f Binary files /dev/null and b/kwordquiz/src/pics/cr48-mime-kwordquiz_doc.png differ diff --git a/kwordquiz/src/pics/crsc-mime-kwordquiz_doc.svg b/kwordquiz/src/pics/crsc-mime-kwordquiz_doc.svg new file mode 100644 index 00000000..e4504e71 --- /dev/null +++ b/kwordquiz/src/pics/crsc-mime-kwordquiz_doc.svg @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KWordQuiz + + + + + + + + + + + diff --git a/kwordquiz/src/pics/hi128-app-kwordquiz.png b/kwordquiz/src/pics/hi128-app-kwordquiz.png new file mode 100644 index 00000000..8713c681 Binary files /dev/null and b/kwordquiz/src/pics/hi128-app-kwordquiz.png differ diff --git a/kwordquiz/src/pics/hi16-app-kwordquiz.png b/kwordquiz/src/pics/hi16-app-kwordquiz.png new file mode 100644 index 00000000..8b86f279 Binary files /dev/null and b/kwordquiz/src/pics/hi16-app-kwordquiz.png differ diff --git a/kwordquiz/src/pics/hi22-app-kwordquiz.png b/kwordquiz/src/pics/hi22-app-kwordquiz.png new file mode 100644 index 00000000..06bc0582 Binary files /dev/null and b/kwordquiz/src/pics/hi22-app-kwordquiz.png differ diff --git a/kwordquiz/src/pics/hi32-app-kwordquiz.png b/kwordquiz/src/pics/hi32-app-kwordquiz.png new file mode 100644 index 00000000..92eecf42 Binary files /dev/null and b/kwordquiz/src/pics/hi32-app-kwordquiz.png differ diff --git a/kwordquiz/src/pics/hi48-app-kwordquiz.png b/kwordquiz/src/pics/hi48-app-kwordquiz.png new file mode 100644 index 00000000..50d45633 Binary files /dev/null and b/kwordquiz/src/pics/hi48-app-kwordquiz.png differ diff --git a/kwordquiz/src/pics/hisc-app-kwordquiz.svg b/kwordquiz/src/pics/hisc-app-kwordquiz.svg new file mode 100644 index 00000000..27c11e0c --- /dev/null +++ b/kwordquiz/src/pics/hisc-app-kwordquiz.svg @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kwordquiz/src/prefcardappearance.cpp b/kwordquiz/src/prefcardappearance.cpp new file mode 100644 index 00000000..165abeab --- /dev/null +++ b/kwordquiz/src/prefcardappearance.cpp @@ -0,0 +1,95 @@ +// +// C++ Implementation: +// +// Description: KWordQuiz flashcard appearance preferences +// +// +// Author: Peter Hedlund , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include +#include + +#include +#include +#include + +#include "prefcardappearance.h" + +PrefCardAppearance::PrefCardAppearance(QWidget *parent, const char *name) + : PrefCardAppearanceBase(parent, name) +{ + widgetStack->raiseWidget(frontStackPage); +} + + +PrefCardAppearance::~PrefCardAppearance() +{ +} + +void PrefCardAppearance::slotFlipButtonClicked( ) +{ + if (widgetStack->visibleWidget() == frontStackPage) + widgetStack->raiseWidget(backStackPage); + else + widgetStack->raiseWidget(frontStackPage); +} + +void PrefCardAppearance::slotFontChanged(const QFont & font) +{ + textLabel->setFont(font); +} + +void PrefCardAppearance::slotTextColorChanged( const QColor & color) +{ + textLabel->setPaletteForegroundColor(color); +} + +void PrefCardAppearance::slotCardColorChanged( const QColor & color) +{ + cardFrame->setPaletteBackgroundColor(color); + titleLabel->setPaletteBackgroundColor(color); + textLabel->setPaletteBackgroundColor(color); + line->setPaletteBackgroundColor(color); +} + +void PrefCardAppearance::slotFrameColorChanged( const QColor & color) +{ + cardFrame->setPaletteForegroundColor(color); + line->setPaletteForegroundColor(color); +} + +void PrefCardAppearance::slotAboutToShowWidget(QWidget * widget) +{ + if (widget == backStackPage) + { + titleLabel->setText(i18n("Back of the flashcard", "Back")); + titleLabel->setPaletteBackgroundColor(kcfg_BackCardColor->color()); + textLabel->setText(i18n("Answer")); + textLabel->setFont(kcfg_BackFont->font()); + textLabel->setPaletteForegroundColor(kcfg_BackTextColor->color()); + textLabel->setPaletteBackgroundColor(kcfg_BackCardColor->color()); + cardFrame->setPaletteBackgroundColor(kcfg_BackCardColor->color()); + cardFrame->setPaletteForegroundColor(kcfg_BackFrameColor->color()); + line->setPaletteForegroundColor(kcfg_BackFrameColor->color()); + line->setPaletteBackgroundColor(kcfg_BackCardColor->color()); + } + else + { + titleLabel->setText(i18n("Front")); + titleLabel->setPaletteBackgroundColor(kcfg_FrontCardColor->color()); + textLabel->setText(i18n("Question")); + textLabel->setFont(kcfg_FrontFont->font()); + textLabel->setPaletteForegroundColor(kcfg_FrontTextColor->color()); + textLabel->setPaletteBackgroundColor(kcfg_FrontCardColor->color()); + cardFrame->setPaletteBackgroundColor(kcfg_FrontCardColor->color()); + cardFrame->setPaletteForegroundColor(kcfg_FrontFrameColor->color()); + line->setPaletteForegroundColor(kcfg_FrontFrameColor->color()); + line->setPaletteBackgroundColor(kcfg_FrontCardColor->color()); + } +} + + +#include "prefcardappearance.moc" diff --git a/kwordquiz/src/prefcardappearance.h b/kwordquiz/src/prefcardappearance.h new file mode 100644 index 00000000..14c1d70b --- /dev/null +++ b/kwordquiz/src/prefcardappearance.h @@ -0,0 +1,36 @@ +// +// C++ Interface: +// +// Description: KWordQuiz flashcard appearance preferences +// +// +// Author: Peter Hedlund , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef PREFCARDAPPEARANCE_H +#define PREFCARDAPPEARANCE_H + +#include + +/** +@author Peter Hedlund +*/ +class PrefCardAppearance : public PrefCardAppearanceBase +{ +Q_OBJECT +public: + PrefCardAppearance(QWidget *parent = 0, const char *name = 0); + ~PrefCardAppearance(); + +public slots: + void slotFlipButtonClicked(); + void slotFontChanged(const QFont &); + void slotTextColorChanged(const QColor &); + void slotCardColorChanged(const QColor &); + void slotFrameColorChanged(const QColor &); + void slotAboutToShowWidget(QWidget *); +}; + +#endif diff --git a/kwordquiz/src/prefcardappearancebase.ui b/kwordquiz/src/prefcardappearancebase.ui new file mode 100644 index 00000000..46762ed3 --- /dev/null +++ b/kwordquiz/src/prefcardappearancebase.ui @@ -0,0 +1,553 @@ + +PrefCardAppearanceBase + + + PrefCardAppearanceBase + + + + 0 + 0 + 606 + 181 + + + + Card Appearance + + + + unnamed + + + 0 + + + + cardFrame + + + + 5 + 5 + 0 + 0 + + + + + 175 + 100 + + + + + 175 + 100 + + + + + 255 + 255 + 255 + + + + Box + + + Plain + + + The flashcard + + + + textLabel + + + + 11 + 42 + 153 + 47 + + + + + 7 + 7 + 0 + 0 + + + + + 255 + 255 + 255 + + + + This is the question + + + AutoText + + + false + + + WordBreak|AlignCenter + + + The flashcard + + + The flashcard. Select Quiz -> Check to see the other side. + + + + + line + + + + 11 + 33 + 153 + 16 + + + + + 1 + 0 + 0 + 0 + + + + + 255 + 0 + 0 + + + + + 255 + 255 + 255 + + + + HLine + + + Plain + + + Horizontal + + + The flashcard + + + + + titleLabel + + + + 11 + 11 + 153 + 16 + + + + + 7 + 0 + 0 + 0 + + + + + 255 + 255 + 255 + + + + + 1 + + + + Front + + + AlignTop + + + The flashcard + + + Language or other identifier for this card + + + + + + flipButton + + + &Flip + + + Flip card + + + Use to show the other side of the card + + + + + textColorLabel + + + + 1 + 5 + 0 + 0 + + + + Text color: + + + textColorButton + + + + + frameColorLabel + + + + 1 + 5 + 0 + 0 + + + + Frame color: + + + + + + + + fontLabel + + + + 1 + 5 + 0 + 0 + + + + Font: + + + + + + + + cardColorLabel + + + + 1 + 5 + 0 + 0 + + + + Card color: + + + + + + + + widgetStack + + + + 7 + 5 + 0 + 0 + + + + + backStackPage + + + 0 + + + + unnamed + + + 0 + + + + kcfg_BackFont + + + + 7 + 0 + 0 + 0 + + + + TabFocus + + + Font: + + + Font for back of card + + + Use to select the font for displaying text on the back of the card + + + + + kcfg_BackTextColor + + + + + + Select text color + + + Use to select the color for text shown on the card + + + + + kcfg_BackFrameColor + + + + + + Select card frame color + + + Use to select the color for drawing the frame of the card + + + + + kcfg_BackCardColor + + + + + + Select card color + + + Select color used to draw the card + + + + + + + frontStackPage + + + 0 + + + + unnamed + + + 0 + + + + kcfg_FrontFont + + + + 7 + 0 + 0 + 0 + + + + TabFocus + + + Font: + + + Font for front of card + + + Use to select the font for displaying text on the front of the card + + + + + kcfg_FrontTextColor + + + + + + Select text color + + + Use to select the color for text shown on the card + + + + + kcfg_FrontFrameColor + + + + + + Select card frame color + + + Use to select the color for drawing the frame of the card + + + + + kcfg_FrontCardColor + + + + + + Select card color + + + Select color used to draw the card + + + + + + + + spacer + + + Vertical + + + Expanding + + + + 400 + 20 + + + + + + + + flipButton + clicked() + PrefCardAppearanceBase + slotFlipButtonClicked() + + + kcfg_FrontFont + fontSelected(const QFont&) + PrefCardAppearanceBase + slotFontChanged(const QFont&) + + + kcfg_FrontTextColor + changed(const QColor&) + PrefCardAppearanceBase + slotTextColorChanged(const QColor&) + + + kcfg_FrontCardColor + changed(const QColor&) + PrefCardAppearanceBase + slotCardColorChanged(const QColor&) + + + kcfg_FrontFrameColor + changed(const QColor&) + PrefCardAppearanceBase + slotFrameColorChanged(const QColor&) + + + widgetStack + aboutToShow(QWidget*) + PrefCardAppearanceBase + slotAboutToShowWidget(QWidget*) + + + + flipButton + kcfg_FrontFont + kcfg_FrontTextColor + kcfg_FrontCardColor + kcfg_FrontFrameColor + + + slotFlipButtonClicked() + slotFontChanged(const QFont &) + slotTextColorChanged(const QColor &) + slotAboutToShowWidget(QWidget *) + slotFrameColorChanged(const QColor &) + slotCardColorChanged(const QColor &) + + + + kpushbutton.h + kfontrequester.h + kcolorbutton.h + kcolorbutton.h + kcolorbutton.h + + diff --git a/kwordquiz/src/prefcharacter.cpp b/kwordquiz/src/prefcharacter.cpp new file mode 100644 index 00000000..7197b798 --- /dev/null +++ b/kwordquiz/src/prefcharacter.cpp @@ -0,0 +1,31 @@ +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "prefcharacter.h" + +PrefCharacter::PrefCharacter(QWidget *parent, const char *name) + : PrefCharacterBase(parent, name) +{ +} + + +PrefCharacter::~PrefCharacter() +{ +} + +#include "prefcharacter.moc" diff --git a/kwordquiz/src/prefcharacter.h b/kwordquiz/src/prefcharacter.h new file mode 100644 index 00000000..c863093e --- /dev/null +++ b/kwordquiz/src/prefcharacter.h @@ -0,0 +1,36 @@ +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PREFCHARACTER_H +#define PREFCHARACTER_H + +#include "prefcharacterbase.h" + +/** +@author Peter Hedlund +*/ +class PrefCharacter : public PrefCharacterBase +{ +Q_OBJECT +public: + PrefCharacter(QWidget *parent = 0, const char *name = 0); + + ~PrefCharacter(); +}; + +#endif diff --git a/kwordquiz/src/prefcharacterbase.ui b/kwordquiz/src/prefcharacterbase.ui new file mode 100644 index 00000000..7202c6d9 --- /dev/null +++ b/kwordquiz/src/prefcharacterbase.ui @@ -0,0 +1,409 @@ + +PrefCharacterBase + + + PrefCharacterBase + + + + 0 + 0 + 300 + 356 + + + + + 300 + 350 + + + + + unnamed + + + 0 + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + lblShortCutInfo + + + NoFrame + + + Plain + + + Note: Select Settings -> Configure Shortcuts... to change the shortcut associated with each action. + + + WordBreak|AlignVCenter + + + + + + Action + + + true + + + true + + + + + Shortcut + + + true + + + true + + + + + Character + + + true + + + true + + + + + Special Character 1 + + + Ctrl+1 + + + A + + + + + + + + + + + + + + Special Character 2 + + + Ctrl+2 + + + B + + + + + + + + + + + + + + Special Character 3 + + + Ctrl+3 + + + C + + + + + + + + + + + + + + Special Character 4 + + + Ctrl+4 + + + D + + + + + + + + + + + + + + Special Character 5 + + + Ctrl+5 + + + E + + + + + + + + + + + + + + Special Character 6 + + + Ctrl+6 + + + F + + + + + + + + + + + + + + Special Character 7 + + + Ctrl+7 + + + G + + + + + + + + + + + + + + Special Character 8 + + + Ctrl+8 + + + H + + + + + + + + + + + + + + Special Character 9 + + + Ctrl+9 + + + I + + + + + + + + + + + + + lstCharacters + + + Manual + + + Single + + + true + + + Select character to modify + + + Customizable special character actions + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 220 + 30 + + + + + + layout9 + + + + unnamed + + + + spacer5 + + + Horizontal + + + Fixed + + + + 30 + 50 + + + + + + btnCharacter + + + C&haracter... + + + Click to choose a new character + + + Choose a character for the selected action + + + + + spacer4 + + + Vertical + + + Fixed + + + + 31 + 31 + + + + + + lblPreview + + + + 1 + 1 + 0 + 0 + + + + + 36 + + + + A + + + AlignBottom + + + Preview of current character + + + Preview of the character associated with the selected action + + + + + + + + + + lstCharacters + btnCharacter + + + + kpushbutton.h + + diff --git a/kwordquiz/src/prefeditor.cpp b/kwordquiz/src/prefeditor.cpp new file mode 100644 index 00000000..2ff2a92e --- /dev/null +++ b/kwordquiz/src/prefeditor.cpp @@ -0,0 +1,32 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "prefeditor.h" + + +PrefEditor::PrefEditor(QWidget *parent, const char *name, WFlags f) + : PrefEditorBase(parent, name, f) +{ +} + +PrefEditor::~PrefEditor() +{ +} + + +#include "prefeditor.moc" diff --git a/kwordquiz/src/prefeditor.h b/kwordquiz/src/prefeditor.h new file mode 100644 index 00000000..762e4afe --- /dev/null +++ b/kwordquiz/src/prefeditor.h @@ -0,0 +1,37 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PREFEDITOR_H +#define PREFEDITOR_H + +#include "prefeditorbase.h" + +/** +@author Peter Hedlund +*/ +class PrefEditor : public PrefEditorBase +{ +Q_OBJECT +public: + + PrefEditor(QWidget *parent, const char *name=0, WFlags f=0); + ~PrefEditor(); + +}; + +#endif diff --git a/kwordquiz/src/prefeditorbase.ui b/kwordquiz/src/prefeditorbase.ui new file mode 100644 index 00000000..71ef99ed --- /dev/null +++ b/kwordquiz/src/prefeditorbase.ui @@ -0,0 +1,126 @@ + +PrefEditorBase + + + PrefEditorBase + + + + 0 + 0 + 250 + 256 + + + + + 250 + 250 + + + + Editor + + + + unnamed + + + 0 + + + + kcfg_EnterMove + + + Enter Ke&y Moves + + + How enter key moves + + + Select how the Enter key should behave in the editor + + + + unnamed + + + + optDown + + + &Down + + + How enter key moves + + + Select if the next cell below should become active when pressing Enter. + + + + + optRight + + + &Right + + + How enter key moves + + + Select if the next cell to the right should become active when pressing Enter + + + + + optNoMove + + + Does not &move + + + How enter key moves + + + Select if the current cell should remain active when pressing Enter + + + + + + + kcfg_EnableBlanks + + + E&nable fill-in-the-blank + + + Check to enable fill-in-the-blank + + + Select to enable the functions for Fill-in-the-blank + + + + + spcVert + + + Vertical + + + Expanding + + + + 41 + 81 + + + + + + + diff --git a/kwordquiz/src/prefquiz.cpp b/kwordquiz/src/prefquiz.cpp new file mode 100644 index 00000000..ebd62cb3 --- /dev/null +++ b/kwordquiz/src/prefquiz.cpp @@ -0,0 +1,41 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include "prefquiz.h" + + +PrefQuiz::PrefQuiz(QWidget *parent, const char *name, WFlags f) + : PrefQuizBase(parent, name, f) +{ + kcfg_FlipDelay -> setEnabled(kcfg_AutoFlip->isChecked()); + kcfg_KeepDiscard->setEnabled(kcfg_AutoFlip->isChecked()); + //optCorrect -> setEnabled(kcfg_AutoFlip->isChecked()); + //optError -> setEnabled(kcfg_AutoFlip->isChecked()); +} + + +PrefQuiz::~PrefQuiz() +{ +} + +#include "prefquiz.moc" diff --git a/kwordquiz/src/prefquiz.h b/kwordquiz/src/prefquiz.h new file mode 100644 index 00000000..baee69ac --- /dev/null +++ b/kwordquiz/src/prefquiz.h @@ -0,0 +1,36 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef PREFQUIZ_H +#define PREFQUIZ_H + +#include "prefquizbase.h" + +/** +@author Peter Hedlund +*/ +class PrefQuiz : public PrefQuizBase +{ +Q_OBJECT +public: + + PrefQuiz(QWidget *parent, const char *name=0, WFlags f=0); + ~PrefQuiz(); +}; + +#endif diff --git a/kwordquiz/src/prefquizbase.ui b/kwordquiz/src/prefquizbase.ui new file mode 100644 index 00000000..82cdf626 --- /dev/null +++ b/kwordquiz/src/prefquizbase.ui @@ -0,0 +1,295 @@ + +PrefQuizBase + + + PrefQuizBase + + + + 0 + 0 + 300 + 356 + + + + + 300 + 350 + + + + Quiz + + + + unnamed + + + 0 + + + + grpMultiple + + + Multiple Choice + + + Specify behavior for a multiple choice session + + + + unnamed + + + + kcfg_AutoCheck + + + Check selection a&utomatically + + + Check to correct automatically + + + Select if a choice should be checked immediately + + + + + + + grpQA + + + Question && Answer + + + Specify behavior for a question and answer session + + + + unnamed + + + + kcfg_HintError + + + &Treat hint as error + + + Check to count hint as error + + + Select if questions where the hint function has been used should be counted as errors + + + + + + + grpScore + + + Score + + + Specify behavior of the score presentation in any session + + + + unnamed + + + + kcfg_Percent + + + &Show score as a percentage + + + Check to show score as a percentage + + + Select if the score should be shown as a percentage + + + + + + + spcVert + + + Vertical + + + Expanding + + + + 21 + 31 + + + + + + KeepDiscard + + + GroupBoxPanel + + + Flashcard + + + Specify behavior of a flashcard session + + + + unnamed + + + + spcHorz + + + Horizontal + + + Fixed + + + + 20 + 70 + + + + + + lblSeconds + + + + 7 + 5 + 0 + 0 + + + + seconds and + + + Specify the amount of time between card flips + + + + + kcfg_FlipDelay + + + Delay to flip card + + + Delay in seconds to flip card + + + + + kcfg_KeepDiscard + + + NoFrame + + + + + + 0 + + + + unnamed + + + 0 + + + + optCorrect + + + Count &as correct + + + Select how to count card + + + Select if the previous card should be counted as correct when moving to the next card + + + + + optError + + + Count as &error + + + Select how to count card + + + Select if the previous card should be counted as incorrect when moving to the next card + + + + + + + kcfg_AutoFlip + + + &Flip card automatically after + + + 2 + + + Check to flip card automatically + + + Select if you want a card to turn over automatically after the given amount of time + + + + + + + + + kcfg_AutoFlip + toggled(bool) + kcfg_FlipDelay + setEnabled(bool) + + + kcfg_AutoFlip + toggled(bool) + kcfg_KeepDiscard + setEnabled(bool) + + + + slotAutoFlipClicked() + + + + knuminput.h + knuminput.h + + diff --git a/kwordquiz/src/prefs.kcfgc b/kwordquiz/src/prefs.kcfgc new file mode 100644 index 00000000..8a1e7d8b --- /dev/null +++ b/kwordquiz/src/prefs.kcfgc @@ -0,0 +1,5 @@ +# Code generation options for kconfig_compiler +File=kwordquiz.kcfg +ClassName=Prefs +Singleton=true +Mutators=true diff --git a/kwordquiz/src/qaview.cpp b/kwordquiz/src/qaview.cpp new file mode 100644 index 00000000..9e4deca9 --- /dev/null +++ b/kwordquiz/src/qaview.cpp @@ -0,0 +1,329 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include + +#include "qaview.h" +#include "prefs.h" +#include "kwordquiz.h" + +QString highlightError(const QString & c, const QString & e) +{ + if (c == e) + return c; + + QString s = c; + if (s.left(4) == "" && e.left(4) != "") + s = s.mid(4, s.length() - 9); + + if (s == e) + return s; + + QString result = ""; + int i = 0; + while (s[i] == e[i]) + result.append(e[i++]); + result.append(""); + QString result2 = ""; + int j = s.length() - 1; + int k = e.length() - 1; + while (s[j] == e[k] && k > i) + { + result2.prepend(e[k]); + j--; + k--; + } + result2.prepend(""); + + for (int m = i; m <= k; m++) + result.append(e[m]); + + result.append(result2); + return result; +} + + +QAView::QAView(QWidget *parent, const char *name, WFlags f):QAViewBase(parent, name, f) +{ + m_score = new WQScore(); +} + + +QAView::~QAView() +{ + delete txtAnswer; //Fixes #122110 on PCLOS and Ubuntu +} + +void QAView::setQuiz(WQQuiz *quiz) +{ + m_quiz = quiz; +} + +void QAView::init() +{ + m_score -> setQuestionCount(m_quiz->questionCount()); + m_score -> setAsPercent(Prefs::percent()); + m_hintUsed = false; + m_question = 0; + m_error = 0; + picAnswered -> clear(); + picCorrect -> clear(); + picError -> clear(); + + QFont f = Prefs::editorFont(); + f.setWeight(QFont::Normal); + lblQuestion -> setFont(f); + //lblQuestion -> font().setBold(false); + lblAnswerBlank -> setFont(f); + //lblAnswerBlank -> font().setBold(false); + txtAnswer -> setFont(f); + //txtAnswer -> font().setBold(false); + lblPreviousQuestion -> setFont(f); + //lblPreviousQuestion -> font().setBold(false); + lblYourAnswer -> setFont(f); + //lblYourAnswer -> font().setBold(false); + lblCorrect -> setFont(f); + //lblCorrect -> font().setBold(false); + + lblPreviousQuestionHeader->clear(); + lblPreviousQuestion->clear(); + lblYourAnswerHeader->clear(); + lblYourAnswer->clear(); + lblCorrectHeader->clear(); + lblCorrect->clear(); + + picPrevious->clear(); + picYourAnswer->clear(); + picCorrectAnswer->clear(); + + KWordQuizApp *win=(KWordQuizApp *) parent(); + win->actionCollection()->action("quiz_check")->setEnabled(true); + win->actionCollection()->action("qa_hint")->setEnabled(true); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled(false); + + updateScore(); + showQuestion(0); + txtAnswer->show(); + txtAnswer->setFocus(); +} + +void QAView::slotCheck() +{ + KWordQuizApp *win=(KWordQuizApp *) parent(); + if (win->actionCollection()->action("quiz_check")->isEnabled()) + { + bool fIsCorrect; + + if (m_hintUsed && Prefs::hintError()) + { + //Force an Error + fIsCorrect = m_quiz->checkAnswer(m_question, ""); + } + else + { + //Really check the answer + fIsCorrect = m_quiz->checkAnswer(m_question, txtAnswer->text()); + } + //Reset for next question + m_hintUsed = false; + + if (fIsCorrect) + { + + picYourAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + lblYourAnswer->setText(m_quiz->yourAnswer(m_question, txtAnswer->text())); + lblCorrectHeader->clear(); + picCorrectAnswer->clear(); + lblCorrect->clear(); + m_score->countIncrement(WQScore::cdCorrect); + updateScore(); + KNotifyClient::event(winId(), "QuizCorrect", i18n("Your answer was correct!")); + } + else + { + m_error++; + + picYourAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("error", KIcon::Panel)); + lblYourAnswer->setText(highlightError(m_quiz->answer(m_question), m_quiz->yourAnswer(m_question, txtAnswer->text()))); + lblCorrect->setText(m_quiz->answer(m_question)); + picCorrectAnswer->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + lblCorrectHeader->setText(i18n("Correct Answer")); + m_score->countIncrement(WQScore::cdError); + updateScore(); + KNotifyClient::event(winId(), "QuizError", i18n("Your answer was incorrect.")); + } + + lblPreviousQuestionHeader->setText(i18n("Previous Question")); + lblPreviousQuestion->setText(m_quiz->question(m_question)); + picPrevious->setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + lblYourAnswerHeader->setText(i18n("Your Answer")); + + if (++m_question < m_quiz->questionCount()) + { + showQuestion(m_question); + } + else + { + m_quiz->finish(); + win->actionCollection()->action("quiz_check")->setEnabled(false); + win->actionCollection()->action("qa_hint")->setEnabled(false); + win->actionCollection()->action("quiz_repeat_errors")->setEnabled((m_error > 0)); + + lblQuestionLanguage->setText(i18n("Summary")); + lblQuestion->clear(); + lblAnswerLanguage->clear(); + lblAnswerBlank->hide(); + txtAnswer->hide(); + picQuestion->setPixmap(KGlobal::iconLoader()->loadIcon("kwordquiz", KIcon::Panel)); + picAnswer->clear(); + } + } +} + +void QAView::slotHint() +{ + QString answer = txtAnswer->text(); + QString correctAnswer = m_quiz->hint(m_question); + if (correctAnswer.left(4) == "") + { + correctAnswer = correctAnswer.remove(""); + correctAnswer = correctAnswer.remove(""); + } + + int correctCharCount = 1; + + if (answer.length() > 0) + { + for(uint i = 0; i <= answer.length(); i++) + { + if (answer.at(i) == correctAnswer.at(i)) + correctCharCount++; + } + } + + txtAnswer->setText(correctAnswer.left(correctCharCount)); + txtAnswer->setFocus(); + txtAnswer->setCursorPosition(txtAnswer->text().length()); + + m_hintUsed = true; +} + +void QAView::slotRestart() +{ + m_quiz->activateBaseList(); + init(); +} + +void QAView::slotRepeat() +{ + m_quiz->activateErrorList(); + init(); +} + +void QAView::updateScore() +{ + QString s; + s = s.setNum(m_quiz->questionCount(), 10); + lblScoreCount->setText(s); + picCount->setPixmap(KGlobal::iconLoader()->loadIcon("kwordquiz", KIcon::Panel)); + + s = m_score->answerText(); + lblScoreAnswered->setText(s); + if (!s.isEmpty()) + picAnswered->setPixmap(KGlobal::iconLoader()->loadIcon("question", KIcon::Panel)); + + s = m_score->correctText(); + lblScoreCorrect->setText(s); + if (!s.isEmpty()) + picCorrect->setPixmap(KGlobal::iconLoader()->loadIcon("check", KIcon::Panel)); + + s = m_score->errorText(); + lblScoreError->setText(s); + if (!s.isEmpty()) + picError->setPixmap(KGlobal::iconLoader()->loadIcon("error", KIcon::Panel)); +} + + +/*! + \fn QAView::showQuestion(int i) + */ +void QAView::showQuestion(int i) +{ + //m_quiz->setColumn(i); + lblQuestionLanguage -> setText(m_quiz ->langQuestion(i)); + lblQuestion -> setText(m_quiz ->question(i)); + //lblQuestion -> setFont(m_quiz->fontQuestion(i)); + + picQuestion->setPixmap(KGlobal::iconLoader()->loadIcon(m_quiz->quizIcon(i, WQQuiz::qiLeftCol), KIcon::Panel)); + + lblAnswerLanguage -> setText(m_quiz ->langAnswer(i)); + + if (!QString(m_quiz ->blankAnswer(i)).isEmpty()) + { + lblAnswerBlank->show(); + //lblAnswerBlank->setFont(m_quiz->fontAnswer(i)); + lblAnswerBlank->setText(m_quiz->blankAnswer(i)); + } + else + lblAnswerBlank->hide(); + + //txtAnswer->setFont(m_quiz->fontAnswer(i)); + txtAnswer -> setText(""); + + picAnswer->setPixmap(KGlobal::iconLoader()->loadIcon(m_quiz->quizIcon(i, WQQuiz::qiRightCol), KIcon::Panel)); + + //@todo handle keyboard layouts +} + +void QAView::slotApplySettings( ) +{ + m_score ->setAsPercent(Prefs::percent()); + updateScore(); +} + +void QAView::slotSpecChar( const QChar & c) +{ + if (txtAnswer->hasFocus()) + { + if (txtAnswer->hasSelectedText()) + { + QString ls = txtAnswer->text(); + QString s = txtAnswer->selectedText(); + int len = s.length(); + int ss = txtAnswer->selectionStart(); + ls = ls.replace(ss, len, c); + txtAnswer->setText(ls); + txtAnswer->setSelection(ss, 1); + } + else + { + QString s = txtAnswer->text(); + int i = txtAnswer->cursorPosition(); + s.insert(i, c); + txtAnswer->setText(s); + txtAnswer->setCursorPosition(i + 1); + } + } +} + +#include "qaview.moc" diff --git a/kwordquiz/src/qaview.h b/kwordquiz/src/qaview.h new file mode 100644 index 00000000..9ba26fdf --- /dev/null +++ b/kwordquiz/src/qaview.h @@ -0,0 +1,69 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef QAVIEW_H +#define QAVIEW_H + +#include + +#include "qaviewbase.h" + +#include "wqquiz.h" +#include "wqscore.h" + +/** +@author Peter Hedlund +*/ +class QAView : public QAViewBase +{ +Q_OBJECT +public: + QAView(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + + ~QAView(); + + void setQuiz(WQQuiz *quiz); + void init(); + +public slots: + void slotCheck(); + void slotHint(); + void slotRepeat(); + void slotRestart(); + void slotApplySettings(); + void slotSpecChar(const QChar &); + +private: + WQQuiz *m_quiz; + WQScore *m_score; + + KAction* actCheck; + KAction* actHint; + KAction* actRepeat; + KAction* actRestart; + + int m_question; + int m_error; + + bool m_hintUsed; + + void updateScore(); + void showQuestion(int i); +}; + +#endif diff --git a/kwordquiz/src/qaviewbase.ui b/kwordquiz/src/qaviewbase.ui new file mode 100644 index 00000000..96baa0cc --- /dev/null +++ b/kwordquiz/src/qaviewbase.ui @@ -0,0 +1,869 @@ + +QAViewBase + + + QAViewBase + + + + 0 + 0 + 560 + 529 + + + + + unnamed + + + + line1_2 + + + HLine + + + Sunken + + + Horizontal + + + + + layout23 + + + + unnamed + + + + picError + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Incorrect answers + + + The number of questions answered incorrectly. May be shown as a percentage. + + + + + lblScoreError + + + + 255 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Incorrect answers + + + The number of questions answered incorrectly. May be shown as a percentage. + + + + + picAnswered + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Answered questions + + + The number of questions already answered. May be shown as a percentage. + + + + + picCount + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Questions + + + The number of questions in the session + + + + + lblScoreCount + + + + 0 + 0 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Questions + + + The number of questions in the session + + + + + lblScoreCorrect + + + + 0 + 255 + 0 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Correct answers + + + The number of questions answered correctly. May be shown as a percentage. + + + + + lblScoreAnswered + + + + 0 + 0 + 255 + + + + + 24 + + + + 00 + + + AlignVCenter|AlignLeft + + + Answered questions + + + The number of questions already answered. May be shown as a percentage. + + + + + picCorrect + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image0 + + + true + + + Correct answers + + + The number of questions answered correctly. May be shown as a percentage. + + + + + + + layout51 + + + + unnamed + + + + lblPreviousQuestionHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Previous Question + + + AlignTop + + + Previous question + + + The previous question + + + + + lblPreviousQuestion + + + + 7 + 5 + 0 + 0 + + + + This was your question + + + AutoText + + + false + + + WordBreak|AlignTop + + + Previous question + + + The previous question + + + + + picPrevious + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Previous question + + + + + + + layout52 + + + + unnamed + + + + lblYourAnswerHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Your Answer + + + AlignTop + + + Your previous answer + + + Your answer to the previous question + + + + + lblYourAnswer + + + + 7 + 5 + 0 + 0 + + + + This was your answer + + + AutoText + + + false + + + WordBreak|AlignTop + + + Your previous answer + + + Your answer to the previous question + + + + + picYourAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Your previous answer + + + + + + + layout53 + + + + unnamed + + + + picCorrectAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + Previous correct answer + + + + + lblCorrectHeader + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Correct Answer + + + AlignTop + + + Previous correct answer + + + The correct answer to the previous question + + + + + lblCorrect + + + + 7 + 5 + 0 + 0 + + + + This was the correct answer + + + AutoText + + + false + + + WordBreak|AlignTop + + + Previous correct answer + + + The correct answer to the previous question + + + + + + + layout54 + + + + unnamed + + + + lblAnswerBlank + + + + 7 + 5 + 0 + 0 + + + + This is _____ answer + + + AutoText + + + false + + + WordBreak|AlignTop + + + Type your answer + + + The answer showing blanks for a Fill-in-the-blank question + + + + + txtAnswer + + + + 7 + 0 + 0 + 0 + + + + AlignAuto + + + Type your answer + + + Type the answer to the question + + + + + lblAnswerLanguage + + + + 7 + 0 + 0 + 0 + + + + + 0 + 32 + + + + + 1 + + + + Language 2 + + + AlignTop + + + Type your answer + + + Language or other identifier for the answer + + + + + picAnswer + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image2 + + + true + + + Type your answer + + + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + layout57 + + + + unnamed + + + + lblQuestionLanguage + + + + 7 + 5 + 0 + 0 + + + + + 0 + 20 + + + + + 1 + + + + Language 1 + + + AlignTop + + + The question + + + Language or other identifier for the question + + + + + picQuestion + + + + 0 + 0 + 0 + 0 + + + + + 32 + 32 + + + + image1 + + + true + + + The question + + + + + lblQuestion + + + + 7 + 5 + 0 + 0 + + + + This is your question + + + AutoText + + + false + + + WordBreak|AlignTop + + + The question + + + The question + + + + + + + + + 789cdd9c59532bb996a8dfcfafa8387a3bd1a1068307e2c67d0003060366da8c1dfda031014f80070c1df7bfdfa53588b43114bb6a5777451fc2b5f9c84c494b6bd05a52fafcfbbf7ebb3e39faed5ffffe8fd1d88cefdd6feece3cfff62f3fe9f75fffe33fffef7ffde39fab2b2bbfa54fb5baf25be59ffff68f7faae96fee37b582ff43ae656e24364fc2ab747dc2bccef7d733d3fd8fc27cff98b941f79b6666ba7f4598eef79b99e9ba8cc7d1f3a19e99ae33aff2f8fd33338fcfee203764bce639333dbf254cfd8787cc78ddee32f3f85523335d3f13e6e76799e97a9f99c7efb73253ff23619eaf2ab1c8137a99a9bd57616a5fbd308b3eb8bd551eafbd67e6fe2d8e1f5ae3fec22bb1f4175784e9baf3ccd2fe11b3cc478799db379bc415b1277ebec2cf172d667e3ee0f8561b72bfb960e6fb632f33c9eb98a5ff0d66ee3fae26aee4feec15b3ccc70333dfaf02f19a8c77c6cccfbb1b66e96f1d7943ee8fb5cca4cf1366b1b736b3f43f63167be0f6d6b93d87f6bab62af79b3b66bedf9d64a6fe4e89e5791533d3f521338fc7dbcc783dde0bb3be9f98b97f87f6b896c7675bcc32bf1b99493f87c26ccfcfcc327fc799697c6366d187c98cd78b0131042c1a3fdebfbe2acf07cf2cf1e13833c9f72c4ce3b18ab82af6b69f19ef77f7c23cfe5766ee3f9c66a6f16d316ff0f8ef32537b15e2c62acfef0f6453adf27806cc72ffa3305f5f23aef1f316eda55aa97af2ffd817ae6ce0f802716d95dbdb14e6e72f99b9ff789c99eecf5ca1f95e6166f9e236b3e7f9bd4586f1adad62fbd7cc3c3fe64d98e3fb9099e5556bc23c9e16b3b4bf25cccf3f65a67878274ce3359ab82ef33dc94cf7bf08d3fd458f59f4ab33937ddd0ad3f301e5afc17cace17cfb5b661e4f7814a6f6c39b30cd4f6864c6e70b4f2ce335ab99a9bd28ccfa1831f378e2ae30cbb3c7ccfa0a1d615e2fb430df2fcfcb7cd2f359dee885c9be62102679fc3e33b71f32d3fdea8d99f5671a99f17ebf21ccf21d64a6fe68bca6c1f361ce8479fcb81ed4d7847d3f333e6f26cc3c3f7133335dbf64e6f1c6ba30db33b195ebc59d305fef328bfd0d32d3fd4fc41b3cfee25198ede32a33de6fa330b51f511f8d35594f946596f5e48d383f3f14a6e7d50333cb6ba7c2acbf3a33cb67f684d95eaf3393bde37c35acac078526de6079d5a330dbf736b1117d1c0873ffd3cc34ff0366b1b73b619e8f8bcc741de3312c37b27e1499c91e0f8539fedd10cb788a1761964f98fb73a79969feacf03ae97fc26cf87923bc6e707c67cc81fa731d61ba5f3784a93dd723b6155eef5685d97ef73353bc57c2acef01738d9fef6626ffd965361c1f5a99c9df27c21c8f313e6f3891cfdd31f3f8dd5098c66f22318c87eca12d4cd78b71669c1fffcacce32df63393feee84693cc55098e6435f0a537f4609537ff144b84af54e8b99e537d799697ebac2d49fdecf8cd7f50f61b6dfc3cca44f912f50fbfa2d333d3f13e6f6373353ff2fc2249f3bc84cf271ff8eed430f3353fb5d616e7f9299e22dcbeb78bed576665a1fae8439ff6932f3fc1468df66bdc1ebb73d27b6159adfd865667df83761d2879f6446fdbb55617ebec1ccf36d6f85395e4e8579beaf85b9fd2233d9d78530b5efce98591ffe5898eba15a66ca879ac2bcbe5432937cf97eb2079ddb67ffb812a6f1059399e4df10a6f1f913e2acdfd7cca4df4298f5dbcc4cd7f784d93f3a99693c5698e3452f33cde73a33db87f699a97d25ccfddbcc747d5b98fab7e3cc14af2e85399e1f64a678dc6666ffd48799a9fd6761eeff2e33e96b5f98fb3b17e6fe46cce29f0799e9f92361ce67b0fe31aec1f9a82984d93f683edc86e46fdbcc9cefba5b66f6174ff6e0c43ec28b30c7abc7cc681fc503b1e8d3b633533ce80973fcbb11667f7867f2072dccfec0e3177ddaa3cc24ef9a30f5aff632d37ad81466fb3fc94ce36909f3faf69a99c6b32dccf62ff2b1beddb930ebfb3133c5a37b61f6cf4166b2e78a30e76bbdccb43e9d0ad3f8f46d661a9fcc3fc70fb3ceccf6e34f3393bdc87c703c513f3293fdd684597f5e98f38dddcce40f64afceb3ffbbba30dbfb8b30e707e85f765decd1ad31b33d0661b6c76226ccebfd5b666aff9a99eddfc975c9dfef8579fe23b1e8bbe833b33ee25498ed6326ccf6d1cd8cf36f5785797d3099c93f9e99797ead16667fb91066fd1f67a6fe1f84d9ffce3353fed621f6e26f47c2bcfeef6426f9c6ccec1f9edaf3325fd10af37cdd65a6f66f898dd47f47c2ec6fa7c28d356c4f65b6783fb76fb87ef34d619e8f2762c7eb4da4f9f79efd31623de5aa46eaab26b3d8cf4498d7e3be308fa760667fb599397edc33b37ec28fcce48fabc49ee341b1c3ccfaf7381fce4b7da79e98a55e581766fdec314bfd169879fed501b131347eef33d37ce2755f95fa2adc101bde5f31c7c496ef778159fc7d83d855b83ddc4ff141ea2bd72696f63c3d1f24bf705a98edd708737b5de18d75944f11cbfa5e6c66a6f9e1fe72bcac324b7e83f13ad4247ec723e6c0fabd12a6fe6c2016fbf7bbc274dd61bc0b41eaa5f89019ed4d6d128bbf14afc25c6f5584397f5a15e6f69f9939be987b618eef5d619aafb8c3ccfeaf6e8903e75bf13533f9df9930cfff1633e747c665a6f8b8c7cceb57d814e6f500e58935912f3c0b73fc7bc84ceb8f63e6f868b785497ef39ad9e1fc4d99c55e5c66ea6f2cccf3b9274ccf47195f30d87e7c22cef3b12bccf1603d33d9fb8530e7035799c99e7e08737cf7c2d4bfda6196fae42633b5bf25ccf1a59a99c63712667bfe9199f2817361dedf1866a6ebf2bce49fadccd4ff8b30e723d3cca4fffc3cd76f4e98ec4fcb7825ffec67a6f61f84d95ece3353fb4698d7fb66661aff1a71647b569799a9bebb16e6f6595f91e737d2f508eb03d527642f51e271ac32f3fa68f785497f8eda8b81f3cfb09199fcfd4498eccb1e308bfe9e84793fed4a98f38928cceb4321ccfd4f85a97db7cdccfab387c26c3f2b9929fe3e0af37af99c99e28bc8c3f964d8ca4cf16428ccfe9adb637f6e08f3f827c2641fe65c98fc3b0c32a37ca12d4cf2153633c9df6716fb1a6426fbea09b3fd86cc745dda97fc699499eceb5898e4378799e9fa8d30ef07e5f1707ef122ccf5c74c98d617fb2333ad6f156192379c6446794d8758ec5dbbcc28cfe95898e5359949de1d61f6d756665a7f07c21ccf4e33d37aa784b9decae3617d9f09937cee3233ad471bc2bc9ed632a37cf64498f5ddcd4cf690c7efaad85eccec91d91ea3d4f3bb99497eb95feaf9fbcc74fd4898fdb19a99ec5de493fa6f35335ddf17e6785064a6f892fba7f9d1f5cce40f221faff7266426fd5784d93e5c665acf6e843dce8f5f63e6f8ae643e249e3f65a6fcce0a73bed817e6fd93adcc141fc4bea49e5cc94cf152ec43f2cd5966ca1f737bacefb7cc24cfa1b0a5f8b6ce1c797d90f98dac1fe93f72be799899ecbb21ccfe3acd4ce3dd14667fcdedd1f87c2f33d9e385308def74acd55ff5d166ee779b3e999df6fcf9257da12eff32497ee72392f85fd3de2fd08b2fcdefcf8ccefffdf4b24c92c551a67f7fd588ff52bdfcae749fde97fc27bcfbcfffbc5ebe21cde7f7995f27c95fa397d34f7ce82b2bfcfbeae527a5fb9be94547fcb780cf9dbe077ed0dde40bbca6646bd23df87b844f1fefef02dffdbdf4a2077a08a32bf0f7071ca102891ee173c75214f0f7027e4f92d2eff72845f1eb74ff2bf4a29ff4338c6e08bf3f27fd805443b49e24e1488fb33e489aa4a7899ec2e745cfe0f3cba4f965fef2ca923c9fbefbc62b4895fe7d4b3ae308bca9b77413feddd63ba82fb1b6bf875e3c8e78172449a36ee9b7d235cb1234e1df34fa3dd0c7be6e03bfe0bde9b983bfd5ba7f08233a44ebeac1c88f60c46dddd1c7fa449fea337dae7fe80b7da9aff4b5bed1b77a05febeaa2b709f85670ef5dadf2a1fdbd5ebba8ade5ed37518e98d6ee80da595524659e594c71fa7828aaa5077ea5e3da8aeeaa93edcdf53835f23c937f5f2d93af0be46f4c18bdbfa440dd5a37a52cf30ea911aab097e266a9a7f26f8b7b17a5133f5aaded4263cb3057a042b641dff89f5e61b7a81d655133edbd81bd720a08357b5a30fd5ae6ae917b5a7f6555b1da8437584e3959fe9273f1396aaa38e417f27ea549d415c6ba5f620f6a53807d1419d834f3da81fbf4e2f69aed4856aaa4b75a5ae4912750371e949bfa95b5da815b5aa2a6a4dadab2a8ebec63fcba590ab75d5401e83f41b461b65527468e921f471977c0924b1c66a65beada7efea05a4d95ef8fb9b9e1a6f8289a630772cc714c6f89524efb2903c5396076c0ee4b9370fba6eba10e3521e91a23cacb4a6fb6bfd0574b2ad2eb38f244b502049cff4cdc00c612c6237f54f652849631ecd93792269ccb36a98113efd62c666a22fcdd4bcc0aa2a7e88baf9657a818fba9af3f62ae8a46d66e6d5bc99cda40f18ddd6b7e458aa9f249969e25c74ccb66e981dbdcd7d3d7306f4adbaf57beb0bd8b048b2ae9dd9d547a665f6ccbe78489ee7e51ebfcceaea0bb23ce11d499ab6393087e608a2cb10a5e97f37b7fe99f525b5623ad0521b24393627386ab2ac8f635d98f7b988d0809f3a4b54c7a7a7f91a4437736aceccb9da03bf199a8ef9f1ddfd849f5af7a9a5a04fa0af0b9684c64d63fa28c73c97259db254efad94e2b5393197e64aed419f6915fe857ac1f524697a60ae412737e616d6f049ee79cad1956d25eb607135612d9aa659298f1d3c655e9f14d93a66d554cc9ada3160d5988363ec845540fd29bda4f5c443ec7a3355b0ae3396843451d20e4af2681e4bd652839f3ac407ca623aa6fe2e15c850679d512ef06eadf497601a660382d80ecfe8802a3e58d7fe441c03bda41ae3590788c2c7605d62377371b6a48d89a9c1b84fac32ab1052ad75909679d5b6c1465bd83b35b3f73876988ff7e89cfd4768621f6cd704c870a4825ba841177de75b7a7983b918eaa9eda907f2f83cf7f33109e5b07d15ecc00eeda37d52fba6679f75c78eec18b2940ae4cd9079da899dda173b3369fea7f6356974c19bf08a1adb997db39b98af49b59d2aba79ff753fa317bb059963b04dbb6d95c4e0d4a7ddb13b2c49ddee923e6ccbeed97dc8f48f6ddb1e98ae3db429baa60a6d986a1b884d5ddbb1c7f604f4750a79f3885bdcb2672579b2dd417be7f607d43b5b50c5eda0348f7f5c2fb8cedfda0bd3b797b09e94a20e4a32e5989a66f1ca5edb1b7d6a6fed0af4de03ab18406df91e7bd621a2a75ac7eb1758db57edaaadd8355a6db3ff4db3174e41c35355b5eb106daa7ad356215f4b55ddd1bc24efd27c271f4b198badd93af62a6b4a29f6d8064ab2e1b4b981fa057ccb29f9a0447dcce5b882a6bc0e56df4d679c754e376ccbf91c13252a4e733f472ee88a8b588f6e425d6af9ece04384ce7a591ab3f9ceb12bdc9d39e53c7ddeae7104a6e6eedd83ebdaaaebe1fd7dd0c700bd357d5e39974b12a4fafe0d25a37fefdcc00ddda3a19ca1867a696439d073dc937bb6c76e049204ac363ef17ed6cbe20af48cdeded7cfc92aeca11b9b82fbca2b226485d053d289a9bb89834c13e6cd2ef600bd2b90e410dabb03af4dba19c2e70d3d39ed3ef5dd8b9bb957f706d24cd167e633089c2db7e9b65cd36de3decef3c25817fc6559669024d111328801545a15b73317bdca365635da3dbb5dd78208d1c71d896c01dcd621acddc394a1ba3db8e7c8edbbb63b70877a13acf008fed6b523d771c7e88d8b192af6e84edc29e8efccf5dd3948236dd32ee28738b69819e01e17d8b71ee999499556152db99657c75c7bb81feec2f66c07ade75d1f65ddc4e473308a966eba4b77e5aedd8dbbd5d7fa187ca085997dd7adb85557410b9e2c91c5bb35f0c5a00bb7eecef2498899f788397f91792c3082c21ca47f5d0baadff5527532e15c10570057753595acab9b7796e287d8ffac775d1dfebee91a2eed69a4bd808e7df1506881344f6a1baeed416260bcc57576fae167a2d6bdb3695fed31adff5faffb73273f0fef398f36b6e77dd20aad20d9e7d157ed830f3e82246fa413b048d9892d6782bb7a0cf36fcd8e2ffc9d1ab1678ffcbd7f70039f66e100f2ac7ddfb391f3a30f199da9f9be3dc1dcf9d398bb542f5db42ecce8fc400ded06f65d8a2eb44e43fb431ffd23679ebb20c928efa8962366ca7537d596d7fe09aae109e66d2b6ae29ffd485fbb819ea94b78b6e507fa06ee186769dea3fe2edc3df613bdeabbacf725e7360b7a215df4b8966be96d77e9a718fdeb7359e416ced5a97ff133ff8a11c29187f36ef89c5e20162ad0c91be824edd2d4fda679b2677e0b5ab8f04dbf0d7e934608fdf91dbf6bda1f6541ebeef89699e92db4fc0fbe32bfee97ac4caad299a9aa9edf9b8fc5a00fc88653fcf2fb5ee9c2747c1b6b8c5dccccef385f4a12accbec80eeaefd41ca5730c3afe5952959da13acff239006da30d61ffaa3ac99059ff17ddff1c712c378cc9fe4c9592ff7ecc93dc8ea6ed433ca52ce95e8f760f75d13acf0644ea7b226effa53ac41a3b6fe0c2439079de4b854aa7e60f5756fee4aad40e55dd5cffe87bf5021af9465cd8cfda57bb587b8c6bce22a5c92ea433e96f50277a65a5b418edbc096176bc494b30cfc955d71ca95ea716ee75557fdb55ea3486047fec6dfaa0ee6074fa8e109d7644d96c7fb15bf0a7916b461c7e6ca0e209695f30bb1b2601de4632ee71438de776b5baa970790268dcef88adec04cb6a415cecf3b760876de3c5d767ab7ebaffd1af80f588e3f7357e0279d52a545b9e338c744c887fdbaaf1a8f6d1df91ae4759b1f64497d8e7c1d6226eaa53cde4ff592ae6e8295a5dfad4e3ba463555abdb8764af1be61dbbae7969ceffb53b096b4ef3f537d7de637709d9dfaad927d4a9b2897d90c3a249f4a6d253d1650252dd3cbd834608d19a05ee6b297e57a41ada51509f5a24f949acf8a51966461ca3ed9038cc0af1fa5c1e83c7397c1040b356479764996c6fb7fa1e629fc215469fbd09f878a783bb8e01773718a9c21e853f07ed6cbe771aca417c845d1d62d78be59a217e83fc45084bb343fe08d8beb49ca4a603d090662d47d69548d0f717612eefd2d78fe991deb1d95fa847fcdcc68d64bf6d2f0801a1c9b1ba8638ae56bff52bda4fa7a84bb4767ca2ecc0fca62fba10bd5ef618a27304fbd854ae19ef22edf4c92845e96a4516a094719ee43df43a5a5ae30d788b8276aa19a1b925d2e78e9c4b4c300f4d7fb19bdc0670cbf37c3b0b47bc4b2e028aad69a0da87e1d647abd0fadeee9639004a30648b2fcec02ab9ef0e86fc2939e9d5205edb1e6ec391b9e31d3c915265b27e44cfa3a8c502f059e557f585fcaf10075d3c3391aeae00f955f8826948975c258773042f4b1d23ac4ac6797d6785d87287c07d98aec8ccdefeea79dcc51ca7dc3244c93cfe18e04d802546acf58dbb4f52544be69cecab3fce6c25da4350d7dbab9b4de9775259d90caef1e23f3d5125930f218056b35546a6a1b46e0796f719c4efafc637831ab3816c9a6cb3b97f0df3003eb7a0d6ffec2a598b4abaec2a64e27136f58338185862d88ca597fef3fe05d6f29dee158c3b27d98520d48eb4ac49db522cd0fef86cddb39ac6ed6db6485ebec1f43b51b9ab85f5387decec3fd872ae4ddebd35e5af2b8ed005e1e76310e0e5127add0c2196cbb2b96654133e05f7bba8333fdae17b55c2fa7725290d6fd94c15c81bf7c94650a3db5d559dab9c65385b40397768d9a6acba8b08f19e418d7938f7522b551471b8bee0256e32da85faaa0df54fbb4f49b3a4f6bff72596066db600fc913b25e3e896392dfd2bb13492fd76ab64c16756483ae40cfeb29dfc2ba1d2a64b30351f88ebd9664988f5d8bad802d8674627b8deb513aa14a33b2edcfec24dbe89c2cf6016ad836ceb8f99d755ff263ac2d41ee3dd3577149149a98ba8db0babd254f4fd601357bd335d27a82d94a9d776445a277fb7a8f6994957542347db78f27ae23dc6d8248609be1c0c85ef39c6d9b3b5f408ea8b24f7f9e278b5efa6835333d75dd7098bdb71c4f27b6d02770df21dcd7859174a1ced1e188b3faf9dde5f92af13dc6d671153e0a8ffa02aab023f0fc11e50bfa347430637b7f8af7e1c37138b1b729abfcdd7c4cf4922a2a0bd5e8a65e09a71f6bd6741e67eff40d58d62ed87a1f3e47ee0afca44392cc9dc62ca978b1dae68808bf8fcd249c857375ce3369606dbfc43a765116c8cd61764794ed2f4ab25c2fa469f4ae93f003b3891a451ff400944505d77111f7be863afa81bb4e7e621e21de966d9c6dcc9e6116572b6966ee54c08fc245b84c3523e8662d0cec832a9fb6d5f833f67d358488d45b7e36f65eef2ff84bda7b9ab941b8f25c8bf17eb8ec608fc2b5ed710dd90d37ee26590c67d10d5e235937784e9cf606cb31ed7dc549d6340ab750b7a4d99b419e5ce7955264a9f3e725ace813bbf2d9fb19a57a5fe533db1e566356b7ec38ac622d26a712623bd0bf7d0915d74c7b91a7637710d6d0c21e5956b49dec17b032e23e77f9c4752e96a45ad9e85031bdb06e5aa12ab6f02e4bdabd8091b421f7ae2d645b0b7a59d807ece2c9cd7dca59554fbd66dbcd63081085eccc5ab50f3e9576ea0e83b12f698f855615b0c231eb02636f688406d6c8efb3321719d33e86bd074bdbb0abf079c815f2bb8da538f10afded71fe27d5c9927c8ceb157927f20e3ecff8eed12a38c5a434a3d90f4c2daa689c49efac98ae3ef6dbd1e219de98f79fa44aa946e756c34ef449d6a5bb125c69428b21c6b0cf3972d922715f2016f6586fd1f98ba653e0e607bd485e6359cee4f90578f435d4888378c7bb0e224d836912efe343b84cfe029f7dd7f00f7e84e7cba59a11b28ec7d8d5a7aeeb2e42e41570f187e61d34197bb18f7ba40be72229f285fb383055732dfba29c937dae97b29c3e0e419a1773a38ed1621a658fc1a836b26bce810efb5045bd982e440a132638fb1c45cd45e8c747c8855fe393af84364873b4ac02c0483ea5e852daa3798f12492bcffa26d4a05e6a67fffe4a2ff3dff0e8c711e449033305eb382ac94271f9d1a43d8d0e78632b8e21ab1ceaa7387103f7ea9f0c9dd04da83ee1757aacb7e234be84c70fef94899da573e8ad92a6b2d6d0ebaa607eb3f80ab336c871cc7eaa97c58a4a62c59e9b266f04ffe4b88c1641b33531a76e687fa82b5867bc5ed36f1051b7e31beea3785b84a9493e67a06e74a9760ce7d6c5cdd21ecc475b5b6e831333b4135dc715bcbc9338f716fd37ce2b838f712bf923ef5b90fdd624db753ffc4d6cea09d8f1014893ce52aee2b65f8fdb50516d6104e9427d32d455c850ee7525eec4ddf7dad96f2d19fba2dec097620bf2bf2664b0b2c39bce3ecbbb8bea5be7954d75a6da710fe6e6399f5d631c208b80e8f366276e456fab5b7f0db959e10ee37e6c070575fb38bdef8a39db35643a69a7f5281ec443ff842bf0576ffebd7b4ccafe66f128767036e2fcdec4a7f9d872bdf4424dedfb5bac794bd56179dd8ec7f1c42b5c6ba0c684587364bc6be14969dacd4d99fcb3dac5dd3fa84fc2a51abae46be30fbb60cb254afb623d68633d0eb1ae9a3b49d41fcec5be94a665dbde41345b7c0391ec2cc5e81757f1c6f720df6d512d82efecf7c0539fd25b74f0b76a922665a2d0de96aed81388df75ac0f9e968c7e2e9ec5d378e60a3d8e438846adf9f39d9fd48bf36d7b18cf21afeb6409debdb446f916c4ae63a8696e60353bc29e867c8af48cef2e57cd2ed6f20e4f37945d7136fe88016ae929e7ac1f7fe41da6a37801b1d0266f4f756c39327d5ebf7cf28111b9335d8fdd7899f7eae7238eec113bff14aff425f4bc871eda572dd4d16e3e01f7b8ef36d04518c5eb78136f4bf3ff513b204d5c89abb1a23b29fae2e8efff9c5e606d18f863d7886bf836cca434fa77ff4de78cc9b2db71dd4fa0b639c137dd0d46d1b7e4b1f87e2be4de509facd99169c52a642cb5a5924ce6fe7b14ebe05fd656e1f998df8759f256dc37dfeb7b5437b1113720b9b92bd51fe59edfa3e95859b759a8f8682a66660e1d7e274cefd8b14f6ff7ac421e5cb1d3c2c09a5555931c3f3efa496ed3d4ec4b6121dbaf62b634942c78d1d2bef59e529a5f650fcd9ad9281cbf9b48d98cbc5352f6a3b482d6cd85695b55783b743513f5953fd457f1ae0846bb4d90a22323ceef597e15c720e6d9bb229a07888b43b7ce3b7d61d1d2be15c7da98f7bcea9ebd288ae20ea3e9fb5ecbbc2c1ca5e907ecee451d994df8b980acb3839a288fbbf6850cef3f294f1841bdd476bb30ab74f612e6de8ffdf6fa02f6bdc2ef1c19db345721528581757b39375facb316b344f1e85ae95dc60fdebe34574b6f5fdd878e392ceecbdf97f903eb4b281ee80d2a77660f6cb3e8fa0d7b85edf7f31b57f37dcf717ab77a218e7f9458febb743fcde0e999f2450f7ce6b17c3af27371ec740c95d6913d4ae72c491a6d8a7ed8b25d3ebb9e2cab13d99fca6beabcce3ecf5e3ef9bb49f965ad1814c3d2fefecfaf2f0a4ff2f0bb454ea5154bed4018d9291e6d0bedffeb37f853e5dfe0f744bf9602afc6954fa2344862dac513c442fcde93c4b19fd54bf1ac76528e95b2197f623ac50856bca6991663bbbebcb6fa9d999ef7fe5a9631ad25abfcad933939d408f412c2b54eef0bd2faf2e1edae6feae5c379649a17d72c26eeca05f7f4bbd22c4ab0284b8dbef70379d745acc47af9cd5f853bbeb8065fe03bb1bdfc7d98cfdfebfb3a8b5994e41ee2c98ede537de38ba9bd7427ce73dff3bebb2cdba92f4884ebab9d99463cb3cfbe9272e854df4055dac3ab2f20c9d81c401e8e6fc52f1bd39fd04b0bcfb12ce4bbfbfe0ca274a5782966100bdebf0383efc69aadf0f0e16d5dda9fade37e17650955338cad78647b900b438ee06c38b177f856c1d8d4c84f40929e6daa737a9f7671967fc65fe625a26880dfd7db867578d356cd9a1b985ef11af6d571b85fa84a964505d967192b179ffd1354bfa7319d108dd3b981adaad322a234633c5178f053af6c13a2b14a6fb17e3ec63ff23d3efd84fb9a057e671272027593def38fd3e2cd17c566d8f797f9bb6f8bb563feee9b3929b68a66b1ad6f8a1da8e39b50dfa44a2bd5f077b66a7b6a58ec16ada4133b4d7e9276ce934ed249d767e3fa43dfafa4a8d8c26fe0ce20629fa7f364587ff6403fb350b857eb7cdd3442003b6fdb077311eec3bdb980dfeec2b11df87e58f16fa1b0c7a61a6a60a9365570a9d2e2b7810a68b7026bfc1ec8fb847b952f388343ace4fed4babff8b15bf89eacc577c5c0dadcb63b77eb5043f68afdf8a467205553b76d539f424e3cd0d7ee0246bea7daee223e822facea1bd37333d7b42bf46e008cf40ecfad5b78f2dac5df1ff476582f862ee2ae6b777126ff701cfb686569bfb9cfdf6e8fa417fa1e44fa9d7b809a076c7c3f8c5cd33fdab6834adbc2efe129d4f8bd7219119d96f4b0ca4adf214fb9f030ed20a691eb16fe4bdfdc4eefd9de7f8c487f5c2f9f44ebf7bfd1db37f96debb959a0b7af97b5f5e1adc3257b764bfbff53fef29524e9f35a9226bf53b418d997db3c49c5fb91737ffffdff6f8c3fa3972523a36f76cceba2e0caa9b9e43d7c791f93f6204bfbda5c69a9d21eb7d54bdeb12c7fbebfee7fa197c5bfcf5911fcde943a70d90cc81ee45c5ec19516ebe3d7e96569ad501ed5c29c7d66451fff4e12daafacef9bb6f14dbd7c56f9945b9a3b1ff89e24365bde127dcde9e80b897e3a8e7de6e15f59df173d2eb93e5f8ba47bd74bf72feb37b71b8745fb97eae5631c9af7d24f4753be7f2eaa97dafc6216e09ea20d99cf1fc8937fefbe5ff5f96e7fbf66ddff7b7efeeaff5fb8ffcecfff2abdfcbffff38fff0ff70d099f + + + 789cdd9c5b536ac996a8dff7afa8d8f9b6a3235b1410e2c47940515054c0bb76f4435e270888cadd8ef3dfcfc81c63a413c455aeaa55dd15bd0d6af9c92433478e7bcec9fef77ffd76df39ffed5ffffe8fc9544dfbe637d3536fbffdcbce46a3d57ffce7fffdaf7ffcb3b0b3f35b78952ae5df76fff96ffff8a758fe667e133bf17f91ab892b81d594b980ef2f888b78bd9289f1fa09335d3f27aed0f5c789f1fa3d66bcde9e27c6f7793d063fef5f12c7f735cd5fa0f5db3a31ad4f9f44aea4f5ce12e3f847cc38bf7b4f8ce39f12f3fa45627cff8e993e7f9118df7f21a6f5db8bc438ff9c99f6ab82ccf2b883c438de21338e2f56c4249f20f90ab45e3d24a6f98d0e0ca3d17cae8dccf36563667cdf0c88797cbe9ec6171d621a5fd59177d99e3c317dbe6789e9f32eaebf50e1ebd53d315def9b89515e47ccfa50c4347f16f77b37cda70bc4bc1f2362ba5e64c87bbcde7762fabca910b3bcfb91ab7c7d364f8cfabc22667b3b27e6f90f88697ee7918b349e89d7ef15f87a352066fddd27c6f9ae91f9f3a29718df7f23a6f5d851e2f8be3f62267d2f89697e1bf5b597d6a75bc4bc3f2631eae78299ec794accfbd74d8ceb5b10b33e4ce2f87e86f2554b255a4f8c1fc5027fde4d88793ff713a37c17ccb81e6d904b6c6f6789e3f5e68599d65f23a6f95d3571bcbe2789abb4fea7c4f17dab90f74bb4bf31de15558958bf12d3f566c14cef5790cb05e2387f69b764d1fffd09f36e35ae6f8a5c2ed07827ccf4f91d629a3f5389f1fa3be65d945713937c9e3f6f493fcf91617d7b8538fe2e31ed8f3a64a6f85e232679459919dff77bc434be7f60a6cf1f26c6783860c6f52a5cafda2779cd4162bcbec68cd7675d62d6ef2831cedf63c6cfbb9bc065d88f3ddc6f454ceb71c7ccb47f1d66dc1fff96387e3e6b20f37a5531318e3763c6f1ec1131adc7ef32e3fb3d474cfa726566ca178a99ae37c46c4f38bfe2f8252c31c7af33e434ff3b33da9faf31a3bcf68698e6778fcc78bd382026fd6a9118af1f3293fcf78971be297285f64bdd30d3f5d17ff6f7387e65c7c8e9fd65e2389e62a6fdf4f789f1fd07625a7fb6604679b3b85ffb3ac5b37e6294a7c84cf6a990d37867cce44fcfc46cdfaf89f17a5c9fae92fcd91d33addf258ed7eb3e338d1ff375652fbdffc68cef8b2131c9afdf99f17dd727a6f5ab1633d9bb4f8ceb8dfe5bd1fb1c3f703c5d2579c41b335edf53c88af573c14cf6d54c8cf6704accf6586726fdf413e3fb717f211d51bc544fcc14ff3531c52fd520a67865aac4248fde43e6f56625669ccf9e10d37acc4362dc5fc75c44fdac88157d7ec85c54717cbedee17ce69619af179219c7331364bd4bf1c13093bd9413637c7b66267b78212e533e9e27c6fd23f9b4a2f1ef1363bcb864a6fc83fb6d787fad26e67c3024667b2933d3fb7789317fed235739ff3599f17d3b65a6f88ffb61787fcd9898f6cfcc9971ff541f19f603f7f78c19dfcf0a89a37e6c8b98f6abe713633c5830d37edc30e3fae41d33cea70c33cda7994bd8cf9d10d3feab9dc4a89f67669c4f9e268eef4b9e5f917f3d248ef3cb19b1c3f1652d317e7ec54ce31f24c6f9df99513e739518e523790dd9a71c27c6f107cc34fe3c31eea724a6fd16c78931ff3d32937f1f11d3fed8e8afaac8f6e217cc942f268971bdbbc45c1ff0e7395ede3297a33df819f3fe5ebcfe8598f2a36d33e37cfa1e59efa27e7d8398ecc19e31a33dd8f43ed99f60c6cf674b62d2b72e3253bdc2e3b1be1f9869fcb7c438fe3e338e6f7688c91e6c8199fc759c18fdb3c54cf3dbc4187f7acc688ff22a31fa679919d7e7d2f8b4bef4795c9f257d25fb7a4f8cf69531937dd513e3fb27cce49fedc4b89e3e33c5cbe7c4b89fb45eb64f6913e3f88299e6d789f1fd2366b28f4562cc678699f26f2531e653da0f43f1419e27c6f127cc347fba9ef4d565a6f978bd142f3cef07c787b3c4f8f91b66f22fb44753e5fa551053fc772d66b28f4366f22766ae1f9f98f17a3140565c0fa9c4e83f5564b62777ce8cf6e4cf1263be45f90ceb5f7f30c6833133c5eb0233d9a7488cf6d96726ffc98849fffa3231c6cf3233c9779a18e34d8399fca59b18d793aea77a205d4febe93093bfdc11937d189687ede32531e6e70b668a97ef89d1fef798a9fe1c27c67c7ac58ceb933b89717d33665c9fda27267bb37b89311e5f3353bcbf4b8cf65e6126fdf1fe53bc311789b19e7b44b6142fac6726ff386226f9e3f5bac8fd859810537ec8a6cc946faf89b91f6812b33d9f23572ddabf1d33633eb1afc8acdfec9298fdf58a99eca1c64cf6f096388eafcbcc947fe689d11f1e88693fb56626ff7864267d5f27c6f947ccb4de2c318e2f902dfb578799f6ab9b18e563267f70d11eb4e57ced717cabb8debf2476b87f6688ac499f421097f17d8dfab286f289bf41b6e43f3efab32971ff632e91793efb82ccf5b5b1ccb43f89a93ea825d6713f98c9bfb36a62946f9f98f36986ccf14a14912df9774f13937e6db40f6339ff6712d9eca2bd6503665c8fee11733d72c98cefdbd89fd812f733fe38711c4f1c22b37d66fbccd40f25a6cf3f31e3f86645ccfe3b64a6783262c6fdf40564b617b14b4cf9d8df26c6fc2499493fb47ecbf5b54f8cfedf21e6f873c94cf127d687d6b17caec94cfef79a18fdfb9998fc43f3f50ee55707cc95285f564466ffd03e31ce77ca4cf9e881993eff9a388eefcf89b95fb963a67a6e9418e3e92d33e59ffbc4a8df1e33c5978c19e7170d62da5f51488ce31f3253ff2d13e3fa4e9829fe961363feb966a6f38ba3c4f8fe9498eb9766629c7fc94cf96f9118f5ffce4cfdcd1333da9f447b768eebcf51621cff8999ece536318edf63a67ae63131ae9feccb71fff39018e3d90e338d4ffa71b4bf59ccafae6ca93ed1e7cca81f5324a6fce22789d19f2f99d17e748798f5d360a6f3ac47668aff27ccd4afb49869fec3c4e8ff67c4a41fdd65a6faa99418e3ef0133e5a759628c378a99ece32a31c68b57665aef2e33ea57dd26c678cdfbe768bd53e4a4ffe7c4a8ff2133d9974b8cefb79869fdf3c4a8ff0e33ae5fb513a37c4b668a37c7cc18dff50333c943fbc9f6244de2b89e2ecbc3fd8a4a8cebe5f1a95e35edc498ff66ccb4dfaf89315eed3253bdcff273ffd2488cf379665a4f3f31be5f64a6fcc8fb4bfe2e6e9829bed413a37fa03d38b6076f99293e4f12c7f5ba0133dab3ab33a33dbb4262b497f47eb518df7f42667dbb9dc4a8cf0b66aa070e12a33d3c32d3f9d54b62dccf6b66aa6706ccb81e5761c6f5184fcce7554789f17e58c64cfae5f9391f5c26c67a81e7e3f38b2233eadb9498d11eb355628c2f37ccb4de2e31e7e35d66b287d7c4680fbc7f1c8f2a89d1df797f285fc8341ee93f8d47fe3462c6f5cb2a33f9533331ea7b8f99f21fbfcff9e52d31d6ab8e99eab93133f9cf3231d6439699ecf38a99eab953644ff125f3ccd41fc778e6cb493f3b89513f8219d76f578951be0e33d9731a4f99b8fe1631ed9f9b27c6f11d33e9ff3631d63f3d669c5f9512a33dbc31e3fca24e4cfb639f98a9df2c24c6faeb9499fa83c4245f8519c7f7d5c4513e6b90797fcd3333d9d71e33f50bd789717d1933e5db4e625c9f64a67a8de4f7dcefaf98a99f8af9c57be85f707f6bc8dc0f78bcdeb37efc01b38ef2652362a56d64b407cfebd147ccd44f2c98697f74e2387ef646ccfdaa61c6ebbb5329feaa97546bbfebf04a6ca4a5d72f992bdad65f26c9efbc5812fb6bc6fb057ab1b9fdfd99d5d9bf9f5eb649b2b9caf0efaf5af15faa97df95eecbeb82ffb80ffff99fd7cb37a4f9fa3af5eb24f96bf4d2fdc2877e64857f5fbdfca4747f33bd481fffcde0d5937de0273908be40392559931cc2df3dbc46f1fa0170efefa517f92cc7b0ba2cfefe14572840a217f90a92a11419fc3d83df7bf037fcbd1fa5c87e9dee7f855ee49b9cc0eac6f0fb24e807a41a47eb09124ee52ce903a5097a9acb05bc967205af5f26cd2ff397779264d2fdf08d77902afc5b0b3aa3087c200f651dfe3d92c7515f6c6d7f0fbdd8b8e206481256dd94b5dc7b9a24a8c3bf61f527a08f53d9025ec66bc3e7cefe5679ff1c56741ead6b082bbf8015b7645b7664575eca2b792d6fe4adbc93f7f2413eca1d5980bfefca3d59846b3d7caef4b7aac71ab22cf741925759915558e9a390420825b430c20a277cfc7122133dd1174f62208662249ec518ae1f8a975f23c937f5f2551ef8c81123f0e296ec8a57f12626620aab9e89b958c4d7422cd3cf22fe6d2e56e25dd4c4813884cfd4418f6085a4e33f916fbea117185d1cc1eb38ce463d0844d4770196259ae2442ec5a9688933712e2e443bae977f965ffc2c48aa8ee882fe2ec595b886b8d684f16e20f6853807d141dc824f3d89bb5fa797b057e25e1c8907f1287650125180b8f4266b625766624f14454994c5bea8c4d557e967bb14f4ae924a449e8bb6524a2ba32c4487a61cc31cbde04b2089564e0ae57fb55e409ae38dbfd7e44265aaa7faea490d488e25a4f81f49f221699487fe166d0ee419aa91acaa678871a18e08511e32ad7afeb5fe023a39160fc947c0b260b6851aab17f5aade602d643769753ffaa9aa899aaa296967a6849ac74fafd4422de59d5aa977c8aaec875137bf4c2ff0128f6bdebe0f3a69a99a3a5087aa1ef401ab3bfa961cdbf50392a9e3e8411dd500976cca239a6b4215d0b7fad6efe517b06196a42c8d3a9117ea54b5d4197b08eff3171ebfc5ea922db22cd3784590e65c5da8b6ea407419476946dfadad7f26bf84515417466a812497ea2aae1a2debb3876cec7b3e22805509d422d8988c9f5ea61120baa96b75a36ec529f8cd5875d5dd77cf137e2aefe3484e7661ae7b92043d00d7f4598e75ce4b8ada11b95172f15a5da907f5284e61ce90857fa15e623e099a7e563ba09382da851cbe48332f29ba92ad241d6c6613d6e2b1da5bb3b6e30d7d6264eba8a22aa9b268a87d58f99863276401f1a7f412f28985d8555315b0ae1b94843491d74e9064a226396ba9aa2a24a43a55311d2d3fa4029924e90c6b810f6bc5bf645a68a5356464dcd167ecf820affd8938068b0e3dc6443a88c297605d6c376b7136a78d85aac2be5e69a38ada6aa7bd323a1367baa7fbfa490fc4bb1ec6b587fd48d199fd27d1428ff4b3ea4185a362af9a6df6a09bbef32dbdd4602fc672a1c762881e9ff67e3d264539f40bece8ab7ed3133d152d35d633d9d673bd802a650feae6ae5eea957ed7357da0c2fe2ff561d0e88637c577c45c1fe8ba3e8af51a77dba1a35bf75ff3337ad1c750393addd04d6d38068739f5893e4149609a53d4876ee9337d2eaff4856eeb8e7ad65d7d09f573e8d0c6a1b781d834d057fa5adf80be6ea16e9ed18847fa2e274fb23b18ef5e3f40bf73085ddc7194e6e58feb25e6f95dfda85ef40ee4935cd409929056a2bfea82ded5b0f7baa84b30fb10ace2197acb8fd85386881e7a1d2b9790db777559efeb0a66dbe47fcbe4854bd0f0327c8503a24d451e1809f55ae8ea2ed625f990e63bf558a8588c302ace4ad1281f7b8c0e921863ac2a182733e34d7a458946b196a30e1aeb3ac8be07a667fae64948dd32038e89292a2ed33c6d33947b6614fbd103e84b35dd3bf814a1935eb6c66cba72669ecd585d539dbe6ed71895abe6c5bc9a3723cd245e0ffd3fe80425194277f090ea87d0dfd7a264f86fcfccccdc2c14d60cd5a81f91e4889e639666a5afcd3b48e262b7f185f7935e3633d0247afb484e8255e8aea9a9279ceb2323aa599829e8444b73600ed518f64d6fce00b30b90e4dcd421163d45dd8ce1558b9e1c4e9f46e6c81c9b86698234cbe833eb1544dc2d73624e4dcb9cc5b39dc9c65a37fc655b651024911e2a8867e8b44ae67c2d7ae56daca2b459990bd38608318a2712c90268ac73c8dde350a19a0e5c53345d7369aeccb53ce84ecd0dfc6da0e7e6d6dc056ffc54a1c619cdbd79308f66c74c4d01a4e1b1f114f1531cdbac0cc21997d90569a672a542a75589965ce5ecf8d17b983d53d4637d15ade7431f79ddf8e073b08aa6ac9b92299b7d533155f9203be003cd58d90f2c5c6295988bcd8a06651958ad0aa0e3cc1ab393ee84a8758f58f317dec72c46d09129847f4d1bbadffd5c77b2a05a3066006bad13cf605d8374b2e43fc5fe896c580f7f3fb099ed416119ce023aba66fbf609a47913c7f0de891dd8a11dc53cbbfcf4b310fbf65937409a9790ff7f9cf7d7eefc3c7dd43c52e9b11d07ad6006493e1f7d558fec8b7d05496aa813b0483e89cd57820d3983fdd7aa69dfec042441cf9ed9a99d99473b87cf9c419d756a17ba4f95dea78a4e55edd2ae62edfc65ccddaa97707a3dc18acebe8b5763a25672d105f3348c5fb3aff6802acf0648f2713e9c8f98a1d63d1075d0c32174c38b58b7ed8985addb23f9606672251ee0b34dfb2e1fe18a799226c902fbb8b0c7b62177ed1c2c3fd688bfab17d4c5907a39e8ef4cc93643f45772ad8a3c8a7b756d4feca96dc50861d0c3e9347c4d2f100b05e8e40c74d20e966acfd554dfd90bf8fddeb66d07fc26ec1ecc67bbf6529d7f96255a77c75ea99a3c8c96ffc957d6f37ececab82b5da98a78b6d7ebb11846866a38c42f7b636f65a6baf62ef6188d5899f7a85e0a1294797740770ff63ed42bb1c2afa6cc142ced10f2ff1ca4813194b30ff6316966c367c0ca766c816318adf98b3a39e9a54f9e3c84aaee514ca3b7e76b25fc3dd3e710f3bddd5dd329e7e486dd8b3da897da16419212e8e4a33ff9e87e20fb9aa6298b3de8bcf7e5c496edbec852a6cc6b666e2ba6a1bb31c7bcc72c9c93ea533d96f40257865e5be8999071e4cd1e31545fafb6aa4b50a97cbe4fff2ef79d94258c047aee8453a213eb8369d4f0827ab26392c73bed0cd45930865ea847fd0ab16cbeae95681799f6508f995453c4f57e58db56bd3c81346175a0722162259bd30ad5e71da8ea2f205ff82d1d6cc349e7c07f208ad8a229839f743e3a2daa1de72926423decbccb541677f3c2f5a0aeab6fca12e79cb9be7b42bde4d7fba55ec2bb076065e1772d3b42a559d957a6311eefbb816ecba1c93ef7e2760fac259cfbafc4585eb961acae97e0eb1ff6394f27832186d4ddc83d834f85d5811eed1b7449dbf432874eb3112dec79bd7ad9ae97a8b59091a25e6457e8f5aa38ca1246357aaa3ba1265eabeae915a3f3ca94dcd8bd400fb9598d522d4cffadea27fbe05e216b4288838ef8c8bdb9c9662d8e91d34de5a52db05ebe8e6339bd68f91a6d5d83e79b2d7a81f9ddcccddd22ec0f78e3663e0955c9815bba31c4a8e1c7aaa806caeff4c2ad9c02cfbfd60b792cc29c3379ac6a4a935e9297baf7a8c105741532f6453fc8fb6b7a09fdf5349e1e5d09bbb13f5116fde26ad0fd76433c817d1a6e740a7dacbb6c3b48e20e58925c6742ab04490e9d5015f1186b0d1fcf443574736f68971b5eba50e7ae0efa1bfe8c5ee03583dfebee28777a44b2c45554a0c355d0fd864a6ff869d413d93165f093599464fbbd8bd8f5b86388710db9ea62076d63cf39347dd70c95ce478749d60935937c7027512f59bc57fd29bfe4e341d4cd30eed15842e6127e239a6025d671a7b20d393e5853e8b4ce63d5d3c01c2fab4e40ec5a093e195b3bc58cb16c1e6a5fd77267c1e7e28904d802746a93d8dbb4e41d44be65aaca93fceade144dab8b7d517d6bbfcf7925dc21e5df6d8cccf75b6489914719c8d5d0a989635881a5b3c559b8d3670fdcb92ac6b570359d3fb984ff3a8868aeed3a76df3cca77d7158fee520ebad358a14e8285ba2b88ca497f1f3f6e0595d001add56d3b87c9f58098577c3c59cbc2fed069d8ba9d4376d319782b548de41f63d174d7f1bca60ab395dcea531792cf5093e87137ee56d5dc5d8c83e3a893a6bb8f3bd8326592654333e05f0fb2dd455faeaf4bb2a9972edf2908793f5430f7e02f9f6559c24c67e23a9c5cc7bb0ae1042e9c1ad505e8cb3dc6fb7cf3984f3ef789288d8c3636334567e521f42ffba0df9b208dac89db90fbb7cb023b7be676a22724bd7c11c7b8bec56727825e1ec4fb3659445bf7e41ecc5c0ef556ecdb9b508936210a4fd06be97c683d766d8eb2524557801cb613f351b8571976e4c8edea55b2d13559f4087a58d48bfa9dbccff571ec2d41ee13f5227a5ba2d0424bdd9797b2163c3d5807f4ec759b857c12aa15906482d50a69e5c3be3e720d56651d37532fa61befb8e269134402dd707b9acf9ad76c5b0dec9b9ea5f8653fc7b14f7a1945ab59c9857973c5e4bdf978bad04fb20bd79dc3750358c900fa9cbe2b5155bf7ebabcde25a6181b2a5fa0b63b96b7d08515c1f3a7582fc84b578e155bfa149fc3bb7d57d1c55055fe6e3dc67a091d95866ef440165cf573cf1aeec7e9815e826535c0d647f0820a12fca44392e4efc66ce97863b74d11117e9faba5975e885bda49a50a7a27f6b19bb2406d0ebb7b22b3cd68fcb55e50d3d1bbba1ecf46aa187db0868af71633736b46f1ec6b2cbd7d37fbd14f26106f7336ce36a6ef621597ef5dd6ee0ad823afbd093d23e8a6ecea7ab476b7ad4aafb95d7a0b1169b8fdded847bfbfe12fe1ec69651ebdb375ec5fe83c9c4fb067deeb31f590039f994ab018aca2e3ddaedc5de5789f78a9666b31ed23e3046b9af91ef42de19c6505fd4e9f322557a2927665e5fbb2ab4b5f3d9f91ebf7f9d93b1b9fd009afa65ef8a7d08bf15d89643b30bfaef9816985b3c8eed45cf961b4b009c91a6d27f90564c678ce9dbfe3ba164b42afacb41fa8b11fa953ffccb6f0214b38bd80959c99921f6f545b1b7ad938071cc43b37fd50b38a67514bb69bd6e05f60b507daf957f0a91178feb51beb5a3863a1ac722c4817187bfd9b7f8b3df2c79dafb5c818ce31f4102c6da2cbf01aa50ef9c3c6429ca88956b4b014c3a4dbd44baad43f9e89ecc16b129f3ddaf553bc83955f43d47ad5cffcdcf4c2332bea59766cc72fe23dbc399d3ff1897dc52fadf02bff1e64dd762ac19d268c58f30710432a395ffbd0dcdc1fea6b7988f75f24de05ae7fd20bd7359ae40c9e9f490f3dbbb1efbe8ea70ec9ce04e7077fe48fbd09fe02af539bd9993d8af797733d23541dc7be212fcd1be4f81965c06d9933dc395afaa63f8967a41bf74542e4732b7faa2a6a87cec72cd5645feb252fa7f52d9066a90aa21be6413b4b193d44b599ae9827d0e108baa8a57a368fd047b6e2ee531455f7eed0875af8dd9f87afc98234ed6d1d4088e4b19fc867a0b56a1fb472211f3d5456f62ef9f78ff4b2fe0d8f916f439df4e23b601ded0f59282e4f54b0e00e7863db77a1aa1ccb377f691e4dc31eaa2a595aec4f284fcfe4a1bff2d7eef8d333656c67e13ef4514e53496bd1eb2a6ee66ffc2decda738a63fa4bbd6c76541c2b4ecc61f046f04f8acbd122e844595d9bb90e4f633dc0f52559d373f09bbb788ee2f5933b5395b043d0379ad03b7aa1bdbfcf9dc17cb6b5ed36b8506f1a6af098c1f327896b4fd17fe37ea5b3affe21deb398b22c60bf55ae76cd9e13fe51cea1ca3c0369c2bd94b2df71deefc83bb78c116400fdc958ee4385d2977bbee0773f7a678c7b1b3f9b7a035ff2e11e741d2a583ee10df73ef3a78be25bf72bebe25a9c79a8cb20db4d53c4afd2a9728867777a65a53c12bba0f2a6cc7cc997fdbe7b86be7d119e778d35db0e543ae1d4bde82bbe6a0f6d3df59c5fff2c58327d90c94cc4ddf0eb67135fd663dbf532f463d1722af6bcb9ee309fb73395693b88b9067a4cb5238b2a33ed78a7349ce6864a7e02156838fd83fec41bf16a0ec0d7e69f4ef4b64b14cec542862cfb56ecabd6ee24ca4ff7c57e284d53b7ed3344b3cd2710abe959c3955576984104974dec45e233fb43f0d4b7f0149d0aa7e7204da84461bc43b9a76fec51c846e1c98b2ff54194413b917939f32d8846cdf5fb3b3fa91763ef7437cbec32f5471b7d45a8b7207675a1a779846c7611671ad35da4497c76795f9dc45edec4bb1b42974c3febf91af4d218ddb7fca46798da591f62a10ede1efad87c64faba7ff9e2655dd7ec18e71bd9533aabdfb8d74b99dbd9c36c20ef60e693e8a123711275d44877c06d3c777b96993bc986d9287bceedff27ed0469b271f692bdca7688be71f5fd3fa717c80dcfb690bd6593f834cc22b7fa0fffc53bf473759e4d6d433e42a7d68ae73a3a3eedee63ff1962d00afa93b29eabd36ce66bd97cab248bb5ffb6b305f857df48f8bc4fcfc36c792aee3bfe62bc7c11856c99adb27735c8f51ff9993fa2e95c587392d5fc992aa95a7660faf17ce7582f6c51eec95da88307fa3d0b39ab92ee862c3ec990d74f55d7b2baec8234a15a1a7315bc6969df7a4ea99e1d857363d84f951dd3b38958cdf03325793f0a3154aa7b75ae4dd6d06fd6a9bebcb70ff2ded7b3a6d2e604a4e8a46e6d9a93e5ab3806f5851e64276a0471719c9dd2499fdbb4b46fc5b156bccff22e87fa316b6567319a2e37fae0cdee2afe80ddad445bd5e1e71eaace4ed4447edd5f3fc79cff09963803dd9c9b0b9814efbdb8b5e763bf9d5f401f257ce6283bd20df5e866d861c4be3d5f9b6ff6599b55227b7435f72ce3276fdf5aab85a7af86aeacdad945fefb327f20bfb8ac8d4f50991dddd18dace386ba10c77f494f5cadcfbdce938d756f937891a4d9a29978cf0f2abc2cf8cc4bfeeec8cfc5b1ee143aad0b7d19eeb30469b2a3ec32bbd2cf74ef7ab1ad4f447fcae7d40d9d7d5dbd7cf1f710255535bbce6e72e7fb3f9f5f44bc93e742043059c858a2a175769bdde956b0ffdf79821f3a7f25e839d11f4b11dfcdc65f44699004e2fd3dc4c2f8bd278e633fab97ec4134a0c60af9bc697755377b9421b6ed64055dddde5bfdce4eaf7b3f9f342d622e79a16f9dacc92166a097cc7b5980f885f9e5d3d35ddfd4cba7fb91615f4c2bdb356533343f8ea8db24d894a58adffb81baab9fbd668bfc93bf51b332e6e07eb6174e2ed2f761be7eaeef8755cc2749fa104f8ee58918ab2c2bea1d736f30876efaee966a672392537ed5075a644ecf9c0d3574e86fa02b3d88efae409285ba803afc243c15bf6d4d7f422fcd781f4b43bd7bea76214a97b25256865850e1530b7c36561db9f7cda775f17c363e37cbdf4daaa837bf97493dcec23d0367faaea207f1a982397a7cf8b642667443dce2f3b49bbbfc33feb22e114683f87dbd23c8c30746aab27954e36cdf3d8a2e54beeb5dc9b6a8c0e72c73e1fc853d84eef7320b73ccc27d0350fb557612a599c73b0a23dbb403dd80682c44f3476bfc23dfe3936ff15c338bdf99849a4014c273fefe2aabd8b7acea1e6d257df76db3774cdf7d53573dd9133d251f7b1afaf83af437a1d30a3d7ccf808ec46bcff46cd009d46ee027e1e43ce824dce9fa6a5d7fe8fb9518159bf11bb82b88d885703f19f2cf09e8a7e6e6a6a1bdeb6be1a660e7e77aa4eeddcaadd43dfc3670fbfad52e7ddf9eb9b9be56153f064bd5a1830b9d163d0d94c1b87baadd733d99ddfbd7e827829e66157f2eef6fbef4717c4e56c767c5c0dacc992958033de4b0e7fdb95c815475f7a41bf2529dbaba7c304558f9833833457f06be50966091e6d8b474099f0d8095f6e27deb66bcf33a30bb329cba1ff951766346f1d475b0b9937f388e7db6b270de3c8adff916d2a35ec2b995d935853403f43c60e3a7eec4b4ec816ef732ddd673d3720d3fa6e7ca794578b76418bbacf01df2500b8fc3096258b96cc67ff19bdbe139dbfee788f4c7f5f245b4fef81b3e7d939eb65edb057cfa7adb589f9e3adc7266b775fe3fe52f3f9224bcde73d2a4678a3623fb769b47a9e83c72edefbfffff8df167f4b26565f8cd8e755d64d439d5b73c87cfcf63e21964ee5c9b3a2d913be3d6f913e26dafefe7fd1fe865f3ef6b5604bfd7b90fdcb6037c06b9565750a745faf8757ad9da2be457b5b1675f59d1e7bfa384fa47d6f74ddbf8a65ebeea7cf223addd1ff89e243a59de167dade9e80712fd741cfbcac37f647d3f9871cbfbebbd48b8b69cbb7edbbc695cdfeaf57ea95e3ec7a1752ffd7235f9ebd7a27a6ecc1fec025cd3eb41e5f307eae4dfbbee57bdbe3bdfafc9fb7fcfd75ffdff0bf7dff9fa5fa597fff77ffef1ff0167adac06 + + + 789cdd9cdb5372c992e8dff75fd1b1eb6dc7448d2820c489f380a2a0a88077999887ba2e141015b93971fef7935599592e106dbf6e7ba663b6417ffe6451555979afb5d8fffeafdf6e3ba7bffdebdfff317955aff7e637d3572fbffdcb4e47a3e57ffce7fffdaf7ffcb3b0b5f55b78952ac5dfb6fff96ffff8a758fc667e135bf17f91ab892b81d52b7301df9f1317f17a2513e3f51366ba7e465ca1eb0f13e3f53bcc78bd3d4d8ceff37a0c7ede3f258eef6b9abf40ebb775625a9f3e8a5c49eb9d26c6f10f98717ef79618c73f26e6f58bc4f8fe0d337dfe2c31beff444cebb7678971fe1933ed570599e5717b8971bc7d661c5f2c89493e41f21568bd7a484cf31b1d1846a3f95c1b99e7cb1e99f17d3320e6f1f97a1a5f7488697c5547de667bf2c4f4f93ecdbf4d9f7771fd850a5faf6e89e97adf488cf23a62d68722a6f9b371e0ed349f2e10f37e8c88e97a9121eff07adf88e9f3a642ccf2ee46aef2f5d93431eaf38298eded9498e7df23a6f99d472ed278265ebf53e0ebd58098f5779b18e7bb44e6cf8b7e627cff8598d6634789e3fbbece4cfa5e10d3fcd6464eebd32d62de1f9318f573c64cf6fc4accfbd74d8ceb9b13b33e4ce2f87e76815c2ad17a62fc2816f8f36e42ccfbb99b18e53b65c6f568835c627b3b491caf374fccb4fe1a31cdefaa89717d15e22aadff21717cdf2ae4dd2aed6f8c7745552ad17a9e89e97a3367a6f7717c552e10c7f94bdb258bfeef9bccdbd5b8be57e47281c63b62a6cf6f11d3fc99488cd7df306fa3bc9a98e4f33d624bf2477b2ac1fa760a71fc6d62da1fb5cf4cf1bd464cf28a3233beeff9f334bebf65a6cfef27c6783860c6f52a5cafda2579cd5e62bcbec68cd7671d62d6ef2831cedf67c6cfbbabc065d88f1ddc6f454ceb7187ccb47f1d66dc1fff92387e3ea3eb79bdaa9818c79b32e378f68098d6e30bccf87edf1093be5c9999f28562a6eb99793fa33f9493bc7ec98cf6e5df98511e7b454ce3bb1e335e2ff688497f5a24c6eb87cc24df6d629cef15b942fba1ae98f17a1ffd697787e3adb0c4146fb20364bede2e12c7f11533ed9fbf498cefdf11933cd98c99e48ffeb9ab53fc56c8e9fa1633f9c72331dbeb7362bc1ee7d7559237bb66a6f5b9c4f17a7dcf8ce36751ff959d144fef13e37e1799491f75e434de0b338e2786c4b41ffa8d19df77347e95e4552d66b2779f18e58bf654d1559257bc30e3fb7d89ac583f67ccb4dfcdc4681f47c46c9ffbccb41ffdc4387fb447483f141ff50e32cf9725c6ebed11318d67ee12e37e38e622ea7749ace8f343e6a28ae35b6287f3996b66bc5e48661ccf4c90f536f9b361267b2825c678f4c84cfa7b222e53fe9c25467f22f9b4a2f16f13a3ff7799293ee3f8a6c2f1fd8199f2a526a678ae1ac4e4ffa68a5ca5fdcf5e9079bfcc9898f6c3cc98713fd43d32c887fb75c28cef67bdc471bf6d8b98e4efdbc4e80f7366ca8797ccb8bff28619e7538699e653cc25eca78e88693fd55662dcaf47669c4f1e278eefcb2b66b2f7bbc4717e39257638beac25c6cf2f9969fcbdc438ff1b33ca672e12a37c24af217b93e3c438fe8099c69f25c6fd94c4b4dfe23031e69f1e33d9cb0131ed4f16f5ab8a6c3f561393fdf82172b29f2233bd7f9d18eb995d62b257d364c6f7ed2b33ee87be45d6dba84f7f484cfab727cca87fdb488cf62698f1f3d99c98f4ab8bcc541ff078acdf3b661aff25318ebfcb8ce39b2d62d2bf2d30d37e8c13a3fc2d669adf26c6f8d16746fb931789d11fcbccb83e97c6a7f5a5cfe3faec3672b2a7b7c4684f1933d9533d31be7fc44cfed84e8cebb967a678f79818f793d6cbf6286d621c5f30d3fc3a31be7fc04cf6314f8cf9c63053bedb4d8cf9cc13533c90a78971fc0933cddf4f8cfaea32d37cbc5e8a0ffe8c98e3c14962fcfc1533d97bcc17cab0fdfb3933d54793c4180fb689b9bee3cf53bed7d7ccbb3b71bc69621daf7f22a67acfb69969be2a32db973b6546fbf2adc4983f515ec3f6a0db8971bd63668ad70566b2579118edf59e99fc2923267bd0e789317e9699717e719c18f7a3c14cfed34d8ceb49d7537e4fd7d37a3acce43f37c4642f86e5617b794a8cf1f09499f6f72d31fac30e33d5a3e3c4984f2f98717d722b31ae6fca8ceb53bbc4647f762731dacb2533c5fb9bc468ff1566d21fef3fc51f739618eb338c8fc652fcb09e99fce58099eaa358dfeb6295fa9dac4a4cf9c4b598291eee33933def212bee9f1f9849ff0362ee1f5462cc17cfc8acefac4bccfe7cce4cf6516326fb78491cf75f9799293fcd12a37fdc12d3fe6acd4cfed26326fd5f26c6f947ccb45e9f18c797c896fdadc34cf54a3731cac7ef937f589cdf72ff2526c4b45f59621aef9298fba90631e94b9c22ab02eacb8e13c7f8a35f910de5234fe359f23717edd594b8fff119b2a2fa429d23eb6d1ccf0c89291e0841acf07d5144b6e4bf7d7adfb2be62bc3196fb2383e35b9ecf3e216bda2f6399495f8929bed6982b51feec8d98fc3bdb4d8cf29591397eba8c98e2998dfe6f4b1c8f7d15d994717fb307669c4ff789b9df3967c6f76dec8face3fec81f248efb2ff691d9ffb31233f557bbccf4f907661cdf2c91933d0e99299e8d9871bffc1631c563b14d4cf9d95f25c6fc289969ff0f8929de299f18e34f07d9517c72e7cc14ffa27caeccf2b92633f9fb73628cb78fc896f2976e32a3fc6a2f71942fdb26667bf18971be6366ca8777ccf4f927e66a31ca7f424cfbe16e98a9be1c25c6787ecd4cf9ef3631ea3763a6789618e7170d62da5f51488ce3ef33533f2913e3fa8e98c99ecb8931ff5d32d3f9c541627cff15d971bdda4c8cf32f9829ffce13a3fedf98a9bf7a6046fb93bbc45c8f8e12e3f87c3df747d78971fc3e33e59bbbc4b87eb22f47f62cee1263bcda62a6f1493f8ef63743f91dc7477dca8cfa314562ca4f7e9218fdf99c19ed477788593f0d663affea3153be693253ff74cc4cf3ef33e3f806ed33f99bee3253be2e25c6f8bac74cf9709a18e38d6226fbb8488cf1e29999d6bbc58cfa55d7cc148fd3fa68bdb4bf49ff8f8951ff4366b22f9718df6f31d3fa678951ff1d665cbf6a2746f916cc146f0e9931beebbbc4280fef27f72f26715c4f97e5e17a5425c6f5f2f8548f9a7662cc6fbcff142fdc73628c57dbcc548f913d38ee771a89713ecf4cebb94f8cef179929ffd1fe7af27771c54cf1a59e18fd23dab72fb33d78cb4cf1799218eb8b0133dab3ab33a33dbb0233da47b69fd8c4f71f8849df6e2b31eaf38c99f27d2d31da438f99cecf9e12c7f5f90b66aa4f78bd14ff5d25715c8ff1c4a4efac9e38ee4fdf31937e797ece07e789b15ee0f9f8bca3c88cfa36a5c4989f16cc547f5c31d37abbc49c8fb799c91e9e13a33df0fe713caa24467fbf64a6f5a7f148ff693cf2a71133ae5f5613a33f3599293e141263fea3f7d9fee44b62ac471d33d5bf6366f29f4562ac872c33d9e70533d57347c4145f321e9fec2b43fd78a89fa3bd18b42fcff5adbd464efadb4a8cd70b6694cf2e99c9dedb89d1ded3781aeb8f5a621be56d11f3f9d32c31cee798c95eae98a95eea27467d9498c97e5e12c7f5644366538af3a3bd7bde5ffbc04cfd722131d66fc7ccd43f2426f9cb89e37cbec2ace2fbd61073fe7f6426fbdc61a67ee23231ae2f63a67cdd4e8cf9fd8099f42999717d769e18d7a799717dbe48ccf5dd3333c59b6562ec1ff9f3a4efeeab147fd54baa95df75782536d2d2eb47e68abaffcb24f99d174b627f66bc1fd08bcdedefafaccefefdf4b24992f555867f7f6ac57fa95e7e57ba4faf0bfee3defde77f5e2fdf90e6f3ebd4cf49f2d7e8a5fb890f7d65857f5fbdfca2747f33bd481fffcde0d597f7c00f72107c81724ab2263984bf7b788de2f503e0fedf4b2ff2518e617559fcfd21ae5080444ff21924432932f87b06bff7e16ff8fb7d9422fb39ddff845ee48b9cc0eac6f0fb24e807a41a47eb0912beca69d2074a13f4349373782de4125e3f26cd8ff9cb1b4932e9befbc61b4815fead059d5104de93fbb20eff1ec8c3a82fb6b6bf875e6c5c71032409ab6eca5aee3d4d12d4e1dfb0fa23d0c7b16c012fe2b5e173277fabbc7f0a2b3a8dd63584959fc18a5bb22d3bb22bcfe585bc9457f25adec85b79277b724b16e0efdb724716e15a0f9f2bfdadeab1862ccb5d90e45956641556da135208a184164658e1848f3f4e64a22feec5831888a11889473186eb87e2e96724f9a65e3ecb03ef3962045edc925df12c5ec444bcc2aaa76226e6f135178bf4338f7f9b89a5781335b127f6e13375d0235821e9f84fe49b6fe805461707f03a8cb3510f0211f54d806589a638920b712c5ae2449c8a33d18eebe59fc5273f7392aa23baa0bf7371212e21ae3561bc2b887d21ce417410d7e0530fe2e6e7f412f64adc8a0371277a620b251105884b2fb226b66526764451944459ec8a4a5c7d957e364b41ef2aa944e499682ba5b432ca427468ca31ccd10fbe049268e5a450fea7f502d21caefdbd26e72a537d75af1ed480e458408aff4a927749a33cf4b7687320cf508d64553d428c0b754488f29069d5e3cffa0be8e450dc251f01cb82d9e66aac9ed4b37a81b590dda4d57df5535513f5aa5e493b5325d42c7e7aa9e66a216fd452bd4156653f8cbaf931bdc04bf456bc7d1774d25235b5a7f6553de8035677f02d3936eb07245387d1833aaa012ed9940734d7842aa06ff5addfcb2f60c32c49591a7524cfd4b16aa913f610dee74f3c7e83d5255b64595ee315419a5375a6daaa03d1651ca5197db7b6fe95fc1246515d18a905929cab8bb86ab4ac8f1eb2b6eff988005625508b6063327e7a914680e8a62ed595ba16c7e03763d55537df3d4ff8a5bc8f2339d985b96e4912f4005cd3473956392f296a47e446c9c56b75a1ee544f1cc39c210bffa05e623e099a7e545ba09382da861c3e4f332f28ba92ad241dac6713d6e2a1da59b1b6c3357d6264eba8a22aa9b268a85d58f99863276401f1a7f412f28985d8555315b0ae2b94843491d74e9064a226396ba9aa2a24a43a55311d2ddfa5029924e90c6b81776bc5bf645a68a5356464dcd147ecf820affd8938068b0e3dc6443a88c2e7605d6c372b7136a78db9aac2be5e68a38ada6aa7bd323a1327baafeff5831e88373d8c6b0ffb91a233fb4fa2b91ee947d5870a47c55e355bef41d77de75b7aa9c15e8ce55c8fc5103d3eedfd6a4c8a72e827d8d167fda227fa55b4d4584f655bcff41caa941da89bbb7aa197fa4dd7f49e0afbbfd0fb41a36bde14df1133bda7ebfa20d66bdc6d878e6ed57fcdafe8451f42e5e8744337b5e1181ce6d447fa082581698e511fbaa54ff4a9bcd067baad3bea5177f539d4cfa1431b87de0662d3405fe84b7d05faba86ba794a231ee89b9c3cc9ee60bc5b7d07fdce3e747187519aa73fae9798e7b7754f3de92dc827b9a8132421ad447fd505bdad61ef75519760f62158c523f496efb1a70c113df43a562e20b76febb2ded515ccb6c9ff16c90b17a0e145f8ca06449b8adc3312eab5d0d59dad4af22ecd77eab150b11861549c95a2513ef6181d2431263c29659ccc8c37e915251ac55a8e3a68aceb20fbee99beb9370f42ea9619704c4c517191e6699ba1dc31a3d88fee415faae9dec187089df4b23166d39553f368c6ea92eaf455bbc6a85c354fe6d9bc186926f17ae8ff412728c910ba83bb543f84febe1625c37ffb666a6666aeb066a846fd882447f41cb3304b7d69de401217bb8d4fbc9ff4b29e8126d1db477212ac42774d4d3de05cef19514dc34c41275a9a3db3afc6b06f7a7d06985d8024a7a60eb1e821ea660caf5af4e470fa343207e6d0344c13a459449f59ad20e26e9923736c5ae6249eed4cd6d6bae62f9b2a832089f450413c42a75532a72bd12b6f6315a5cdd29c99364488513c91481640639d42ee1e870ad574e09aa2e99a7373612ee55ef7d55cc1df067a66aecd4df0c60f156a9cd1dc9a3bd3335be6d514401a1e1b4f113fc4b1f5ca209c71996d90e6552e55e8b42ad192ab9c1ddf7b0fb3638a7aac2fa2f5bceb23af1b1f7c0e56d19475533265b36b2aa62aef64077ca0192bfb81854bac1233b15ed1a02c03ab5501749c5963b6d29d10b5ea112bfec2fb98c5083a3285f0af6943f7bb9beb4ee6540bc60c60ad75e211ac6b904e96fc87d83f910debe1ef7b36b37d282cc3594047d7ecbd7d00695ec421bc77640776684731cf2e3efcccc5ae7dd40d90e629e4ffaff3feca9d9f87f79a472a3db6e3a015cc20c9e7a3afea917db2cf20490d750216c927b1f94ab021a7b0ff5a35ed8b9d8024e8d953fb6aa7a66767f09913a8b38eed5cdf53a5f7a1a25355bbb0cb583b7f1a7337ea259c5e4fb0a2b36fe2d998a8955c74c13c0de3d7ecb3dda3cab30192bc9f0fe72366a875f7441df4b00fddf03cd66d3b626eebf640de99a95c8a3bf86cd3bec91e5c314bd22459601fe7f6d036e4b69d81e5c71af177f582ba18522f07fd9d29d96688fe4aae54910771af2eed913db6ad18210c7a389d86afe80562a1009d9c804edac152eda97ad537f60c7ebfb56ddb01bf09bb07f3d9ae3d57a71f6589d6ddb117aa26f7a3e57ff095d5bc9fb332ee4a97aa221eede56a2c8691a11a0ef1cb5ed96b99a9aebd893d462356e67daa97820465de1dd0dd9dbd0df54aacf0ab2933054bdb87fc3f0369600ce5ec9ded25cdacf90c58d9962d700ca3357f522727bddc93270fa1aaeb89d7e8edf95a097fcff429c47c6fb75774ca39b96177620feaa5b64590a4043a79ef4fdebb1fc8bea669ca62073aef5d39b165bb2bb29429f39a99d98a69e86ecc316f310be7a4fa508f25bdc095a1d7167a2a641c79bd470cd5d7b3adea12542a1fefd3bfc95d27650923819e39e194e8c4fae0356a784e3dd921c9e39d7606ea2c1843cf554f3f432c9bad6a25da45a63dd46326d51471bdefd6b6512f0f204d581da85c8858c9e6b442f57907aafa33c8177e4307db70d239f01f8822b668cae0279df74e8b6ac7598a89500f3bef3295c5dd3c737da8ebeaebb2c439a7eede3da05ef2ebfd542fe1dd3db0b2f0bb961da1d2acec2baf311eefba816ecba1c93ef6e27607ac259cfb2fc5585eb861acae17e0ebeff6394b27832186d4ddc83d824f85d5811eed0b74499bf432834eb3112dec71b57ad9ac97a8b59091a25e6457e8d5aa38ca124635fa5577424dbc52d5d32b46e7a529b9b17b821e72bd1aa55a98fe5bd50ff6ce3d43d68410071df1817b7193f55a1c23a77b95e7b6c07af93c8ee5f4a2e573b4750d9e6f36e805e677533773f3b03fe08debf92454257b6ee1c610a386efaba21a28bfd373b7740a3cff52cfe5a108734ee5a1aa294d7a495eeadea206e7d055c8d8177d91f757f412faebd7787a7421ecdafe4459f493ab41f7db0df104f669b8d629dc63dd65db4112b7c792e43a135a2548b2ef84aa885eac357c3c13d5d0cdbda05dae79e95c9dba3ae86ff82b7a81d7147eafbb83dce911c9125751810e5741f71b2abde187518f64c794c14fa65192cdf72e62d7e30e21c635e4b28b1db48d3de7d0dcbb66a874de3b4cb24ea899e49d3b8a7ac9e2bdea0ff9251f0fa26e86718fc6123297f06bd1042bb18e3b966dc8f1c19a42a7751aab9e06e67859750262d752f0c9d8ca29668c65b350fbba963b093e174f24c016a0539bc4dea6256f20f22d52559ee457b7a6685a5dec8bea1bfb7dce2be10e29ff6e6364bedd204b8c3cca40ae864e4d1cc20a2c9d2d4ec39d3ebbe74e5531ae85abe9fcc925fcd74144736dd7b1bba627df5c57f4dcb91c745f63853a0916ea2e202a27fdbdffb82554427bb456b7e91c26d703625ef1f1642d0bfb43a761ab760ed94d67e0ad5035927f8c45d35dc6f39a2acc5672cb0f5d483e434da2c75db96b557337310e8ea34e9aee36ee60cb94499635cd807fddc976177db9be2ac9ba5eba7ca720e4fd50c1dc82bf7c946501339d88cb70721def2a8413b8706a5417a02fd78bf7f966319f7cec13511a196d6c6a8aceca7de85f7641bf57411a5913d721f76f960576f6c46d454f487af9248e717d8bcf4e04bddc89b74db288b6eecb1d98b91ceaadd8b737a1126d42149ea0d7d2f9d06aec5a1f65a98aae00396c2be6a370af32ecc881dbd6cb64a32bb2e811f4b0a817f53b799febe3d85b82dc47ea49f43744a1b996fa5e9ecb5af0f4601dd0b3d76d16f249a856409209562ba49577fb7acf35589575dc543d996ebce38aa74d100974c3ed683e6b5eb16d35b02f7a9ae297fd18c73ee86514ad6629e7e6c51593f7e6e3e95c3fc82e5c770ad70d602503e873ee5d89aafad5d3e5d52e31c5d850f902b5dda1bc862eac089eff8af5823c77e558b1a54ff139bcdb75155d0c55e5efd663ac97d05169e846f764c1553ff6ace17e9c1ee8055856036c7d042fa820c14f3a2449fe6ecc868e3776db1411e1f7995a78e985b8a69d54aaa0b7621fbb2e0bd4e6b0bb47325b8fc69feb05351dbdabebf16ca48ad1076ba8786f3133d76614cfbec6d2db37b31bfd6402f13667e36c63fa265671f9de65e5ae803df0da9bd033826ecaaeae472b77dbaaf49ad985b71091869bef8dbdf7fb6bfe12ce9e96a6e79dad63ff42e7e17c823df55e8fa9871cf8cc5482c560151def76e5ee2ac7fbc40b355d8969ef192758d3d4f7a16f09e72c4be877ee295372252a695796fe5e7675e9b3e73372fd3e3f7b67e3133ae1d5d473ff107a31be2b916c07e6d7353f30ad7016d97d35177e182d6c42b246db497e0199319e73e7efb8aec492d02b2bed076aec47ead83fb22dbccb124e2f602527a6e4c76bd5d69a5ed6ce0107f1cecd7da859c5a3a825db4d6bf04fb0da3dedfc33f8d4083cffd28d752d9cb150563914a40b8cbdfec5bfc41ef9fdced74a640ce7187a089636d165788d5287fc6e63214ed4442b5a588a61d2adeb2555eaefcf44f6e13589cf1e6dfb57bc83955f43d47ad54ffdccf4c3332bea51766cc7cfe33dbc199d3ff1897dc52fac70d77e1964dd742ac19d268cf8e66b10432a395f7bd7dcccefe94bb98ff75f24de05ae7fd00bd7359ae40c9e9f490f3dbbb16f7e1f4f1d929d09ce0fbeee0fbc09fe02af639bd9a93d88f797733d23541d87fe509e9b17c8f153ca809b3267b873b4f00ddf8c67a46bf74542e4734b7fa42a6a8bcec72cd5649feb252fa7f5c720cd42154437cc837696327a886a535d310fa0c31174510bf5687ad047b6e2ee531455b76edfb7a0167ef327e16b9e204d7b5307102279ec27f21968a5da07ad9cca9e87cacade24fffe4a2fabdff018f933a8939e7c1baca3fd2e0bc5e5890a16dc016f6cfb0e549563f9e2bba6671a765f55c9d2627f42797a2af7fdb9bf70871f9e29633b0bf7a10f729a4a5a8b5e5771537fe9af60d71e531cd39fea65bda3e2587164f68337827f525c8e164127caead2cc74781aeb0eae2fc99a9e81df5cc77314af1fdc89aa841d82bed184ded10bedfd4dee0ce6a3ad6db6c1b97ad15083c70c9e3f495c798afe1bf72b9d7df6b7f19ec52bcb02f65be56ad7ec38e1efe40caacc139026dc4b29fb9ef3be276fdc22469001f42763b90b15cabddcf15bbef0de3b63dc5bfb59d71bf892df86faaf0e152c9ff0867b9ff9d345f1adfb957571294efc0eeccd94ef5dd34957b408883ed77a69a53c10dba0f2a6cc7cd1977cd93d42df3e0fcfbbc69a6d0b2a9d70ea5ef4bbbe62f76d3df59c9fffcc5932bde7ab998cbbe157cf263eadc736eb65e8c7a2e554ec7973dd613e6f6722537610730df4986a4b165566daf14e6938cd0d95fc042ad070fa07fd8937e2d9ec81afcd3e9ce86d96289c8b850c59f6c7b1af5ab993283fdc17fb529aa66edb478866eb4f2056d3b3864babec30d350ef36b11789cfec0fc1535fc253742a9c9e8334a11285f1f6e58ebeb207211b85272f3ed5075166326828e4d41f43346aaededff945bd187ba3bb99b78bd41fadf515a1de82d8d5859ea607d9ec2cce34a6bb4893f8ecf2ae3a8abdbc897737842e99fb2cf36fd04b6374dff0939e616a677d88853a787be863f391e9f3fee59397755db3659c3fcceed359fddabd5ecadcceee670ff206663e8a1e3a124751478d7407dcc673b74799b9a36c900db3516eff3f682748933d66e3ec49b643f48dabbfff737a81dcf0680bd973f6129f8699e756ffeebf78877ea64eb3896dc81e746aad78aea3e3d3ee3ef69f21062da13f29eb993ace5efd5b36fdecec2cf7df763603ffba37123eefd3f3301b9e8afb8ebf182f9f44219b678b6ca906b9fe233ff37b349d096b8eb237df522555cb6ae63e9eef1ceab92dca1db90d75f040bf657b90b32ae96ec8fc830c79fd54752ddb975d9026544b63ae82d72ded5bcf29d5b37a383786fd54d9013d9b88d50c3f5392f7a31043a5ba55a7da6487fac53a752f6fed9dbcf5fb5943697304527452b7f69a93e5b33806f5851e644d3582b838ce8ee8a4cfad5bdab7e2582bde67799343ddcb8eb3568ca68bb53e78bdbb8a3f607750ffa83afcdc42d5d9899ac8affbf3e798f33fa14e98826e4ecc194c8af75edccaf3b1dfce2fa08f123e7394d57543f5dc143b8cd8b7e76bf3f53e6bbd4a648faee69e65fce0ed1b6bb5f0f4d5d095553b3bcd7f5fe60fe417979de11354664b7774236bbba12ec4f19fd21357ab73aff2646ddd9b249e2769366826def3830a2feb80cf3ce5ef8efc5a1cebbe42a775a6cfc37d96204d56cfbad9b97ea47bd7f34d7d22fa533ea7aee9ecf3eae593bf8728a9aad94576993bdffff5fc22e29d3c172280c942c6120dadb3abec5ab782fdffce13fcd0f92b41cf897e2d457c377bfc244a832410ef6f2016c6ef3d711cfb55bd64b7a2013556c8e74dbbadbad91d64bcba6f673d5ddddc5bfdce4eaf7a3f9f34cd632e19d3b74e56e41053d04be6bd2c40fcc2fcf2e1e9ae6feae5c3fdc8b02fa6956d99b2199aaf23ea2609d665a9e2f77ea0eeea674fd92cffe46fd4ac8c39b89f15c2c945fa3ecce7cff57d59c57c90e41ee2c9a13c12639565db7acbdc1acca1ebbebba1da598be4945ff59e1699d55367430d1dfa1be84af7e2bb4b9064aecea00e3f0a4fc56f5ad39fd04b33dec7d250ef1ebb6d88d2a56c272b422ca8f0a9053e1bab0edcdbfad3ba783e1b9f9be5ef2655d48bdff6553dce427de0ccbdabe8417caa60861e1fbead9069dd10d7f83cedfa2eff8abfac4a84d1207e5fef00f2f09e91aa6c7a6a9c955c4f74a1f25ded4a3645053e679909e74fed3e74bfe7998471a7e1be01a8fd226b466966f18ec2c836ed4037201a0bd1fc6a8d7fe47b7cf2259e6b66f13b935013884278cedf9f6765fb92edba9eada4efbeadf78ee9bb6fea22ab64d5be94bdbe803ebe0efd4de8b4420fdf37528fc5735ff575d009d46ee027e1e43ce824dce9fa6c5d7fe8fb9518159bf11bb84b88d885703f19f2cf11e8a7e666a6a1bdbbd7c2bd829d9fea91ba754bb754b7f0dbc0edea67bbf0f7f6c4cdf4a5aaf83158aa0e1d5ce8b4e869a00cc6dd51edbe01796ffc73f413414fb38a3f97f7d75ffa303e27abe3b362606de6c414ac811e72d8b7fe442e41aaba7bd00d79ae8e5d5dde9922acfc4e9c98a26f812f942558a439342d5dc2670360a5fd78dfba19efbc0eccb60ca7ee077e945d9a513c751dacefe41f8e631fad2c9c378fe277be85f4a897706e65b64d21cd003d0fd8f8b13b322dbba7db7da7db7a665aaee1c7f45c39af08ef960c639715be431e6ae17138410c2b97cdf82f7e733b3c677bff3122fd71bd7c12addfff864fdfa4a7ad5776019fbede34d687a70e379cd96d9cff4ff9cb579284d75b4e9af44cd17a64df6cf328159d47aefcfdf7ffbf31fe8c5e36ac0cbfd9b1aa8b8c3aa7fa86e7f0f9794c3c83cc9d6b53a7257267dc3a7f42bce9f5fdbcff855ed6ffbe6245f07b9dfbc04d3bc067902b7505755aa48f9fd3cbc65e21bfaab53dfbcc8a3efe1d25d45f59df376de39b7af9acf3c98fb4727fe07b92e864791bf4b5a2a32f24fae538f699877f657d5fccb8e1fdd55e245c5bce5dbf69de34ae3feefb1fd5cbc738b4eaa59fae267ffd4a54cf8df9c52ec0357d0f95cf1fa8937fefba9f7a7d77be9fc9fb7fcfd75ffdff0bf7dff9fa5fa597fff77ffef1ff0139bda7d7 + + + + + txtAnswer + returnPressed() + QAViewBase + slotCheck() + + + + slotCheck() + + + diff --git a/kwordquiz/src/version.h b/kwordquiz/src/version.h new file mode 100644 index 00000000..d202ba2e --- /dev/null +++ b/kwordquiz/src/version.h @@ -0,0 +1 @@ +#define KWQ_VERSION "0.8.1" diff --git a/kwordquiz/src/wqlistitem.cpp b/kwordquiz/src/wqlistitem.cpp new file mode 100644 index 00000000..597337f8 --- /dev/null +++ b/kwordquiz/src/wqlistitem.cpp @@ -0,0 +1,54 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "wqlistitem.h" + +WQListItem::WQListItem() +{ +} + + +WQListItem::~WQListItem() +{ +} + + +void WQListItem::setQuestion(int i) +{ + m_question = i; +} + +void WQListItem::setCorrect(int c) +{ + m_correct = c; +} + +void WQListItem::setOneOp(int i) +{ + m_oneOp = i; +} + +void WQListItem::setTwoOp(int i) +{ + m_twoOp = i; +} + +void WQListItem::setThreeOp(int i) +{ + m_threeOp = i; +} diff --git a/kwordquiz/src/wqlistitem.h b/kwordquiz/src/wqlistitem.h new file mode 100644 index 00000000..8924aa0c --- /dev/null +++ b/kwordquiz/src/wqlistitem.h @@ -0,0 +1,53 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WQLISTITEM_H +#define WQLISTITEM_H + + +/** +@author Peter Hedlund +*/ + +class WQListItem{ +public: + WQListItem(); + + ~WQListItem(); + void setQuestion(int i); + void setCorrect(int c); + void setOneOp(int i); + void setTwoOp(int i); + void setThreeOp(int i); + + int question() {return m_question;} + int correct() const {return m_correct;} + int oneOp() {return m_oneOp;} + int twoOp() {return m_twoOp;} + int threeOp() {return m_threeOp;} + +private: + int m_question; //the column containing the question + int m_correct; + int m_oneOp; //the row for correct or option 1 + int m_twoOp; //the row for option 2 + int m_threeOp; //the row for option 3 + +}; + +#endif diff --git a/kwordquiz/src/wqlreader.cpp b/kwordquiz/src/wqlreader.cpp new file mode 100644 index 00000000..5d60a186 --- /dev/null +++ b/kwordquiz/src/wqlreader.cpp @@ -0,0 +1,199 @@ +/*************************************************************************** + wqlreader.cpp + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include +#include + +#include +#include + +#include "wqlreader.h" + +KWqlDataItem::KWqlDataItem() +{ + +} + +KWqlDataItem::KWqlDataItem(const QString &front, const QString &back, int height) +{ + m_front = front; + m_back = back; + m_height = height; +} + +KWqlDataItem::~KWqlDataItem() +{ + +} + +/*! + \fn WqlReader::WqlReader + */ +WqlReader::WqlReader() +{ + +} + +KWqlDataItemList WqlReader::parse(const QString &fileName) +{ + KWqlDataItemList list; + QFile file(fileName); + file.open(IO_ReadOnly); + QTextStream ts(&file); + ts.setEncoding(QTextStream::Latin1); + + QString s = ""; + s=ts.readLine(); + if (s != "WordQuiz") + { + KMessageBox::error(0, i18n("This does not appear to be a (K)WordQuiz file") + s); + file.close(); + return list; + } + s = ts.readLine(); + s = s.left(1); + int iFV = s.toInt(0); + if (iFV != 5) + { + KMessageBox::error(0, i18n("KWordQuiz can only open files created by WordQuiz 5.x")); + file.close(); + return list; + } + + while (ts.readLine() != "[Font Info]"); + s = ts.readLine(); + int p = s.find("=", 0); + QString fam = s.right(s.length() - (p + 1)); + fam = fam.mid(1, fam.length() - 2); + //g->font().setFamily(s); + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + int ps = s.toInt(0); + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + int b = 0; + if (s == "1") + { + b = QFont::Bold; + } + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + bool it = (s == "1"); + + QFont m_font(fam, ps, b, it); + + while (ts.readLine() != "[Character Info]"); + s = ts.readLine(); + p = s.find("=", 0); + m_specialCharacters = s.right(s.length() - (p + 1)); + + while (ts.readLine() != "[Grid Info]"); + ts.readLine(); //skip value for width of row headers + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_colWidth1 = s.toInt(0, 10); + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_colWidth2 = s.toInt(0, 10); + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_numRows = (s.toInt(0, 10) - 1); //We need to reduce by one since the header is not included + + // Selection + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_topLeft =s.toInt(0, 10) - 1; + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_topRight =s.toInt(0, 10) - 1; + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_bottomLeft =s.toInt(0, 10) - 1; + + s = ts.readLine(); + p = s.find("=", 0); + s = s.right(s.length() - (p + 1)); + m_bottomRight =s.toInt(0, 10) - 1 ; + + while (ts.readLine() != "[Vocabulary]"); + + s = ts.readLine(); + p = s.find(" [", 0); + s = s.left(p); + s = s.stripWhiteSpace(); + m_language1 = s; + m_language2 = ts.readLine(); + + while (!s.isNull()) + { + s = ts.readLine(); + p = s.find("[", 0); + QString r = s.mid(p + 1, 10); + int h = r.toInt(0, 10); + s = s.left(p); + s = s.stripWhiteSpace(); + + QString b; + b = ts.readLine(); + + KWqlDataItem item(s, b, h /15); + list.append(item); + } + file.close(); + return list; +} + + +/*! + \fn WqlReader::colWidth(int col) + */ +int WqlReader::colWidth(int col) +{ + if (col == 0) + return m_colWidth1; + else + return m_colWidth2; +} + + +/*! + \fn WqlReader::language(int col) + */ +QString WqlReader::language(int col) +{ + if (col == 0) + return m_language1; + else + return m_language2; +} + diff --git a/kwordquiz/src/wqlreader.h b/kwordquiz/src/wqlreader.h new file mode 100644 index 00000000..37920f5d --- /dev/null +++ b/kwordquiz/src/wqlreader.h @@ -0,0 +1,75 @@ +/*************************************************************************** + wqlreader.h + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef WQLREADER_H +#define WQLREADER_H + +/** +@author Peter Hedlund +*/ + +#include +#include +#include + +class KWqlDataItem +{ +public: + KWqlDataItem(); + KWqlDataItem(const QString &front, const QString &back, int height); + virtual ~KWqlDataItem(); + + QString frontText() const {return m_front;} + QString backText() const {return m_back;} + int rowHeight() const {return m_height;} + +private: + QString m_front; + QString m_back; + int m_height; +}; + +typedef QValueList KWqlDataItemList; + +class WqlReader{ +public: + WqlReader(); + KWqlDataItemList parse(const QString &fileName); + int colWidth(int col); + int numRows() {return m_numRows;} + int startCol() {return m_topLeft;} + int startRow() {return m_topRight;} + int endCol() {return m_bottomLeft;} + int endRow() {return m_bottomRight;} + QString language(int col); + QFont font() {return m_font;} + QString specialCharacters() {return m_specialCharacters;} + +private: + QFont m_font; + int m_colWidth1; + int m_colWidth2; + int m_numRows; + int m_topLeft; + int m_topRight; + int m_bottomLeft; + int m_bottomRight; + QString m_language1; + QString m_language2; + QString m_specialCharacters; + +}; + +#endif diff --git a/kwordquiz/src/wqlwriter.cpp b/kwordquiz/src/wqlwriter.cpp new file mode 100644 index 00000000..6428036e --- /dev/null +++ b/kwordquiz/src/wqlwriter.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + wqlwriter.cpp - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "wqlwriter.h" + +#define winendl "\r\n" + +WqlWriter::WqlWriter(QFile *file) +{ + outputFile = file; + if(outputFile->open(IO_WriteOnly)) + { + outputStream.setDevice(outputFile); + outputStream.setEncoding(QTextStream::Latin1); + + outputStream << "WordQuiz" << winendl; + outputStream << "5.9.0" << winendl << winendl; + } +} + +void WqlWriter::writeFont( const QFont & font ) +{ + outputStream << "[Font Info]" << winendl; + outputStream << "FontName1=\"" << font.family() << "\"" << winendl; + outputStream << "FontSize1=" << QString::number(font.pointSize()) << winendl; + outputStream << QString("FontBold1=%1").arg(font.bold() ? "1" : "0") <close(); +} diff --git a/kwordquiz/src/wqlwriter.h b/kwordquiz/src/wqlwriter.h new file mode 100644 index 00000000..c5cd1320 --- /dev/null +++ b/kwordquiz/src/wqlwriter.h @@ -0,0 +1,42 @@ +/*************************************************************************** + wqlwriter.h - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef WQLWRITER_H +#define WQLWRITER_H + +#include +#include +#include + +/** +@author Peter Hedlund +*/ +class WqlWriter{ +public: + WqlWriter(QFile *file); + + ~WqlWriter(); + void writeFont(const QFont & font); + void writeCharacters(const QString & s); + void writeGridInfo(int col0, int col1, int col2, int numRows); + void writeSelection(int lc, int tr, int rc, int br); + void writeFirstItem(const QString &ll, const QString &rl); + void writeItem(const QString &left, const QString &right, int rh); +private: + QFile *outputFile; + QTextStream outputStream; +}; + +#endif diff --git a/kwordquiz/src/wqprintdialogpage.cpp b/kwordquiz/src/wqprintdialogpage.cpp new file mode 100644 index 00000000..2e5710d1 --- /dev/null +++ b/kwordquiz/src/wqprintdialogpage.cpp @@ -0,0 +1,83 @@ +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include + +#include "wqprintdialogpage.h" + +WQPrintDialogPage::WQPrintDialogPage(QWidget *parent, const char *name ) + : KPrintDialogPage( parent, name ) +{ + setTitle(i18n("Vocabulary Options")); + + QGridLayout * l = new QGridLayout( this, 1, 1, 11, 6); + + g = new QButtonGroup(i18n("Select Type of Printout"), this ); + g->setColumnLayout(0, Qt::Vertical ); + g->layout()->setSpacing( 6 ); + g->layout()->setMargin( 11 ); + QGridLayout * v = new QGridLayout( g->layout() ); + v->setAlignment( Qt::AlignTop ); + + rb0 = new QRadioButton(i18n("Vocabulary &list"), g ); + v->addWidget( rb0, 0, 0 ); + rb1 = new QRadioButton(i18n("Vocabulary e&xam"), g); + v->addWidget( rb1, 1, 0 ); + rb2 = new QRadioButton(i18n("&Flashcards"), g); + v->addWidget( rb2, 2, 0 ); + l->addWidget( g, 0, 0 ); + + QWhatsThis::add(g, i18n("Specify type of printout to make")); + QWhatsThis::add(rb0, i18n("Select to print the vocabulary as displayed in the editor")); + QWhatsThis::add(rb1, i18n("Select to print the vocabulary as a vocabulary exam")); + QWhatsThis::add(rb2, i18n("Select to print flashcards")); +} + + +WQPrintDialogPage::~WQPrintDialogPage() +{ +} + +void WQPrintDialogPage::getOptions(QMap< QString, QString > & opts, bool incldef) +{ + opts[ "kde-kwordquiz-type" ] = QString::number(g->selectedId()); +} + +void WQPrintDialogPage::setOptions(const QMap< QString, QString > & opts ) +{ + QString type = opts[ "kde-kwordquiz-type" ]; + switch (type.toInt()) + { + case 0: rb0->setChecked(true); break; + case 1: rb1->setChecked(true); break; + case 2: rb2->setChecked(true); break; + } +} + +bool WQPrintDialogPage::isValid(const QString & msg ) +{ + return true; +} + + +#include "wqprintdialogpage.moc" diff --git a/kwordquiz/src/wqprintdialogpage.h b/kwordquiz/src/wqprintdialogpage.h new file mode 100644 index 00000000..a7834241 --- /dev/null +++ b/kwordquiz/src/wqprintdialogpage.h @@ -0,0 +1,49 @@ +/* This file is part of KWordQuiz + Copyright (C) 2004 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WQPRINTDIALOGPAGE_H +#define WQPRINTDIALOGPAGE_H + + +#include + +/** +Print dialog page to provide specific print options for KWordQuiz + +@author Peter Hedlund +*/ +class WQPrintDialogPage : public KPrintDialogPage +{ +Q_OBJECT +public: + WQPrintDialogPage( QWidget *parent = 0, const char *name = 0 ); + + ~WQPrintDialogPage(); + //reimplement virtual functions + void getOptions(QMap& opts, bool incldef = false); + void setOptions(const QMap& opts); + bool isValid(const QString& msg ); + +private: + QButtonGroup * g; + QRadioButton * rb0; + QRadioButton * rb1; + QRadioButton * rb2; +}; + +#endif diff --git a/kwordquiz/src/wqquiz.cpp b/kwordquiz/src/wqquiz.cpp new file mode 100644 index 00000000..23399e5e --- /dev/null +++ b/kwordquiz/src/wqquiz.cpp @@ -0,0 +1,586 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include + +#include "wqquiz.h" +#include "prefs.h" + +WQQuiz::WQQuiz(KWordQuizView * parent, const char *name) : QObject(parent, name) +{ + m_table = parent; + + m_list.clear(); + m_errorList.clear(); + m_quizList.clear(); +} + +void WQQuiz::activateErrorList() +{ + m_list.clear(); + + WQListItem l; + + QuizList::iterator it; + for ( it = m_errorList.begin(); it != m_errorList.end(); ++it ) + m_list.append(*it); + + m_errorList.clear(); + m_questionCount = m_list.count(); + +} + +void WQQuiz::activateBaseList() +{ + m_list.clear(); + + if (m_quizMode > 2) + { + listRandom(); + }; + + QuizList::iterator it; + for (it = m_quizList.begin(); it != m_quizList.end(); ++it) + m_list.append(*it); + + m_questionCount = m_list.count(); + +} + +void WQQuiz::addToList(int aCol, int bCol) +{ + //build a list of row numbers containing text in both columns + + typedef QValueList IntList; + IntList tempList; + for (int current = 0; current < m_table ->numRows(); ++current) + { + if (!m_table->text(current, 0).isEmpty() && !m_table->text(current, 1).isEmpty()) + { + tempList.append(current); + } + } + + KRandomSequence *rs = new KRandomSequence(0); + + int count = tempList.count(); + + IntList::ConstIterator it; + for ( it = tempList.begin(); it != tempList.end(); ++it ) + { + WQListItem *li; + li = new WQListItem(); + li->setQuestion(aCol); + li->setCorrect(1); + li->setOneOp(*it); + + if (count > 2) + { + + int a, b; + do + a = rs->getLong(count); //rand() % count; + while(a==*it); + + li->setTwoOp(a); + + do + b = rs->getLong(count); //rand() % count; + while(b == *it || b == a /*|| b < 0*/); + + li->setThreeOp(b); + + } + m_quizList.append(*li); + + } + +} + +bool WQQuiz::init() +{ + + bool result = false; + if (Prefs::enableBlanks()) + { + result = m_table->checkSyntax(true, true); + } + else + { + result = true; + } + + if (!result) + { + return false; + } + + int aCol; + int bCol; + + switch (m_quizMode) + { + case 1: + aCol = 0; + bCol = 1; + break; + case 2: + aCol = 1; + bCol = 0; + break; + case 3: + aCol = 0; + bCol = 1; + break; + case 4: + aCol = 1; + bCol = 0; + break; + case 5: + default: + aCol = 0; + bCol = 1; + break; + } + + addToList(aCol, bCol); + + //check if enough in list + switch (m_quizType) + { + case qtEditor: + // + break; + case qtFlash: + result = (m_quizList.count() > 0); + break; + case qtQA: + result = (m_quizList.count() > 0); + break; + case qtMultiple: + result = (m_quizList.count() > 2); + break; + } + + if (!result) + { + return false; + } + + if (m_quizMode == 5) + { + aCol = 1; + bCol = 0; + addToList(aCol, bCol); + } + + //Prepare final lists + activateBaseList(); + return true; +} + +void WQQuiz::listRandom() +{ + QPtrList list; + + for(int i = 0; i < m_quizList.count(); i++) + list.append((void*) i); + + KRandomSequence seq; + seq.randomize(&list); + + QuizList items; + for(int i = 0; i < m_quizList.count(); i++) + items.append(m_quizList[(long) list.take()]); + + m_quizList.clear(); + + for(int i = 0; i < items.count(); i++) + m_quizList.append(items[i]); +} + +bool WQQuiz::checkAnswer(int i, const QString & a) +{ + bool result = false; + WQListItem li = m_list[i]; + int j; + if (li.question() == 0) + { + j = 1; + } + else + { + j= 0; + } + QString ans = a; + QString tTemp = m_table -> text(li.oneOp(), j); + tTemp = tTemp.stripWhiteSpace(); + ans = ans.stripWhiteSpace(); + + if (m_quizType == qtQA) + { + if (QString(m_correctBlank).length() > 0) + { + QStringList la, ls; + if (ans.find(";") > 0) + ls = QStringList::split(";", ans); + else + ls.append(ans); + + if (m_correctBlank.find(";") > 0) + la = QStringList::split(";", m_correctBlank); + else + la.append(m_correctBlank); + + result = (ls.count() == la.count()); + if (result) + { + for (uint counter = 0; counter < la.count(); counter++) + { + result = (ls[counter].stripWhiteSpace() == la[counter].stripWhiteSpace()); + if (!result) + break; + } + } + } + else + { + result = (ans == tTemp); + } + } + else + { + if (m_quizType == qtMultiple) + { + if (Prefs::enableBlanks()) + { + tTemp.remove("["); + tTemp.remove("]"); + } + result = (ans == tTemp); + + } + else + { + result = (ans == tTemp); + } + + } + + if (!result) + { + m_errorList.append(li); + } + + return result; +} + +QStringList WQQuiz::multiOptions(int i) +{ + QString *s; + QStringList Result; + WQListItem li = m_list[i]; + + typedef QPtrList LS; + LS *ls; + ls = new QPtrList(); + + int j; + if (li.question() == 0) + { + j = 1; + } + else + { + j= 0; + } + + s= new QString(m_table->text(li.oneOp(), j)); + if (Prefs::enableBlanks()) + { + s->remove("["); + s->remove("]"); + } + ls->append(s); + + s = new QString(m_table->text(li.twoOp(), j)); + if (Prefs::enableBlanks()) + { + s->remove("["); + s->remove("]"); + } + ls->append(s); + + s = new QString(m_table->text(li.threeOp(), j)); + if (Prefs::enableBlanks()) + { + s->remove("["); + s->remove("]"); + } + ls->append(s); + + KRandomSequence rs; + rs.randomize(ls); + + while (ls->count()) + { + Result.append(*ls->first()); + ls->removeFirst(); + } + return Result; +} + +QString WQQuiz::quizIcon(int i, QuizIcon ico) +{ + QString s; + WQListItem li = m_list[i]; + if (ico == qiLeftCol) + { + if (li.question() == 0) + s = "question"; + else + s = "answer"; + } + + if (ico == qiRightCol) + { + if (li.question() == 0) + s = "answer"; + else + s = "question"; + } + return s; +} + +QString WQQuiz::yourAnswer(int i, const QString & s) +{ + QString result =""; + + if (QString(m_answerBlank).length() > 0) + { + QStringList ls; + + if (s.find(";") > 0) + ls = QStringList::split(";", s, true); + else + ls.append(s); + + result = m_answerBlank.replace("..........", ""); + + int offset = 0, counter = 0; + while (offset >= 0) + { + offset = result.find("", offset); + if (offset >= 0) + { + result.insert(offset + 3, ls[counter]); + offset++; + counter++; + } + } + result.append(""); + result.prepend(""); + } + else + { + result = s; + } + return result; +} + +QString WQQuiz::hint(int i) +{ + if (QString(m_correctBlank).length() > 0) + { + return m_correctBlank; + } + else + { + return answer(i); + } +} + +void WQQuiz::setQuizType(QuizType qt) +{ + m_quizType = qt; +} + +void WQQuiz::setQuizMode(int qm) +{ + m_quizMode = qm; +} + + +QString WQQuiz::question(int i) +{ + WQListItem li = m_list[i]; + QString s = m_table->text(li.oneOp(), li.question()); + if (Prefs::enableBlanks()) + { + s.remove("["); + s.remove("]"); + } + if (m_quizType != qtFlash && i > 0) + { + WQListItem li2 = m_list[i - 1]; + emit checkingAnswer(li2.oneOp()); + } + else + emit checkingAnswer(li.oneOp()); + + return s; +} + +QString WQQuiz::blankAnswer(int i) +{ + + QString r = ""; + m_correctBlank = ""; + m_answerBlank = ""; + QString tTemp; + + if (m_quizType == qtQA && Prefs::enableBlanks()) + { + WQListItem li = m_list[i]; + int j; + if (li.question() == 0) + { + j = 1; + } + else + { + j= 0; + } + tTemp = m_table->text(li.oneOp(), j); + r = tTemp; + QRegExp rx; + rx.setMinimal(true); + rx.setPattern("\\[.*\\]"); + + r.replace(rx, ".........."); + + if (r != tTemp) + { + m_answerBlank = r; + int offset = 0; + while (offset >= 0) + { + offset = rx.search(tTemp, offset); + if (offset >= 0) + { + if (m_correctBlank.length() > 0) + m_correctBlank = m_correctBlank + ";" + " " + tTemp.mid(offset + 1, tTemp.find(']', offset) - offset - 1); + else + m_correctBlank = tTemp.mid(offset + 1, tTemp.find(']', offset) - offset - 1); + offset++; + } + } + } + } + return m_answerBlank; +} + +QString WQQuiz::answer(int i) +{ + QString s; + WQListItem li = m_list[i]; + int j; + if (li.question() == 0) + { + j = 1; + } + else + { + j= 0; + } + + + if (m_quizType == qtQA) + { + s = m_table->text(li.oneOp(), j); + if (Prefs::enableBlanks()) + { + s.replace("[", ""); + s.replace("]", ""); + s.prepend(""); + s.append(""); + } + } + else + { + s = m_table->text(li.oneOp(), j); + if (Prefs::enableBlanks()) + { + s.remove("["); + s.remove("]"); + } + } + return s; +} + +QString WQQuiz::langQuestion(int i) +{ + WQListItem li = m_list[i]; + return m_table->horizontalHeader()->label(li.question()); +} + +QString WQQuiz::langAnswer(int i) +{ + + WQListItem li = m_list[i]; + + int j; + if (li.question() == 0) + { + j = 1; + } + else + { + j= 0; + } + + return m_table->horizontalHeader()->label(j); +} + +int WQQuiz::kbAnswer(int i) +{ +/* WQListItem *li = m_list->at(i); + if (li->question() == 0) + { + //@todo return m_table ->layoutLeft(); + } + else + { + //@todo return m_table -> layoutRight(); + }*/ + return 0; +} + +int WQQuiz::questionCount() +{ + return m_questionCount; +} + +void WQQuiz::finish() +{ + emit checkingAnswer(-1); +} + +#include "wqquiz.moc" diff --git a/kwordquiz/src/wqquiz.h b/kwordquiz/src/wqquiz.h new file mode 100644 index 00000000..94f77f4f --- /dev/null +++ b/kwordquiz/src/wqquiz.h @@ -0,0 +1,87 @@ +/* This file is part of KWordQuiz + Copyright (C) 2003 Peter Hedlund + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WQQUIZ_H +#define WQQUIZ_H + +#include + +#include "wqlistitem.h" +#include "kwordquizview.h" + +/** +@author Peter Hedlund +*/ + +typedef QValueList QuizList; + +class WQQuiz : public QObject +{ + Q_OBJECT + public: + enum QuizType {qtEditor, qtFlash, qtMultiple, qtQA}; + enum QuizIcon {qiLeftCol, qiRightCol, qiQuestion, qiCorrect, qiError}; + + WQQuiz(KWordQuizView * parent, const char * name=0); + + void activateErrorList(); + void activateBaseList(); + + bool init(); + void finish(); + bool checkAnswer(int i, const QString & ); + QStringList multiOptions(int i); + QString quizIcon(int i, QuizIcon ico); + QString yourAnswer(int i, const QString & s); + QString hint(int i); + + QuizType quizType() const {return m_quizType;} + void setQuizType(QuizType qt); + + int quizMode() const {return m_quizMode;} + void setQuizMode(int qm); + + int questionCount(); + QString question(int i); + QString blankAnswer(int i); + QString answer(int i); + QString langQuestion(int i); + QString langAnswer(int i); + + int kbAnswer(int i); + + signals: + void checkingAnswer(int ); + + private: + KWordQuizView *m_table; + int m_quizMode; + int m_questionCount; + QuizList m_list; + QuizList m_errorList; + QuizList m_quizList; + + QuizType m_quizType; + QString m_correctBlank; + QString m_answerBlank; + + void addToList(int aCol, int bCol); + void listRandom(); +}; + +#endif diff --git a/kwordquiz/src/wqscore.cpp b/kwordquiz/src/wqscore.cpp new file mode 100644 index 00000000..420a002d --- /dev/null +++ b/kwordquiz/src/wqscore.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + wqscore.cpp - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "wqscore.h" + +WQScore::WQScore() +{ + m_questionCount = 0; + m_percent = false; + m_error = 0; + m_correct = 0; + m_answerCount = 0; +} + + +WQScore::~WQScore() +{} + + +void WQScore::setAsPercent(bool p) +{ + m_percent = p; +} + +void WQScore::setQuestionCount(int c) +{ + m_questionCount = c; + //m_percent = false; + m_error = 0; + m_correct = 0; + m_answerCount = 0; +} + +void WQScore::countIncrement(CountDirection d) +{ + + if (d != cdNone) + m_answerCount++; + if (d == cdCorrect) + m_correct++; + if (d == cdError) + m_error++; +} + +/*! + \fn WQScore::answerText() + */ +QString WQScore::answerText() +{ + QString s; + if (m_percent) + { + float f = ((m_answerCount * 100.0) / m_questionCount); + if (m_answerCount > 0) + { + if (f < 1) + s = s.setNum(f, 'f', 1) + "%"; //for long lists (i.e. each question is less than 1%) we show one decimal + else + s = s.setNum(f, 'f', 0) + "%"; + } + else + s= valueToString(m_answerCount); + } + else + s = valueToString(m_answerCount); + return s; +} + +/*! + \fn WQScore::correctText() + */ +QString WQScore::correctText() +{ + QString s; + if (m_percent) + { + if (m_correct > 0) + { + float f = ((m_correct * 100.0) / m_answerCount); + s = s.setNum(f, 'f', 0) + "%"; + } + else + s = valueToString(m_correct); + + } + else + s = valueToString(m_correct); + return s; +} + +/*! + \fn WQScore::errorText() + */ +QString WQScore::errorText() +{ + QString s; + if (m_percent) + { + if (m_error > 0) + { + float f = ((m_error * 100.0) / m_answerCount); + s = s.setNum(f, 'f', 0) + "%"; + } + else + s = valueToString(m_error); + + } + else + s = valueToString(m_error); + return s; +} + +/*! + \fn WQScore::valueToString(int i) + */ +QString WQScore::valueToString(int i) +{ + QString s = ""; //return empty string for 0 + + if (i > 0) + s = s.setNum(i, 10); + + return s; +} + + + + diff --git a/kwordquiz/src/wqscore.h b/kwordquiz/src/wqscore.h new file mode 100644 index 00000000..6e493c58 --- /dev/null +++ b/kwordquiz/src/wqscore.h @@ -0,0 +1,50 @@ +/*************************************************************************** + wqscore.h - description + ------------------- + copyright : (C) 2003 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef WQSCORE_H +#define WQSCORE_H + +#include + +/** +@author Peter Hedlund +*/ +class WQScore{ +public: + enum CountDirection {cdCorrect, cdError, cdNone}; + WQScore(); + + ~WQScore(); + + void setAsPercent(bool p); + void setQuestionCount(int c); + void countIncrement(CountDirection d); + + QString answerText(); + QString correctText(); + QString errorText(); +private: + + + bool m_percent; + int m_questionCount; + int m_error; + int m_correct; + int m_answerCount; + QString valueToString(int i); +}; + +#endif diff --git a/kwordquiz/src/wqundo.cpp b/kwordquiz/src/wqundo.cpp new file mode 100644 index 00000000..99f81152 --- /dev/null +++ b/kwordquiz/src/wqundo.cpp @@ -0,0 +1,18 @@ +/*************************************************************************** + wqundo.cpp - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#include "wqundo.h" + + diff --git a/kwordquiz/src/wqundo.h b/kwordquiz/src/wqundo.h new file mode 100644 index 00000000..cc30425c --- /dev/null +++ b/kwordquiz/src/wqundo.h @@ -0,0 +1,67 @@ +/*************************************************************************** + wqundo.h - description + ------------------- + copyright : (C) 2004 by Peter Hedlund + email : peter.hedlund@kdemail.net + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef WQUNDO_H +#define WQUNDO_H + +#include + +#include "wqlreader.h" + +/** +@author Peter Hedlund +*/ +class WQUndo{ +public: + QFont font() const {return m_font;} + void setFont(const QFont & font) {m_font = font;} + + int colWidth0() {return m_colWidth0;} + void setColWidth0(int cw) {m_colWidth0 = cw;} + int colWidth1() {return m_colWidth1;} + void setColWidth1(int cw) {m_colWidth1 = cw;} + int colWidth2() {return m_colWidth2;} + void setColWidth2(int cw) {m_colWidth2 = cw;} + int numRows() {return m_numRows;} + void setNumRows(int n) {m_numRows = n;} + + int currentRow() {return m_currentRow;} + void setCurrentRow(int r) {m_currentRow = r;} + int currentCol() {return m_currentCol;} + void setCurrentCol(int c) {m_currentCol = c;} + QTableSelection selection() const {return m_selection;} + void setSelection(const QTableSelection & sel) {m_selection = sel;} + + KWqlDataItemList list() const {return m_list;} + void setList(const KWqlDataItemList & list) {m_list = list;} + + QString text() const {return m_text;} + void setText(const QString & s) {m_text = s;} + +private: + QFont m_font; + int m_colWidth0; + int m_colWidth1; + int m_colWidth2; + int m_numRows; + int m_currentRow; + int m_currentCol; + QTableSelection m_selection; + KWqlDataItemList m_list; + + QString m_text; +}; + +#endif diff --git a/kwordquiz/src/x-kwordquiz.desktop b/kwordquiz/src/x-kwordquiz.desktop new file mode 100644 index 00000000..ed10fa40 --- /dev/null +++ b/kwordquiz/src/x-kwordquiz.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Comment=KWordQuiz Vocabulary +Comment[af]=KWordQuiz Woordeskat +Comment[be]=Слоўнік KWordQuiz +Comment[bg]=Речник KWordQuiz +Comment[bn]=কে-ওয়ার্ড-কুইজ-এর শব্দ ভাণ্ডার +Comment[br]=Geriaoueg KWordQuiz +Comment[bs]=KWordQuiz rječnik +Comment[ca]=Vocabulari de KWordQuiz +Comment[cs]=KWordQuiz slovní zásoba +Comment[csb]=Słowizna KWordQuiz +Comment[cy]=Geirfa KWordQuiz +Comment[da]=KWordQuiz ordforråd +Comment[de]=KWordQuiz-Vokabeln +Comment[el]=Λεξικό του KWordQuiz +Comment[eo]=KWordQuiz vorprovizo +Comment[es]=Vocabulario de KWordQuiz +Comment[et]=KWordQuiz sõnastik +Comment[eu]=KWordQuiz hiztegia +Comment[fi]=KWordQuiz-sanasto +Comment[fr]=Vocabulaire de KWordQuiz +Comment[ga]=Stór Focal KWordQuiz +Comment[gl]=Vocabulario de KWordQuiz +Comment[he]=KWordQuiz אוצר מילים +Comment[hi]=के-वर्ड-क्विज़ शब्दावली +Comment[hr]=KWordQuiz vokabular +Comment[hu]=KWordQuiz-szótárfájl +Comment[is]=KWordQuiz orðaforði +Comment[it]=Vocabolario KWordQuiz +Comment[ja]=KWordQuiz 単語集 +Comment[ka]=KWordQuiz სიტყვარი +Comment[km]=វាក្យសព្ទ KWordQuiz +Comment[lt]=KWordQuiz žodynas +Comment[mk]=KWordQuiz Речник +Comment[ms]=Perbendaharaan Kata KWordQuiz +Comment[nb]=KWordQuiz-vokabular +Comment[nds]=KWordQuiz-Vokaveln +Comment[ne]=केडीई वर्ड क्विज शब्दज्ञान +Comment[nl]=KWordQuiz-woordenschat +Comment[nn]=KWordQuiz-vokabular +Comment[pl]=Słownik programu KWordQuiz +Comment[pt]=Vocabulário do KWordQuiz +Comment[pt_BR]=Vocabulário do KWordQuiz +Comment[ru]=Словарь KWordQuiz +Comment[sk]=Slovník KWordQuiz +Comment[sl]=Besednjak za KWordQuiz +Comment[sr]=Речник KWordQuiz-а +Comment[sr@Latn]=Rečnik KWordQuiz-a +Comment[sv]=Kwordquiz-ordlista +Comment[ta]=கேவார்த்தை வினாவிடை சொல்லாக்கம் +Comment[tg]=Луғати KҲарфИмтиҳон +Comment[tr]=KWordQuiz Sözlüğü +Comment[uk]=Словник KWordQuiz +Comment[vi]=Từ vựng Đố Từ K +Comment[zh_CN]=KWordQuiz 词汇 +Comment[zh_TW]=KWordQuiz 字彙 +Hidden=false +Icon=kwordquiz_doc +MimeType=application/x-kwordquiz +Patterns=*.wql +Type=MimeType + -- cgit v1.2.1