studium 0.14.16

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of studium might be problematic. Click here for more details.

Files changed (883) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +2987 -0
  3. data/bin/ask_exam_question +7 -0
  4. data/bin/check_description_of_these_lectures +7 -0
  5. data/bin/curriculum_module_displayer +7 -0
  6. data/bin/cycle +7 -0
  7. data/bin/d10 +7 -0
  8. data/bin/d100 +7 -0
  9. data/bin/d15 +7 -0
  10. data/bin/d20 +7 -0
  11. data/bin/d25 +7 -0
  12. data/bin/d3 +7 -0
  13. data/bin/d30 +7 -0
  14. data/bin/d5 +7 -0
  15. data/bin/determine_curricula +7 -0
  16. data/bin/display_lecture_url +7 -0
  17. data/bin/exam_registration_at +7 -0
  18. data/bin/exam_statistics +7 -0
  19. data/bin/exams_per_month +9 -0
  20. data/bin/finished_exams_at_this_university +7 -0
  21. data/bin/flashcards +7 -0
  22. data/bin/from_curriculum_id_to_university +9 -0
  23. data/bin/location_to_this_exam_topic.rb +7 -0
  24. data/bin/mandatory_continuous_assessment +7 -0
  25. data/bin/mandatory_upcoming_courses +10 -0
  26. data/bin/n_ECTS +7 -0
  27. data/bin/n_exam_questions_already_answered +16 -0
  28. data/bin/nquestions +7 -0
  29. data/bin/nsolved +7 -0
  30. data/bin/open_last_exam_question_asked_file +7 -0
  31. data/bin/passed_exams +7 -0
  32. data/bin/passed_pr/303/274fungsimmanente_courses +7 -0
  33. data/bin/pdf_for +7 -0
  34. data/bin/random_exam_topic +7 -0
  35. data/bin/report_solved_topics +7 -0
  36. data/bin/return_n_ects_from_this_file +7 -0
  37. data/bin/search_for_n_ects +7 -0
  38. data/bin/show_lectures_on_the_commandline +7 -0
  39. data/bin/show_themes +7 -0
  40. data/bin/solved +9 -0
  41. data/bin/solved_ects +7 -0
  42. data/bin/studienkennzahl +7 -0
  43. data/bin/studium +7 -0
  44. data/bin/studium_skeleton +7 -0
  45. data/bin/ufind +7 -0
  46. data/bin/upcoming_exams +7 -0
  47. data/bin/week_parser +7 -0
  48. data/doc/ECTS_CONSIDERATIONS.md +82 -0
  49. data/doc/HOW_TO_DETERMINE_WHICH_PART_IS_THE_QUESTION_AND_WHICH_PART_IS_THE_ANSWER.md +44 -0
  50. data/doc/README.gen +2947 -0
  51. data/doc/SQL_database_specification.md +46 -0
  52. data/doc/deprecated_components.md +24 -0
  53. data/doc/documentation_for_the_file_lecture_information.md +311 -0
  54. data/doc/elegant_colours.md +21 -0
  55. data/doc/statistics/yearly_statistics.md +5 -0
  56. data/doc/todo/todo_for_the_graphical_parts_of_the_studium_gem_including_www_related_aspects.md +32 -0
  57. data/doc/todo/todo_for_the_studium_gem.md +58 -0
  58. data/img/STUDIES.png +0 -0
  59. data/lib/studium/autoinclude.rb +7 -0
  60. data/lib/studium/base/base.rb +3054 -0
  61. data/lib/studium/base/prototype.rb +592 -0
  62. data/lib/studium/c/README.md +2 -0
  63. data/lib/studium/c/a.out +0 -0
  64. data/lib/studium/c/obtain_random_entry.c +11 -0
  65. data/lib/studium/check_and_sanitize/README.md +15 -0
  66. data/lib/studium/check_and_sanitize/check_curriculum_for_correct_separation_of_bachelor_and_master.rb +141 -0
  67. data/lib/studium/check_and_sanitize/check_for_all_exam_topics_being_registered.rb +118 -0
  68. data/lib/studium/check_and_sanitize/check_for_correct_themes_of_each_course.rb +100 -0
  69. data/lib/studium/check_and_sanitize/check_for_existing_description_of_this_lecture.rb +191 -0
  70. data/lib/studium/check_and_sanitize/check_important_exams.rb +113 -0
  71. data/lib/studium/check_and_sanitize/check_the_lecture_information_file.rb +163 -0
  72. data/lib/studium/check_and_sanitize/find_duplicate_lectures.rb +124 -0
  73. data/lib/studium/check_and_sanitize/missing_priority_entry.rb +44 -0
  74. data/lib/studium/check_and_sanitize/sanitize_lecture_information.rb +428 -0
  75. data/lib/studium/check_and_sanitize/sanitize_this_string_containing_the_lva_dates.rb +79 -0
  76. data/lib/studium/colours/colours.rb +572 -0
  77. data/lib/studium/colours/sfancy.rb +46 -0
  78. data/lib/studium/colours/sfile.rb +35 -0
  79. data/lib/studium/colours/simp.rb +40 -0
  80. data/lib/studium/colours/use_colours.rb +39 -0
  81. data/lib/studium/colours/use_this_colour_for_exam_questions_and_exam_answers.rb +80 -0
  82. data/lib/studium/commandline/commandline.rb +932 -0
  83. data/lib/studium/commandline/menu.rb +906 -0
  84. data/lib/studium/constants/colours.rb +14 -0
  85. data/lib/studium/constants/constants.rb +1708 -0
  86. data/lib/studium/constants/image_constants.rb +271 -0
  87. data/lib/studium/constants/regexes.rb +44 -0
  88. data/lib/studium/constants/web_constants.rb +28 -0
  89. data/lib/studium/css/project.css +267 -0
  90. data/lib/studium/curricula/curriculum.rb +210 -0
  91. data/lib/studium/curricula/curriculum_as_string.rb +280 -0
  92. data/lib/studium/curricula/curriculum_module_displayer/constants.rb +33 -0
  93. data/lib/studium/curricula/curriculum_module_displayer/curriculum_module_displayer.rb +417 -0
  94. data/lib/studium/curricula/curriculum_module_displayer/initialize.rb +25 -0
  95. data/lib/studium/curricula/curriculum_module_displayer/menu.rb +45 -0
  96. data/lib/studium/curricula/curriculum_module_displayer/reset.rb +74 -0
  97. data/lib/studium/curricula/curriculum_module_displayer/run.rb +20 -0
  98. data/lib/studium/curricula/curriculum_module_displayer/set_use_this_curriculum.rb +93 -0
  99. data/lib/studium/curricula/curriculum_module_displayer/show_and_report.rb +190 -0
  100. data/lib/studium/curricula/determine_curricula/constants.rb +11 -0
  101. data/lib/studium/curricula/determine_curricula/determine_curricula.rb +36 -0
  102. data/lib/studium/curricula/determine_curricula/help.rb +39 -0
  103. data/lib/studium/curricula/determine_curricula/initialize.rb +48 -0
  104. data/lib/studium/curricula/determine_curricula/menu.rb +151 -0
  105. data/lib/studium/curricula/determine_curricula/misc.rb +403 -0
  106. data/lib/studium/curricula/determine_curricula/report.rb +143 -0
  107. data/lib/studium/curricula/determine_curricula/reset.rb +59 -0
  108. data/lib/studium/curricula/determine_curricula/run.rb +19 -0
  109. data/lib/studium/curricula/determine_elective_courses_in_this_curriculum.rb +112 -0
  110. data/lib/studium/curricula/display_bachelor_curricula.rb +90 -0
  111. data/lib/studium/curricula/handle_curricula/README.md +9 -0
  112. data/lib/studium/curricula/handle_curricula/handle_curricula.rb +179 -0
  113. data/lib/studium/curricula/handle_curricula/misc.rb +705 -0
  114. data/lib/studium/curricula/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.rb +323 -0
  115. data/lib/studium/curricula/modules/display_on_the_commandline.rb +319 -0
  116. data/lib/studium/curricula/modules/return_n_ects_in_this_module.rb +75 -0
  117. data/lib/studium/curricula/n_percent_solved_in_this_curriculum.rb +75 -0
  118. data/lib/studium/curricula/prepare_individual_curriculum.rb +304 -0
  119. data/lib/studium/curricula/random_curriculum_creator/random_curriculum_creator.rb +163 -0
  120. data/lib/studium/curricula/show_lectures_of_this_curriculum.rb +114 -0
  121. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/constants.rb +11 -0
  122. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/initialize.rb +27 -0
  123. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/menu.rb +35 -0
  124. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/misc.rb +264 -0
  125. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/report.rb +163 -0
  126. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/reset.rb +64 -0
  127. data/lib/studium/curricula/show_lectures_of_this_curriculum_id/show_lectures_of_this_curriculum_id.rb +38 -0
  128. data/lib/studium/curricula/show_solved_percentage_among_the_registered_curricula.rb +87 -0
  129. data/lib/studium/curricula/sorted_individual_curricula.rb +121 -0
  130. data/lib/studium/ects/boku_ects_splitter.rb +128 -0
  131. data/lib/studium/ects/ects_per_university.rb +179 -0
  132. data/lib/studium/ects/ects_scanner.rb +141 -0
  133. data/lib/studium/ects/ects_to_university_parser.rb +142 -0
  134. data/lib/studium/ects/last_entry_is_curriculum.rb +150 -0
  135. data/lib/studium/ects/n_ects_in_these_lectures.rb +196 -0
  136. data/lib/studium/ects/n_ects_points_in_mandatory_presence_courses.rb +50 -0
  137. data/lib/studium/ects/return_n_ects_from_this_file.rb +59 -0
  138. data/lib/studium/ects/return_n_ects_from_this_url.rb +196 -0
  139. data/lib/studium/ects/search_for_n_ects.rb +614 -0
  140. data/lib/studium/ects/show_completed_ects_in_all_curricula.rb +191 -0
  141. data/lib/studium/ects/show_passed_credits_per_curriculum.rb +276 -0
  142. data/lib/studium/ects/simple_total_ects_points.rb +135 -0
  143. data/lib/studium/ects/solved_ects/constants.rb +19 -0
  144. data/lib/studium/ects/solved_ects/reset.rb +51 -0
  145. data/lib/studium/ects/solved_ects/solved_ects.rb +325 -0
  146. data/lib/studium/ects/solved_ects_per_university/reset.rb +25 -0
  147. data/lib/studium/ects/solved_ects_per_university/solved_ects_per_university.rb +106 -0
  148. data/lib/studium/ects/still_missing.rb +129 -0
  149. data/lib/studium/ects/sum_of_ects.rb +144 -0
  150. data/lib/studium/encoding/encoding.rb +108 -0
  151. data/lib/studium/exam_topics/RNAi_siRNA_and_miRNA +100 -0
  152. data/lib/studium/exam_topics/abfall_als_ressource +86 -0
  153. data/lib/studium/exam_topics/advanced_biochemistry +793 -0
  154. data/lib/studium/exam_topics/advanced_biotechnology +225 -0
  155. data/lib/studium/exam_topics/advanced_cellbiology +105 -0
  156. data/lib/studium/exam_topics/advanced_chemistry +518 -0
  157. data/lib/studium/exam_topics/advanced_microbiology +44 -0
  158. data/lib/studium/exam_topics/advanced_topics_in_plant_sciences +85 -0
  159. data/lib/studium/exam_topics/advanced_virology +229 -0
  160. data/lib/studium/exam_topics/ageing +117 -0
  161. data/lib/studium/exam_topics/agrar_ecology +63 -0
  162. data/lib/studium/exam_topics/agrarmarkt +74 -0
  163. data/lib/studium/exam_topics/agrarphysik +35 -0
  164. data/lib/studium/exam_topics/alcohols +29 -0
  165. data/lib/studium/exam_topics/algorithms +59 -0
  166. data/lib/studium/exam_topics/allergie +76 -0
  167. data/lib/studium/exam_topics/allgemeine_genetik +1006 -0
  168. data/lib/studium/exam_topics/allgemeine_mikrobiologie +977 -0
  169. data/lib/studium/exam_topics/aminoacids +447 -0
  170. data/lib/studium/exam_topics/analytische_chemie_1 +132 -0
  171. data/lib/studium/exam_topics/analytische_chemie_2 +31 -0
  172. data/lib/studium/exam_topics/anatomie +292 -0
  173. data/lib/studium/exam_topics/anorganische_chemie +323 -0
  174. data/lib/studium/exam_topics/anthropologie +117 -0
  175. data/lib/studium/exam_topics/antibodies_and_antigens +770 -0
  176. data/lib/studium/exam_topics/apoptosis +35 -0
  177. data/lib/studium/exam_topics/archaea +95 -0
  178. data/lib/studium/exam_topics/architecture +8 -0
  179. data/lib/studium/exam_topics/artificial_intelligence +85 -0
  180. data/lib/studium/exam_topics/atomemissionsspektrometrie +6 -0
  181. data/lib/studium/exam_topics/audio +11 -0
  182. data/lib/studium/exam_topics/bacteriophages +243 -0
  183. data/lib/studium/exam_topics/basic_biochemistry +1005 -0
  184. data/lib/studium/exam_topics/basic_biotechnology +1004 -0
  185. data/lib/studium/exam_topics/basic_chemistry +1007 -0
  186. data/lib/studium/exam_topics/basic_virology +1010 -0
  187. data/lib/studium/exam_topics/bauwesen +6 -0
  188. data/lib/studium/exam_topics/betriebssysteme +126 -0
  189. data/lib/studium/exam_topics/betriebswirtschaftslehre +29 -0
  190. data/lib/studium/exam_topics/bioanalytik_und_biosensoren +389 -0
  191. data/lib/studium/exam_topics/biochips +79 -0
  192. data/lib/studium/exam_topics/bioelektrochemie +57 -0
  193. data/lib/studium/exam_topics/biofilms +24 -0
  194. data/lib/studium/exam_topics/bioinformatics +507 -0
  195. data/lib/studium/exam_topics/biological_therapeutics +155 -0
  196. data/lib/studium/exam_topics/biologie +139 -0
  197. data/lib/studium/exam_topics/biomarkers +135 -0
  198. data/lib/studium/exam_topics/biomaterials +89 -0
  199. data/lib/studium/exam_topics/biomembranes +6 -0
  200. data/lib/studium/exam_topics/bionik +65 -0
  201. data/lib/studium/exam_topics/biophysik +34 -0
  202. data/lib/studium/exam_topics/biopolymers +10 -0
  203. data/lib/studium/exam_topics/bioprozesstechnik +149 -0
  204. data/lib/studium/exam_topics/bioressourcenmanagement +78 -0
  205. data/lib/studium/exam_topics/birds +3 -0
  206. data/lib/studium/exam_topics/bodenkunde +373 -0
  207. data/lib/studium/exam_topics/bodenmikrobiologie +40 -0
  208. data/lib/studium/exam_topics/cancerbiology +454 -0
  209. data/lib/studium/exam_topics/cell_cultures +221 -0
  210. data/lib/studium/exam_topics/cellbiology +1011 -0
  211. data/lib/studium/exam_topics/cellular_transport_and_protein_secretion +27 -0
  212. data/lib/studium/exam_topics/cellular_vesicles +11 -0
  213. data/lib/studium/exam_topics/cellulose +6 -0
  214. data/lib/studium/exam_topics/chemische_technologie_anorganischer_stoffe +209 -0
  215. data/lib/studium/exam_topics/chemische_technologie_organischer_stoffe +25 -0
  216. data/lib/studium/exam_topics/chemisches_labor +60 -0
  217. data/lib/studium/exam_topics/chemotaxis_quorum_sensing_and_motility_in_prokaryotes +91 -0
  218. data/lib/studium/exam_topics/citric_acid_cycle +80 -0
  219. data/lib/studium/exam_topics/clinical_microbiology +506 -0
  220. data/lib/studium/exam_topics/computer_science +284 -0
  221. data/lib/studium/exam_topics/computer_vision_and_computer_graphics +12 -0
  222. data/lib/studium/exam_topics/crispr +48 -0
  223. data/lib/studium/exam_topics/cyanobacteria +43 -0
  224. data/lib/studium/exam_topics/cytogenetics_and_chromosome_biology +570 -0
  225. data/lib/studium/exam_topics/cytokines +6 -0
  226. data/lib/studium/exam_topics/databases_and_sql +116 -0
  227. data/lib/studium/exam_topics/dna_mutation_and_dna_repair +69 -0
  228. data/lib/studium/exam_topics/dna_replication +57 -0
  229. data/lib/studium/exam_topics/ecogenetics +26 -0
  230. data/lib/studium/exam_topics/ecological_agriculture +12 -0
  231. data/lib/studium/exam_topics/ecology +317 -0
  232. data/lib/studium/exam_topics/economy +211 -0
  233. data/lib/studium/exam_topics/elektronenmikroskopie +356 -0
  234. data/lib/studium/exam_topics/elektrophorese +89 -0
  235. data/lib/studium/exam_topics/elektrotechnik_und_elektrizit/303/244t +41 -0
  236. data/lib/studium/exam_topics/elisa +54 -0
  237. data/lib/studium/exam_topics/embryologie_und_entwicklung +603 -0
  238. data/lib/studium/exam_topics/endospores_and_spores +104 -0
  239. data/lib/studium/exam_topics/enzymes_and_cofactors +353 -0
  240. data/lib/studium/exam_topics/epigenetik +184 -0
  241. data/lib/studium/exam_topics/erste_hilfe +158 -0
  242. data/lib/studium/exam_topics/ethik +138 -0
  243. data/lib/studium/exam_topics/evolution_and_evolutionary_genetics +356 -0
  244. data/lib/studium/exam_topics/excel +7 -0
  245. data/lib/studium/exam_topics/fish +19 -0
  246. data/lib/studium/exam_topics/fluorescence_microscopy +7 -0
  247. data/lib/studium/exam_topics/food_microbiology_and_food_biotechnology +83 -0
  248. data/lib/studium/exam_topics/forensik +11 -0
  249. data/lib/studium/exam_topics/forstwirtschaft +53 -0
  250. data/lib/studium/exam_topics/fortgeschrittene_genetik +576 -0
  251. data/lib/studium/exam_topics/fortgeschrittene_gentechnik +217 -0
  252. data/lib/studium/exam_topics/fortgeschrittene_physik +6 -0
  253. data/lib/studium/exam_topics/fungi +80 -0
  254. data/lib/studium/exam_topics/genetische_krankheiten +187 -0
  255. data/lib/studium/exam_topics/genexpression +1008 -0
  256. data/lib/studium/exam_topics/genomics_and_metagenomics +272 -0
  257. data/lib/studium/exam_topics/gentechnik_und_praktische_biochemie +928 -0
  258. data/lib/studium/exam_topics/geochemistry +67 -0
  259. data/lib/studium/exam_topics/geography +8 -0
  260. data/lib/studium/exam_topics/geologie_und_mineralogie +626 -0
  261. data/lib/studium/exam_topics/geometrie +54 -0
  262. data/lib/studium/exam_topics/geschichte +94 -0
  263. data/lib/studium/exam_topics/gluconeogenesis +64 -0
  264. data/lib/studium/exam_topics/glycogen +25 -0
  265. data/lib/studium/exam_topics/glycolysis +109 -0
  266. data/lib/studium/exam_topics/glykomik +101 -0
  267. data/lib/studium/exam_topics/glyoxylatzyklus +31 -0
  268. data/lib/studium/exam_topics/grassland_cultivation +32 -0
  269. data/lib/studium/exam_topics/hormone +139 -0
  270. data/lib/studium/exam_topics/html +7 -0
  271. data/lib/studium/exam_topics/human_ecology +8 -0
  272. data/lib/studium/exam_topics/hygiene +224 -0
  273. data/lib/studium/exam_topics/imaging_and_microscopy +265 -0
  274. data/lib/studium/exam_topics/immunanalytik +94 -0
  275. data/lib/studium/exam_topics/immunologie +998 -0
  276. data/lib/studium/exam_topics/informatik +103 -0
  277. data/lib/studium/exam_topics/innate_immunity +24 -0
  278. data/lib/studium/exam_topics/insekten +64 -0
  279. data/lib/studium/exam_topics/insulin_and_diabetes +57 -0
  280. data/lib/studium/exam_topics/java +597 -0
  281. data/lib/studium/exam_topics/javascript +14 -0
  282. data/lib/studium/exam_topics/klima +6 -0
  283. data/lib/studium/exam_topics/kryptographie +9 -0
  284. data/lib/studium/exam_topics/landtechnik +26 -0
  285. data/lib/studium/exam_topics/lebensmittel +222 -0
  286. data/lib/studium/exam_topics/lebensmitteltechnologie +16 -0
  287. data/lib/studium/exam_topics/linux +5 -0
  288. data/lib/studium/exam_topics/lipids +95 -0
  289. data/lib/studium/exam_topics/macroeconomics +40 -0
  290. data/lib/studium/exam_topics/marketing +7 -0
  291. data/lib/studium/exam_topics/mathematics +280 -0
  292. data/lib/studium/exam_topics/medizin_und_biomedizinische_technik +251 -0
  293. data/lib/studium/exam_topics/medizinische_chemie_und_pharmazie +416 -0
  294. data/lib/studium/exam_topics/messtechnik_und_regeltechnik +104 -0
  295. data/lib/studium/exam_topics/metabolismus +423 -0
  296. data/lib/studium/exam_topics/meteorologie_und_atmosph/303/244re +91 -0
  297. data/lib/studium/exam_topics/microbial_ecology +35 -0
  298. data/lib/studium/exam_topics/microcontrollers +11 -0
  299. data/lib/studium/exam_topics/mikrobielle_lebensgemeinschaften +33 -0
  300. data/lib/studium/exam_topics/mikrobielle_physiologie +204 -0
  301. data/lib/studium/exam_topics/mitochondria +33 -0
  302. data/lib/studium/exam_topics/mixed +286 -0
  303. data/lib/studium/exam_topics/molecular_biology_of_plants +249 -0
  304. data/lib/studium/exam_topics/molekulare_medizin +133 -0
  305. data/lib/studium/exam_topics/nanotechnologie +453 -0
  306. data/lib/studium/exam_topics/nature_conservation_and_biodiversity +211 -0
  307. data/lib/studium/exam_topics/naturstoffe +9 -0
  308. data/lib/studium/exam_topics/netzwerke +34 -0
  309. data/lib/studium/exam_topics/neurobiology +272 -0
  310. data/lib/studium/exam_topics/nucleotide_sequencing +38 -0
  311. data/lib/studium/exam_topics/nutztierethologie +11 -0
  312. data/lib/studium/exam_topics/object_oriented_modeling +14 -0
  313. data/lib/studium/exam_topics/obstbau +249 -0
  314. data/lib/studium/exam_topics/organische_chemie +1007 -0
  315. data/lib/studium/exam_topics/organische_chemie_2 +125 -0
  316. data/lib/studium/exam_topics/paleobiology +39 -0
  317. data/lib/studium/exam_topics/parasitic_diseases_and_molecular_infection_biology +336 -0
  318. data/lib/studium/exam_topics/patent_law +55 -0
  319. data/lib/studium/exam_topics/pathologie +723 -0
  320. data/lib/studium/exam_topics/pcr +152 -0
  321. data/lib/studium/exam_topics/pentosephosphatweg +41 -0
  322. data/lib/studium/exam_topics/peroxisomes_glycosomes_and_lysosomes +66 -0
  323. data/lib/studium/exam_topics/pflanzenanatomie +255 -0
  324. data/lib/studium/exam_topics/pflanzenbau +24 -0
  325. data/lib/studium/exam_topics/pflanzenschutz +35 -0
  326. data/lib/studium/exam_topics/pflanzenwissenschaften +1009 -0
  327. data/lib/studium/exam_topics/pharmaceutical_biotechnology +251 -0
  328. data/lib/studium/exam_topics/physik +443 -1
  329. data/lib/studium/exam_topics/physikalische_chemie +86 -0
  330. data/lib/studium/exam_topics/physiology_and_histology +520 -0
  331. data/lib/studium/exam_topics/phytochemie +33 -0
  332. data/lib/studium/exam_topics/plant_biotechnology +129 -0
  333. data/lib/studium/exam_topics/plant_breeding +64 -0
  334. data/lib/studium/exam_topics/plant_development +50 -0
  335. data/lib/studium/exam_topics/populationsgenetik +137 -0
  336. data/lib/studium/exam_topics/posttranslationale_modifikation_von_proteinen +195 -0
  337. data/lib/studium/exam_topics/projektmanagement +220 -0
  338. data/lib/studium/exam_topics/prokaryote_genetics +547 -0
  339. data/lib/studium/exam_topics/protein_engineering +16 -0
  340. data/lib/studium/exam_topics/proteolyse +36 -0
  341. data/lib/studium/exam_topics/proteomik +40 -0
  342. data/lib/studium/exam_topics/prozesstechnik +95 -0
  343. data/lib/studium/exam_topics/psychologie +14 -0
  344. data/lib/studium/exam_topics/python +355 -0
  345. data/lib/studium/exam_topics/quality_management +263 -0
  346. data/lib/studium/exam_topics/rechtsgrundlagen +116 -0
  347. data/lib/studium/exam_topics/research_topics_in_immunobiology +42 -0
  348. data/lib/studium/exam_topics/rna_and_dna +457 -0
  349. data/lib/studium/exam_topics/rna_seq +11 -0
  350. data/lib/studium/exam_topics/robotik +6 -0
  351. data/lib/studium/exam_topics/ruby +183 -0
  352. data/lib/studium/exam_topics/ruby_on_rails +63 -0
  353. data/lib/studium/exam_topics/scientific_writing_and_publishing +38 -0
  354. data/lib/studium/exam_topics/semisynthese_von_proteinen_und_nukleotiden +120 -0
  355. data/lib/studium/exam_topics/sexualbiologie +108 -0
  356. data/lib/studium/exam_topics/signal_transduction_and_laser_systems +197 -0
  357. data/lib/studium/exam_topics/splicing_exons_and_introns +63 -0
  358. data/lib/studium/exam_topics/statistik +241 -0
  359. data/lib/studium/exam_topics/stemcells +159 -0
  360. data/lib/studium/exam_topics/stickstofffixierung +76 -0
  361. data/lib/studium/exam_topics/structural_bioinformatics +54 -0
  362. data/lib/studium/exam_topics/strukturbiologie +387 -0
  363. data/lib/studium/exam_topics/system_biology_and_synthetic_biology +103 -0
  364. data/lib/studium/exam_topics/systematische_zoologie +436 -0
  365. data/lib/studium/exam_topics/technical_ecology +144 -0
  366. data/lib/studium/exam_topics/technische_chemie +204 -0
  367. data/lib/studium/exam_topics/technische_grundlagen_der_informatik +39 -0
  368. data/lib/studium/exam_topics/technische_mikrobiologie +393 -0
  369. data/lib/studium/exam_topics/technisches_zeichnen +5 -0
  370. data/lib/studium/exam_topics/the_bacterial_cell_wall +97 -0
  371. data/lib/studium/exam_topics/the_c_plus_plus_programming_language +491 -0
  372. data/lib/studium/exam_topics/the_c_programming_language +129 -0
  373. data/lib/studium/exam_topics/the_cellcycle +89 -0
  374. data/lib/studium/exam_topics/the_european_union +119 -0
  375. data/lib/studium/exam_topics/the_interferon_system +39 -0
  376. data/lib/studium/exam_topics/the_microbiome +164 -0
  377. data/lib/studium/exam_topics/the_universe +26 -0
  378. data/lib/studium/exam_topics/theoretische_chemie +5 -0
  379. data/lib/studium/exam_topics/theoretische_informatik +157 -0
  380. data/lib/studium/exam_topics/thermodynamics +3 -0
  381. data/lib/studium/exam_topics/tierzucht +139 -0
  382. data/lib/studium/exam_topics/toxikologie +447 -0
  383. data/lib/studium/exam_topics/transcription +164 -0
  384. data/lib/studium/exam_topics/translation_ribosomes_and_translational_control +144 -0
  385. data/lib/studium/exam_topics/umweltbiotechnologie +64 -0
  386. data/lib/studium/exam_topics/umweltchemie +233 -0
  387. data/lib/studium/exam_topics/urbanism_and_traffic +19 -0
  388. data/lib/studium/exam_topics/urea_cycle +55 -0
  389. data/lib/studium/exam_topics/vaccines_and_vaccination +246 -0
  390. data/lib/studium/exam_topics/vectors_and_gene_therapy +246 -0
  391. data/lib/studium/exam_topics/verfahrenstechnik +37 -0
  392. data/lib/studium/exam_topics/veterinary_medicine +10 -0
  393. data/lib/studium/exam_topics/vitamine +25 -0
  394. data/lib/studium/exam_topics/wasserkunde +137 -0
  395. data/lib/studium/exam_topics/weinbau +82 -0
  396. data/lib/studium/exam_topics/wissenschaft +18 -0
  397. data/lib/studium/exam_topics/yeast +102 -0
  398. data/lib/studium/exam_topics/zoologie +333 -0
  399. data/lib/studium/exams/afterburn/afterburn.rb +257 -0
  400. data/lib/studium/exams/ask_exam_from_the_upcoming_exams_pool.rb +150 -0
  401. data/lib/studium/exams/ask_exam_topic_question.rb +112 -0
  402. data/lib/studium/exams/ask_question_from_alias.rb +141 -0
  403. data/lib/studium/exams/ask_question_from_any_of_the_still_missing_lectures.rb +131 -0
  404. data/lib/studium/exams/ask_question_from_grouped_themes.rb +141 -0
  405. data/lib/studium/exams/ask_question_from_last_topic.rb +91 -0
  406. data/lib/studium/exams/ask_random_question.rb +195 -0
  407. data/lib/studium/exams/autoinclude.rb +7 -0
  408. data/lib/studium/exams/average_grade.rb +396 -0
  409. data/lib/studium/exams/csv/create_csv_passed_exams_file.rb +217 -0
  410. data/lib/studium/exams/cycle.rb +291 -0
  411. data/lib/studium/exams/dataset.rb +124 -0
  412. data/lib/studium/exams/designate_ten_random_exam_topics/designate_ten_random_exam_topics.rb +88 -0
  413. data/lib/studium/exams/exam/exam.rb +130 -0
  414. data/lib/studium/exams/exam_question/README.md +3 -0
  415. data/lib/studium/exams/exam_question/answer.rb +193 -0
  416. data/lib/studium/exams/exam_question/constants.rb +111 -0
  417. data/lib/studium/exams/exam_question/exam_question.rb +1136 -0
  418. data/lib/studium/exams/exam_question/menu.rb +333 -0
  419. data/lib/studium/exams/exam_question/misc.rb +898 -0
  420. data/lib/studium/exams/exam_question/question.rb +91 -0
  421. data/lib/studium/exams/exam_question/reset.rb +96 -0
  422. data/lib/studium/exams/exam_registration_at/constants.rb +49 -0
  423. data/lib/studium/exams/exam_registration_at/exam_registration_at.rb +242 -0
  424. data/lib/studium/exams/exam_registration_at/help.rb +46 -0
  425. data/lib/studium/exams/exam_registration_at/menu.rb +81 -0
  426. data/lib/studium/exams/exam_registration_at/report_and_show.rb +133 -0
  427. data/lib/studium/exams/exam_registration_at/reset.rb +54 -0
  428. data/lib/studium/exams/exam_statistics_from_this_file/exam_statistics_from_this_file.rb +119 -0
  429. data/lib/studium/exams/exam_topics.rb +194 -0
  430. data/lib/studium/exams/exams.rb +20 -0
  431. data/lib/studium/exams/exams_per_month/exams_per_month.rb +2438 -0
  432. data/lib/studium/exams/exams_this_week.rb +182 -0
  433. data/lib/studium/exams/fix_exam_dates.rb +121 -0
  434. data/lib/studium/exams/frozen.rb +36 -0
  435. data/lib/studium/exams/last_exams/last_exams.rb +398 -0
  436. data/lib/studium/exams/lectures_without_exam_entry.rb +137 -0
  437. data/lib/studium/exams/mandatory_continuous_assessment/mandatory_continuous_assessment.rb +1359 -0
  438. data/lib/studium/exams/move_the_last_exam_question_to_the_top_of_the_file/move_the_last_exam_question_to_the_top_of_the_file.rb +111 -0
  439. data/lib/studium/exams/n_exams_in_these_topics.rb +404 -0
  440. data/lib/studium/exams/next_exam.rb +107 -0
  441. data/lib/studium/exams/next_exams.rb +378 -0
  442. data/lib/studium/exams/open_exam_associated_url.rb +154 -0
  443. data/lib/studium/exams/open_last_exam_question_asked_file/constants.rb +15 -0
  444. data/lib/studium/exams/open_last_exam_question_asked_file/initialize.rb +29 -0
  445. data/lib/studium/exams/open_last_exam_question_asked_file/open_last_exam_question_asked_file.rb +109 -0
  446. data/lib/studium/exams/push_solved_questions_on_top.rb +180 -0
  447. data/lib/studium/exams/questions_solved_from_day_to_day/questions_solved_from_day_to_day.rb +377 -0
  448. data/lib/studium/exams/remote_ftp_url.rb +52 -0
  449. data/lib/studium/exams/repeat_last_question.rb +78 -0
  450. data/lib/studium/exams/show_all_passed_exams_of_this_university.rb +252 -0
  451. data/lib/studium/exams/show_backlog_of_exams.rb +117 -0
  452. data/lib/studium/exams/show_next_exams_for.rb +133 -0
  453. data/lib/studium/exams/show_themes/constants.rb +28 -0
  454. data/lib/studium/exams/show_themes/menu.rb +61 -0
  455. data/lib/studium/exams/show_themes/misc.rb +537 -0
  456. data/lib/studium/exams/show_themes/reset.rb +62 -0
  457. data/lib/studium/exams/show_themes/show_themes.rb +27 -0
  458. data/lib/studium/exams/show_upcoming_exams/show_upcoming_exams.rb +1146 -0
  459. data/lib/studium/exams/solve_all_questions_from_this_topic.rb +114 -0
  460. data/lib/studium/exams/solved/constants.rb +32 -0
  461. data/lib/studium/exams/solved/help.rb +24 -0
  462. data/lib/studium/exams/solved/initialize.rb +55 -0
  463. data/lib/studium/exams/solved/menu.rb +41 -0
  464. data/lib/studium/exams/solved/reset.rb +28 -0
  465. data/lib/studium/exams/solved/solved.rb +317 -0
  466. data/lib/studium/exams/timetable/timetable.rb +510 -0
  467. data/lib/studium/exams/unsolve_all_questions_from_this_topic.rb +162 -0
  468. data/lib/studium/exams/upcoming_exams/upcoming_exams.rb +556 -0
  469. data/lib/studium/exams/upcoming_exams_at_the_boku/constants.rb +23 -0
  470. data/lib/studium/exams/upcoming_exams_at_the_boku/html.rb +64 -0
  471. data/lib/studium/exams/upcoming_exams_at_the_boku/upcoming_exams_at_the_boku.rb +194 -0
  472. data/lib/studium/exams/upcoming_exams_dataset.rb +247 -0
  473. data/lib/studium/exams/upcoming_registered_exams/upcoming_registered_exams.rb +257 -0
  474. data/lib/studium/exams/upload_exam_topics.rb +360 -0
  475. data/lib/studium/graphviz/README.md +4 -0
  476. data/lib/studium/graphviz/bachelor_vector_based_strategies.dot +160 -0
  477. data/lib/studium/graphviz/master_vector_based_strategies.dot +46 -0
  478. data/lib/studium/gui/gtk3/README.md +1 -0
  479. data/lib/studium/gui/gtk3/ask_exam_question/ask_exam_question.config +6 -0
  480. data/lib/studium/gui/gtk3/ask_exam_question/ask_exam_question.rb +760 -0
  481. data/lib/studium/gui/gtk3/ask_exam_question/manifest.yml +12 -0
  482. data/lib/studium/gui/gtk3/control_panel/control_panel.rb +39 -0
  483. data/lib/studium/gui/gtk3/curriculum_viewer/curriculum_viewer.rb +510 -0
  484. data/lib/studium/gui/gtk3/ects_per_university/ects_per_university.rb +217 -0
  485. data/lib/studium/gui/gtk3/exam_question_widget/exam_question_widget.rb +1888 -0
  486. data/lib/studium/gui/gtk3/expand_time_range/expand_time_range.rb +34 -0
  487. data/lib/studium/gui/gtk3/information_about_a_lecture/information_about_a_lecture.rb +34 -0
  488. data/lib/studium/gui/gtk3/lecture_information/lecture_information.rb +200 -0
  489. data/lib/studium/gui/gtk3/show_upcoming_exams/show_upcoming_exams.rb +34 -0
  490. data/lib/studium/gui/java/exam_question/ExamQuestion$1.class +0 -0
  491. data/lib/studium/gui/java/exam_question/ExamQuestion.class +0 -0
  492. data/lib/studium/gui/java/exam_question/ExamQuestion.java +215 -0
  493. data/lib/studium/gui/javafx/exam_question_widget/exam_question_widget.rb +58 -0
  494. data/lib/studium/gui/jruby/exam_question_widget/exam_question_widget.rb +317 -0
  495. data/lib/studium/gui/libui/ask_exam_question/ask_exam_question.rb +349 -0
  496. data/lib/studium/gui/shared_code/control_panel/control_panel_module.rb +314 -0
  497. data/lib/studium/gui/shared_code/exam_question_widget/exam_question_widget_module.rb +39 -0
  498. data/lib/studium/gui/shared_code/expand_time_range/expand_time_range.css +0 -0
  499. data/lib/studium/gui/shared_code/expand_time_range/expand_time_range_module.rb +190 -0
  500. data/lib/studium/gui/shared_code/information_about_a_lecture/information_about_a_lecture_module.rb +180 -0
  501. data/lib/studium/gui/shared_code/show_upcoming_exams/show_upcoming_exams_module.rb +206 -0
  502. data/lib/studium/images/libui_ask_exam_question.png +0 -0
  503. data/lib/studium/images/outdated.png +0 -0
  504. data/lib/studium/images/small_logos/DNA.png +0 -0
  505. data/lib/studium/images/small_logos/README.md +2 -0
  506. data/lib/studium/images/small_logos/solved.png +0 -0
  507. data/lib/studium/images/studies_favicon.png +0 -0
  508. data/lib/studium/java/Mkdir.java +15 -0
  509. data/lib/studium/java/README.md +2 -0
  510. data/lib/studium/java/ask_exam_question/AskExamQuestion.class +0 -0
  511. data/lib/studium/java/ask_exam_question/AskExamQuestion.java +480 -0
  512. data/lib/studium/java/constants/Constants.class +0 -0
  513. data/lib/studium/java/constants/Constants.java +77 -0
  514. data/lib/studium/java/solved/Solved.class +0 -0
  515. data/lib/studium/java/solved/Solved.java +110 -0
  516. data/lib/studium/java/utility_scripts/OpenLastExamQuestionurlLinkViaTheBrowser.class +0 -0
  517. data/lib/studium/java/utility_scripts/OpenLastExamQuestionurlLinkViaTheBrowser.java +80 -0
  518. data/lib/studium/logging/README.md +2 -0
  519. data/lib/studium/logging/ensure_that_the_log_directory_exists.rb +47 -0
  520. data/lib/studium/logging/html_log_directory.rb +41 -0
  521. data/lib/studium/logging/log_directory.rb +112 -0
  522. data/lib/studium/logging/store_last_question_asked_into_file.rb +137 -0
  523. data/lib/studium/parsers/README.md +2 -0
  524. data/lib/studium/parsers/custom_exam_results_parser.rb +206 -0
  525. data/lib/studium/parsers/parse_lva_dates.rb +233 -0
  526. data/lib/studium/parsers/parse_remote_lecture.rb +331 -0
  527. data/lib/studium/project/project.rb +76 -0
  528. data/lib/studium/requires/common_popular_requires.rb +37 -0
  529. data/lib/studium/requires/commonly_used_requires.rb +14 -0
  530. data/lib/studium/requires/require_class_exams_solved.rb +7 -0
  531. data/lib/studium/requires/require_ects_scripts.rb +27 -0
  532. data/lib/studium/requires/require_encoding.rb +7 -0
  533. data/lib/studium/requires/require_the_check_and_sanitize_files.rb +31 -0
  534. data/lib/studium/requires/require_the_curricula_files.rb +28 -0
  535. data/lib/studium/requires/require_the_exam_question_class.rb +7 -0
  536. data/lib/studium/requires/require_the_exams_files.rb +45 -0
  537. data/lib/studium/requires/require_the_logging_files.rb +23 -0
  538. data/lib/studium/requires/require_the_parsers.rb +28 -0
  539. data/lib/studium/requires/require_the_studium_constants.rb +10 -0
  540. data/lib/studium/requires/require_the_studium_project.rb +60 -0
  541. data/lib/studium/requires/require_the_toplevel_methods.rb +27 -0
  542. data/lib/studium/requires/require_the_utility_scripts.rb +49 -0
  543. data/lib/studium/requires/require_upcoming_exams.rb +7 -0
  544. data/lib/studium/requires/require_yaml.rb +7 -0
  545. data/lib/studium/requires/return_remote_homepage_of_this_lecture.rb +7 -0
  546. data/lib/studium/requires/with_GUI.rb +13 -0
  547. data/lib/studium/requires/www_mode.rb +17 -0
  548. data/lib/studium/statistics/README.md +4 -0
  549. data/lib/studium/statistics/best_exam_months.rb +92 -0
  550. data/lib/studium/statistics/curriculum_comparer.rb +337 -0
  551. data/lib/studium/statistics/determine_exam_statistics_from_this_file.rb +142 -0
  552. data/lib/studium/statistics/exam_topics_that_are_about_to_be_completed.rb +119 -0
  553. data/lib/studium/statistics/max_stats.rb +170 -0
  554. data/lib/studium/statistics/new_questions_per_year.rb +147 -0
  555. data/lib/studium/statistics/report_how_many_ects_points_per_curriculum_were_completed.rb +167 -0
  556. data/lib/studium/statistics/report_how_many_exam_questions_were_answered.rb +473 -0
  557. data/lib/studium/statistics/show_exam_statistics.rb +66 -0
  558. data/lib/studium/statistics/show_which_courses_are_in_a_bachelor_or_master_curriculum_respectively.rb +104 -0
  559. data/lib/studium/statistics/top_stats.rb +127 -0
  560. data/lib/studium/toplevel_methods/all_passed_exams.rb +37 -0
  561. data/lib/studium/toplevel_methods/already_solved_this_lecture.rb +100 -0
  562. data/lib/studium/toplevel_methods/available_topics.rb +156 -0
  563. data/lib/studium/toplevel_methods/calculate_pr/303/274fungsimmanente_lectures_from_this_file.rb +55 -0
  564. data/lib/studium/toplevel_methods/copy_the_last_backup_of_file_lecture_information.rb +34 -0
  565. data/lib/studium/toplevel_methods/curriculum_related_code.rb +1082 -0
  566. data/lib/studium/toplevel_methods/determine_local_directory_of_this_lecture.rb +72 -0
  567. data/lib/studium/toplevel_methods/does_this_course_require_mandatory_presence.rb +51 -0
  568. data/lib/studium/toplevel_methods/download.rb +163 -0
  569. data/lib/studium/toplevel_methods/e.rb +16 -0
  570. data/lib/studium/toplevel_methods/ects_from_lectures.rb +250 -0
  571. data/lib/studium/toplevel_methods/editor.rb +65 -0
  572. data/lib/studium/toplevel_methods/esystem.rb +22 -0
  573. data/lib/studium/toplevel_methods/filter_away_invalid_questions.rb +77 -0
  574. data/lib/studium/toplevel_methods/find_exam_topic_and_exam_title.rb +3538 -0
  575. data/lib/studium/toplevel_methods/handle_archive_of_the_exam_questions.rb +136 -0
  576. data/lib/studium/toplevel_methods/has_this_lecture_been_already_passed_but_the_id_was_changed_lateron.rb +42 -0
  577. data/lib/studium/toplevel_methods/has_this_module_been_completed.rb +206 -0
  578. data/lib/studium/toplevel_methods/install_the_project_on_the_given_hostsystem.rb +32 -0
  579. data/lib/studium/toplevel_methods/is_on_roebe.rb +26 -0
  580. data/lib/studium/toplevel_methods/is_this_exam_topic_included.rb +46 -0
  581. data/lib/studium/toplevel_methods/is_this_homepage_registered.rb +31 -0
  582. data/lib/studium/toplevel_methods/is_this_lecture_a_practical_course.rb +93 -0
  583. data/lib/studium/toplevel_methods/is_this_lecture_registered_in_upcoming_exams.rb +42 -0
  584. data/lib/studium/toplevel_methods/java.rb +32 -0
  585. data/lib/studium/toplevel_methods/lecture_information.rb +108 -0
  586. data/lib/studium/toplevel_methods/lva_numbers.rb +355 -0
  587. data/lib/studium/toplevel_methods/main_dataset.rb +73 -0
  588. data/lib/studium/toplevel_methods/map_input_to_this_curriculum_filename.rb +595 -0
  589. data/lib/studium/toplevel_methods/methods_related_to_directories.rb +225 -0
  590. data/lib/studium/toplevel_methods/methods_related_to_files.rb +209 -0
  591. data/lib/studium/toplevel_methods/misc.rb +288 -0
  592. data/lib/studium/toplevel_methods/n_questions_available.rb +137 -0
  593. data/lib/studium/toplevel_methods/n_topics_available.rb +63 -0
  594. data/lib/studium/toplevel_methods/names_of_all_solved_exams.rb +71 -0
  595. data/lib/studium/toplevel_methods/note_down_the_start_time_and_how_many_exams_have_been_already_solved.rb +69 -0
  596. data/lib/studium/toplevel_methods/opnn.rb +25 -0
  597. data/lib/studium/toplevel_methods/passed_this_exam_on.rb +105 -0
  598. data/lib/studium/toplevel_methods/pristine.rb +69 -0
  599. data/lib/studium/toplevel_methods/read_delay_between_questions_from_file.rb +34 -0
  600. data/lib/studium/toplevel_methods/regexes.rb +90 -0
  601. data/lib/studium/toplevel_methods/registered_for_this_exam.rb +82 -0
  602. data/lib/studium/toplevel_methods/remove_comments.rb +26 -0
  603. data/lib/studium/toplevel_methods/remove_exam_topics_that_were_already_answered.rb +27 -0
  604. data/lib/studium/toplevel_methods/remove_tags.rb +32 -0
  605. data/lib/studium/toplevel_methods/report.rb +435 -0
  606. data/lib/studium/toplevel_methods/return_all_exams_on_this_day.rb +66 -0
  607. data/lib/studium/toplevel_methods/return_dataset_for_this_exam_topic.rb +41 -0
  608. data/lib/studium/toplevel_methods/return_ects_from_this_lecture_stored_in_the_file_lecture_information.rb +194 -0
  609. data/lib/studium/toplevel_methods/return_hash_of_already_solved_lectures.rb +46 -0
  610. data/lib/studium/toplevel_methods/return_last_exam_question.rb +34 -0
  611. data/lib/studium/toplevel_methods/return_local_path_of_this_pwdstud.rb +60 -0
  612. data/lib/studium/toplevel_methods/return_lva_number_of_this_lecture.rb +72 -0
  613. data/lib/studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb +90 -0
  614. data/lib/studium/toplevel_methods/return_n_questions_were_answered_for_this_topic.rb +60 -0
  615. data/lib/studium/toplevel_methods/return_proper_university_image.rb +86 -0
  616. data/lib/studium/toplevel_methods/return_question_answer_string_from_this_topic.rb +63 -0
  617. data/lib/studium/toplevel_methods/return_remote_homepage_of_this_lecture.rb +10951 -0
  618. data/lib/studium/toplevel_methods/return_remote_moodle_link_of_this_lecture.rb +2201 -0
  619. data/lib/studium/toplevel_methods/return_sanitized_dataset_from_the_file_lecture_information.rb +110 -0
  620. data/lib/studium/toplevel_methods/return_theme_of_the_next_upcoming_exam.rb +38 -0
  621. data/lib/studium/toplevel_methods/rinstall2.rb +34 -0
  622. data/lib/studium/toplevel_methods/rti_conflict.rb +35 -0
  623. data/lib/studium/toplevel_methods/runmode.rb +87 -0
  624. data/lib/studium/toplevel_methods/sanitized_dataset_from_file_passed_exams_per_month.rb +52 -0
  625. data/lib/studium/toplevel_methods/set_last_file_for_exam_questions.rb +64 -0
  626. data/lib/studium/toplevel_methods/set_this_cd_alias_to.rb +86 -0
  627. data/lib/studium/toplevel_methods/show_passed_exams_having_this_grade.rb +34 -0
  628. data/lib/studium/toplevel_methods/spacer.rb +18 -0
  629. data/lib/studium/toplevel_methods/time.rb +297 -0
  630. data/lib/studium/toplevel_methods/total_ects_points_passed.rb +72 -0
  631. data/lib/studium/toplevel_methods/try_to_guess_the_most_likely_lva_id.rb +57 -0
  632. data/lib/studium/toplevel_methods/try_to_return_the_expanded_name_of_this_lecture.rb +63 -0
  633. data/lib/studium/toplevel_methods/unfinished.rb +51 -0
  634. data/lib/studium/toplevel_methods/url.rb +100 -0
  635. data/lib/studium/toplevel_methods/verbose_truth.rb +36 -0
  636. data/lib/studium/toplevel_methods/when_was_this_lecture_passed.rb +54 -0
  637. data/lib/studium/toplevel_methods/word_wrap.rb +56 -0
  638. data/lib/studium/toplevel_methods/write_into_file_related_functionality.rb +195 -0
  639. data/lib/studium/toplevel_methods/yes_or_no_ja_oder_nein.rb +33 -0
  640. data/lib/studium/universities_in_austria/README.md +2 -0
  641. data/lib/studium/universities_in_austria/boku/README.md +4 -0
  642. data/lib/studium/universities_in_austria/boku/boku_/303/266ffnungszeiten.rb +28 -0
  643. data/lib/studium/universities_in_austria/boku/show_three_pillars_of_these_lectures.rb +110 -0
  644. data/lib/studium/universities_in_austria/boku/three_pillars.rb +237 -0
  645. data/lib/studium/universities_in_austria/tu_vienna/README.md +6 -0
  646. data/lib/studium/universities_in_austria/tu_vienna/tu_ferien.rb +42 -0
  647. data/lib/studium/universities_in_austria/tu_vienna/tu_/303/266ffnungszeiten.rb +34 -0
  648. data/lib/studium/university_course/university_course.rb +384 -0
  649. data/lib/studium/utility_scripts/attribute_lecture_to_curriculum/attribute_boku_lecture_to_curriculum.rb +384 -0
  650. data/lib/studium/utility_scripts/attribute_lecture_to_curriculum/attribute_lecture_to_curriculum.rb +238 -0
  651. data/lib/studium/utility_scripts/attribute_lectures_to_university/attribute_lectures_to_university.rb +375 -0
  652. data/lib/studium/utility_scripts/audio_stats.rb +171 -0
  653. data/lib/studium/utility_scripts/auto_stud/auto_stud.rb +252 -0
  654. data/lib/studium/utility_scripts/auto_stud/constants.rb +18 -0
  655. data/lib/studium/utility_scripts/auto_stud/initialize.rb +23 -0
  656. data/lib/studium/utility_scripts/auto_stud/misc.rb +18 -0
  657. data/lib/studium/utility_scripts/autopurge_this_lecture_date.rb +93 -0
  658. data/lib/studium/utility_scripts/average_grade_of_this_curriculum.rb +143 -0
  659. data/lib/studium/utility_scripts/blocked_courses.rb +141 -0
  660. data/lib/studium/utility_scripts/calendar/README.md +2 -0
  661. data/lib/studium/utility_scripts/calendar/calendar.rb +251 -0
  662. data/lib/studium/utility_scripts/calendar/misc.rb +35 -0
  663. data/lib/studium/utility_scripts/check_description_of_these_lectures.rb +221 -0
  664. data/lib/studium/utility_scripts/course_registrations/course_registrations.rb +98 -0
  665. data/lib/studium/utility_scripts/create/README.md +2 -0
  666. data/lib/studium/utility_scripts/create/webpage_of_university.rb +129 -0
  667. data/lib/studium/utility_scripts/create/webpage_of_university_BOKU.rb +59 -0
  668. data/lib/studium/utility_scripts/create/webpage_of_university_TU.rb +58 -0
  669. data/lib/studium/utility_scripts/create/webpage_of_university_UniWien.rb +57 -0
  670. data/lib/studium/utility_scripts/create_database/create_database.rb +106 -0
  671. data/lib/studium/utility_scripts/current_lectures_belonging_to_both_bachelor_and_master_curriculum.rb +113 -0
  672. data/lib/studium/utility_scripts/currently_participating_in_these_lectures/currently_participating_in_these_lectures.rb +104 -0
  673. data/lib/studium/utility_scripts/display_lecture_url.rb +176 -0
  674. data/lib/studium/utility_scripts/expand_time_range/expand_time_range.rb +488 -0
  675. data/lib/studium/utility_scripts/finished_exams_at_this_university.rb +94 -0
  676. data/lib/studium/utility_scripts/foreign_language_percentage/constants.rb +23 -0
  677. data/lib/studium/utility_scripts/foreign_language_percentage/foreign_language_percentage.rb +149 -0
  678. data/lib/studium/utility_scripts/foreign_language_percentage/help.rb +31 -0
  679. data/lib/studium/utility_scripts/foreign_language_percentage/initialize.rb +25 -0
  680. data/lib/studium/utility_scripts/foreign_language_percentage/menu.rb +158 -0
  681. data/lib/studium/utility_scripts/foreign_language_percentage/report.rb +62 -0
  682. data/lib/studium/utility_scripts/foreign_language_percentage/reset.rb +50 -0
  683. data/lib/studium/utility_scripts/foreign_language_percentage/run.rb +19 -0
  684. data/lib/studium/utility_scripts/generate_spreadsheet/generate_spreadsheet.rb +354 -0
  685. data/lib/studium/utility_scripts/generate_spreadsheet/misc.rb +144 -0
  686. data/lib/studium/utility_scripts/holidays/holidays.rb +150 -0
  687. data/lib/studium/utility_scripts/homepage_of_these_courses.rb +118 -0
  688. data/lib/studium/utility_scripts/lecture_downloader.rb +107 -0
  689. data/lib/studium/utility_scripts/lectures_attributed_to_universities.rb +336 -0
  690. data/lib/studium/utility_scripts/lva_dates_of_the_important_courses.rb +111 -0
  691. data/lib/studium/utility_scripts/lva_nummer.rb +431 -0
  692. data/lib/studium/utility_scripts/mandatory_lectures_in_this_month/mandatory_lectures_in_this_month.rb +316 -0
  693. data/lib/studium/utility_scripts/name_of_this_lva_id.rb +110 -0
  694. data/lib/studium/utility_scripts/new_stud.rb +324 -0
  695. data/lib/studium/utility_scripts/next_week.rb +103 -0
  696. data/lib/studium/utility_scripts/open_last_exam_question_url_link_via_the_browser.rb +76 -0
  697. data/lib/studium/utility_scripts/passed_ects_per_year/passed_ects_per_year.rb +288 -0
  698. data/lib/studium/utility_scripts/passed_pr/303/274fungsimmanente_courses/passed_pr/303/274fungsimmanente_courses.rb +181 -0
  699. data/lib/studium/utility_scripts/pdf/README.md +2 -0
  700. data/lib/studium/utility_scripts/pdf/create_pdf_file_for_this_exam_topic.rb +355 -0
  701. data/lib/studium/utility_scripts/pdf/hexapdf_support.rb +50 -0
  702. data/lib/studium/utility_scripts/preparatory_meetings/preparatory_meetings.rb +312 -0
  703. data/lib/studium/utility_scripts/priority.rb +164 -0
  704. data/lib/studium/utility_scripts/priority_points/priority_points.rb +263 -0
  705. data/lib/studium/utility_scripts/publish_my_exams.rb +174 -0
  706. data/lib/studium/utility_scripts/regexes/README.md +1 -0
  707. data/lib/studium/utility_scripts/regexes/generate_regex.rb +314 -0
  708. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_available_moodle_links.rb +55 -0
  709. data/lib/studium/utility_scripts/regexes/generate_regexes_for_the_registered_lectures.rb +48 -0
  710. data/lib/studium/utility_scripts/report_outdated_timetable_entries/report_outdated_timetable_entries.rb +142 -0
  711. data/lib/studium/utility_scripts/report_total_amount_of_questions_and_answers_for.rb +116 -0
  712. data/lib/studium/utility_scripts/report_whether_this_lecture_is_registered_in_the_file_lecture_information.rb +128 -0
  713. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/individual_resolve_practical_courses_date_conflicts.rb +254 -0
  714. data/lib/studium/utility_scripts/resolve_practical_courses_date_conflicts/resolve_practical_courses_date_conflicts.rb +265 -0
  715. data/lib/studium/utility_scripts/scrape_remote_university_url.rb +138 -0
  716. data/lib/studium/utility_scripts/semester_schedule_creator/semester_container.rb +144 -0
  717. data/lib/studium/utility_scripts/semester_schedule_creator/semester_schedule_creator.rb +374 -0
  718. data/lib/studium/utility_scripts/semesterplaner.rb +289 -0
  719. data/lib/studium/utility_scripts/set_aliases_based_on_this_file.rb +97 -0
  720. data/lib/studium/utility_scripts/show_all_passed_master_lectures.rb +119 -0
  721. data/lib/studium/utility_scripts/show_conflicting_lva_lectures/show_conflicting_lva_lectures.rb +1339 -0
  722. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/constants.rb +23 -0
  723. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/menu.rb +63 -0
  724. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/reset.rb +33 -0
  725. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/run.rb +50 -0
  726. data/lib/studium/utility_scripts/show_descriptions_of_lectures_belonging_to_this_module/show_descriptions_of_lectures_belonging_to_this_module.rb +145 -0
  727. data/lib/studium/utility_scripts/show_lecturers/show_lecturers.rb +147 -0
  728. data/lib/studium/utility_scripts/show_lectures/constants.rb +11 -0
  729. data/lib/studium/utility_scripts/show_lectures/help.rb +35 -0
  730. data/lib/studium/utility_scripts/show_lectures/initialize.rb +23 -0
  731. data/lib/studium/utility_scripts/show_lectures/menu.rb +138 -0
  732. data/lib/studium/utility_scripts/show_lectures/misc.rb +606 -0
  733. data/lib/studium/utility_scripts/show_lectures/reset.rb +89 -0
  734. data/lib/studium/utility_scripts/show_lectures/run.rb +28 -0
  735. data/lib/studium/utility_scripts/show_lectures/show_lectures.rb +49 -0
  736. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_language/show_lectures_fitting_to_this_language.rb +121 -0
  737. data/lib/studium/utility_scripts/show_lectures_fitting_to_this_theme/show_lectures_fitting_to_this_theme.rb +105 -0
  738. data/lib/studium/utility_scripts/show_lectures_on_the_commandline/show_lectures_on_the_commandline.rb +3142 -0
  739. data/lib/studium/utility_scripts/show_lectures_on_this_day.rb +149 -0
  740. data/lib/studium/utility_scripts/show_lva_dates_of_this_lecture.rb +169 -0
  741. data/lib/studium/utility_scripts/show_mixed_bachelor_master_courses/show_mixed_bachelor_master_courses.rb +91 -0
  742. data/lib/studium/utility_scripts/show_outdated_lva_dates/show_outdated_lva_dates.rb +210 -0
  743. data/lib/studium/utility_scripts/show_solved_english_lectures/show_solved_english_lectures.rb +139 -0
  744. data/lib/studium/utility_scripts/steop/README.md +4 -0
  745. data/lib/studium/utility_scripts/steop/show_all_steop_lectures.rb +93 -0
  746. data/lib/studium/utility_scripts/steop/steop_lectures_in_this_curriculum.rb +284 -0
  747. data/lib/studium/utility_scripts/steop/steop_lva_dates.rb +119 -0
  748. data/lib/studium/utility_scripts/studienkennzahl.rb +116 -0
  749. data/lib/studium/utility_scripts/studium_skeleton/studium_skeleton.rb +231 -0
  750. data/lib/studium/utility_scripts/stundenplan.rb +595 -0
  751. data/lib/studium/utility_scripts/sync_studium_relevant_entries_one_level_downwards.rb +217 -0
  752. data/lib/studium/utility_scripts/ufind/ufind.rb +98 -0
  753. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/constants.rb +26 -0
  754. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/run.rb +20 -0
  755. data/lib/studium/utility_scripts/upcoming_mandatory_presence_courses/upcoming_mandatory_presence_courses.rb +187 -0
  756. data/lib/studium/utility_scripts/week_parser/constants.rb +23 -0
  757. data/lib/studium/utility_scripts/week_parser/help.rb +32 -0
  758. data/lib/studium/utility_scripts/week_parser/menu.rb +59 -0
  759. data/lib/studium/utility_scripts/week_parser/misc.rb +373 -0
  760. data/lib/studium/utility_scripts/week_parser/reset.rb +65 -0
  761. data/lib/studium/utility_scripts/week_parser/run.rb +18 -0
  762. data/lib/studium/utility_scripts/week_parser/show.rb +236 -0
  763. data/lib/studium/utility_scripts/week_parser/week_parser.rb +49 -0
  764. data/lib/studium/utility_scripts/weekday_parser.rb +155 -0
  765. data/lib/studium/utility_scripts/weekly_schedule.rb +198 -0
  766. data/lib/studium/utility_scripts/wochenplanung.rb +261 -0
  767. data/lib/studium/version/version.rb +46 -0
  768. data/lib/studium/www/curriculum_displayer.rb +162 -0
  769. data/lib/studium/www/exams.cgi +54 -0
  770. data/lib/studium/www/fast_ask_exam_question.cgi +156 -0
  771. data/lib/studium/www/handle_curricula/handle_curricula.cgi +154 -0
  772. data/lib/studium/www/next_generation_exam_question_trainer/next_generation_exam_question_trainer.cgi +79 -0
  773. data/lib/studium/www/sinatra/app.rb +231 -0
  774. data/lib/studium/www/sinatra/misc.rb +115 -0
  775. data/lib/studium/www/statistics/statistics.cgi +70 -0
  776. data/lib/studium/yaml/ad_hoc_trainer/README.md +2 -0
  777. data/lib/studium/yaml/ad_hoc_trainer/exam_topics.md +15 -0
  778. data/lib/studium/yaml/allowed_themes_for_exams/allowed_themes_for_exams.yml +347 -0
  779. data/lib/studium/yaml/array_allowed_entries_for_the_file_lecture_information.yml +71 -0
  780. data/lib/studium/yaml/available_exam_topics/available_exam_topics.yml +234 -0
  781. data/lib/studium/yaml/backlog_of_exams.yml +37 -0
  782. data/lib/studium/yaml/colours/custom_colours.yml +28 -0
  783. data/lib/studium/yaml/colours/use_colours.yml +1 -0
  784. data/lib/studium/yaml/current_exams.yml +30 -0
  785. data/lib/studium/yaml/curricula/README.md +39 -0
  786. data/lib/studium/yaml/curricula/bachelor/bachelor_agrarwissenschaften_033255.yml +147 -0
  787. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_basisblock_033630.yml +71 -0
  788. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_botanik_033630.yml +100 -0
  789. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_ecology_033630.yml +74 -0
  790. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_mikrobiologie_und_genetik_033630.yml +122 -0
  791. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_molekulare_biologie_033630.yml +106 -0
  792. data/lib/studium/yaml/curricula/bachelor/bachelor_biologie_zoologie_033630.yml +87 -0
  793. data/lib/studium/yaml/curricula/bachelor/bachelor_chemie_033662.yml +165 -0
  794. data/lib/studium/yaml/curricula/bachelor/bachelor_dummy_curriculum.yml +182 -0
  795. data/lib/studium/yaml/curricula/bachelor/bachelor_elektrotechnik_und_informationstechnik_033235.yml +13 -0
  796. data/lib/studium/yaml/curricula/bachelor/bachelor_forstwirtschaft_033225.yml +115 -0
  797. data/lib/studium/yaml/curricula/bachelor/bachelor_informatik_033521.yml +136 -0
  798. data/lib/studium/yaml/curricula/bachelor/bachelor_ktww_033231.yml +84 -0
  799. data/lib/studium/yaml/curricula/bachelor/bachelor_lmbt_033217.yml +121 -0
  800. data/lib/studium/yaml/curricula/bachelor/bachelor_medizinische_informatik_033533.yml +283 -0
  801. data/lib/studium/yaml/curricula/bachelor/bachelor_molekularbiologie_033665.yml +95 -0
  802. data/lib/studium/yaml/curricula/bachelor/bachelor_nutrition_science_033638.yml +119 -0
  803. data/lib/studium/yaml/curricula/bachelor/bachelor_pharmazie_033305.yml +170 -0
  804. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_chemie_033290.yml +131 -0
  805. data/lib/studium/yaml/curricula/bachelor/bachelor_technische_informatik_033535.yml +23 -0
  806. data/lib/studium/yaml/curricula/bachelor/bachelor_ubrm_033227.yml +143 -0
  807. data/lib/studium/yaml/curricula/bachelor/bachelor_verfahrenstechnik_033273.yml +167 -0
  808. data/lib/studium/yaml/curricula/bachelor/bachelor_wirtschaftsinformatik_033526.yml +29 -0
  809. data/lib/studium/yaml/curricula/experimental/bachelor_informatik_in_den_lebenswissenschaften.yml +137 -0
  810. data/lib/studium/yaml/curricula/individual/bachelor_formale_logik.yml +88 -0
  811. data/lib/studium/yaml/curricula/individual/bachelor_informatik_und_molekulare_biologie.yml +1161 -0
  812. data/lib/studium/yaml/curricula/individual/bachelor_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +1157 -0
  813. data/lib/studium/yaml/curricula/individual/master_bioinformatics_and_nanobiotechnology_in_molecular_medicine.yml +306 -0
  814. data/lib/studium/yaml/curricula/individual/master_vector_based_strategies_in_life_sciences_molecular_medicine_and_biotechnology.yml +741 -0
  815. data/lib/studium/yaml/curricula/master/master_bioinformatik_066875.yml +75 -0
  816. data/lib/studium/yaml/curricula/master/master_biologie_molekulare_mikrobiologie_mikrobielle_oekologie_und_immunbiologie_066830.yml +78 -0
  817. data/lib/studium/yaml/curricula/master/master_biologische_chemie_066863.yml +66 -0
  818. data/lib/studium/yaml/curricula/master/master_dummy_curriculum.yml +197 -0
  819. data/lib/studium/yaml/curricula/master/master_genetik_und_entwicklungsbiologie_066877.yml +89 -0
  820. data/lib/studium/yaml/curricula/master/master_lmbt_066418.yml +112 -0
  821. data/lib/studium/yaml/curricula/master/master_molecular_biology_066865.yml +72 -0
  822. data/lib/studium/yaml/curricula/master/master_molekulare_biologie_066834.yml +151 -0
  823. data/lib/studium/yaml/curricula/master/master_pharmazie_066605.yml +176 -0
  824. data/lib/studium/yaml/curricula/master/master_technische_chemie_066490.yml +123 -0
  825. data/lib/studium/yaml/curricula/outdated/master_bioinformatics_and_molecular_biotechnology_including_aspects_from_molecular_medicine.yml +438 -0
  826. data/lib/studium/yaml/curricula/outdated/master_food_science_and_plant_biotechnology.yml +31 -0
  827. data/lib/studium/yaml/curricula.yml +562 -0
  828. data/lib/studium/yaml/daily_questions_solved.yml +1654 -0
  829. data/lib/studium/yaml/default_delay.yml +4 -0
  830. data/lib/studium/yaml/default_encoding.yml +1 -0
  831. data/lib/studium/yaml/directory_to_the_exam_topics.yml +0 -0
  832. data/lib/studium/yaml/editor.yml +1 -0
  833. data/lib/studium/yaml/exams/next_exams_to_do.md +9 -0
  834. data/lib/studium/yaml/file_for_exam_questions.yml +1 -0
  835. data/lib/studium/yaml/german/README.md +2 -0
  836. data/lib/studium/yaml/german/german_to_english_month_names.yml +16 -0
  837. data/lib/studium/yaml/grouped_themes.yml +192 -0
  838. data/lib/studium/yaml/holidays.yml +201 -0
  839. data/lib/studium/yaml/important_exams.yml +266 -0
  840. data/lib/studium/yaml/inscription_dates_of_universities.yml +60 -0
  841. data/lib/studium/yaml/lecture_aliases.yml +138 -0
  842. data/lib/studium/yaml/lecture_information/lecture_information.yml +61740 -0
  843. data/lib/studium/yaml/log_dir.yml +1 -0
  844. data/lib/studium/yaml/main_topic.yml +11 -0
  845. data/lib/studium/yaml/max_stats.yml +249 -0
  846. data/lib/studium/yaml/meta_themes/README.md +13 -0
  847. data/lib/studium/yaml/meta_themes/biochemistry.md +6 -0
  848. data/lib/studium/yaml/meta_themes/bioinformatics.md +6 -0
  849. data/lib/studium/yaml/meta_themes/biotechnology.md +9 -0
  850. data/lib/studium/yaml/meta_themes/cellbiology.md +9 -0
  851. data/lib/studium/yaml/meta_themes/chemistry.md +9 -0
  852. data/lib/studium/yaml/meta_themes/genetics.md +10 -0
  853. data/lib/studium/yaml/meta_themes/immunology.md +5 -0
  854. data/lib/studium/yaml/meta_themes/metabolic_pathways.md +12 -0
  855. data/lib/studium/yaml/meta_themes/molecular_biology.md +9 -0
  856. data/lib/studium/yaml/meta_themes/protein_engineering.md +10 -0
  857. data/lib/studium/yaml/meta_themes/statistics.md +2 -0
  858. data/lib/studium/yaml/mitbelegung/README.md +4 -0
  859. data/lib/studium/yaml/mitbelegung/mitbelegung.yml +21 -0
  860. data/lib/studium/yaml/mitteilungsbl/303/244tter/mitteilungsbl/303/244tter.yml +363 -0
  861. data/lib/studium/yaml/n_total_questions.yml +1 -0
  862. data/lib/studium/yaml/rename_konsole_tab.yml +1 -0
  863. data/lib/studium/yaml/semester_planner/README.md +4 -0
  864. data/lib/studium/yaml/semester_planner/semester_planner.yml +189 -0
  865. data/lib/studium/yaml/show_topic.yml +1 -0
  866. data/lib/studium/yaml/statistics/lecture_information.yml +1 -0
  867. data/lib/studium/yaml/statistics/max_stats.yml +239 -0
  868. data/lib/studium/yaml/statistics/statistics.yml +75 -0
  869. data/lib/studium/yaml/week/01_monday.yml +25 -0
  870. data/lib/studium/yaml/week/02_tuesday.yml +68 -0
  871. data/lib/studium/yaml/week/03_wednesday.yml +63 -0
  872. data/lib/studium/yaml/week/04_thursday.yml +20 -0
  873. data/lib/studium/yaml/week/05_friday.yml +31 -0
  874. data/lib/studium/yaml/week/06_saturday.yml +16 -0
  875. data/lib/studium/yaml/week/07_sunday.yml +0 -0
  876. data/lib/studium/yaml/week/README.md +10 -0
  877. data/lib/studium.rb +5 -0
  878. data/studium.gemspec +82 -0
  879. data/test/testing_studium.rb +244 -0
  880. data/test/testing_studium_base_class.rb +31 -0
  881. data/test/testing_the_file_lecture_information.rb +18 -0
  882. data/test/testing_time_component.rb +29 -0
  883. metadata +1094 -0
