mirror of
https://github.com/pepaskopec-blip/Graduately.git
synced 2026-10-27 15:14:35 +00:00
1547 lines
59 KiB
C
1547 lines
59 KiB
C
#include "maturita.h"
|
||
|
||
/* ------------------------------------------------------------------ */
|
||
/* Unit 3 exercises ("Bei uns zu Hause") */
|
||
/* ------------------------------------------------------------------ */
|
||
|
||
/* Sentence fill-ins: a row is made of literal text segments that
|
||
* alternate with one or more blank widgets (dropdowns). `num` is the
|
||
* optional item number shown at the start of the line. */
|
||
|
||
/* Build the complete German sentence of a fill row (segments spliced
|
||
* with the correct answers) – used as the model shown after Check. */
|
||
char *u3_fill_sentence(const U3Fill *f) {
|
||
const char *segs[4];
|
||
const char *ans[3];
|
||
GString *s;
|
||
int i, g;
|
||
|
||
segs[0] = f->s0;
|
||
segs[1] = f->s1;
|
||
segs[2] = f->s2;
|
||
segs[3] = f->s3;
|
||
ans[0] = f->a0;
|
||
ans[1] = f->a1;
|
||
ans[2] = f->a2;
|
||
g = 0;
|
||
while (g < 3 && ans[g])
|
||
g++;
|
||
|
||
s = g_string_new(NULL);
|
||
for (i = 0; i <= g; i++) {
|
||
if (segs[i] && segs[i][0])
|
||
g_string_append(s, segs[i]);
|
||
if (i < g && ans[i])
|
||
g_string_append(s, ans[i]);
|
||
}
|
||
if (s->len == 0) {
|
||
g_string_free(s, TRUE);
|
||
return NULL;
|
||
}
|
||
return g_string_free(s, FALSE);
|
||
}
|
||
|
||
/* Append one horizontal fill row to `body`. The answer of blank i sits
|
||
* between text segments s[i] and s[i+1]; empty segments are skipped.
|
||
* `gloss` (may be NULL) is an i18n key for a small grey note shown at
|
||
* the end of the line, e.g. the meaning of the expected possessive. */
|
||
void u3_fill_row(ComboListCtx *ctx, GtkWidget *body, const U3Fill *f,
|
||
const char **pool, int pool_n, const char *gloss) {
|
||
const char *segs[4];
|
||
const char *ans[3];
|
||
int i, g;
|
||
GtkWidget *line;
|
||
|
||
segs[0] = f->s0;
|
||
segs[1] = f->s1;
|
||
segs[2] = f->s2;
|
||
segs[3] = f->s3;
|
||
ans[0] = f->a0;
|
||
ans[1] = f->a1;
|
||
ans[2] = f->a2;
|
||
g = 0;
|
||
while (g < 3 && ans[g])
|
||
g++;
|
||
|
||
line = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
||
gtk_widget_set_halign(line, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), line);
|
||
|
||
if (f->num && f->num[0]) {
|
||
GtkWidget *nl = gtk_label_new(f->num);
|
||
gtk_widget_set_valign(nl, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(nl, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), nl);
|
||
}
|
||
for (i = 0; i <= g; i++) {
|
||
if (segs[i] && segs[i][0]) {
|
||
GtkWidget *lb = gtk_label_new(segs[i]);
|
||
gtk_widget_set_valign(lb, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(lb, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), lb);
|
||
}
|
||
if (i < g) {
|
||
GtkWidget *combo = make_word_combo(pool, pool_n);
|
||
gtk_widget_set_size_request(combo, 96, -1);
|
||
gtk_widget_set_valign(combo, GTK_ALIGN_CENTER);
|
||
gtk_box_append(GTK_BOX(line), combo);
|
||
combo_list_add(ctx, combo, ans[i]);
|
||
}
|
||
}
|
||
|
||
if (gloss && gloss[0]) {
|
||
GtkWidget *gl = gtk_label_new(NULL);
|
||
i18n_bind(gl, gloss, 0);
|
||
gtk_widget_set_valign(gl, GTK_ALIGN_CENTER);
|
||
gtk_widget_set_margin_start(gl, 8);
|
||
gtk_widget_add_css_class(gl, "meaning");
|
||
gtk_box_append(GTK_BOX(line), gl);
|
||
}
|
||
|
||
if (f->mean && f->mean[0]) {
|
||
GtkWidget *m = meaning_add(body, f->mean);
|
||
combo_list_add_trans(ctx, m);
|
||
if (ctx->trans_upfront)
|
||
gtk_widget_set_visible(m, TRUE);
|
||
}
|
||
|
||
if (ctx->reveal_german) {
|
||
char *sentence = u3_fill_sentence(f);
|
||
|
||
if (sentence && sentence[0]) {
|
||
GtkWidget *w = model_answer_add(body, sentence);
|
||
|
||
g_array_append_val(ctx->models, w);
|
||
}
|
||
g_free(sentence);
|
||
}
|
||
}
|
||
|
||
void u3_sample_line(GtkWidget *body, const char *text) {
|
||
GtkWidget *sl = gtk_label_new(text);
|
||
|
||
gtk_widget_set_halign(sl, GTK_ALIGN_START);
|
||
gtk_widget_set_margin_top(sl, 2);
|
||
gtk_widget_set_margin_bottom(sl, 4);
|
||
gtk_widget_add_css_class(sl, "hint");
|
||
gtk_label_set_wrap(GTK_LABEL(sl), TRUE);
|
||
gtk_box_append(GTK_BOX(body), sl);
|
||
}
|
||
|
||
GtkWidget *u3_build_drop(UnitCtx *unit, int ex_num, const char *title,
|
||
const char *sub, const char *sample,
|
||
const U3Fill *rows, int n,
|
||
const char **pool, int pool_n,
|
||
const char **glosses, gboolean show_german) {
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, title, sub, "check",
|
||
&body, &feedback, &check);
|
||
ComboListCtx *ctx = combo_list_ctx_new(unit, ex_num, feedback);
|
||
|
||
ctx->trans_upfront = show_german;
|
||
ctx->reveal_german = show_german;
|
||
|
||
if (sample && sample[0])
|
||
u3_sample_line(body, sample);
|
||
|
||
for (int i = 0; i < n; i++)
|
||
u3_fill_row(ctx, body, &rows[i], pool, pool_n,
|
||
glosses ? glosses[i] : NULL);
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(combo_list_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex1: Familienpaare (match the pair) ---------------------------- */
|
||
|
||
const char *ex1_u3_pool[] = {
|
||
"die Cousine", "die Tante", "die Oma", "der Bruder",
|
||
"die Freundin", "der Sohn",
|
||
};
|
||
|
||
const U3Fill ex1_u3_rows[] = {
|
||
{"1.", "der Cousin", "die Cousine", NULL, NULL, NULL, NULL, NULL,
|
||
"bratranec / sestřenice"},
|
||
{"2.", "der Onkel", "die Tante", NULL, NULL, NULL, NULL, NULL,
|
||
"strýc / teta"},
|
||
{"3.", "der Opa", "die Oma", NULL, NULL, NULL, NULL, NULL,
|
||
"dědeček / babička"},
|
||
{"4.", "die Schwester", "der Bruder", NULL, NULL, NULL, NULL, NULL,
|
||
"sestra / bratr"},
|
||
{"5.", "der Freund", "die Freundin", NULL, NULL, NULL, NULL, NULL,
|
||
"kamarád / kamarádka"},
|
||
{"6.", "die Tochter", "der Sohn", NULL, NULL, NULL, NULL, NULL,
|
||
"dcera / syn"},
|
||
};
|
||
|
||
GtkWidget *u3ex1(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 1, "Familienpaare", "sub3_pair",
|
||
"Beispiel: der Vater ↔ die Mutter",
|
||
ex1_u3_rows, G_N_ELEMENTS(ex1_u3_rows),
|
||
ex1_u3_pool, G_N_ELEMENTS(ex1_u3_pool), NULL, FALSE);
|
||
}
|
||
|
||
/* ---- ex2: Possessivpronomen im Nominativ ----------------------------- */
|
||
|
||
const char *ex2_u3_pool[] = {
|
||
"dein", "deine", "mein", "meine", "sein", "seine",
|
||
};
|
||
|
||
/* The Czech sentence is shown straight away, and pressing "Check" only
|
||
* adds the translations of the words the student picked in the blanks. */
|
||
|
||
|
||
const Ex2Row ex2_u3_rows2[] = {
|
||
{"2.", {"Ist das ", " Mutter? – Nein, das ist nicht ", " Mutter.", NULL},
|
||
{"deine", "meine", NULL}, 2},
|
||
{NULL, {"Das ist ", " Tante.", NULL, NULL}, {"seine", NULL, NULL}, 1},
|
||
};
|
||
|
||
const Ex2Row ex2_u3_rows3[] = {
|
||
{"3.", {"Ist das ", " Bruder? – Nein, das ist nicht ", " Bruder.", NULL},
|
||
{"dein", "mein", NULL}, 2},
|
||
{NULL, {"Das ist ", " Cousin.", NULL, NULL}, {"sein", NULL, NULL}, 1},
|
||
};
|
||
|
||
const Ex2Row ex2_u3_rows4[] = {
|
||
{"4.",
|
||
{"Sind das ", " Eltern? – Nein, das sind nicht ",
|
||
" Eltern. Das sind die Eltern von Markus.", NULL},
|
||
{"deine", "meine", NULL}, 2},
|
||
};
|
||
|
||
const Ex2Item ex2_u3_items[] = {
|
||
{"Je to tvoje matka? – Ne, to není moje matka. To je jeho teta.",
|
||
ex2_u3_rows2, G_N_ELEMENTS(ex2_u3_rows2)},
|
||
{"Je to tvůj bratr? – Ne, to není můj bratr. To je jeho bratranec.",
|
||
ex2_u3_rows3, G_N_ELEMENTS(ex2_u3_rows3)},
|
||
{"Jsou to tvoji rodiče? – Ne, to nejsou moji rodiče. To jsou rodiče "
|
||
"Markuse.",
|
||
ex2_u3_rows4, G_N_ELEMENTS(ex2_u3_rows4)},
|
||
};
|
||
|
||
|
||
const char *ex2_word_cs(const char *w) {
|
||
if (!w)
|
||
return NULL;
|
||
if (g_strcmp0(w, "dein") == 0) return "tvůj";
|
||
if (g_strcmp0(w, "deine") == 0) return "tvoje";
|
||
if (g_strcmp0(w, "mein") == 0) return "můj";
|
||
if (g_strcmp0(w, "meine") == 0) return "moje";
|
||
if (g_strcmp0(w, "sein") == 0) return "jeho";
|
||
if (g_strcmp0(w, "seine") == 0) return "jeho";
|
||
return NULL;
|
||
}
|
||
|
||
void ex2_check(GtkButton *button, gpointer data) {
|
||
Ex2Ctx *ctx = data;
|
||
guint total = ctx->combos->len;
|
||
guint ok = 0;
|
||
|
||
(void)button;
|
||
|
||
for (guint i = 0; i < total; i++) {
|
||
GtkComboBox *combo = g_array_index(ctx->combos, GtkComboBox *, i);
|
||
const char *ans = g_array_index(ctx->answers, const char *, i);
|
||
gchar *sel = gtk_combo_box_text_get_active_text(
|
||
GTK_COMBO_BOX_TEXT(combo));
|
||
gboolean good = FALSE;
|
||
if (sel) {
|
||
gchar *t = normalize_answer(sel);
|
||
good = answer_accepts(t, ans);
|
||
g_free(t);
|
||
g_free(sel);
|
||
}
|
||
answer_mark(GTK_WIDGET(combo), good);
|
||
if (good)
|
||
ok++;
|
||
}
|
||
|
||
for (int it = 0; it < ctx->n_items; it++) {
|
||
GArray *item = ctx->item_combos[it];
|
||
GtkWidget *note = ctx->notes[it];
|
||
GString *s = g_string_new(NULL);
|
||
for (guint k = 0; k < item->len; k++) {
|
||
GtkComboBox *combo = g_array_index(item, GtkComboBox *, k);
|
||
gchar *sel = gtk_combo_box_text_get_active_text(
|
||
GTK_COMBO_BOX_TEXT(combo));
|
||
const char *cs;
|
||
if (sel) {
|
||
cs = ex2_word_cs(sel);
|
||
if (cs) {
|
||
if (s->len > 0)
|
||
g_string_append(s, " · ");
|
||
g_string_append_printf(s, "%s = %s", sel, tr(cs));
|
||
}
|
||
g_free(sel);
|
||
}
|
||
}
|
||
gtk_label_set_text(GTK_LABEL(note), s->str);
|
||
g_string_free(s, TRUE);
|
||
gtk_widget_set_visible(note, TRUE);
|
||
}
|
||
|
||
if (ok == total) {
|
||
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
|
||
mark_done(ctx->unit, ctx->ex_num);
|
||
} else {
|
||
set_feedback(ctx->feedback, FALSE, tr("feedback_retry"));
|
||
}
|
||
}
|
||
|
||
GtkWidget *u3ex2(UnitCtx *unit) {
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, "mein oder dein", "sub3_poss",
|
||
"check", &body, &feedback, &check);
|
||
Ex2Ctx *ctx = g_new0(Ex2Ctx, 1);
|
||
|
||
ctx->combos = g_array_new(FALSE, FALSE, sizeof(GtkComboBox *));
|
||
ctx->answers = g_array_new(FALSE, FALSE, sizeof(const char *));
|
||
ctx->n_items = G_N_ELEMENTS(ex2_u3_items);
|
||
ctx->notes = g_new0(GtkWidget *, ctx->n_items);
|
||
ctx->item_combos = g_new0(GArray *, ctx->n_items);
|
||
ctx->unit = unit;
|
||
ctx->ex_num = 2;
|
||
ctx->feedback = feedback;
|
||
|
||
u3_sample_line(body, "Beispiel: Ist das dein Vater? – Nein, das ist "
|
||
"nicht mein Vater. Das ist sein Onkel.");
|
||
|
||
for (int it = 0; it < ctx->n_items; it++) {
|
||
const Ex2Item *item = &ex2_u3_items[it];
|
||
GtkWidget *mean;
|
||
GtkWidget *note;
|
||
GArray *item_combos = g_array_new(FALSE, FALSE,
|
||
sizeof(GtkComboBox *));
|
||
ctx->item_combos[it] = item_combos;
|
||
|
||
for (int r = 0; r < item->nrows; r++) {
|
||
const Ex2Row *row = &item->rows[r];
|
||
GtkWidget *line = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
||
|
||
gtk_widget_set_halign(line, GTK_ALIGN_START);
|
||
if (row->num && row->num[0]) {
|
||
GtkWidget *nl = gtk_label_new(row->num);
|
||
gtk_widget_set_valign(nl, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(nl, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), nl);
|
||
}
|
||
for (int i = 0; i <= row->gaps; i++) {
|
||
if (row->seg[i] && row->seg[i][0]) {
|
||
GtkWidget *lb = gtk_label_new(row->seg[i]);
|
||
gtk_widget_set_valign(lb, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(lb, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), lb);
|
||
}
|
||
if (i < row->gaps) {
|
||
GtkWidget *combo = make_word_combo(ex2_u3_pool,
|
||
G_N_ELEMENTS(ex2_u3_pool));
|
||
gtk_widget_set_size_request(combo, 96, -1);
|
||
gtk_widget_set_valign(combo, GTK_ALIGN_CENTER);
|
||
gtk_box_append(GTK_BOX(line), combo);
|
||
g_array_append_val(ctx->combos, combo);
|
||
g_array_append_val(item_combos, combo);
|
||
g_array_append_val(ctx->answers, row->ans[i]);
|
||
}
|
||
}
|
||
gtk_box_append(GTK_BOX(body), line);
|
||
}
|
||
|
||
/* Czech sentence is available before checking. */
|
||
mean = meaning_add(body, item->czech);
|
||
gtk_widget_set_visible(mean, TRUE);
|
||
|
||
/* word translations appear only after pressing "Check". */
|
||
note = gtk_label_new(NULL);
|
||
gtk_widget_set_halign(note, GTK_ALIGN_START);
|
||
gtk_widget_set_margin_bottom(note, 2);
|
||
gtk_widget_add_css_class(note, "meaning");
|
||
gtk_label_set_wrap(GTK_LABEL(note), TRUE);
|
||
gtk_widget_set_visible(note, FALSE);
|
||
gtk_box_append(GTK_BOX(body), note);
|
||
ctx->notes[it] = note;
|
||
}
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(ex2_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex3: Haustiere – ein/kein --------------------------------------- */
|
||
|
||
const char *ex3_u3_pool[] = {
|
||
"ein", "eine", "einen", "kein", "keine", "keinen",
|
||
};
|
||
|
||
const U3Fill ex3_u3_rows[] = {
|
||
{"2.", "Hast du ", "einen",
|
||
" Hamster? – Nein, ich habe ", "keinen", " Hamster.", NULL, NULL,
|
||
NULL},
|
||
{NULL, "Ich habe ", "eine", " Schildkröte.", NULL, NULL, NULL, NULL,
|
||
"Máš křečka? – Ne, nemám křečka. Mám želvu."},
|
||
{"3.", "Hast du ", "ein",
|
||
" Pferd? – Nein, ich habe ", "kein", " Pferd.", NULL, NULL, NULL},
|
||
{NULL, "Ich habe ", "ein", " Kaninchen.", NULL, NULL, NULL, NULL,
|
||
"Máš koně? – Ne, nemám koně. Mám králíka."},
|
||
{"4.", "Hast du ", "einen",
|
||
" Fisch? – Nein, ich habe ", "keinen", " Fisch.", NULL, NULL, NULL},
|
||
{NULL, "Ich habe ", "einen", " Vogel.", NULL, NULL, NULL, NULL,
|
||
"Máš rybu? – Ne, nemám rybu. Mám ptáka."},
|
||
{"5.", "Hast du ", "ein",
|
||
" Meerschweinchen? – Nein, ich habe ", "kein",
|
||
" Meerschweinchen.", NULL, NULL, NULL},
|
||
{NULL, "Ich habe ", "einen", " Wellensittich.", NULL, NULL, NULL, NULL,
|
||
"Máš morče? – Ne, nemám morče. Mám andulku."},
|
||
};
|
||
|
||
GtkWidget *u3ex3(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 3, "ein / kein", "sub3_haustier",
|
||
"Beispiel: Hast du eine Katze? – Nein, ich habe "
|
||
"keine Katze. Ich habe einen Hund.",
|
||
ex3_u3_rows, G_N_ELEMENTS(ex3_u3_rows),
|
||
ex3_u3_pool, G_N_ELEMENTS(ex3_u3_pool), NULL, TRUE);
|
||
}
|
||
|
||
/* ---- inline letter-gap rows (ex15) ----------------------------------- */
|
||
|
||
/* One sentence row whose text is split into segments with up to four
|
||
* small text entries (one per missing-letter group) inserted. */
|
||
|
||
|
||
U3LetCtx *u3_let_ctx_new(UnitCtx *unit, int ex_num,
|
||
GtkWidget *feedback) {
|
||
U3LetCtx *ctx = g_new0(U3LetCtx, 1);
|
||
ctx->entries = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
|
||
ctx->answers = g_array_new(FALSE, FALSE, sizeof(const char *));
|
||
ctx->trans = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
|
||
ctx->models = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
|
||
ctx->unit = unit;
|
||
ctx->ex_num = ex_num;
|
||
ctx->feedback = feedback;
|
||
return ctx;
|
||
}
|
||
|
||
/* Rebuild the full German sentence (letter gaps filled in). */
|
||
char *u3_let_sentence(const U3Let *row) {
|
||
const char *segs[5];
|
||
const char *ans[4];
|
||
GString *s;
|
||
int i, g;
|
||
|
||
segs[0] = row->s0;
|
||
segs[1] = row->s1;
|
||
segs[2] = row->s2;
|
||
segs[3] = row->s3;
|
||
segs[4] = row->s4;
|
||
ans[0] = row->a0;
|
||
ans[1] = row->a1;
|
||
ans[2] = row->a2;
|
||
ans[3] = row->a3;
|
||
g = 0;
|
||
while (g < 4 && ans[g])
|
||
g++;
|
||
|
||
s = g_string_new(NULL);
|
||
for (i = 0; i <= g; i++) {
|
||
if (segs[i] && segs[i][0])
|
||
g_string_append(s, segs[i]);
|
||
if (i < g && ans[i])
|
||
g_string_append(s, ans[i]);
|
||
}
|
||
if (s->len == 0) {
|
||
g_string_free(s, TRUE);
|
||
return NULL;
|
||
}
|
||
return g_string_free(s, FALSE);
|
||
}
|
||
|
||
void u3_let_check(GtkButton *button, gpointer data) {
|
||
U3LetCtx *ctx = data;
|
||
guint total = ctx->entries->len;
|
||
guint ok = 0;
|
||
|
||
(void)button;
|
||
|
||
for (guint i = 0; i < total; i++) {
|
||
GtkWidget *e = g_array_index(ctx->entries, GtkWidget *, i);
|
||
const char *ans = g_array_index(ctx->answers, const char *, i);
|
||
const gchar *txt = gtk_editable_get_text(GTK_EDITABLE(e));
|
||
gchar *norm = normalize_answer(txt);
|
||
gboolean good = txt && txt[0] && answer_accepts(norm, ans);
|
||
g_free(norm);
|
||
answer_mark(e, good);
|
||
if (good)
|
||
ok++;
|
||
}
|
||
|
||
for (guint i = 0; i < ctx->trans->len; i++) {
|
||
GtkWidget *lbl = g_array_index(ctx->trans, GtkWidget *, i);
|
||
if (lbl)
|
||
gtk_widget_set_visible(lbl, TRUE);
|
||
}
|
||
|
||
for (guint i = 0; i < ctx->models->len; i++) {
|
||
GtkWidget *lbl = g_array_index(ctx->models, GtkWidget *, i);
|
||
if (lbl)
|
||
gtk_widget_set_visible(lbl, TRUE);
|
||
}
|
||
|
||
if (ok == total) {
|
||
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
|
||
mark_done(ctx->unit, ctx->ex_num);
|
||
} else {
|
||
set_feedback(ctx->feedback, FALSE, tr("feedback_retry"));
|
||
}
|
||
}
|
||
|
||
void u3_let_row(U3LetCtx *ctx, GtkWidget *body, const U3Let *row) {
|
||
const char *segs[5];
|
||
const char *ans[4];
|
||
int i, g;
|
||
GtkWidget *line;
|
||
|
||
segs[0] = row->s0;
|
||
segs[1] = row->s1;
|
||
segs[2] = row->s2;
|
||
segs[3] = row->s3;
|
||
segs[4] = row->s4;
|
||
ans[0] = row->a0;
|
||
ans[1] = row->a1;
|
||
ans[2] = row->a2;
|
||
ans[3] = row->a3;
|
||
g = 0;
|
||
while (g < 4 && ans[g])
|
||
g++;
|
||
|
||
line = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
|
||
gtk_widget_set_halign(line, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), line);
|
||
|
||
if (row->num && row->num[0]) {
|
||
GtkWidget *nl = gtk_label_new(row->num);
|
||
gtk_widget_set_valign(nl, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(nl, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), nl);
|
||
}
|
||
for (i = 0; i <= g; i++) {
|
||
if (segs[i] && segs[i][0]) {
|
||
GtkWidget *lb = gtk_label_new(segs[i]);
|
||
gtk_widget_set_valign(lb, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(lb, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), lb);
|
||
}
|
||
if (i < g) {
|
||
GtkWidget *e = gtk_entry_new();
|
||
gtk_editable_set_width_chars(GTK_EDITABLE(e), 4);
|
||
gtk_widget_set_valign(e, GTK_ALIGN_CENTER);
|
||
gtk_box_append(GTK_BOX(line), e);
|
||
g_array_append_val(ctx->entries, e);
|
||
g_array_append_val(ctx->answers, ans[i]);
|
||
}
|
||
}
|
||
|
||
if (row->mean && row->mean[0]) {
|
||
GtkWidget *m = meaning_add(body, row->mean);
|
||
gtk_widget_set_visible(m, TRUE);
|
||
g_array_append_val(ctx->trans, m);
|
||
}
|
||
|
||
{
|
||
char *sentence = u3_let_sentence(row);
|
||
|
||
if (sentence && sentence[0]) {
|
||
GtkWidget *w = model_answer_add(body, sentence);
|
||
|
||
g_array_append_val(ctx->models, w);
|
||
}
|
||
g_free(sentence);
|
||
}
|
||
}
|
||
|
||
GtkWidget *u3_build_letters(UnitCtx *unit, int ex_num,
|
||
const char *title, const char *sub,
|
||
const U3Let *rows, int n) {
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, title, sub, "check",
|
||
&body, &feedback, &check);
|
||
U3LetCtx *ctx = u3_let_ctx_new(unit, ex_num, feedback);
|
||
|
||
{
|
||
gboolean need = FALSE;
|
||
|
||
for (int i = 0; i < n && !need; i++) {
|
||
const U3Let *r = &rows[i];
|
||
|
||
need = text_has_german_umlaut(r->s0) ||
|
||
text_has_german_umlaut(r->s1) ||
|
||
text_has_german_umlaut(r->s2) ||
|
||
text_has_german_umlaut(r->s3) ||
|
||
text_has_german_umlaut(r->s4) ||
|
||
text_has_german_umlaut(r->a0) ||
|
||
text_has_german_umlaut(r->a1) ||
|
||
text_has_german_umlaut(r->a2) ||
|
||
text_has_german_umlaut(r->a3);
|
||
}
|
||
if (need)
|
||
add_umlaut_note(body);
|
||
}
|
||
|
||
for (int i = 0; i < n; i++)
|
||
u3_let_row(ctx, body, &rows[i]);
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(u3_let_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex4: missing letters in a paragraph ----------------------------- */
|
||
|
||
/* The Czech sentence is shown straight away; pressing "Check" only adds
|
||
* the translations of the words the student had to complete. */
|
||
|
||
const Ex4Row ex4_u3_rows[] = {
|
||
{{"Wir hab", "n Fre", "nde in Öster", "ich. Sie wo", "nen in Wien."},
|
||
{"e", "u", "re", "h"},
|
||
"Máme přátele v Rakousku. Bydlí ve Vídni.",
|
||
{"haben", "Freunde", "Österreich", "wohnen"},
|
||
{"mít", "přátelé", "Rakousko", "bydlet"}, 4},
|
||
{{"Sie hei", "en Elfriede und Jiri. Sie haben auch ", "inder.", NULL,
|
||
NULL},
|
||
{"ß", "K", NULL, NULL},
|
||
"Jmenují se Elfriede a Jiří. Mají také děti.",
|
||
{"heißen", "Kinder", NULL, NULL},
|
||
{"jmenovat se", "děti", NULL, NULL}, 2},
|
||
{{"Ihr S", "hn heißt Philipp und ihr", " Tochter heißt Sabine.", NULL,
|
||
NULL},
|
||
{"o", "e", NULL, NULL},
|
||
"Jejich syn se jmenuje Philipp a jejich dcera Sabine.",
|
||
{"Sohn", "ihre", NULL, NULL},
|
||
{"syn", "jejich", NULL, NULL}, 2},
|
||
{{"Die Famili", " re", "st gern.", NULL, NULL},
|
||
{"e", "i", NULL, NULL},
|
||
"Rodina ráda cestuje.",
|
||
{"Familie", "reist", NULL, NULL},
|
||
{"rodina", "cestuje", NULL, NULL}, 2},
|
||
{{"Sie ist o", "t bei uns zu Bes", "ch in Tsche", "ien.", NULL},
|
||
{"f", "u", "ch", NULL},
|
||
"Často je u nás na návštěvě v Česku.",
|
||
{"oft", "Besuch", "Tschechien", NULL},
|
||
{"často", "návštěva", "Česko", NULL}, 3},
|
||
{{"Die Kinder ler", "en auch Tsche", "isch.", NULL, NULL},
|
||
{"n", "ch", NULL, NULL},
|
||
"Děti se učí také česky.",
|
||
{"lernen", "Tschechisch", NULL, NULL},
|
||
{"učit se", "čeština", NULL, NULL}, 2},
|
||
};
|
||
|
||
|
||
void ex4_check(GtkButton *button, gpointer data) {
|
||
Ex4LetterCtx *ctx = data;
|
||
guint total = ctx->entries->len;
|
||
guint ok = 0;
|
||
|
||
(void)button;
|
||
|
||
for (guint i = 0; i < total; i++) {
|
||
GtkWidget *e = g_array_index(ctx->entries, GtkWidget *, i);
|
||
const char *ans = g_array_index(ctx->answers, const char *, i);
|
||
const gchar *txt = gtk_editable_get_text(GTK_EDITABLE(e));
|
||
gchar *norm = normalize_answer(txt);
|
||
gboolean good = txt && txt[0] && answer_accepts(norm, ans);
|
||
g_free(norm);
|
||
answer_mark(e, good);
|
||
if (good)
|
||
ok++;
|
||
}
|
||
|
||
for (int r = 0; r < ctx->n_rows; r++) {
|
||
const Ex4Row *row = &ctx->rows[r];
|
||
GtkWidget *note = ctx->notes[r];
|
||
GString *s = g_string_new(NULL);
|
||
for (int k = 0; k < row->gaps; k++) {
|
||
if (k > 0)
|
||
g_string_append(s, " · ");
|
||
if (row->word[k])
|
||
g_string_append_printf(s, "%s = %s", row->word[k],
|
||
tr(row->gmean[k]));
|
||
}
|
||
gtk_label_set_text(GTK_LABEL(note), s->str);
|
||
g_string_free(s, TRUE);
|
||
gtk_widget_set_visible(note, TRUE);
|
||
}
|
||
|
||
if (ok == total) {
|
||
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
|
||
mark_done(ctx->unit, ctx->ex_num);
|
||
} else {
|
||
set_feedback(ctx->feedback, FALSE, tr("feedback_retry"));
|
||
}
|
||
}
|
||
|
||
GtkWidget *u3ex4(UnitCtx *unit) {
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, "Lückentext", "sub3_buchst",
|
||
"check", &body, &feedback, &check);
|
||
Ex4LetterCtx *ctx = g_new0(Ex4LetterCtx, 1);
|
||
|
||
ctx->entries = g_array_new(FALSE, FALSE, sizeof(GtkWidget *));
|
||
ctx->answers = g_array_new(FALSE, FALSE, sizeof(const char *));
|
||
ctx->rows = ex4_u3_rows;
|
||
ctx->n_rows = G_N_ELEMENTS(ex4_u3_rows);
|
||
ctx->notes = g_new0(GtkWidget *, ctx->n_rows);
|
||
ctx->unit = unit;
|
||
ctx->ex_num = 4;
|
||
ctx->feedback = feedback;
|
||
|
||
{
|
||
gboolean need = FALSE;
|
||
|
||
for (int r = 0; r < ctx->n_rows && !need; r++) {
|
||
for (int i = 0; i < ctx->rows[r].gaps; i++) {
|
||
if (text_has_german_umlaut(ctx->rows[r].ans[i]) ||
|
||
text_has_german_umlaut(ctx->rows[r].word[i])) {
|
||
need = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (need)
|
||
add_umlaut_note(body);
|
||
}
|
||
|
||
for (int r = 0; r < ctx->n_rows; r++) {
|
||
const Ex4Row *row = &ctx->rows[r];
|
||
GtkWidget *line = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
|
||
GtkWidget *mean;
|
||
GtkWidget *note;
|
||
|
||
gtk_widget_set_halign(line, GTK_ALIGN_START);
|
||
for (int i = 0; i <= row->gaps; i++) {
|
||
if (row->seg[i] && row->seg[i][0]) {
|
||
GtkWidget *lb = gtk_label_new(row->seg[i]);
|
||
gtk_widget_set_valign(lb, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(lb, "ex-prompt");
|
||
gtk_box_append(GTK_BOX(line), lb);
|
||
}
|
||
if (i < row->gaps) {
|
||
GtkWidget *e = gtk_entry_new();
|
||
gtk_editable_set_width_chars(GTK_EDITABLE(e), 4);
|
||
gtk_widget_set_valign(e, GTK_ALIGN_CENTER);
|
||
gtk_box_append(GTK_BOX(line), e);
|
||
g_array_append_val(ctx->entries, e);
|
||
g_array_append_val(ctx->answers, row->ans[i]);
|
||
}
|
||
}
|
||
gtk_box_append(GTK_BOX(body), line);
|
||
|
||
/* the Czech sentence is available before checking */
|
||
mean = meaning_add(body, row->czech);
|
||
gtk_widget_set_visible(mean, TRUE);
|
||
|
||
/* gapped-word translations appear only after "Check" */
|
||
note = gtk_label_new(NULL);
|
||
gtk_widget_set_halign(note, GTK_ALIGN_START);
|
||
gtk_widget_set_margin_bottom(note, 2);
|
||
gtk_widget_add_css_class(note, "meaning");
|
||
gtk_label_set_wrap(GTK_LABEL(note), TRUE);
|
||
gtk_widget_set_visible(note, FALSE);
|
||
gtk_box_append(GTK_BOX(body), note);
|
||
ctx->notes[r] = note;
|
||
}
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(ex4_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex5: Marcos Familie (word-bank typing) -------------------------- */
|
||
|
||
const char *ex5_u3_bank =
|
||
"Tanten | Job | Vater | Ferien | Zwillinge | Eltern | Kroatien";
|
||
|
||
const TypedQ ex5_u3_rows[] = {
|
||
{"Wir haben eine Männer-Wohngemeinschaft: Mein ________ Johann (50), "
|
||
"Ivo (16) und ich.",
|
||
"vater", "Máme mužskou domácnost: Můj otec Johann (50), Ivo (16) a já."},
|
||
{"Ivo und ich sind gleich alt – wir sind nämlich ________.",
|
||
"zwillinge", "Ivo a já jsme stejně staří – jsme totiž dvojčata."},
|
||
{"Jetzt wohnen wir in Hannover, unser Vater hat hier einen neuen "
|
||
"________.",
|
||
"job", "Náš otec tu má novou práci."},
|
||
{"Unsere ________ sind geschieden.",
|
||
"eltern", "Naši rodiče jsou rozvedení."},
|
||
{"Unsere Mutter Maja (50) lebt in Wien, aber sie kommt aus ________.",
|
||
"kroatien", "Naše matka Maja (50) žije ve Vídni, ale pochází z "
|
||
"Chorvatska."},
|
||
{"Wir haben viele Onkel, ________, Cousinen und Cousins in Kroatien.",
|
||
"tanten", "Máme v Chorvatsku hodně strýců, tet, sestřenic a bratranců."},
|
||
{"Wir sehen sie manchmal in den ________.",
|
||
"ferien", "Vídáme je někdy o prázdninách."},
|
||
};
|
||
|
||
GtkWidget *u3ex5(UnitCtx *unit) {
|
||
return build_typed(unit, 5, "Marcos Familie", "sub3_marco",
|
||
ex5_u3_rows, G_N_ELEMENTS(ex5_u3_rows),
|
||
ex5_u3_bank, FALSE);
|
||
}
|
||
|
||
/* ---- ex6: Wortschatz sortieren --------------------------------------- */
|
||
|
||
const AssignItem ex6_u3_items[] = {
|
||
{NULL, "die Oma", 0},
|
||
{NULL, "der Bruder", 0},
|
||
{NULL, "der Opa", 0},
|
||
{NULL, "die Tochter", 0},
|
||
{NULL, "die Tante", 0},
|
||
{NULL, "der Hamster", 1},
|
||
{NULL, "das Pferd", 1},
|
||
{NULL, "die Katze", 1},
|
||
{NULL, "der Hund", 1},
|
||
{NULL, "der Wellensittich", 1},
|
||
};
|
||
|
||
const char *ex6_u3_groups[] = {"Familienmitglieder", "Haustiere"};
|
||
|
||
const char *ex6_u3_meaning[] = {
|
||
"babička", "bratr", "dědeček", "dcera", "teta",
|
||
"křeček", "kůň", "kočka", "pes", "andulka",
|
||
};
|
||
|
||
GtkWidget *u3ex6(UnitCtx *unit) {
|
||
return build_assign(unit, "Sortieren", "sub3_sort", 6,
|
||
ex6_u3_items, G_N_ELEMENTS(ex6_u3_items),
|
||
ex6_u3_groups, G_N_ELEMENTS(ex6_u3_groups),
|
||
ex6_u3_meaning);
|
||
}
|
||
|
||
/* ---- ex7: Possessivpronomen-Tabelle ---------------------------------- */
|
||
|
||
|
||
void u3_table_check(GtkButton *button, gpointer data) {
|
||
U3TableCtx *ctx = data;
|
||
int ok = 0;
|
||
|
||
(void)button;
|
||
|
||
for (int i = 0; i < ctx->n; i++) {
|
||
const gchar *txt = gtk_editable_get_text(
|
||
GTK_EDITABLE(ctx->entries[i]));
|
||
gchar *norm = normalize_answer(txt);
|
||
gboolean good = txt && txt[0] &&
|
||
g_strcmp0(norm, ctx->answers[i]) == 0;
|
||
g_free(norm);
|
||
answer_mark(ctx->entries[i], good);
|
||
if (good)
|
||
ok++;
|
||
}
|
||
|
||
if (ok == ctx->n) {
|
||
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
|
||
mark_done(ctx->unit, ctx->ex_num);
|
||
} else {
|
||
set_feedback(ctx->feedback, FALSE, tr("feedback_retry"));
|
||
}
|
||
}
|
||
|
||
GtkWidget *u3ex7(UnitCtx *unit) {
|
||
static const char *persons[] = {
|
||
"ich", "du", "er", "sie", "es", "wir", "ihr", "sie / Sie",
|
||
};
|
||
static const char *nouns[] = {
|
||
"der Garten", "die Idee", "das Fest", "die Geschwister",
|
||
};
|
||
static const char *ans[4][8] = {
|
||
{"mein", "dein", "sein", "ihr", "sein", "unser", "euer",
|
||
"ihr"},
|
||
{"meine", "deine", "seine", "ihre", "seine", "unsere", "eure",
|
||
"ihre"},
|
||
{"mein", "dein", "sein", "ihr", "sein", "unser", "euer",
|
||
"ihr"},
|
||
{"meine", "deine", "seine", "ihre", "seine", "unsere", "eure",
|
||
"ihre"},
|
||
};
|
||
const int np = G_N_ELEMENTS(persons);
|
||
const int nn = G_N_ELEMENTS(nouns);
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, "Possessivtabelle",
|
||
"sub3_tabelle", "check",
|
||
&body, &feedback, &check);
|
||
GtkWidget *grid;
|
||
GtkWidget *sample_note;
|
||
GtkWidget *bank_row;
|
||
GtkWidget *bank_hdr;
|
||
GtkWidget *bank1;
|
||
GtkWidget *bank2;
|
||
U3TableCtx *ctx = g_new0(U3TableCtx, 1);
|
||
|
||
ctx->n = nn * np;
|
||
ctx->entries = g_new0(GtkWidget *, ctx->n);
|
||
ctx->answers = g_new0(const char *, ctx->n);
|
||
ctx->unit = unit;
|
||
ctx->ex_num = 7;
|
||
ctx->feedback = feedback;
|
||
|
||
sample_note = gtk_label_new("Beispiel: mein (ich × der Garten)");
|
||
gtk_widget_set_halign(sample_note, GTK_ALIGN_START);
|
||
gtk_widget_set_margin_top(sample_note, 2);
|
||
gtk_widget_set_margin_bottom(sample_note, 4);
|
||
gtk_widget_add_css_class(sample_note, "hint");
|
||
gtk_box_append(GTK_BOX(body), sample_note);
|
||
|
||
bank_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
||
gtk_widget_set_halign(bank_row, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), bank_row);
|
||
bank_hdr = gtk_label_new(NULL);
|
||
i18n_bind(bank_hdr, "wordbank", 0);
|
||
gtk_widget_add_css_class(bank_hdr, "hint");
|
||
gtk_box_append(GTK_BOX(bank_row), bank_hdr);
|
||
bank1 = gtk_label_new("(der Garten / das Fest) "
|
||
"mein · dein · sein · ihr · unser · euer");
|
||
gtk_widget_add_css_class(bank1, "hint");
|
||
gtk_box_append(GTK_BOX(bank_row), bank1);
|
||
|
||
bank_row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
|
||
gtk_widget_set_halign(bank_row, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), bank_row);
|
||
bank2 = gtk_label_new("(die Idee / die Geschwister) "
|
||
"meine · deine · seine · ihre · unsere · eure");
|
||
gtk_widget_add_css_class(bank2, "hint");
|
||
gtk_box_append(GTK_BOX(bank_row), bank2);
|
||
|
||
grid = gtk_grid_new();
|
||
gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
|
||
gtk_grid_set_row_spacing(GTK_GRID(grid), 8);
|
||
gtk_widget_set_halign(grid, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), grid);
|
||
|
||
for (int c = 0; c < np; c++) {
|
||
GtkWidget *h = gtk_label_new(persons[c]);
|
||
gtk_widget_set_halign(h, GTK_ALIGN_CENTER);
|
||
gtk_widget_add_css_class(h, "ex-sub");
|
||
gtk_grid_attach(GTK_GRID(grid), h, c + 1, 0, 1, 1);
|
||
}
|
||
for (int r = 0; r < nn; r++) {
|
||
GtkWidget *h = gtk_label_new(nouns[r]);
|
||
gtk_widget_set_halign(h, GTK_ALIGN_START);
|
||
gtk_widget_add_css_class(h, "ex-sub");
|
||
gtk_grid_attach(GTK_GRID(grid), h, 0, r + 1, 1, 1);
|
||
}
|
||
for (int r = 0; r < nn; r++) {
|
||
for (int c = 0; c < np; c++) {
|
||
GtkWidget *e = gtk_entry_new();
|
||
gtk_editable_set_width_chars(GTK_EDITABLE(e), 6);
|
||
gtk_widget_set_halign(e, GTK_ALIGN_CENTER);
|
||
gtk_grid_attach(GTK_GRID(grid), e, c + 1, r + 1, 1, 1);
|
||
ctx->entries[r * np + c] = e;
|
||
ctx->answers[r * np + c] = ans[r][c];
|
||
}
|
||
}
|
||
/* pre-filled sample cell (ich × der Garten) */
|
||
gtk_editable_set_text(GTK_EDITABLE(ctx->entries[0]), "mein");
|
||
gtk_widget_set_sensitive(ctx->entries[0], FALSE);
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(u3_table_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex8: Possessivpronomen im Akkusativ ------------------------------ */
|
||
|
||
const char *ex8_u3_pool[] = {
|
||
"mein", "meine", "meinen", "dein", "deine", "deinen",
|
||
"sein", "seine", "seinen", "ihr", "ihre", "ihren",
|
||
"unser", "unsere", "unseren", "euer", "eure", "euren",
|
||
};
|
||
|
||
const U3Fill ex8_u3_rows[] = {
|
||
{"2.", "das Handy → Du brauchst ", "dein", " Handy.", NULL, NULL, NULL,
|
||
NULL, "Potřebuješ svůj mobil."},
|
||
{"3.", "das Pferd → Er hat ", "sein", " Pferd.", NULL, NULL, NULL, NULL,
|
||
"Má svého koně."},
|
||
{"4.", "die Party → Sie macht ", "ihre", " Party.", NULL, NULL, NULL,
|
||
NULL, "Dělá svou párty."},
|
||
{"5.", "der Lehrer → Es fragt ", "seinen", " Lehrer.", NULL, NULL, NULL,
|
||
NULL, "Ptá se svého učitele."},
|
||
{"6.", "das Wochenendhaus → Wir besuchen ", "unser", " Wochenendhaus.",
|
||
NULL, NULL, NULL, NULL, "Navštěvujeme náš víkendový dům."},
|
||
{"7.", "der Hund → Ihr seht ", "euren", " Hund.", NULL, NULL, NULL, NULL,
|
||
"Vy vidíte svého psa."},
|
||
{"8.", "die Instrumente → Sie haben ", "ihre", " Instrumente.", NULL,
|
||
NULL, NULL, NULL, "Mají své nástroje."},
|
||
};
|
||
|
||
const char *ex8_u3_gloss[] = {
|
||
"u3g_dein", "u3g_sein", "u3g_ihr_sie", "u3g_sein_es",
|
||
"u3g_unser", "u3g_euer", "u3g_ihr_sie_pl",
|
||
};
|
||
|
||
GtkWidget *u3ex8(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 8, "Akkusativ", "sub3_akk",
|
||
"Beispiel: die Inliner (ich) → Ich brauche meine "
|
||
"Inliner.",
|
||
ex8_u3_rows, G_N_ELEMENTS(ex8_u3_rows),
|
||
ex8_u3_pool, G_N_ELEMENTS(ex8_u3_pool),
|
||
ex8_u3_gloss, TRUE);
|
||
}
|
||
|
||
/* ---- ex9: kein / keine / keinen / nicht ------------------------------ */
|
||
|
||
const char *ex9_u3_pool[] = {
|
||
"kein", "keine", "keinen", "nicht",
|
||
};
|
||
|
||
const U3Fill ex9_u3_rows[] = {
|
||
{"1.", "● Sprichst du Spanisch? ○ Nein, ich spreche ", "kein",
|
||
" Spanisch.", NULL, NULL, NULL, NULL,
|
||
"Mluvíš španělsky? – Ne, nemluvím španělsky."},
|
||
{"2.", "● Hast du einen Bruder? ○ Nein, ich habe ", "keinen",
|
||
" Bruder.", NULL, NULL, NULL, NULL, "Máš bratra? – Ne, nemám bratra."},
|
||
{"3.", "● Gibt es in Opava einen Zoo? ○ Nein, in Opava gibt es ",
|
||
"keinen", " Zoo.", NULL, NULL, NULL, NULL,
|
||
"Je v Opavě zoo? – Ne, v Opavě žádná zoo není."},
|
||
{"4.", "● Gehst du ins Schwimmbad? ○ Nein, ich gehe ", "nicht",
|
||
" ins Schwimmbad.", NULL, NULL, NULL, NULL,
|
||
"Jdeš do bazénu? – Ne, do bazénu nejdu."},
|
||
{"5.", "● Wandert er gern? ○ Nein, er wandert ", "nicht", " gern.",
|
||
NULL, NULL, NULL, NULL, "Rád chodí na túry? – Ne, nerad chodí na túry."},
|
||
{"6.", "● Besuchst du heute ein Schloss? ○ Nein, heute besuche ich ",
|
||
"kein", " Schloss.", NULL, NULL, NULL, NULL,
|
||
"Navštívíš dnes zámek? – Ne, dnes nenavštívím žádný zámek."},
|
||
};
|
||
|
||
GtkWidget *u3ex9(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 9, "kein / nicht", "sub3_nicht", NULL,
|
||
ex9_u3_rows, G_N_ELEMENTS(ex9_u3_rows),
|
||
ex9_u3_pool, G_N_ELEMENTS(ex9_u3_pool), NULL, TRUE);
|
||
}
|
||
|
||
/* ---- ex10: Sätze bauen ------------------------------------------------ */
|
||
|
||
const AssemblyItem ex10_u3_items[] = {
|
||
{NULL, {"Sie", "haben", "eine", "Schildkröte", "."}, 5},
|
||
{NULL, {"Was", "macht", "deine", "Freundin", "am", "Wochenende?"}, 6},
|
||
{NULL, {"Mein", "Vater", "ist", "Lehrer", "von", "Beruf."}, 6},
|
||
{NULL, {"Seid", "ihr", "viele", "zu", "Hause?"}, 5},
|
||
{NULL, {"Julia", "stellt", "ihren", "Hund", "Trixi", "vor."}, 6},
|
||
};
|
||
|
||
const char *ex10_u3_meaning[] = {
|
||
"Mají želvu.",
|
||
"Co dělá tvoje kamarádka o víkendu?",
|
||
"Můj otec je povoláním učitel.",
|
||
"Je vás doma hodně?",
|
||
"Julie představuje svého psa Trixiho.",
|
||
};
|
||
|
||
GtkWidget *u3ex10(UnitCtx *unit) {
|
||
return build_assembly(unit, "Sätze bauen", "sub3_satz", 10,
|
||
ex10_u3_items, ex10_u3_meaning,
|
||
G_N_ELEMENTS(ex10_u3_items));
|
||
}
|
||
|
||
/* ---- keyword-typed builder (ex11 + ex14) ----------------------------- */
|
||
|
||
|
||
|
||
void u3_kw_check(GtkButton *button, gpointer data) {
|
||
U3KwCtx *ctx = data;
|
||
int ok = 0;
|
||
|
||
(void)button;
|
||
|
||
for (int i = 0; i < ctx->n; i++) {
|
||
const gchar *txt = gtk_editable_get_text(GTK_EDITABLE(ctx->entries[i]));
|
||
gchar *norm = normalize_answer(txt);
|
||
gboolean good = txt && txt[0];
|
||
if (good) {
|
||
gchar **parts = g_strsplit(ctx->qs[i].answers, "|", -1);
|
||
good = FALSE;
|
||
for (int j = 0; parts[j]; j++) {
|
||
gchar *a = normalize_answer(parts[j]);
|
||
if (a[0] && g_strrstr(norm, a)) {
|
||
good = TRUE;
|
||
g_free(a);
|
||
break;
|
||
}
|
||
g_free(a);
|
||
}
|
||
g_strfreev(parts);
|
||
}
|
||
g_free(norm);
|
||
answer_mark(ctx->entries[i], good);
|
||
if (good)
|
||
ok++;
|
||
}
|
||
|
||
for (int i = 0; i < ctx->n; i++)
|
||
if (ctx->models[i])
|
||
gtk_widget_set_visible(ctx->models[i], TRUE);
|
||
|
||
if (ok == ctx->n) {
|
||
set_feedback(ctx->feedback, TRUE, tr("feedback_ok"));
|
||
mark_done(ctx->unit, ctx->ex_num);
|
||
} else {
|
||
set_feedback(ctx->feedback, FALSE, tr("feedback_retry"));
|
||
}
|
||
}
|
||
|
||
GtkWidget *u3_build_kw(UnitCtx *unit, int ex_num, const char *title,
|
||
const char *sub, const char *sample,
|
||
const U3Kw *qs, int n) {
|
||
GtkWidget *body, *feedback, *check;
|
||
GtkWidget *page = ex_page_shell(unit->page, title, sub, "check",
|
||
&body, &feedback, &check);
|
||
U3KwCtx *ctx = g_new0(U3KwCtx, 1);
|
||
|
||
ctx->qs = qs;
|
||
ctx->n = n;
|
||
ctx->unit = unit;
|
||
ctx->ex_num = ex_num;
|
||
ctx->feedback = feedback;
|
||
ctx->entries = g_new0(GtkWidget *, n);
|
||
ctx->trans = g_new0(GtkWidget *, n);
|
||
ctx->models = g_new0(GtkWidget *, n);
|
||
|
||
{
|
||
gboolean need = FALSE;
|
||
|
||
for (int i = 0; i < n && !need; i++) {
|
||
need = text_has_german_umlaut(qs[i].prompt) ||
|
||
text_has_german_umlaut(qs[i].answers) ||
|
||
text_has_german_umlaut(qs[i].german);
|
||
}
|
||
if (need)
|
||
add_umlaut_note(body);
|
||
}
|
||
|
||
if (sample && sample[0])
|
||
u3_sample_line(body, sample);
|
||
|
||
for (int i = 0; i < n; i++) {
|
||
GtkWidget *prompt = gtk_label_new(qs[i].prompt);
|
||
GtkWidget *entry;
|
||
|
||
gtk_widget_set_halign(prompt, GTK_ALIGN_START);
|
||
gtk_widget_add_css_class(prompt, "ex-prompt");
|
||
gtk_label_set_wrap(GTK_LABEL(prompt), TRUE);
|
||
gtk_box_append(GTK_BOX(body), prompt);
|
||
|
||
entry = gtk_entry_new();
|
||
gtk_widget_set_hexpand(entry, FALSE);
|
||
gtk_widget_set_halign(entry, GTK_ALIGN_START);
|
||
gtk_box_append(GTK_BOX(body), entry);
|
||
ctx->entries[i] = entry;
|
||
|
||
if (qs[i].mean)
|
||
ctx->trans[i] = meaning_add(body, qs[i].mean);
|
||
|
||
/* Czech meaning acts as a hint and stays visible. */
|
||
if (ctx->trans[i])
|
||
gtk_widget_set_visible(ctx->trans[i], TRUE);
|
||
|
||
/* The model German sentence is only shown after clicking Check. */
|
||
if (qs[i].german && qs[i].german[0]) {
|
||
GtkWidget *model = gtk_label_new(qs[i].german);
|
||
|
||
gtk_widget_set_halign(model, GTK_ALIGN_START);
|
||
gtk_label_set_xalign(GTK_LABEL(model), 0.0);
|
||
gtk_label_set_wrap(GTK_LABEL(model), TRUE);
|
||
gtk_widget_set_margin_top(model, 2);
|
||
gtk_widget_set_margin_bottom(model, 2);
|
||
gtk_widget_set_margin_start(model, 8);
|
||
gtk_widget_add_css_class(model, "u3-answer");
|
||
gtk_widget_set_visible(model, FALSE);
|
||
gtk_box_append(GTK_BOX(body), model);
|
||
ctx->models[i] = model;
|
||
}
|
||
}
|
||
|
||
g_signal_connect(check, "clicked", G_CALLBACK(u3_kw_check), ctx);
|
||
return page;
|
||
}
|
||
|
||
/* ---- ex11: Was siehst du? -------------------------------------------- */
|
||
|
||
const U3Kw ex11_u3_qs[] = {
|
||
{"Ein altes Gebäude aus dem Mittelalter. Es steht auf einem Berg.",
|
||
"burg|schloss", "Vidím hrad / zámek.",
|
||
"Ich sehe eine Burg. / Ich sehe ein Schloss."},
|
||
{"Wasser, Bäume und Berge. Es ist sehr ruhig.",
|
||
"see", "Vidím jezero.", "Ich sehe einen See."},
|
||
{"Eine Frau, ein Mann und zwei Kinder essen zusammen.",
|
||
"familie", "Vidím rodinu.", "Ich sehe eine Familie."},
|
||
};
|
||
|
||
GtkWidget *u3ex11(UnitCtx *unit) {
|
||
return u3_build_kw(unit, 11, "Was siehst du?", "sub3_sehen",
|
||
"Beispiel: Ich sehe eine Burg. / Ich sehe ein Schloss.",
|
||
ex11_u3_qs, G_N_ELEMENTS(ex11_u3_qs));
|
||
}
|
||
|
||
/* ---- ex12: Wem gehört das? ------------------------------------------- */
|
||
|
||
const char *ex12_u3_pool[] = {
|
||
"mein", "meine", "dein", "deine", "sein", "seine",
|
||
"ihr", "ihre", "unser", "unsere", "euer", "eure",
|
||
};
|
||
|
||
const U3Fill ex12_u3_rows[] = {
|
||
{"1.", "Das ist Tom. → Das ist ", "sein", " Handy.", NULL, NULL, NULL,
|
||
NULL, "To je jeho mobil."},
|
||
{"2.", "Das ist Maria. → Das ist ", "ihr", " Kaninchen.", NULL, NULL,
|
||
NULL, NULL, "To je její králík."},
|
||
{"3.", "Das sind Max und Lisa. → Das sind ", "ihre", " Inliner.", NULL,
|
||
NULL, NULL, NULL, "To jsou jejich brusle."},
|
||
{"4.", "Das ist Frau Berger. → Das ist ", "ihr", " Kuchen.", NULL, NULL,
|
||
NULL, NULL, "To je její dort."},
|
||
{"5.", "Das ist Herr Müller. → Das ist ", "sein", " Haus.", NULL, NULL,
|
||
NULL, NULL, "To je jeho dům."},
|
||
{"6.", "Das sind die Schmidts. → Das sind ", "ihre", " Kinder.", NULL,
|
||
NULL, NULL, NULL, "To jsou jejich děti."},
|
||
};
|
||
|
||
GtkWidget *u3ex12(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 12, "Wem gehört das?", "sub3_wem", NULL,
|
||
ex12_u3_rows, G_N_ELEMENTS(ex12_u3_rows),
|
||
ex12_u3_pool, G_N_ELEMENTS(ex12_u3_pool), NULL, TRUE);
|
||
}
|
||
|
||
/* ---- ex13: Es gibt + unbestimmter Artikel ---------------------------- */
|
||
|
||
const char *ex13_u3_pool[] = {"ein", "eine", "einen"};
|
||
|
||
const U3Fill ex13_u3_rows[] = {
|
||
{"1.", "(das Konzert) → Es gibt ", "ein", " Konzert.", NULL, NULL, NULL,
|
||
NULL, "Je tu koncert."},
|
||
{"2.", "(die Ausstellung) → Es gibt ", "eine", " Ausstellung.", NULL,
|
||
NULL, NULL, NULL, "Je tu výstava."},
|
||
{"3.", "(das Sportfest) → Es gibt ", "ein", " Sportfest.", NULL, NULL,
|
||
NULL, NULL, "Je tu sportovní slavnost."},
|
||
{"4.", "(das Familientreffen) → Es gibt ", "ein", " Familientreffen.",
|
||
NULL, NULL, NULL, NULL, "Je tu rodinné setkání."},
|
||
{"5.", "(die Theatervorstellung) → Es gibt ", "eine",
|
||
" Theatervorstellung.", NULL, NULL, NULL, NULL,
|
||
"Je tu divadelní představení."},
|
||
{"6.", "(der Flohmarkt) → Es gibt ", "einen", " Flohmarkt.", NULL, NULL,
|
||
NULL, NULL, "Je tu bleší trh."},
|
||
};
|
||
|
||
GtkWidget *u3ex13(UnitCtx *unit) {
|
||
return u3_build_drop(unit, 13, "Es gibt …", "sub3_gibt", NULL,
|
||
ex13_u3_rows, G_N_ELEMENTS(ex13_u3_rows),
|
||
ex13_u3_pool, G_N_ELEMENTS(ex13_u3_pool), NULL, TRUE);
|
||
}
|
||
|
||
/* ---- ex14: Beschreiben (sentence pairs) ------------------------------ */
|
||
|
||
const U3Kw ex14_u3_qs[] = {
|
||
{"Eine Frau fährt Fahrrad. → Ich sehe ________.",
|
||
"eine frau|frau", "Vidím ženu.", "Ich sehe eine Frau."},
|
||
{"→ Sie ________.",
|
||
"sie fährt fahrrad|sie fährt|fährt fahrrad|fährt", "Jezdí na kole.",
|
||
"Sie fährt Fahrrad."},
|
||
{"Ein Mann wandert im Wald. → Ich sehe ________.",
|
||
"einen mann|mann", "Vidím muže.", "Ich sehe einen Mann."},
|
||
{"→ Er ________.",
|
||
"er wandert im wald|er wandert|wandert im wald|wandert",
|
||
"Chodí po lese.", "Er wandert im Wald."},
|
||
{"Zwei Kinder spielen Fußball. → Ich sehe ________.",
|
||
"zwei kinder|kinder", "Vidím dvě děti.", "Ich sehe zwei Kinder."},
|
||
{"→ Sie ________.",
|
||
"sie spielen fußball|sie spielen fussball|spielen fußball|spielen "
|
||
"fussball|spielen", "Hrají fotbal.", "Sie spielen Fußball."},
|
||
};
|
||
|
||
GtkWidget *u3ex14(UnitCtx *unit) {
|
||
return u3_build_kw(unit, 14, "Beschreiben", "sub3_saetze",
|
||
"Beispiel: Ich sehe einen Jungen. Er liest ein Buch.",
|
||
ex14_u3_qs, G_N_ELEMENTS(ex14_u3_qs));
|
||
}
|
||
|
||
/* ---- ex15: missing letters (Wochenende) ------------------------------ */
|
||
|
||
const U3Let ex15_u3_rows[] = {
|
||
{"1.", "Meine Gr", "oß", "eltern fahr", "en", " ins Wochen", "end",
|
||
"haus.", NULL, NULL,
|
||
"Moji prarodiče jedou o víkendu do víkendového domu."},
|
||
{"2.", "Mein ", "Va", "ter und mein", "e", " Mutter besuch", "en",
|
||
" ein Konz", "er", "t.",
|
||
"Můj otec a moje matka navštíví koncert."},
|
||
{"3.", "Mein", "e", " Sch", "w", "ester geh", "t", " ins K", "in", "o.",
|
||
"Moje sestra jde do kina."},
|
||
{"4.", "Mein Bru", "d", "er f", "äh", "rt an ", "ei", "nen S", "ee",
|
||
".",
|
||
"Můj bratr jede k jezeru."},
|
||
{"5.", "Und ich? Ich besuch", "e", " ein Einka", "ufs", "zentrum.",
|
||
NULL, NULL, NULL, NULL,
|
||
"A já? Navštívím obchodní centrum."},
|
||
};
|
||
|
||
GtkWidget *u3ex15(UnitCtx *unit) {
|
||
return u3_build_letters(unit, 15, "Wochenende", "sub3_wochen",
|
||
ex15_u3_rows, G_N_ELEMENTS(ex15_u3_rows));
|
||
}
|
||
|
||
/* ------------------------------------------------------------------ */
|
||
/* Unit 3 vocabulary (off-path Vokabeltraining branch) */
|
||
/* ------------------------------------------------------------------ */
|
||
|
||
const TypedQ u3_trans_p32[] = {
|
||
{"die Geburtstagsparty, -s",
|
||
"narozeninová slavnost|narozeninová oslava|birthday party",
|
||
"narozeninová slavnost"},
|
||
{"das Haustier, -e", "domácí zvíře|domácí mazlíček|pet", "domácí zvíře"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p33[] = {
|
||
{"die Aktivität, -en", "aktivita|činnost|activity", "aktivita"},
|
||
{"der Stammbaum, Stammbäume", "rodokmen|family tree", "rodokmen"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p34[] = {
|
||
{"der Bruder, Brüder", "bratr|brother", "bratr"},
|
||
{"der Cousin, -s", "bratranec|cousin", "bratranec"},
|
||
{"die Cousine, -n", "sestřenice|cousin", "sestřenice"},
|
||
{"die Ehefrau, -en", "manželka|žena|wife", "manželka"},
|
||
{"der Ehemann, Ehemänner", "manžel|muž|husband", "manžel"},
|
||
{"das Einzelkind, -er", "jedináček|only child", "jedináček"},
|
||
{"die Eltern (mn. č.)", "rodiče|parents", "rodiče"},
|
||
{"die Familie, -n", "rodina|family", "rodina"},
|
||
{"feiern (Infinitiv)", "slavit|oslavovat|to celebrate",
|
||
"slavit, oslavovat"},
|
||
{"das Fest, -e", "oslava|slavnost|svátek|celebration|festival",
|
||
"oslava, slavnost"},
|
||
{"der Garten, Gärten", "zahrada|garden", "zahrada"},
|
||
{"gehören (Infinitiv)", "patřit|to belong", "patřit"},
|
||
{"Er gehört zur Familie.", "patří k rodině|he belongs to the family",
|
||
"Patří k rodině."},
|
||
{"geschieden", "rozvedený|rozvedená|divorced", "rozvedený"},
|
||
{"Meine Eltern sind geschieden.",
|
||
"moji rodiče jsou rozvedení|my parents are divorced",
|
||
"Moji rodiče jsou rozvedení."},
|
||
{"die Geschwister (mn. č.)", "sourozenci|siblings", "sourozenci"},
|
||
{"gleich", "stejný|rovný|same|equal", "stejný"},
|
||
{"groß", "velký|big|large|tall", "velký"},
|
||
{"haben (Infinitiv)", "mít|to have", "mít"},
|
||
{"Unser Haus hat einen großen Garten.",
|
||
"náš dům má velkou zahradu|our house has a big garden",
|
||
"Náš dům má velkou zahradu."},
|
||
{"das Haus, Häuser", "dům|house", "dům"},
|
||
{"hier", "zde|tady|tu|here", "zde, tady"},
|
||
{"der Hund, -e", "pes|dog", "pes"},
|
||
{"ihr, ihre, ihr", "její|jejich|její, jejich|her|their", "její"},
|
||
{"der Iran", "írán|iran", "Írán"},
|
||
{"der Job, -s", "pracovní místo|zaměstnání|práce|job",
|
||
"(pracovní) místo, zaměstnání"},
|
||
{"der Kater, -", "kocour|tomcat", "kocour"},
|
||
{"lange", "dlouho|long", "dlouho"},
|
||
{"manchmal", "někdy|občas|sometimes", "někdy, občas"},
|
||
{"mehr", "více|víc|již|more", "více, již"},
|
||
{"Ich bin kein Einzelkind mehr.",
|
||
"již nejsem jedináček|už nejsem jedináček|i am no longer an only child",
|
||
"Již nejsem jedináček."},
|
||
{"nämlich", "totiž|namely", "totiž"},
|
||
{"natürlich", "samozřejmě|přirozeně|of course|naturally",
|
||
"samozřejmě"},
|
||
{"neu", "nový|new", "nový"},
|
||
{"die Oma, -s", "babička|babi|grandma|grandmother", "babička"},
|
||
{"der Onkel, -", "strýc|uncle", "strýc"},
|
||
{"der Opa, -s", "dědeček|děda|grandpa|grandfather", "dědeček"},
|
||
{"die Patchworkfamilie, -n",
|
||
"patchworková rodina|patchwork family|blended family",
|
||
"patchworková rodina"},
|
||
{"Persisch", "perština|persky|persian", "perština, persky"},
|
||
{"die Person, -en", "osoba|person", "osoba"},
|
||
{"die Schwester, -n", "sestra|sister", "sestra"},
|
||
{"sehen (Infinitiv)", "vidět|to see", "vidět"},
|
||
{"Wir sehen sie manchmal in den Ferien.",
|
||
"vídáme je občas o prázdninách|vidíme je někdy o prázdninách|"
|
||
"we see them sometimes during the holidays",
|
||
"Vídáme je občas o prázdninách."},
|
||
{"die Stiefmutter, Stiefmütter",
|
||
"nevlastní matka|macecha|stepmother", "nevlastní matka"},
|
||
{"die Stiefschwester, -n", "nevlastní sestra|stepsister",
|
||
"nevlastní sestra"},
|
||
{"die Tante, -n", "teta|téta|aunt", "teta"},
|
||
{"die Tochter, Töchter", "dcera|daughter", "dcera"},
|
||
{"tot", "mrtvý|dead", "mrtvý"},
|
||
{"Er ist leider schon tot.",
|
||
"on je již bohužel mrtvý|je bohužel už mrtvý|"
|
||
"he is unfortunately already dead", "(On) Je již bohužel mrtvý."},
|
||
{"typisch", "typický|klasický|typical", "typický, klasický"},
|
||
{"unser, unsere, unser", "náš|naše|our", "náš, naše, naše"},
|
||
{"der Vater, Väter", "otec|táta|father|dad", "otec"},
|
||
{"verstehen sich",
|
||
"rozumět si|rozumí si|to get along|to understand each other",
|
||
"rozumět si"},
|
||
{"Wir verstehen uns alle sehr gut.",
|
||
"všichni si moc dobře rozumíme|všichni si velmi dobře rozumíme|"
|
||
"we all get along very well", "Všichni si moc dobře rozumíme."},
|
||
{"der/die Verwandte, -n", "příbuzný|příbuzná|relative",
|
||
"příbuzný/příbuzná"},
|
||
{"die Wohngemeinschaft, -en",
|
||
"společné bydlení|spolubydlení|flat share|shared apartment",
|
||
"společné bydlení (studentů)"},
|
||
{"die Männer-Wohngemeinschaft",
|
||
"mužská domácnost|mužské spolubydlení|men's shared flat",
|
||
"mužská domácnost"},
|
||
{"zusammen", "spolu|dohromady|together", "spolu, dohromady"},
|
||
{"der Zwilling, -e", "dvojče|dvojčata|twin|twins", "dvojče"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p35[] = {
|
||
{"dein, deine, dein", "tvůj|tvoje|your", "tvůj, tvoje, tvoje"},
|
||
{"euer, eure, euer", "váš|vaše|your", "váš, vaše, vaše"},
|
||
{"ihr, ihre, ihr", "jejich|její|their|her", "jejich"},
|
||
{"sein, seine, sein", "jeho|his", "jeho"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p36[] = {
|
||
{"bitte", "prosím|please", "prosím"},
|
||
{"dann", "tak|pak|then", "tak, pak"},
|
||
{"dauern (Infinitiv)", "trvat|to last|to take", "trvat"},
|
||
{"Die Vorbereitung dauert nicht so lange.",
|
||
"příprava netrvá moc dlouho|příprava netrvá tak dlouho|"
|
||
"the preparation doesn't take that long",
|
||
"Příprava netrvá moc dlouho."},
|
||
{"doch", "přece|přeci|ale ano|yet|but", "přece"},
|
||
{"einladen (Infinitiv)", "pozvat|zvát|to invite", "pozvat"},
|
||
{"Wir laden Oma und Opa ein.",
|
||
"pozveme babičku a dědečka|zveme babičku a dědečka|"
|
||
"we invite grandma and grandpa", "Pozveme babičku a dědečka."},
|
||
{"die Feier, -n", "oslava|slavnost|celebration|party",
|
||
"oslava, slavnost"},
|
||
{"fragen (Infinitiv)", "ptát se|zeptat se|to ask",
|
||
"ptát se, zeptat se"},
|
||
{"Ich frage meine Schwester.",
|
||
"zeptám se své sestry|ptám se své sestry|i ask my sister",
|
||
"Zeptám se své sestry."},
|
||
{"der Geburtstag, -e", "narozeniny|birthday", "narozeniny"},
|
||
{"grillen (Infinitiv)", "grilovat|to grill|to barbecue", "grilovat"},
|
||
{"die Idee, -n", "nápad|myšlenka|idea", "nápad, myšlenka"},
|
||
{"die Köchin, -nen", "kuchařka|cook|chef", "kuchařka"},
|
||
{"der Kuchen, -", "koláč|moučník|dort|cake", "koláč, moučník"},
|
||
{"das Menü, -s", "menu|jídelní lístek", "menu"},
|
||
{"5-Gänge-Menü", "pětichodové menu|pětchodové menu|five-course menu",
|
||
"pětichodové menu"},
|
||
{"ob", "zda|jestli|whether|if", "zda, jestli"},
|
||
{"der Papa, -s", "tatínek|táta|dad|daddy", "tatínek"},
|
||
{"die Party, -s", "party|večírek|oslava", "party, večírek"},
|
||
{"das Restaurant", "restaurace|restaurant", "restaurace"},
|
||
{"schrecklich", "strašný|hrozný|terrible|awful", "strašný, hrozný"},
|
||
{"die Schwarzwälder Kirschtorte",
|
||
"schwarzwaldský dort|black forest cake", "Schwarzwaldský dort"},
|
||
{"singen (Infinitiv)", "zpívat|to sing", "zpívat"},
|
||
{"Wir singen Happy Birthday.",
|
||
"zpíváme happy birthday|we sing happy birthday",
|
||
"Zpíváme Happy Birthday."},
|
||
{"stimmen (Infinitiv)", "souhlasit|to be right|to be correct",
|
||
"souhlasit"},
|
||
{"Ja, stimmt.",
|
||
"ano, správně|ano, souhlasí|yes, that's right|yes, right",
|
||
"Ano, správně."},
|
||
{"die Vorbereitung, -en", "příprava|preparation", "příprava"},
|
||
{"wieder", "opět|zase|again", "opět, zase"},
|
||
{"zu Hause", "doma|at home", "doma"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p37[] = {
|
||
{"das Chamäleon, -s", "chameleon|chameleón", "chameleon"},
|
||
{"der Goldfisch, -e", "zlatá rybka|karas|goldfish",
|
||
"zlatá rybka (karas)"},
|
||
{"der Hamster, -", "křeček|hamster", "křeček"},
|
||
{"der Kanarienvogel, Kanarienvögel", "kanárek|kanár|canary",
|
||
"kanárek"},
|
||
{"das Kaninchen, -", "králík|rabbit", "králík"},
|
||
{"die Katze, -n", "kočka|cat", "kočka"},
|
||
{"das Meerschweinchen, -", "morče|guinea pig", "morče"},
|
||
{"das Pferd, -e", "kůň|horse", "kůň"},
|
||
{"die Schildkröte, -n", "želva|turtle|tortoise", "želva"},
|
||
{"das Tier, -e", "zvíře|animal", "zvíře"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p38[] = {
|
||
{"der Ausflug, Ausflüge", "výlet|trip|excursion", "výlet"},
|
||
{"die Ausstellung, -en", "výstava|exhibition", "výstava"},
|
||
{"die Burg, -en", "hrad|castle", "hrad"},
|
||
{"cool", "cool|skvělý|super", "cool, skvělý"},
|
||
{"es gibt", "je|existuje|there is|there are", "je, existuje"},
|
||
{"das Hochzeitsfest, -e",
|
||
"svatební party|svatební oslava|wedding party", "svatební party"},
|
||
{"die Hochzeitstorte, -n", "svatební dort|wedding cake",
|
||
"svatební dort"},
|
||
{"nach", "do|to", "do"},
|
||
{"Ich fahre nach Wien.",
|
||
"jedu do vídně|i go to vienna|i'm going to vienna",
|
||
"Jedu do Vídně."},
|
||
{"nächster, nächste, nächstes", "příští|next", "příští"},
|
||
{"nächsten Monat / nächste Woche / nächstes Jahr",
|
||
"příští měsíc / příští týden / příští rok|"
|
||
"příští měsíc, příští týden, příští rok|"
|
||
"next month / next week / next year|next month, next week, next year",
|
||
"příští měsíc / příští týden / příští rok"},
|
||
{"das Schloss, Schlösser", "zámek|castle|palace", "zámek"},
|
||
{"das Schwimmbad, Schwimmbäder",
|
||
"koupaliště|plavecký bazén|swimming pool",
|
||
"koupaliště, plavecký bazén"},
|
||
{"der Schwimmbadbesuch, -e",
|
||
"návštěva koupaliště|návštěva plaveckého bazénu|"
|
||
"visit to the swimming pool",
|
||
"návštěva koupaliště, plaveckého bazénu"},
|
||
{"schwimmen (Infinitiv)", "plavat|to swim", "plavat"},
|
||
{"Meine Mutter schwimmt gern.",
|
||
"moje matka ráda plave|my mother likes swimming",
|
||
"Moje matka ráda plave."},
|
||
{"shoppen (Infinitiv)", "nakupovat|to shop", "nakupovat"},
|
||
{"Wir gehen shoppen.", "jdeme nakupovat|jdem nakupovat|we go shopping",
|
||
"Jdeme nakupovat."},
|
||
{"das Sportevent, -s",
|
||
"sportovní akce|sportovní událost|sports event",
|
||
"sportovní akce (zápas, závody)"},
|
||
{"der Vergnügungspark, -s",
|
||
"zábavní park|amusement park|theme park", "zábavní park"},
|
||
{"Wir gehen in den Vergnügungspark.",
|
||
"jdeme do zábavního parku|we go to the amusement park",
|
||
"Jdeme do zábavního parku."},
|
||
{"wandern (Infinitiv)", "putovat|cestovat|to hike|to wander",
|
||
"putovat, cestovat"},
|
||
{"Ich wandere gern.",
|
||
"rád(a) putuji|rád putuji|ráda putuji|i like hiking",
|
||
"Rád(a) putuji."},
|
||
{"die Woche, -n", "týden|week", "týden"},
|
||
{"diese Woche", "tento týden|this week", "tento týden"},
|
||
{"der Zoo, -s", "zoo|zoologická zahrada", "zoo"},
|
||
{"der Zoobesuch, -e", "návštěva zoo|visit to the zoo", "návštěva zoo"},
|
||
};
|
||
|
||
const TypedQ u3_trans_p39[] = {
|
||
{"das Einkaufszentrum",
|
||
"nákupní centrum|shopping centre|shopping mall|shopping center",
|
||
"nákupní centrum"},
|
||
{"die Inliner (mn. č.)",
|
||
"inline brusle|inline bruslení|inliners", "inline brusle"},
|
||
{"Sie fährt Inliner.",
|
||
"(ona) jezdí na inline bruslích|jezdí na inline bruslích|"
|
||
"she goes inline skating", "(Ona) Jezdí na inline bruslích."},
|
||
{"der See, -n", "jezero|lake", "jezero"},
|
||
{"Am Wochenende fahren wir an einen See.",
|
||
"o víkendu pojedeme k jezeru|o víkendu jedeme k jezeru|"
|
||
"at the weekend we drive to a lake",
|
||
"O víkendu pojedeme k (nějakému) jezeru."},
|
||
{"das Wochenende, -n", "víkend|weekend", "víkend"},
|
||
{"am Wochenende", "o víkendu|on the weekend", "o víkendu"},
|
||
{"dieses Wochenende", "tento víkend|this weekend", "tento víkend"},
|
||
{"das Wochenendhaus, Wochenendhäuser",
|
||
"chata|chalupa|víkendový dům|weekend house", "chata, chalupa"},
|
||
{"Wir fahren dieses Wochenende ins Wochenendhaus.",
|
||
"tento víkend jedeme na chatu|tento víkend jedeme na chalupu|"
|
||
"this weekend we go to the cottage", "Tento víkend jedeme na chatu."},
|
||
};
|
||
|
||
const TransSection u3_trans_sections[] = {
|
||
{"Strana 32", u3_trans_p32, (int)G_N_ELEMENTS(u3_trans_p32)},
|
||
{"Strana 33", u3_trans_p33, (int)G_N_ELEMENTS(u3_trans_p33)},
|
||
{"Strana 34", u3_trans_p34, (int)G_N_ELEMENTS(u3_trans_p34)},
|
||
{"Strana 35", u3_trans_p35, (int)G_N_ELEMENTS(u3_trans_p35)},
|
||
{"Strana 36", u3_trans_p36, (int)G_N_ELEMENTS(u3_trans_p36)},
|
||
{"Strana 37", u3_trans_p37, (int)G_N_ELEMENTS(u3_trans_p37)},
|
||
{"Strana 38", u3_trans_p38, (int)G_N_ELEMENTS(u3_trans_p38)},
|
||
{"Strana 39", u3_trans_p39, (int)G_N_ELEMENTS(u3_trans_p39)},
|
||
};
|
||
const int u3_trans_sections_n = (int)G_N_ELEMENTS(u3_trans_sections);
|