studium 0.13.1

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