@@ -0,0 +1,1888 @@
1
+ #!/usr/bin/ruby -w
2
+ # Encoding: UTF-8
3
+ # frozen_string_literal: true
4
+ # =========================================================================== #
5
+ # === Studium::GUI::Gtk::ExamQuestionWidget
6
+ #
7
+ # For SQL we could use this:
8
+ #
9
+ # result = `sqlite3 #{SQLITE_DATABASE_FILE} "SELECT * FROM #{current_exam_topic?} ORDER BY RANDOM() LIMIT 1;"`
10
+ # e result
11
+ #
12
+ # =========================================================================== #
13
+ # require 'studium/gui/gtk3/exam_question_widget/exam_question_widget.rb'
14
+ # Studium::GUI::Gtk::ExamQuestionWidget.run
15
+ # =========================================================================== #
16
+ require 'gtk_paradise/require_gtk3'
17
+
18
+ module Studium
19
+
20
+ module GUI
21
+
22
+ module Gtk
23
+
24
+ class ExamQuestionWidget < ::Gtk::Box # === Studium::GUI::Gtk::ExamQuestionWidget
25
+
26
+ require 'studium/project/project.rb'
27
+ require 'studium/constants/constants.rb'
28
+ require 'studium/exams/solved/solved.rb'
29
+ require 'studium/exams/exam_question/exam_question.rb'
30
+ require 'studium/toplevel_methods/available_topics.rb'
31
+ require 'studium/toplevel_methods/find_exam_topic_and_exam_title.rb'
32
+ require 'studium/toplevel_methods/return_question_answer_string_from_this_topic.rb'
33
+ require 'studium/toplevel_methods/return_n_questions_were_answered_for_this_topic.rb'
34
+ require 'studium/toplevel_methods/write_into_file_related_functionality.rb'
35
+
36
+ require 'studium/gui/shared_code/exam_question_widget/exam_question_widget_module.rb'
37
+ include Studium::GUI::ExamQuestionWidgetModule
38
+
39
+ require 'gtk_paradise/requires/require_the_base_module.rb'
40
+ include ::Gtk::BaseModule
41
+
42
+ begin
43
+ require 'roebe/toplevel_methods/rinstall2.rb'
44
+ rescue LoadError; end
45
+
46
+ # ========================================================================= #
47
+ # === WIDTH
48
+ # ========================================================================= #
49
+ WIDTH = '75%'
50
+
51
+ # ========================================================================= #
52
+ # === HEIGHT
53
+ # ========================================================================= #
54
+ HEIGHT = '85%'
55
+
56
+ # ========================================================================= #
57
+ # === USE_THIS_MARGIN
58
+ # ========================================================================= #
59
+ USE_THIS_MARGIN = 12
60
+
61
+ # ========================================================================= #
62
+ # === DEFAULT_DELAY
63
+ #
64
+ # This constant specifies how long to wait before the answer is
65
+ # revealed, if the user has set the checkbutton to "automatically
66
+ # answer the question".
67
+ # ========================================================================= #
68
+ DEFAULT_DELAY = '18.0'
69
+
70
+ # ========================================================================= #
71
+ # === USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC
72
+ #
73
+ # This constant can be used to specify the default exam topic to be
74
+ # used on startup of this application.
75
+ # ========================================================================= #
76
+ USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC =
77
+ 'virus' # stemcells' # chem1' #anatomy'
78
+
79
+ # ========================================================================= #
80
+ # === DEFAULT_PLACEHOLDER_TEXT
81
+ # ========================================================================= #
82
+ DEFAULT_PLACEHOLDER_TEXT =
83
+ 'You can input your answer to the exam question here.'
84
+
85
+ # ========================================================================= #
86
+ # === WORD_WRAP_AT_N_CHARACTERS
87
+ # ========================================================================= #
88
+ WORD_WRAP_AT_N_CHARACTERS = 78
89
+
90
+ # ========================================================================= #
91
+ # === SQLITE_DATABASE_FILE
92
+ #
93
+ # This is experimental - one day we may want to query from a sqlite
94
+ # database rather than flat files.
95
+ # ========================================================================= #
96
+ SQLITE_DATABASE_FILE = '/Depot/jjjj/exam_questions.db'
97
+
98
+ # ========================================================================= #
99
+ # === initialize
100
+ # ========================================================================= #
101
+ def initialize(
102
+ commandline_arguments = ARGV,
103
+ run_already = true
104
+ )
105
+ super(:vertical)
106
+ reset
107
+ set_commandline_arguments(
108
+ commandline_arguments
109
+ )
110
+ run if run_already
111
+ end
112
+
113
+ # ========================================================================= #
114
+ # === reset (reset tag)
115
+ # ========================================================================= #
116
+ def reset
117
+ reset_the_internal_variables
118
+ Studium.set_runmode :gui # Make it known that we use the gui-runmode in this case.
119
+ infer_the_namespace
120
+ # ======================================================================= #
121
+ # === @configuration
122
+ # ======================================================================= #
123
+ @configuration = [true, __dir__, namespace?]
124
+ # ======================================================================= #
125
+ # === @title
126
+ # ======================================================================= #
127
+ title_width_height_font(TITLE, WIDTH, HEIGHT, USE_THIS_FONT)
128
+ use_gtk_paradise_project_css_file
129
+ infer_the_size_automatically
130
+ # ======================================================================= #
131
+ # === @question_is
132
+ # ======================================================================= #
133
+ @question_is = ''.dup
134
+ # ======================================================================= #
135
+ # === @answer_is
136
+ # ======================================================================= #
137
+ @answer_is = ''.dup
138
+ # ======================================================================= #
139
+ # === @user_configuration
140
+ # ======================================================================= #
141
+ @user_configuration = {}
142
+ # ======================================================================= #
143
+ # === :available_exam_topics
144
+ #
145
+ # Keep a reference to the available exam topics.
146
+ # ======================================================================= #
147
+ @user_configuration[:available_exam_topics] = return_available_exam_topics.sort
148
+ # ======================================================================= #
149
+ # === :use_this_editor
150
+ #
151
+ # This may be :bluefish or :internal usually.
152
+ # ======================================================================= #
153
+ @user_configuration[:use_this_editor] = :bluefish
154
+ # ======================================================================= #
155
+ # === :show_ten_aliases
156
+ # ======================================================================= #
157
+ @user_configuration[:show_ten_aliases] = nil
158
+ # ======================================================================= #
159
+ # === :array_all_exam_questions
160
+ # ======================================================================= #
161
+ @user_configuration[:array_all_exam_questions] = []
162
+ # ======================================================================= #
163
+ # === @hash_dataset_of_all_lectures
164
+ # ======================================================================= #
165
+ @hash_dataset_of_all_lectures =
166
+ Studium::Statistics::ReportHowManyExamQuestionsWereAnswered.new { :be_quiet }.internal_dataset
167
+ # ======================================================================= #
168
+ # The next if-clause must come after @user_configuration has been
169
+ # defined.
170
+ # ======================================================================= #
171
+ if Object.const_defined?(:Roebe)
172
+ begin
173
+ require 'roebe/gui/gtk3/show_ten_aliases/show_ten_aliases.rb'
174
+ @user_configuration[:show_ten_aliases] = ::Roebe::GUI::Gtk::ShowTenAliases.new
175
+ rescue LoadError; end
176
+ end
177
+ handle_CSS
178
+ enable_all_key_combinations
179
+ upon_delete_event_quit_the_application
180
+ end
181
+
182
+ # ========================================================================= #
183
+ # === padding?
184
+ # ========================================================================= #
185
+ def padding?
186
+ 8
187
+ end
188
+
189
+ # ========================================================================= #
190
+ # === border_size?
191
+ # ========================================================================= #
192
+ def border_size?
193
+ 4
194
+ end
195
+
196
+ # ========================================================================= #
197
+ # === the_current_exam_question_is_now_solved (solved tag)
198
+ # ========================================================================= #
199
+ def the_current_exam_question_is_now_solved
200
+ _ = Studium::Exams::Solved.new { :do_not_run_yet }
201
+ _.set_commandline
202
+ _.run
203
+ if is_on_roebe? and Object.const_defined?(:Roebe)
204
+ rinstall2
205
+ end
206
+ end
207
+
208
+ # ========================================================================= #
209
+ # === create_text_view_for_the_answer
210
+ # ========================================================================= #
211
+ def create_text_view_for_the_answer
212
+ @text_view_for_the_answer = return_text_view_for_the_answer(@text_buffer_for_the_answer)
213
+ end
214
+
215
+ # ========================================================================= #
216
+ # === create_text_buffer_for_the_answer
217
+ # ========================================================================= #
218
+ def create_text_buffer_for_the_answer
219
+ @text_buffer_for_the_answer = gtk_text_buffer
220
+ end
221
+
222
+ # ========================================================================= #
223
+ # === text_view_containing_the_current_question?
224
+ # ========================================================================= #
225
+ def text_view_containing_the_current_question?
226
+ @text_view_for_the_question
227
+ end
228
+
229
+ # ========================================================================= #
230
+ # === add_the_status_icon
231
+ # ========================================================================= #
232
+ def add_the_status_icon
233
+ status_icon = return_status_icon
234
+ status_icon.favicon = Studium.project_base_directory?+
235
+ 'images/studies_favicon.png'
236
+ status_icon.hint = 'Exam-question widget: train your brain!'
237
+ menu = gtk_menu
238
+
239
+ button_hello_world = gtk_image_menu_item(stock: ::Gtk::Stock::FIND)
240
+ button_hello_world.signal_connect(:activate) {
241
+ e 'Hello world!'
242
+ }
243
+ menu << button_hello_world
244
+
245
+ quit_button = gtk_image_menu_item(stock: ::Gtk::Stock::QUIT)
246
+ quit_button.signal_connect(:activate) { ::Gtk.main_quit }
247
+ menu.append(quit_button)
248
+ menu.show_all
249
+
250
+ status_icon.signal_connect(:popup_menu) { |icon, button, time|
251
+ menu.popup(nil, nil, button, time)
252
+ }
253
+ end
254
+
255
+ # ========================================================================= #
256
+ # === return_button_solve_the_question
257
+ #
258
+ # .set_size_request() is not necessary as we use a separate method
259
+ # that controls the size of the widget at hand.
260
+ # ========================================================================= #
261
+ def return_button_solve_the_question
262
+ button_solve_the_question = bold_button(
263
+ mnemonic: '😁️ Mark the question as _solved ✓'
264
+ )
265
+ button_solve_the_question.lightblue
266
+ button_solve_the_question.hint = 'Use this button to <b>mark the '\
267
+ 'question as solved</b> (that is, correctly answered).'
268
+ # button_solve_the_question.set_size_request(78, 30)
269
+ return button_solve_the_question
270
+ end
271
+
272
+ # ========================================================================= #
273
+ # === return_available_exam_topics
274
+ # ========================================================================= #
275
+ def return_available_exam_topics
276
+ ::Studium.return_available_exam_topics
277
+ end
278
+
279
+ # ========================================================================= #
280
+ # === deselect_the_entry_containing_the_exam_topic
281
+ # ========================================================================= #
282
+ def deselect_the_entry_containing_the_exam_topic
283
+ @entry_holding_all_exam_topics.deselect
284
+ text_view_containing_the_current_question?.set_focus(true)
285
+ end
286
+
287
+ # ========================================================================= #
288
+ # === create_the_main_grid (grid tag)
289
+ # ========================================================================= #
290
+ def create_the_main_grid
291
+ # ======================================================================= #
292
+ # === @grid
293
+ # ======================================================================= #
294
+ @grid = default_grid
295
+ @grid.spacing1 = 8
296
+ @grid.spacing2 = 8
297
+ @grid.pad8px
298
+ end
299
+
300
+ # ========================================================================= #
301
+ # === do_jump_into_the_entry_containing_the_current_exam_topic
302
+ # ========================================================================= #
303
+ def do_jump_into_the_entry_containing_the_current_exam_topic
304
+ @entry_holding_all_exam_topics.do_focus_on_it
305
+ end
306
+
307
+ # ========================================================================= #
308
+ # === text_view_for_the_answer?
309
+ # ========================================================================= #
310
+ def text_view_for_the_answer?
311
+ @text_view_for_the_answer
312
+ end
313
+
314
+ # ========================================================================= #
315
+ # === return_text_view_for_the_question
316
+ # ========================================================================= #
317
+ def return_text_view_for_the_question(
318
+ text_buffer_for_the_question
319
+ )
320
+ text_view_for_the_question = gtk_text_view(text_buffer_for_the_question)
321
+ text_view_for_the_question.set_left_margin(USE_THIS_MARGIN)
322
+ text_view_for_the_question.set_right_margin(USE_THIS_MARGIN)
323
+ text_view_for_the_question.word_wrap
324
+ return text_view_for_the_question
325
+ end
326
+
327
+ # ========================================================================= #
328
+ # === show_ten_aliases?
329
+ # ========================================================================= #
330
+ def show_ten_aliases?
331
+ @user_configuration[:show_ten_aliases]
332
+ end
333
+
334
+ # ========================================================================= #
335
+ # === return_scrolled_window_for_the_text_view_for_the_question
336
+ # ========================================================================= #
337
+ def return_scrolled_window_for_the_text_view_for_the_question(text_view_for_the_question)
338
+ scrolled_window_containing_the_textarea1 = gtk_scrolled_window(
339
+ text_view_for_the_question
340
+ ) { :only_up_and_bottom }
341
+ scrolled_window_containing_the_textarea1.set_name('textview1') # Contains the question.
342
+ scrolled_window_containing_the_textarea1.set_size_request(1000, 150)
343
+ return scrolled_window_containing_the_textarea1
344
+ end
345
+
346
+ require 'studium/toplevel_methods/word_wrap.rb'
347
+ # ========================================================================= #
348
+ # === do_reveal_the_answer_after_timeout (revel tag)
349
+ #
350
+ # Note that the timeout will be in n ms (milliseconds).
351
+ # ========================================================================= #
352
+ def do_reveal_the_answer_after_timeout(
353
+ answer = answer_is?,
354
+ use_this_as_timeout = @entry_delay_to_use.text
355
+ )
356
+ if use_this_as_timeout.is_a? String
357
+ use_this_as_timeout = use_this_as_timeout.to_f * 1000
358
+ end
359
+ if answer
360
+ case answer
361
+ # ===================================================================== #
362
+ # === :default
363
+ # ===================================================================== #
364
+ when :default
365
+ answer = answer_is?
366
+ end
367
+ answer.gsub!(/\<.+?\>/,'')
368
+ #answer = ::Studium.word_wrap(answer, 78).to_s
369
+ if use_this_as_timeout > 0 and @checkbox_shall_we_reveal_the_answer.is_it_active?
370
+ # =================================================================== #
371
+ # This clause here is only ever entered when we have a delay. We
372
+ # have to check whether the main checkbox is active, because the
373
+ # user may have de-selected it in-between the delay time span.
374
+ # =================================================================== #
375
+ GLib::Timeout.add(use_this_as_timeout) {
376
+ @text_view_for_the_answer.set_text(answer)
377
+ false
378
+ }
379
+ else
380
+ @text_view_for_the_answer.set_text(answer)
381
+ end
382
+ end
383
+ end
384
+
385
+ # ======================================================================= #
386
+ # === set_exam_topic
387
+ # ======================================================================= #
388
+ def set_exam_topic(i)
389
+ i = i.to_s.downcase
390
+ @entry_holding_all_exam_topics.set_text(i)
391
+ end
392
+
393
+ # ========================================================================= #
394
+ # === return_button_open_exam_topic_file
395
+ # ========================================================================= #
396
+ def return_button_open_exam_topic_file
397
+ # ======================================================================= #
398
+ # This button will have the symbol for :open_file, an emoji - if
399
+ # emojis are used. Otherwise an image will be used instead.
400
+ # ======================================================================= #
401
+ if use_emoji?
402
+ _ = gtk_button(return_emoji(:open_box))
403
+ else
404
+ _ = gtk_button_with_this_image(image_open_file)
405
+ end
406
+ _.no_relief
407
+ _.lightblue
408
+ _.hint = 'Click this button to open the current exam-topic file.'
409
+ _.on_clicked {
410
+ do_open_the_current_exam_topic_file
411
+ }
412
+ return _
413
+ end
414
+
415
+ # ========================================================================= #
416
+ # === handle_CSS (CSS tag)
417
+ # ========================================================================= #
418
+ def handle_CSS
419
+ use_gtk_paradise_project_css_file
420
+ append_project_css_file
421
+ #apply_more_CSS_rules ''
422
+ apply_the_CSS_rules
423
+ end
424
+
425
+ # ========================================================================= #
426
+ # === return_checkbox_shall_we_reveal_the_answer
427
+ # ========================================================================= #
428
+ def return_checkbox_shall_we_reveal_the_answer
429
+ _ = gtk_checkbox(
430
+ "Automatically reveal the \nanswer after a delay"
431
+ )
432
+ _.set_font(SMALLEST_FONT)
433
+ # ======================================================================= #
434
+ # Next determine whether the checkbox is active, on startup, or whether
435
+ # it is not active when the GUI starts up.
436
+ # ======================================================================= #
437
+ _.mark_as_unchecked
438
+ _.hint = 'Deselect this if you do not want to automatically reveal '\
439
+ 'the answer. In that case you have to manually click on '\
440
+ 'the Answer button.'
441
+ _.on_toggled { |widget|
442
+ if _.active?
443
+ @entry_delay_to_use.grey_in
444
+ elsif not _.active?
445
+ @entry_delay_to_use.grey_out
446
+ end
447
+ }
448
+ if _.is_it_active?
449
+ @entry_delay_to_use.grey_in
450
+ else
451
+ @entry_delay_to_use.grey_out
452
+ end
453
+ return _
454
+ end
455
+
456
+ # ========================================================================= #
457
+ # === clear_reveal_the_answer
458
+ # ========================================================================= #
459
+ def clear_reveal_the_answer
460
+ @text_view_for_the_answer.set_text('')
461
+ end
462
+
463
+ # ========================================================================= #
464
+ # === do_clear_the_free_form_textarea
465
+ # ========================================================================= #
466
+ def do_clear_the_free_form_textarea
467
+ @textarea3.set_text('')
468
+ end
469
+
470
+ # ========================================================================= #
471
+ # === return_text_view_for_the_answer
472
+ # ========================================================================= #
473
+ def return_text_view_for_the_answer(
474
+ text_buffer_for_the_answer
475
+ )
476
+ _ = gtk_text_view(text_buffer_for_the_answer)
477
+ _.set_left_margin(USE_THIS_MARGIN)
478
+ _.set_right_margin(USE_THIS_MARGIN)
479
+ _.word_wrap
480
+ return _
481
+ end
482
+
483
+ # ========================================================================= #
484
+ # === return_frame_containing_the_label_exam_topic
485
+ # ========================================================================= #
486
+ def return_frame_containing_the_label_exam_topic
487
+ # ======================================================================= #
488
+ # Create the exam-topic label next, showing a watermelon emoji on the
489
+ # left-hand side. The watermelon emoji used to be 🍉️; but it was
490
+ # replaced with the electric light bulb emoji in January 2021, which
491
+ # is 💡️. Unfortunately this does not work on every system, so it
492
+ # was decided to replace this with an image that is determined by
493
+ # the icon theme at hand.
494
+ # ======================================================================= #
495
+ label_exam_topic = bold_label(' Exam topic')
496
+ # label_exam_topic.css_class('small_text_shadow')
497
+ label_emoji = right_arrow_emoji
498
+ label_emoji.set_size_request(30, 30)
499
+ label_emoji.align_right
500
+ tiny_hbox = gtk_hbox
501
+ tiny_hbox.minimal(label_exam_topic)
502
+ tiny_hbox.maximal(label_emoji)
503
+ tiny_hbox.minimal(text(' ')) # Just a "spacer".
504
+ frame_containing_the_label_exam_topic = gtk_frame(tiny_hbox)
505
+ frame_containing_the_label_exam_topic.modify_background(:normal, :oldlace)
506
+ frame_containing_the_label_exam_topic.css_class('bblack1')
507
+ label_exam_topic.hint = 'Denote <b>the current exam </b> topic '\
508
+ 'to the <b>right</b> of this text.'
509
+ return frame_containing_the_label_exam_topic
510
+ end
511
+
512
+ # ========================================================================= #
513
+ # === do_style_all_buttons_uniformly
514
+ # ========================================================================= #
515
+ def do_style_all_buttons_uniformly(
516
+ i = return_all_buttons
517
+ )
518
+ # ======================================================================= #
519
+ # Style all buttons uniformly next, via CSS.
520
+ # ======================================================================= #
521
+ i.each {|this_button|
522
+ # ===================================================================== #
523
+ # Use the same CSS rule for each button.
524
+ # ===================================================================== #
525
+ this_button.clear_background
526
+ this_button.css_class('bblack2')
527
+ this_button.set_size_request(75, 28)
528
+ this_button.set_name('button_hover_transition')
529
+ }
530
+ end
531
+
532
+ # ========================================================================= #
533
+ # === return_textarea_number_three
534
+ # ========================================================================= #
535
+ def return_textarea_number_three
536
+ # ======================================================================= #
537
+ # Next comes the textarea for "free typing", where the user can
538
+ # simply write whatever he wants to.
539
+ # ======================================================================= #
540
+ textarea = gtk_textarea
541
+ textarea.set_left_margin(USE_THIS_MARGIN)
542
+ textarea.set_right_margin(USE_THIS_MARGIN)
543
+ # ======================================================================= #
544
+ # The next code sets up a default placeholder text. Upon a focus-in-event
545
+ # that default placeholder text is removed.
546
+ # ======================================================================= #
547
+ textarea.buffer.set_placeholder_text(
548
+ DEFAULT_PLACEHOLDER_TEXT
549
+ )
550
+ textarea.buffer.sync_placeholder_text
551
+ textarea.focus_in_event {
552
+ if textarea.buffer.text? == DEFAULT_PLACEHOLDER_TEXT
553
+ textarea.buffer.clear # Remove that placeholder text in this case.
554
+ end
555
+ }
556
+ textarea.word_wrap
557
+ return textarea
558
+ end
559
+
560
+ # ========================================================================= #
561
+ # === return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
562
+ # ========================================================================= #
563
+ def return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
564
+ hbox_with_two_icons = gtk_hbox
565
+ first_eventbox = gtk_event_box(image_accessories_text_editor)
566
+ first_eventbox.on_clicked {
567
+ do_clear_the_free_form_textarea
568
+ }
569
+ hbox_with_two_icons.minimal(first_eventbox, 2)
570
+ text = gtk_label(
571
+ 'Below this text you can input your assumed '\
572
+ 'answer to the exam question at hand.'
573
+ )
574
+ text.left_align
575
+ text.make_selectable
576
+ text.set_font(:hack_18)
577
+ hbox_with_two_icons.maximal(text, 4)
578
+ event_box_for_image_accessories_text_editor = gtk_event_box(image_accessories_text_editor)
579
+ event_box_for_image_accessories_text_editor.hint = 'Click here to '\
580
+ 'empty the free-form textarea below this icon.'
581
+ event_box_for_image_accessories_text_editor.on_clicked {
582
+ do_clear_the_free_form_textarea
583
+ }
584
+ hbox_with_two_icons.minimal(event_box_for_image_accessories_text_editor, 2)
585
+ return hbox_with_two_icons
586
+ end
587
+
588
+ require 'studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb'
589
+ # ========================================================================= #
590
+ # === all_questions_have_been_answered_in_this_topic?
591
+ #
592
+ # This method has to determine how many questions have been answered
593
+ # in the current exam topic.
594
+ # ========================================================================= #
595
+ def all_questions_have_been_answered_in_this_topic?(
596
+ this_topic = current_exam_topic?
597
+ )
598
+ (Studium.return_n_percent_solved_from_this_topic(this_topic).to_i == 100)
599
+ end
600
+
601
+ # ========================================================================= #
602
+ # === use_emoji?
603
+ # ========================================================================= #
604
+ def use_emoji?
605
+ @prefer_emoji_or_images == :emoji
606
+ end
607
+
608
+ # ========================================================================= #
609
+ # === activate_the_third_textview
610
+ # ========================================================================= #
611
+ def activate_the_third_textview
612
+ @textarea3.do_focus_on_it
613
+ end
614
+
615
+ # ========================================================================= #
616
+ # === return_scrolled_window_containing_the_textarea3
617
+ # ========================================================================= #
618
+ def return_scrolled_window_containing_the_textarea3(textarea = @textarea3)
619
+ # ======================================================================= #
620
+ # === scrolled_window_containing_the_textarea3
621
+ #
622
+ # This is the scrolled-window containing the free-form text the user
623
+ # can type.
624
+ # ======================================================================= #
625
+ scrolled_window_containing_the_textarea3 = gtk_scrolled_window(textarea) { :only_top_to_bottom }
626
+ scrolled_window_containing_the_textarea3.set_name('textview3')
627
+ scrolled_window_containing_the_textarea3.css_class('pad4px')
628
+ scrolled_window_containing_the_textarea3.set_size_request(
629
+ 1000, 180
630
+ )
631
+ scrolled_window_containing_the_textarea3.do_show_the_scrollbars
632
+ scrolled_window_containing_the_textarea3.min_content_width = 100
633
+ scrolled_window_containing_the_textarea3.min_content_height = 150
634
+ # ======================================================================= #
635
+ # Next, enable select-all-on-click events:
636
+ # ======================================================================= #
637
+ scrolled_window_containing_the_textarea3.signal_connect(:event) {|widget, event|
638
+ case event.event_type.name.to_s
639
+ when 'GDK_BUTTON_PRESS'
640
+ # e 'The left mouse-button was clicked! Selecting everything next.'
641
+ # @text_view_for_simply_typing_anything.signal_emit(:select_all, event)
642
+ textarea.select_everything(event)
643
+ end
644
+ }
645
+ return scrolled_window_containing_the_textarea3
646
+ end
647
+
648
+ # ========================================================================= #
649
+ # === rinstall2
650
+ # ========================================================================= #
651
+ def rinstall2
652
+ Roebe.rinstall2(
653
+ use_this_directory: Studium.ruby_src_dir_at_home?+
654
+ 'studium/'
655
+ )
656
+ end; alias r2 rinstall2 # === r2
657
+
658
+ # ========================================================================= #
659
+ # === use_the_internal_editor?
660
+ # ========================================================================= #
661
+ def use_the_internal_editor?
662
+ @user_configuration[:use_this_editor] == :internal
663
+ end
664
+
665
+ # ========================================================================= #
666
+ # === return_n_answers_from_the_currently_selected_topic
667
+ # ========================================================================= #
668
+ def return_n_answers_from_the_currently_selected_topic(
669
+ i = exam_topic?
670
+ )
671
+ ::Studium.n_answers_available_in_this_topic(i)
672
+ end
673
+
674
+ # ========================================================================= #
675
+ # === main_font?
676
+ # ========================================================================= #
677
+ def main_font?
678
+ USE_THIS_FONT
679
+ end
680
+
681
+ # ========================================================================= #
682
+ # === entry_percentage?
683
+ # ========================================================================= #
684
+ def entry_percentage?
685
+ @entry_percentage
686
+ end
687
+
688
+ # ========================================================================= #
689
+ # === return_scrolled_window_containing_the_text_view_for_the_answer
690
+ # ========================================================================= #
691
+ def return_scrolled_window_containing_the_text_view_for_the_answer(
692
+ text_view_for_the_answer
693
+ )
694
+ @scrolled_window_containing_the_textarea2 = gtk_scrolled_window(
695
+ text_view_for_the_answer
696
+ ) { :only_up_and_bottom }
697
+ @scrolled_window_containing_the_textarea2.set_name('textview2') # Contains the answer.
698
+ @scrolled_window_containing_the_textarea2.set_size_request(1000, 150)
699
+ @scrolled_window_containing_the_textarea2.min_content_width = 100
700
+ @scrolled_window_containing_the_textarea2.min_content_height = 200
701
+ @scrolled_window_containing_the_textarea2.do_show_the_scrollbars
702
+ end
703
+
704
+ # ========================================================================= #
705
+ # === parse_for_URL
706
+ #
707
+ # This method can be used to return all URLs in a given text.
708
+ # ========================================================================= #
709
+ def parse_for_URL(
710
+ i = text_view_for_the_answer?.buffer.text
711
+ )
712
+ array = ::Studium.return_all_URLs_from(i)
713
+ if array.size > 0
714
+ first_entry = array.first
715
+ # ===================================================================== #
716
+ # We first have to assign it to the GUI part. Note that the "browser"
717
+ # is part of the control-panel since the rewrite in January 2021.
718
+ # ===================================================================== #
719
+ control_panel?.browser?.assign_this_text(first_entry)
720
+ ::Studium.open_this_remote_url(first_entry)
721
+ end
722
+ end
723
+
724
+ # ========================================================================= #
725
+ # === create_the_checkbox
726
+ #
727
+ # This has to be created after the entries are created.
728
+ # ========================================================================= #
729
+ def create_the_checkbox
730
+ # ======================================================================= #
731
+ # === @checkbox_shall_we_reveal_the_answer
732
+ # ======================================================================= #
733
+ @checkbox_shall_we_reveal_the_answer = return_checkbox_shall_we_reveal_the_answer
734
+ end
735
+
736
+ # ========================================================================= #
737
+ # === main_combo_box?
738
+ # ========================================================================= #
739
+ def main_combo_box?
740
+ @combo_box_available_exam_topics
741
+ end
742
+
743
+ # ========================================================================= #
744
+ # === return_eventbox_with_an_image_to_exit_the_application
745
+ # ========================================================================= #
746
+ def return_eventbox_with_an_image_to_exit_the_application
747
+ application_exit_image = return_this_image_based_on_the_default_icon_theme(
748
+ 'system-log-out-symbolic.symbolic'
749
+ ) # Or: :application_exit
750
+ _ = gtk_eventbox(application_exit_image)
751
+ _.hint = 'Click on this image to exit the program.'
752
+ _.on_clicked {
753
+ exit_application
754
+ }
755
+ return _
756
+ end
757
+
758
+ # ========================================================================= #
759
+ # === connect_skeleton (connect tag)
760
+ # ========================================================================= #
761
+ def connect_skeleton
762
+ abort_on_exception
763
+ # ======================================================================= #
764
+ # Add the status icon and style it a little bit as well.
765
+ # ======================================================================= #
766
+ add_the_status_icon
767
+ @grid.left(return_frame_containing_the_label_exam_topic)
768
+ mini_hbox = gtk_hbox
769
+ mini_hbox.minimal(@entry_holding_all_exam_topics, 2)
770
+ mini_hbox.minimal(@combo_box_available_exam_topics, 2)
771
+ mini_hbox.minimal(return_event_box_with_face_glasses, 2)
772
+ mini_hbox.rpack(return_eventbox_with_an_image_to_exit_the_application, 2)
773
+ @grid.right(mini_hbox)
774
+ @grid.left(@button_ask_the_exam_question)
775
+
776
+ # ======================================================================= #
777
+ # === @text_view_for_the_question
778
+ # ======================================================================= #
779
+ @text_buffer_for_the_question = gtk_text_buffer
780
+ @text_view_for_the_question = return_text_view_for_the_question(@text_buffer_for_the_question)
781
+ @scrolled_window_containing_the_textarea1 = return_scrolled_window_for_the_text_view_for_the_question(@text_view_for_the_question)
782
+
783
+ @grid.right(@scrolled_window_containing_the_textarea1)
784
+
785
+ @grid.left(@button_reveal_the_answer)
786
+ @scrolled_window_containing_the_textarea2 = return_scrolled_window_containing_the_text_view_for_the_answer(
787
+ @text_view_for_the_answer
788
+ )
789
+ @grid.right(@scrolled_window_containing_the_textarea2)
790
+
791
+ hbox_with_two_icons = return_hbox_containing_two_icons_and_instructions_what_to_do_with_the_free_form_textarea
792
+ @grid.full_line(hbox_with_two_icons)
793
+
794
+ # ======================================================================= #
795
+ # === @textarea3
796
+ # ======================================================================= #
797
+ @textarea3 = return_textarea_number_three
798
+ @scrolled_window_containing_the_textarea3 = return_scrolled_window_containing_the_textarea3(@textarea3)
799
+ @grid.full_row(@scrolled_window_containing_the_textarea3)
800
+
801
+ lower_vbox = gtk_vbox
802
+ @hbox_containing_three_labels_and_three_entries = return_hbox_containing_three_labels_and_three_entries
803
+ middle_hbox = gtk_hbox
804
+ mini_hbox = gtk_hbox
805
+ # ======================================================================= #
806
+ # Add the checkbox for revealing the answer next:
807
+ # ======================================================================= #
808
+ mini_hbox.minimal(@checkbox_shall_we_reveal_the_answer, 2)
809
+ mini_hbox.minimal(@entry_delay_to_use, 2)
810
+ # ======================================================================= #
811
+ # The middle-hbox contains the other hboxes.
812
+ # ======================================================================= #
813
+ middle_hbox.minimal(mini_hbox, 1)
814
+ middle_hbox.minimal(@hbox_containing_three_labels_and_three_entries, 1)
815
+ middle_hbox.minimal(@button_use_random_entry_from_the_ten_aliases, 5)
816
+ middle_hbox.minimal(return_event_box_for_asking_a_random_exam_topic, 10)
817
+ lower_vbox.minimal(middle_hbox, 1)
818
+
819
+ small_hbox = gtk_hbox
820
+ small_hbox.minimal(@button_solve_the_question, 2)
821
+ small_hbox.minimal(return_button_open_exam_topic_file, 2)
822
+ small_hbox.minimal(return_wikipedia_entry, 2)
823
+ small_hbox.minimal(gtk_hseparator)
824
+
825
+ lower_vbox.minimal(small_hbox, 2)
826
+ lower_vbox.minimal(@label_n_questions_were_answered, 8)
827
+
828
+ draggable = draggable_up_and_down(
829
+ @grid,
830
+ lower_vbox
831
+ )
832
+ maximal(draggable)
833
+ end
834
+
835
+ # ========================================================================= #
836
+ # === do_clear_the_question_buffer
837
+ #
838
+ # Clear the question-buffer via this method.
839
+ # ========================================================================= #
840
+ def do_clear_the_question_buffer
841
+ @text_buffer_for_the_question.set_text('')
842
+ end
843
+
844
+ require 'studium/toplevel_methods/n_questions_available.rb'
845
+ # ========================================================================= #
846
+ # === return_n_questions_from_the_currently_selected_topic
847
+ # ========================================================================= #
848
+ def return_n_questions_from_the_currently_selected_topic(
849
+ i = exam_topic?
850
+ )
851
+ ::Studium.n_questions_available_in_this_topic(i)
852
+ end
853
+
854
+ # ========================================================================= #
855
+ # === reveal_the_answer_to_the_exam_question
856
+ # ========================================================================= #
857
+ def reveal_the_answer_to_the_exam_question
858
+ do_reveal_the_answer_after_timeout(:default, 0)
859
+ end
860
+
861
+ # ========================================================================= #
862
+ # === create_the_ask_the_exam_question_button
863
+ # ========================================================================= #
864
+ def create_the_ask_the_exam_question_button
865
+ # ======================================================================= #
866
+ # === @button_ask_the_exam_question
867
+ # ======================================================================= #
868
+ @button_ask_the_exam_question = return_button_ask_the_exam_question(use_emoji?)
869
+ end
870
+
871
+ # ========================================================================= #
872
+ # === return_button_ask_the_exam_question (ask tag)
873
+ # ========================================================================= #
874
+ def return_button_ask_the_exam_question(
875
+ use_emoji = false
876
+ )
877
+ # ======================================================================= #
878
+ # Add the ask-exam-question button next. Note that its click-event
879
+ # is handled separately via a method call.
880
+ #
881
+ # The question mark emoji is Unicode Character "❓" (U+2753).
882
+ # ======================================================================= #
883
+ if use_emoji?
884
+ button_ask_the_exam_question = gtk_bold_button(mnemonic: 'Ask a _Question ❓')
885
+ else
886
+ button_ask_the_exam_question = gtk_bold_button(mnemonic: 'Ask a _Question')
887
+ end
888
+ button_ask_the_exam_question.set_size_request(75, 28)
889
+ button_ask_the_exam_question.clear_background
890
+ button_ask_the_exam_question.pad2px
891
+ button_ask_the_exam_question.hint =
892
+ 'Click on this button to ask an exam-question. '\
893
+ '(Or, use alt+q as shortcut)'
894
+ return button_ask_the_exam_question
895
+ end
896
+
897
+ # ========================================================================= #
898
+ # === button_ask_the_exam_question?
899
+ # ========================================================================= #
900
+ def button_ask_the_exam_question?
901
+ @button_ask_the_exam_question
902
+ end; alias question_button? button_ask_the_exam_question? # === question_button?
903
+ alias button_ask_the_question? button_ask_the_exam_question? # === button_ask_the_question?
904
+
905
+ # ========================================================================= #
906
+ # === do_handle_the_click_event_for_the_ask_question_button (clicked tag)
907
+ #
908
+ # This method requires the Studium.write_what_into() method.
909
+ # ========================================================================= #
910
+ def do_handle_the_click_event_for_the_ask_question_button
911
+ # ======================================================================= #
912
+ # Determine what happens next when the ask-question button is clicked.
913
+ # ======================================================================= #
914
+ button_ask_the_question?.on_clicked {
915
+ the_button_ask_the_question_was_clicked
916
+ }
917
+ end
918
+
919
+ # ========================================================================= #
920
+ # === update_the_label_n_questions_were_answered
921
+ # ========================================================================= #
922
+ def update_the_label_n_questions_were_answered(
923
+ i = @label_n_questions_were_answered
924
+ )
925
+ i.set_text(
926
+ return_string_how_many_exam_questions_are_already_answered
927
+ )
928
+ end
929
+
930
+ # ========================================================================= #
931
+ # === create_the_buttons (buttons tag, button tag)
932
+ # ========================================================================= #
933
+ def create_the_buttons
934
+ create_the_ask_the_exam_question_button
935
+ create_the_button_use_random_entry_from_the_ten_aliases
936
+ create_the_reveal_button
937
+ # ======================================================================= #
938
+ # === @button_solve_the_question
939
+ # ======================================================================= #
940
+ @button_solve_the_question = return_button_solve_the_question
941
+ @button_solve_the_question.on_clicked {
942
+ the_current_exam_question_is_now_solved
943
+ update_three_important_widgets
944
+ do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
945
+ @entry_percentage, current_exam_topic?
946
+ )
947
+ }
948
+ end
949
+
950
+ # ========================================================================= #
951
+ # === return_entry_percentage
952
+ # ========================================================================= #
953
+ def return_entry_percentage
954
+ _ = entry('')
955
+ _.hint = "This denotes how many questions have already\n"\
956
+ "been answered successfully, <b>in percent</b>.\n"\
957
+ "Note that this requires a specific exam topic to "\
958
+ "have been set, so no percentage value may be "\
959
+ "shown initially.\nSimply assign to an exam topic "\
960
+ "and it should work fine."
961
+ _.do_center
962
+ _.disable_user_input
963
+ _.set_name('BG_bisque')
964
+ _.bblack1
965
+ return _
966
+ end
967
+
968
+ # ========================================================================= #
969
+ # === create_the_reveal_button
970
+ # ========================================================================= #
971
+ def create_the_reveal_button
972
+ # ======================================================================= #
973
+ # === The reveal-button is created next, also known as the
974
+ # "answer button". (answer tag)
975
+ # The mnemonic-key is set to "A".
976
+ # ======================================================================= #
977
+ @button_reveal_the_answer = gtk_bold_button(
978
+ mnemonic: 'Reveal the _Answer' # This was the old emoji: ❗
979
+ )
980
+ @button_reveal_the_answer.set_size_request(78, 30)
981
+ @button_reveal_the_answer.lightblue
982
+ @button_reveal_the_answer.on_clicked {
983
+ if all_questions_have_been_answered_in_this_topic?
984
+ notify_the_user_that_all_questions_have_been_answered_in_this_topic(
985
+ current_topic?,
986
+ @button_reveal_the_answer
987
+ )
988
+ else
989
+ do_reveal_the_answer_after_timeout(answer_is?, 0)
990
+ end
991
+ }
992
+ @button_reveal_the_answer.hint = 'Click on this button in order to '\
993
+ 'reveal the answer to the current exam question at hand.'
994
+ end
995
+
996
+ # ========================================================================= #
997
+ # === update_three_important_widgets
998
+ # ========================================================================= #
999
+ def update_three_important_widgets
1000
+ update_the_label_n_questions_were_answered
1001
+ update_the_entry_n_unanswered_questions
1002
+ update_the_percentage_entry
1003
+ end
1004
+
1005
+ require 'studium/toplevel_methods/return_n_percent_solved_from_this_topic.rb'
1006
+ # ========================================================================= #
1007
+ # === do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value
1008
+ # ========================================================================= #
1009
+ def do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
1010
+ entry_percentage = entry_percentage?,
1011
+ use_this_exam_topic = current_exam_topic?.to_s
1012
+ )
1013
+ percentage_value = Studium.n_percent_questions_answered_of_this_topic?(
1014
+ use_this_exam_topic.downcase
1015
+ )
1016
+ if percentage_value == false
1017
+ percentage_value = -1
1018
+ end
1019
+ percentage_value = percentage_value.to_s.to_f.round(1)
1020
+ percentage_value = percentage_value.to_s.dup
1021
+ percentage_value << '%' unless percentage_value.end_with? '%'
1022
+ entry_percentage.set_text(percentage_value) # And sync it onto the proper entry.
1023
+ end; alias update_the_percentage_entry do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value # === update_the_percentage_entry
1024
+
1025
+ # ========================================================================= #
1026
+ # === enable_alt_y_key_combination
1027
+ # ========================================================================= #
1028
+ def enable_alt_y_key_combination
1029
+ # ======================================================================= #
1030
+ # Add alt+y key combination, to assign a new exam topic:
1031
+ # ======================================================================= #
1032
+ use_this_key = Gdk::Keyval::KEY_Y
1033
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+y
1034
+ do_assign_a_new_exam_topic
1035
+ }
1036
+ end
1037
+
1038
+ # ========================================================================= #
1039
+ # === enable_alt_w_key_combination
1040
+ #
1041
+ # This method will specifically enable the "alt+w" shortcut.
1042
+ # ========================================================================= #
1043
+ def enable_alt_w_key_combination
1044
+ # ======================================================================= #
1045
+ # Add alt+w key combination, to open the current exam topic file:
1046
+ # ======================================================================= #
1047
+ use_this_key = Gdk::Keyval::KEY_W
1048
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+w
1049
+ do_open_the_current_exam_topic_file
1050
+ }
1051
+ end
1052
+
1053
+ # ========================================================================= #
1054
+ # === enable_alt_1_key_combination
1055
+ # ========================================================================= #
1056
+ def enable_alt_1_key_combination
1057
+ # ======================================================================= #
1058
+ # Add alt+1 key combination:
1059
+ # ======================================================================= #
1060
+ use_this_key = Gdk::Keyval::KEY_1
1061
+ @accel_group.connect(use_this_key, :mod1_mask, :visible) { # alt+1
1062
+ entry_ask_questions?.set_focus(true)
1063
+ }
1064
+ end
1065
+
1066
+ # ========================================================================= #
1067
+ # === Studium::GUI::Gtk::ExamQuestionWidget.run
1068
+ # ========================================================================= #
1069
+ def self.run(
1070
+ i = ARGV
1071
+ )
1072
+ require 'gtk_paradise/app/app.rb'
1073
+ _ = ::Studium::GUI::Gtk::ExamQuestionWidget.new(i)
1074
+ r = ::Gtk.run
1075
+ r << _
1076
+ r.add_context_menu_with_the_default_accel_group
1077
+ r.on_button_press_event { |widget, event|
1078
+ if ::Gtk.right_mouse_click?(event) # right mouse click event.
1079
+ _.context_menu?.popup_based_on_this_event(event)
1080
+ end
1081
+ }
1082
+ r.automatic_size_then_automatic_title
1083
+ r.top_left_then_run
1084
+ end
1085
+
1086
+ # ========================================================================= #
1087
+ # === Studium::GUI::Gtk::AskExamQuestion.gtk_accel_group
1088
+ # ========================================================================= #
1089
+ def self.gtk_accel_group
1090
+ ::Gtk::AccelGroup.new
1091
+ end
1092
+
1093
+ # ========================================================================= #
1094
+ # === popup_pick_a_new_font
1095
+ # ========================================================================= #
1096
+ def popup_pick_a_new_font
1097
+ _ = gtk_hbox
1098
+ _.minimal(text(' → '))
1099
+ file_chooser_widget = gtk_button('Choose font here')
1100
+ file_chooser_widget.set_size_request(1200, 960)
1101
+ file_chooser_widget.css_class('bblack2')
1102
+ file_chooser_widget.set_size_request(500, 300)
1103
+ file_chooser_widget.disallow_resizing
1104
+ _.minimal(file_chooser_widget)
1105
+ file_chooser_widget.on_click {
1106
+ result = gtk_font_chooser_dialog
1107
+ set_use_this_font(::Gtk.main_file?)
1108
+ result.destroy
1109
+ }
1110
+ # ======================================================================= #
1111
+ # Next create the popup for the font-choosing.
1112
+ # ======================================================================= #
1113
+ popup_widget = popup_over_this_widget(
1114
+ text_view_for_the_question?,
1115
+ '',
1116
+ _
1117
+ )
1118
+ # popup_widget.no_arrow # ← This will only work on gtk4, I think.
1119
+ popup_widget.popup
1120
+ end
1121
+
1122
+ # ========================================================================= #
1123
+ # === text_view_for_the_question?
1124
+ # ========================================================================= #
1125
+ def text_view_for_the_question?
1126
+ @text_view_for_the_question
1127
+ end
1128
+
1129
+ # ========================================================================= #
1130
+ # === top_textbuffer?
1131
+ # ========================================================================= #
1132
+ def top_textbuffer?
1133
+ @text_view_for_the_question.buffer
1134
+ end
1135
+
1136
+ # ========================================================================= #
1137
+ # === current_exam_topic?
1138
+ # ========================================================================= #
1139
+ def current_exam_topic?
1140
+ @entry_holding_all_exam_topics.text?.strip
1141
+ end; alias main_exam_topic? current_exam_topic? # === main_exam_topic?
1142
+ alias exam_topic? current_exam_topic? # === exam_topic?
1143
+ alias current_topic? current_exam_topic? # === current_topic?
1144
+
1145
+ # ========================================================================= #
1146
+ # === the_button_ask_the_question_was_clicked
1147
+ # ========================================================================= #
1148
+ def the_button_ask_the_question_was_clicked
1149
+ # ======================================================================= #
1150
+ # (1) First, clear the old question-buffer, just in case.
1151
+ # ======================================================================= #
1152
+ do_clear_the_question_buffer
1153
+ # ======================================================================= #
1154
+ # (2) Query the exam-topic that is part of the combo box
1155
+ # ======================================================================= #
1156
+ _ = @combo_box_available_exam_topics.text?.tr(' ','_').downcase
1157
+ if _.empty?
1158
+ bold_popover_message = bold_label(
1159
+ 'You have to provide an exam-topic - see the text above.'
1160
+ )
1161
+ popover_message(
1162
+ bold_popover_message,
1163
+ button_ask_the_exam_question?
1164
+ ).popup
1165
+ end
1166
+ # ======================================================================= #
1167
+ # (3) Check whether there is no exam-topic selected. We have to be
1168
+ # careful here, as an infinite loop may result.
1169
+ # ======================================================================= #
1170
+ unless entry_ask_questions_from_this_topic?.empty?
1171
+ # This clause is entered when the user has a gtk-entry point.
1172
+ _ = entry_ask_questions_from_this_topic?.text.to_s
1173
+ use_this_index = ::Studium.find_corresponding_exam_title(_)
1174
+ use_this_topic = available_exam_topics?.index(use_this_index)
1175
+ # ===================================================================== #
1176
+ # Next be careful - we don't want an infinite loop:
1177
+ # ===================================================================== #
1178
+ if use_this_topic
1179
+ #@combo_box_available_exam_topics.set_active(use_this_topic)
1180
+ #entry_ask_questions_from_this_topic?.set_text(_) # Need to sync it back again.
1181
+ do_updated_the_entries_n_answered_and_n_unanswered
1182
+ end
1183
+ end
1184
+ if @entry_percentage.text.to_f == 100.0
1185
+ # ===================================================================== #
1186
+ # Handle the case where the exam-topic at hand has been answered
1187
+ # completely.
1188
+ # ===================================================================== #
1189
+ bold_popover_message = gtk_bold_label(
1190
+ "All questions have been answered for the topic "\
1191
+ "#{exam_topic?}.\n\n Please choose another exam topic.\n"
1192
+ )
1193
+ popover_message(
1194
+ bold_popover_message,
1195
+ @button_ask_the_exam_question
1196
+ ).popup
1197
+ else
1198
+ # ===================================================================== #
1199
+ # Check whether the exam-topic is registered:
1200
+ # ===================================================================== #
1201
+ if ::Studium.is_this_exam_topic_available?(_)
1202
+ @question_answer = Studium.ask_question(_) { :do_not_run_yet }
1203
+ @question_answer.initial_steps
1204
+ line = @question_answer.line?.to_s.tr("\n", ' ').rstrip
1205
+ array_all_exam_questions? << line
1206
+ # =================================================================== #
1207
+ # Store it as well.
1208
+ # =================================================================== #
1209
+ into = ::Studium.file_last_question_asked?
1210
+ Studium.write_what_into(line, into)
1211
+ index = @question_answer.split_position?
1212
+ question = line[0 .. index]
1213
+ question.tr!("\n", ' ')
1214
+ question.rstrip!
1215
+ if line
1216
+ @answer_is = line[(index+1) .. -1].strip.dup
1217
+ @answer_is = ::Gtk.replace_all_URL_entries_in_this_string(@answer_is)
1218
+ @answer_is.lstrip!
1219
+ if @answer_is.start_with? 'A: '
1220
+ @answer_is.sub!(/A: /,'')
1221
+ end
1222
+ # ================================================================= #
1223
+ # Replace all "(2) foo" entries with "(2) foo\n" entries.
1224
+ # ================================================================= #
1225
+ require 'studium/toplevel_methods/misc.rb'
1226
+ @answer_is = ::Studium.add_newlines_to_numbered_exam_question(@answer_is)
1227
+ end
1228
+ # =================================================================== #
1229
+ # Remove <one> and similar tags.
1230
+ # =================================================================== #
1231
+ question.gsub!(/\<.+?\>/,'')
1232
+ # @question = ::Studium.word_wrap(question, WORD_WRAP_AT_N_CHARACTERS).to_s
1233
+ @question = question.to_s.dup
1234
+ if @question.start_with?('- ')
1235
+ @question[0,2] = ''
1236
+ end
1237
+ # =================================================================== #
1238
+ # Replace all URL entries with <a href> entries next:
1239
+ # =================================================================== #
1240
+ @question = ::Gtk.replace_all_URL_entries_in_this_string(@question)
1241
+ @text_buffer_for_the_question.set_text(@question)
1242
+ @text_view_for_the_answer.set_text('') # ← This is needed to clear old entries.
1243
+ if @checkbox_shall_we_reveal_the_answer.active?
1244
+ do_reveal_the_answer_after_timeout(answer_is?)
1245
+ end
1246
+ # =================================================================== #
1247
+ # Reveal the exam-file onto the gtk-based editor as well.
1248
+ # Unfortunately this has a bug, in February 2021 - x11
1249
+ # crashes. I may have to re-evaluate this at a later time
1250
+ # to determine WHY it crashes...
1251
+ # =================================================================== #
1252
+ # dataset = File.read(
1253
+ # ::Studium.directory_containing_the_exam_topics?+
1254
+ # ::Studium.find_corresponding_exam_topic(
1255
+ # current_exam_topic?
1256
+ # )
1257
+ # )
1258
+ # @gtk_editor.update_the_main_buffer(dataset)
1259
+ else # else we can notify the user that this exam-topic is not registered.
1260
+ popover = return_popover(
1261
+ ' <b>⚠️</b> The exam topic `<b>'+
1262
+ entry_ask_questions_from_this_topic?.text.to_s+
1263
+ '</b>` could <b>not</b> be found. <b>⚠️</b>',
1264
+ question_button?
1265
+ )
1266
+ popover.show_all
1267
+ popover.popup # Display it at once.
1268
+ end
1269
+ end
1270
+ end; alias do_ask_a_new_question the_button_ask_the_question_was_clicked # === do_ask_a_new_question
1271
+ alias do_ask_an_exam_question the_button_ask_the_question_was_clicked # === do_ask_an_exam_question
1272
+ alias do_ask_the_exam_question the_button_ask_the_question_was_clicked # === do_ask_the_exam_question
1273
+ alias ask_an_exam_question the_button_ask_the_question_was_clicked # === ask_an_exam_question
1274
+ alias do_all_the_internal_actions_associated_with_the_button_ask_the_question_having_been_clicked the_button_ask_the_question_was_clicked # === do_all_the_internal_actions_associated_with_the_button_ask_the_question_having_been_clicked
1275
+
1276
+ # ========================================================================= #
1277
+ # === handle_the_combo_box_available_exam_topics_on_changed_event
1278
+ # ========================================================================= #
1279
+ def handle_the_combo_box_available_exam_topics_on_changed_event(
1280
+ combo_box = @combo_box_available_exam_topics
1281
+ )
1282
+ # ======================================================================= #
1283
+ # The event where the combo-box is changed is handled next.
1284
+ # ======================================================================= #
1285
+ combo_box.on_changed {
1286
+ entry_ask_questions_from_this_topic?.set_text(
1287
+ combo_box.active_text.to_s.downcase.tr(' ','_')
1288
+ )
1289
+ # ===================================================================== #
1290
+ # Get a reference to the current exam topic.
1291
+ # ===================================================================== #
1292
+ current_exam_topic = combo_box.active_text.to_s.strip.dup
1293
+ current_exam_topic.strip! if current_exam_topic.end_with? '_'
1294
+ do_update_this_gtk_entry_with_that_exam_topic_for_its_percentage_value(
1295
+ @entry_percentage, current_exam_topic
1296
+ )
1297
+ @entry_containing_n_questions.set_text(
1298
+ return_n_questions_from_the_currently_selected_topic(current_exam_topic).to_s
1299
+ )
1300
+ do_update_the_entry_n_answered(current_exam_topic)
1301
+ do_ask_a_new_question
1302
+ }
1303
+ end
1304
+
1305
+ # ========================================================================= #
1306
+ # === create_the_combobox
1307
+ # ========================================================================= #
1308
+ def create_the_combobox
1309
+ # ======================================================================= #
1310
+ # Next, create the combo-box that contains all exam-topics. It will be
1311
+ # a bit truncated, largely for display-reasons rather than any other
1312
+ # reason.
1313
+ # ======================================================================= #
1314
+ @combo_box_available_exam_topics = return_combo_box_available_exam_topics
1315
+ end
1316
+
1317
+ # ========================================================================= #
1318
+ # === return_combo_box_available_exam_topics
1319
+ # ========================================================================= #
1320
+ def return_combo_box_available_exam_topics
1321
+ use_this_sorted_array = return_available_exam_topics.map {|entry|
1322
+ if entry.size > 24 # Truncate it a bit in this case.
1323
+ entry = entry[0 .. 24]
1324
+ end
1325
+ entry
1326
+ }.sort
1327
+
1328
+ _ = combo_box(
1329
+ use_this_sorted_array
1330
+ )
1331
+ _.first_entry_is_active
1332
+ _.bblack1
1333
+ _.set_size_request(100, 28)
1334
+ # ======================================================================= #
1335
+ # Wrap-width determines how many entries per row are shown when the
1336
+ # combo-box is expanded. We stick to the default of 1 here.
1337
+ # ======================================================================= #
1338
+ _.set_wrap_width(1)
1339
+ handle_the_combo_box_available_exam_topics_on_changed_event(_)
1340
+ return _
1341
+ end
1342
+
1343
+ # ========================================================================= #
1344
+ # === return_wikipedia_entry
1345
+ #
1346
+ # This method will return the widget that, upon user-mouse-button-click
1347
+ # event, will open the corresponding wikipedia entry. This defaults
1348
+ # to the german wikipedia entry right now; if others want to change
1349
+ # the default then this could be changed easily.
1350
+ # ========================================================================= #
1351
+ def return_wikipedia_entry
1352
+ begin
1353
+ require 'roebe/classes/wikipedia.rb'
1354
+ rescue LoadError; end
1355
+
1356
+ hbox = gtk_hbox
1357
+ wikipedia_entry = gtk_entry
1358
+ wikipedia_entry.clear_background
1359
+ wikipedia_entry.bblack2
1360
+ wikipedia_entry.center
1361
+ wikipedia_entry.css_class('pad5px')
1362
+ wikipedia_entry.lightgreen_background
1363
+ wikipedia_entry.width_height(720, 32)
1364
+ wikipedia_entry.hint =
1365
+ 'Click the "enter" key to open the assorted keyword in the '\
1366
+ 'german-wikipedia. Simply replace <b>de</b> with <b>en</b> in '\
1367
+ 'the URL to have the english wikipedia.'
1368
+ wikipedia_entry.on_enter {
1369
+ if Object.const_defined?(:Roebe) and
1370
+ Roebe.const_defined?(:Wikipedia)
1371
+ Roebe::Wikipedia.new(wikipedia_entry.text?)
1372
+ else
1373
+ e 'You need to install the roebe gem for this functionality.'
1374
+ end
1375
+ }
1376
+ hbox.minimal(wikipedia_entry, 1)
1377
+ return hbox
1378
+ end
1379
+
1380
+ # ========================================================================= #
1381
+ # === create_skeleton (create tag)
1382
+ # ========================================================================= #
1383
+ def create_skeleton
1384
+ create_text_buffer_for_the_answer
1385
+ create_text_view_for_the_answer
1386
+ create_the_buttons
1387
+ create_the_labels
1388
+ create_the_entries
1389
+ create_the_checkbox # This must come after the entries.
1390
+ create_the_combobox
1391
+ create_the_main_grid
1392
+ create_the_context_menu
1393
+ end
1394
+
1395
+ # ========================================================================= #
1396
+ # === context_menu?
1397
+ # ========================================================================= #
1398
+ def context_menu?
1399
+ @context_menu
1400
+ end
1401
+
1402
+ # ========================================================================= #
1403
+ # === create_the_context_menu
1404
+ #
1405
+ # This is the context-menu which will appear on a right-mouse
1406
+ # click event.
1407
+ # ========================================================================= #
1408
+ def create_the_context_menu
1409
+ # ======================================================================= #
1410
+ # === @context_menu
1411
+ # ======================================================================= #
1412
+ @context_menu = create_context_menu(self) {{
1413
+ numbered_actions: {
1414
+ 'Ask an exam question': :ask_an_exam_question,
1415
+ 'Reveal the answer to the exam question': :reveal_the_answer_to_the_exam_question,
1416
+ 'Mark the exam question as solved': :mark_the_exam_question_as_solved,
1417
+ 'Pick a new font (show the widget)': :popup_pick_a_new_font,
1418
+ 'Debug': :debug
1419
+ #'Change the font in use': :do_interactively_change_the_font,
1420
+ }
1421
+ }}
1422
+ @context_menu.make_bold
1423
+ @context_menu.set_font(:hack_18)
1424
+ end
1425
+
1426
+ # ========================================================================= #
1427
+ # === enable_all_key_combinations
1428
+ # ========================================================================= #
1429
+ def enable_all_key_combinations
1430
+ # ======================================================================= #
1431
+ # === @accel_group
1432
+ # ======================================================================= #
1433
+ @accel_group = create_and_add_gtk_accel_group
1434
+ enable_alt_w_key_combination
1435
+ enable_alt_y_key_combination
1436
+ enable_alt_1_key_combination
1437
+ end
1438
+
1439
+ # ========================================================================= #
1440
+ # === create_the_entries (entries tag, entry tag)
1441
+ # ========================================================================= #
1442
+ def create_the_entries
1443
+ # ======================================================================= #
1444
+ # === The entry keeping track as to how many answers have been
1445
+ # given for that particular exam-topic.
1446
+ # ======================================================================= #
1447
+ @entry_containing_n_answers = gtk_entry('')
1448
+ @entry_containing_n_answers.center
1449
+ @entry_containing_n_answers.set_font(:hack_15)
1450
+ @entry_containing_n_answers.bblack1
1451
+ # ======================================================================= #
1452
+ # === @entry_containing_n_questions
1453
+ #
1454
+ # Next, the entry containing the questions
1455
+ # ======================================================================= #
1456
+ @entry_containing_n_questions = entry('')
1457
+ @entry_containing_n_questions.center
1458
+ @entry_containing_n_questions.set_font(:hack_15)
1459
+ @entry_containing_n_questions.bblack1
1460
+ # ======================================================================= #
1461
+ # === @entry_containing_n_unanswered_questions
1462
+ # ======================================================================= #
1463
+ @entry_containing_n_unanswered_questions = entry('')
1464
+ @entry_containing_n_unanswered_questions.center
1465
+ @entry_containing_n_unanswered_questions.set_font(:hack_15)
1466
+ @entry_containing_n_unanswered_questions.bblack1
1467
+ # ======================================================================= #
1468
+ # === The entry holding all exam topics.
1469
+ #
1470
+ # This is the entry that the user can modify at his or her own
1471
+ # discretion. It is the most important entry, among the entries
1472
+ # used in this GUI application.
1473
+ #
1474
+ # This entry is positioned very close on top, on the left hand side.
1475
+ # The user can thus simply manipulate it by clicking on it.
1476
+ #
1477
+ # Another entry may depend on this entry, so it should come early
1478
+ # in this method.
1479
+ # ======================================================================= #
1480
+ @entry_holding_all_exam_topics = gtk_entry(
1481
+ USE_THIS_AS_THE_DEFAULT_EXAM_TOPIC
1482
+ )
1483
+ # The next line of code was disabled as of September 2021.
1484
+ # @entry_holding_all_exam_topics.on_click_select_everything
1485
+ @entry_holding_all_exam_topics.set_font(SMALLER_FONT)
1486
+ @entry_holding_all_exam_topics.bblack1
1487
+ @entry_holding_all_exam_topics.very_light_yellowish_background
1488
+ enhanced_gtk_entry = gtk_entry_completion
1489
+ enhanced_gtk_entry.populate_with_this_array(
1490
+ ::Studium.return_all_exam_topics
1491
+ )
1492
+ @entry_holding_all_exam_topics.completion = enhanced_gtk_entry
1493
+ # ======================================================================= #
1494
+ # We need this entry to be fairly wide, hence the following method call.
1495
+ # ======================================================================= #
1496
+ @entry_holding_all_exam_topics.set_size_request(500, 40)
1497
+ @entry_holding_all_exam_topics.set_hexpand(false)
1498
+ @entry_holding_all_exam_topics.set_vexpand(false)
1499
+ # ======================================================================= #
1500
+ # Allow for scroll-events.
1501
+ # ======================================================================= #
1502
+ @entry_holding_all_exam_topics.enable_scroll_events
1503
+ @entry_holding_all_exam_topics.on_scroll_event {|widget, event|
1504
+ # ===================================================================== #
1505
+ # For now this simply sets a new, random topic.
1506
+ # ===================================================================== #
1507
+ if scroll_up?(event)
1508
+ set_exam_topic(
1509
+ available_exam_topics?.sample.downcase
1510
+ )
1511
+ sync_entry_holding_all_exam_topics_onto_the_combo_box # Sync towards the combo-box.
1512
+ elsif scroll_down?(event)
1513
+ set_exam_topic(
1514
+ available_exam_topics?.sample.downcase
1515
+ )
1516
+ sync_entry_holding_all_exam_topics_onto_the_combo_box # Sync towards the combo-box.
1517
+ end
1518
+ }
1519
+ # ======================================================================= #
1520
+ # Respond to the enter-key pressed next.
1521
+ # ======================================================================= #
1522
+ @entry_holding_all_exam_topics.on_enter_key_pressed { |widget, event|
1523
+ old_text = @entry_holding_all_exam_topics.text?
1524
+ new_possible_text = Studium.expand_this_exam_topic(old_text)
1525
+ unless old_text == new_possible_text
1526
+ @entry_holding_all_exam_topics.set_text(new_possible_text)
1527
+ end
1528
+ do_update_the_entry_n_questions
1529
+ question_button?.signal_emit(:clicked)
1530
+ sync_entry_holding_all_exam_topics_onto_the_main_combo_box
1531
+ }
1532
+ # ======================================================================= #
1533
+ # === @entry_delay_to_use
1534
+ #
1535
+ # Next create the delay-entry that keeps track how many seconds to wait,
1536
+ # before revealing the answer (IF the user has decided to make use of
1537
+ # that functionality).
1538
+ # ======================================================================= #
1539
+ @entry_delay_to_use = gtk_entry(DEFAULT_DELAY)
1540
+ @entry_delay_to_use.center
1541
+ @entry_delay_to_use.hint = 'Provide the delay here, as <b>n seconds</b>. '\
1542
+ 'This will only work when the checkbox on the left-hand side is active.'
1543
+ @entry_delay_to_use.set_size_request(45, 20)
1544
+ @entry_delay_to_use.bblack1
1545
+ # ======================================================================= #
1546
+ # === Percentage entry
1547
+ #
1548
+ # This is the percentage-entry, situated right next to a combo-box
1549
+ # entry.
1550
+ # ======================================================================= #
1551
+ @entry_percentage = return_entry_percentage
1552
+ end
1553
+
1554
+ # ========================================================================= #
1555
+ # === return_hbox_containing_three_labels_and_three_entries
1556
+ #
1557
+ # This should only be invoked after the entries were created.
1558
+ # ========================================================================= #
1559
+ def return_hbox_containing_three_labels_and_three_entries
1560
+ _ = gtk_hbox
1561
+
1562
+ # ======================================================================= #
1563
+ # === n questions
1564
+ # ======================================================================= #
1565
+ vbox1 = gtk_vbox
1566
+ label_n_questions = text('n questions').set_font(:hack_15)
1567
+ label_n_questions.center_and_make_bold
1568
+ vbox1.minimal(label_n_questions, 2)
1569
+ vbox1.minimal(@entry_containing_n_questions, 2)
1570
+ _.minimal(vbox1, 2)
1571
+
1572
+ # ======================================================================= #
1573
+ # === n unanswered
1574
+ # ======================================================================= #
1575
+ vbox2 = gtk_vbox
1576
+ label_n_unanswered = text('n unanswered').set_font(:hack_15)
1577
+ label_n_unanswered.make_bold
1578
+ vbox2.minimal(label_n_unanswered, 2)
1579
+ vbox2.minimal(@entry_containing_n_unanswered_questions, 2)
1580
+ _.minimal(vbox2, 2)
1581
+
1582
+ # ======================================================================= #
1583
+ # === n answered
1584
+ # ======================================================================= #
1585
+ vbox3 = gtk_vbox
1586
+ label_n_answered = text('n answered').set_font(:hack_15)
1587
+ label_n_answered.royalblue
1588
+ label_n_answered.center_and_make_bold
1589
+ vbox3.minimal(label_n_answered, 2)
1590
+ vbox3.minimal(@entry_containing_n_answers, 2)
1591
+ _.minimal(vbox3, 2)
1592
+
1593
+ # ======================================================================= #
1594
+ # Last but not least, add the entry showing the percentage values.
1595
+ # ======================================================================= #
1596
+ _.minimal(@entry_percentage, 2)
1597
+ return _
1598
+ end
1599
+
1600
+ # ========================================================================= #
1601
+ # === do_update_the_entry_n_questions
1602
+ # ========================================================================= #
1603
+ def do_update_the_entry_n_questions(
1604
+ current_exam_topic = current_exam_topic?
1605
+ )
1606
+ @entry_containing_n_questions.set_text(
1607
+ return_n_questions_from_the_currently_selected_topic(current_exam_topic).to_s
1608
+ )
1609
+ end; alias update_n_questions do_update_the_entry_n_questions # === update_n_questions
1610
+
1611
+ # ========================================================================= #
1612
+ # === create_the_button_use_random_entry_from_the_ten_aliases
1613
+ # ========================================================================= #
1614
+ def create_the_button_use_random_entry_from_the_ten_aliases
1615
+ # ======================================================================= #
1616
+ # === @button_use_random_entry_from_the_ten_aliases
1617
+ #
1618
+ # This is an eventbox rather than a button, but I think this is still
1619
+ # fine. The unicode character "🕵" (U+1F575) is the spy character.
1620
+ # ======================================================================= #
1621
+ if use_emoji?
1622
+ label = gtk_label('🕵️')
1623
+ else
1624
+ label = image_avatar_default
1625
+ end
1626
+ # ======================================================================= #
1627
+ # === @button_use_random_entry_from_the_ten_aliases
1628
+ # ======================================================================= #
1629
+ @button_use_random_entry_from_the_ten_aliases = gtk_eventbox(label)
1630
+ @button_use_random_entry_from_the_ten_aliases.on_clicked {
1631
+ if @user_configuration[:show_ten_aliases]
1632
+ set_exam_topic(
1633
+ @user_configuration[:show_ten_aliases].return_random_entry
1634
+ )
1635
+ update_n_questions
1636
+ update_n_unanswered
1637
+ do_ask_an_exam_question
1638
+ end
1639
+ }
1640
+ @button_use_random_entry_from_the_ten_aliases.set_size_request(40, 40)
1641
+ @button_use_random_entry_from_the_ten_aliases.lightblue
1642
+ @button_use_random_entry_from_the_ten_aliases.hint =
1643
+ 'Click on this small widget to randomly assign one of '\
1644
+ 'the 10 exam-topics currently being studied as the '\
1645
+ 'new main exam-topic in use.'
1646
+ return @button_use_random_entry_from_the_ten_aliases
1647
+ end
1648
+
1649
+ # ========================================================================= #
1650
+ # === do_update_the_entry_n_unanswered_questions
1651
+ #
1652
+ # This method depends on two entries being set correctly.
1653
+ # ========================================================================= #
1654
+ def do_update_the_entry_n_unanswered_questions
1655
+ _ = @entry_containing_n_questions.text?.to_i -
1656
+ @entry_containing_n_answers.text?.to_i
1657
+ @entry_containing_n_unanswered_questions.set_text(_.to_s)
1658
+ end; alias update_the_entry_n_unanswered_questions do_update_the_entry_n_unanswered_questions # === update_the_entry_n_unanswered_questions
1659
+ alias update_n_unanswered do_update_the_entry_n_unanswered_questions # === update_n_unanswered
1660
+
1661
+ # ========================================================================= #
1662
+ # === do_update_the_entry_n_answered
1663
+ # ========================================================================= #
1664
+ def do_update_the_entry_n_answered(
1665
+ current_exam_topic = @combo_box_available_exam_topics.active_text.to_s.strip.dup,
1666
+ entry = @entry_containing_n_answers # The entry that is to be updated.
1667
+ )
1668
+ current_exam_topic.strip! if current_exam_topic.end_with? '_'
1669
+ entry.set_text(
1670
+ return_n_answers_from_the_currently_selected_topic(current_exam_topic).to_s
1671
+ )
1672
+ end; alias update_n_answered do_update_the_entry_n_answered # === update_n_answered
1673
+
1674
+ # ========================================================================= #
1675
+ # === do_updated_the_entries_n_answered_and_n_unanswered
1676
+ # ========================================================================= #
1677
+ def do_updated_the_entries_n_answered_and_n_unanswered
1678
+ do_update_the_entry_n_unanswered_questions
1679
+ update_n_unanswered
1680
+ end
1681
+
1682
+ # ========================================================================= #
1683
+ # === do_open_the_current_exam_topic_file
1684
+ #
1685
+ # This method can either open the exam-file in the bluefish editor,
1686
+ # or in the integrated ruby-gtk editor. Since as of July 2021 we
1687
+ # will try the integrated variant. Unfortunately ruby-gtk is somehow
1688
+ # buggy - reading a large file leads to a BadAlloc error.
1689
+ # ========================================================================= #
1690
+ def do_open_the_current_exam_topic_file(
1691
+ combo_box_available_exam_topics = @combo_box_available_exam_topics
1692
+ )
1693
+ _ = Studium.find_corresponding_exam_topic(
1694
+ current_exam_topic?
1695
+ )
1696
+ if _.empty? and combo_box_available_exam_topics
1697
+ _ = combo_box_available_exam_topics.active_text.to_s
1698
+ end
1699
+ _ = Studium.path_to_exam_topic?+_
1700
+ if use_the_internal_editor?
1701
+ set_save_into_this_local_file(_)
1702
+ set_editor_buffer(File.read(_))
1703
+ @notebook_tab.focus_on_this_tab(2)
1704
+ else
1705
+ # ===================================================================== #
1706
+ # Or simply use bluefish or whatever else the editor is.
1707
+ # ===================================================================== #
1708
+ esystem "#{@user_configuration[:use_this_editor]} #{_}"
1709
+ end
1710
+ end
1711
+
1712
+ # ========================================================================= #
1713
+ # === answer_is?
1714
+ # ========================================================================= #
1715
+ def answer_is?
1716
+ @answer_is
1717
+ end
1718
+
1719
+ # ========================================================================= #
1720
+ # === array_all_exam_questions?
1721
+ #
1722
+ # Query-method to keep track of all exam-questions that were asked in
1723
+ # the current run.
1724
+ # ========================================================================= #
1725
+ def array_all_exam_questions?
1726
+ @user_configuration[:array_all_exam_questions]
1727
+ end
1728
+
1729
+ # ========================================================================= #
1730
+ # === debug
1731
+ # ========================================================================= #
1732
+ def debug
1733
+ pp array_all_exam_questions?
1734
+ pp array_all_exam_questions?.size
1735
+ end
1736
+
1737
+ # ========================================================================= #
1738
+ # === do_popup_the_array_of_all_exam_questions
1739
+ # ========================================================================= #
1740
+ def do_popup_the_array_of_all_exam_questions
1741
+ content = array_all_exam_questions?.map.with_index {|line, index| index += 1
1742
+ line = line.dup
1743
+ line.prepend(
1744
+ "(#{index}) "
1745
+ )
1746
+ line
1747
+ }.join("\n")
1748
+ text_buffer = gtk_text_buffer(content)
1749
+ text_view = gtk_text_view(text_buffer)
1750
+ scrolled_window = gtk_scrolled_window(text_view)
1751
+ scrolled_window.width_height(1400, 700)
1752
+ scrolled_window.pad8px
1753
+ popup_over_this_widget(
1754
+ entry_exam_topic?,
1755
+ scrolled_window
1756
+ ).popup
1757
+ end
1758
+
1759
+ # ========================================================================= #
1760
+ # === return_event_box_with_face_glasses
1761
+ # ========================================================================= #
1762
+ def return_event_box_with_face_glasses
1763
+ event_box = gtk_event_box
1764
+ image = gtk_icon('face-glasses')
1765
+ event_box.add(image)
1766
+ event_box.on_clicked {
1767
+ do_popup_the_array_of_all_exam_questions
1768
+ }
1769
+ return event_box
1770
+ end
1771
+
1772
+ # ========================================================================= #
1773
+ # === entry_holding_all_exam_topics?
1774
+ # ========================================================================= #
1775
+ def entry_holding_all_exam_topics?
1776
+ @entry_holding_all_exam_topics
1777
+ end; alias entry_ask_questions_from_this_topic? entry_holding_all_exam_topics? # === entry_ask_questions_from_this_topic?
1778
+ alias entry_ask_questions? entry_holding_all_exam_topics? # === entry_ask_questions?
1779
+ alias entry_exam_topic? entry_holding_all_exam_topics? # === exam_topic?
1780
+
1781
+ # ========================================================================= #
1782
+ # === sync_entry_holding_all_exam_topics_onto_the_combo_box
1783
+ #
1784
+ # An alternative to the functionality in this method may be this:
1785
+ #
1786
+ # Studium.find_corresponding_exam_topic "Festkörper Chemie und Geochemie" # => "geochemistry"
1787
+ #
1788
+ # ========================================================================= #
1789
+ def sync_entry_holding_all_exam_topics_onto_the_combo_box(
1790
+ value = @entry_holding_all_exam_topics.text?.
1791
+ downcase.delete(' ').delete('_')
1792
+ )
1793
+ array = available_exam_topics?.map {|entry|
1794
+ entry.delete(' ').downcase
1795
+ }
1796
+ index = array.find_index {|entry| entry.delete('_').include?(value) }
1797
+ if index
1798
+ @combo_box_available_exam_topics.set_active(index)
1799
+ else
1800
+ e 'The index was not found. Input was '+steelblue(value)+'.'
1801
+ end
1802
+ end; alias sync_entry_holding_all_exam_topics_onto_the_main_combo_box sync_entry_holding_all_exam_topics_onto_the_combo_box # === sync_entry_holding_all_exam_topics_onto_the_main_combo_box
1803
+
1804
+ # ========================================================================= #
1805
+ # === return_event_box_for_asking_a_random_exam_topic
1806
+ # ========================================================================= #
1807
+ def return_event_box_for_asking_a_random_exam_topic
1808
+ event_box_for_image_view_refresh_symbolic_symbolic = gtk_event_box(
1809
+ image_view_refresh_symbolic_symbolic
1810
+ )
1811
+ event_box_for_image_view_refresh_symbolic_symbolic.hint =
1812
+ "Click on this icon to <b>set a random exam topic</b>, "\
1813
+ "and then ask an exam question from this topic.\n\n"\
1814
+ "Note that since as of <b>August 2022</b> this will ignore "\
1815
+ "exam topics that were already solved."
1816
+ # ======================================================================= #
1817
+ # Let the event-box respond to an on-click event.
1818
+ # ======================================================================= #
1819
+ event_box_for_image_view_refresh_symbolic_symbolic.on_clicked {
1820
+ do_assign_a_new_exam_topic
1821
+ }
1822
+ return event_box_for_image_view_refresh_symbolic_symbolic
1823
+ end
1824
+
1825
+ # ========================================================================= #
1826
+ # === do_assign_a_new_exam_topic
1827
+ # ========================================================================= #
1828
+ def do_assign_a_new_exam_topic
1829
+ clear_reveal_the_answer
1830
+ this_topic = select_not_yet_completed_exam_topics(
1831
+ available_exam_topics?
1832
+ ).sample # Obtain a random exam topic here.
1833
+ @entry_holding_all_exam_topics.set_text(this_topic.to_s)
1834
+ sync_entry_holding_all_exam_topics_onto_the_combo_box
1835
+ do_ask_an_exam_question
1836
+ update_three_important_widgets
1837
+ end
1838
+
1839
+ # ========================================================================= #
1840
+ # === available_exam_topics?
1841
+ # ========================================================================= #
1842
+ def available_exam_topics?
1843
+ @user_configuration[:available_exam_topics]
1844
+ end
1845
+
1846
+ # ========================================================================= #
1847
+ # === select_not_yet_completed_exam_topics
1848
+ # ========================================================================= #
1849
+ def select_not_yet_completed_exam_topics(i)
1850
+ if i and i.is_a?(Array)
1851
+ return ::Studium.reject_already_completed_exam_topics(i, @hash_dataset_of_all_lectures)
1852
+ end
1853
+ return i # else return the original input unmodified.
1854
+ end
1855
+
1856
+ # ========================================================================= #
1857
+ # === create_the_labels
1858
+ # ========================================================================= #
1859
+ def create_the_labels
1860
+ # ======================================================================= #
1861
+ # === @label_n_questions_were_answered
1862
+ # ======================================================================= #
1863
+ @label_n_questions_were_answered = selectable_label
1864
+ update_the_label_n_questions_were_answered(@label_n_questions_were_answered)
1865
+ end
1866
+
1867
+ # ========================================================================= #
1868
+ # === return_string_how_many_exam_questions_are_already_answered
1869
+ # ========================================================================= #
1870
+ def return_string_how_many_exam_questions_are_already_answered
1871
+ ::Studium.return_string_how_many_exam_questions_are_already_answered
1872
+ end
1873
+
1874
+ # ========================================================================= #
1875
+ # === run (run tag)
1876
+ # ========================================================================= #
1877
+ def run
1878
+ super()
1879
+ do_style_all_buttons_uniformly
1880
+ deselect_the_entry_containing_the_exam_topic
1881
+ do_handle_the_click_event_for_the_ask_question_button
1882
+ end
1883
+
1884
+ end; end; end; end
1885
+
1886
+ if __FILE__ == $PROGRAM_NAME
1887
+ Studium::GUI::Gtk::ExamQuestionWidget.run
1888
+ end