update
This commit is contained in:
@@ -5,6 +5,7 @@ unter allen Fenstern, über dem Wallpaper.
|
|||||||
|
|
||||||
## Bedienung
|
## Bedienung
|
||||||
|
|
||||||
|
- **Woche:** startet mit der aktuellen Uhrzeit in der Mitte, rote Linie markiert jetzt.
|
||||||
- **Termin anlegen:** in der Wochenansicht auf eine Stunde drücken und bis zur Endstunde ziehen,
|
- **Termin anlegen:** in der Wochenansicht auf eine Stunde drücken und bis zur Endstunde ziehen,
|
||||||
auch über mehrere Tage. Klick ohne Ziehen = eine Stunde. Ziehen in der Zeile „ganz“ = ganztägig.
|
auch über mehrere Tage. Klick ohne Ziehen = eine Stunde. Ziehen in der Zeile „ganz“ = ganztägig.
|
||||||
Oder Rechtsklick auf einen Tag (Monat), eine Stunde (Woche) oder die Tagesfläche: „Termin erstellen“.
|
Oder Rechtsklick auf einen Tag (Monat), eine Stunde (Woche) oder die Tagesfläche: „Termin erstellen“.
|
||||||
@@ -12,7 +13,7 @@ unter allen Fenstern, über dem Wallpaper.
|
|||||||
- **Todo anlegen:** Rechtsklick ins Todo-Panel oder in den Kalender, „Todo erstellen“. Text plus Datum und Uhrzeit.
|
- **Todo anlegen:** Rechtsklick ins Todo-Panel oder in den Kalender, „Todo erstellen“. Text plus Datum und Uhrzeit.
|
||||||
- **Notiz:** Rechtsklick irgendwo im Notiz-Panel, „Notiz erstellen“ fragt den Namen und öffnet den Editor.
|
- **Notiz:** Rechtsklick irgendwo im Notiz-Panel, „Notiz erstellen“ fragt den Namen und öffnet den Editor.
|
||||||
Klick in die Notizfläche bearbeitet. Mit Fokus steht der rohe Markdown-Text, ohne Fokus die formatierte Ansicht.
|
Klick in die Notizfläche bearbeitet. Mit Fokus steht der rohe Markdown-Text, ohne Fokus die formatierte Ansicht.
|
||||||
Gespeichert wird alle paar Sekunden und beim Klick woanders hin.
|
Gespeichert wird alle 5 Sekunden und beim Klick woanders hin.
|
||||||
- **Bearbeiten:** Linksklick auf Termin, Todo oder Notiz.
|
- **Bearbeiten:** Linksklick auf Termin, Todo oder Notiz.
|
||||||
- **Rechtsklick auf freie Fläche:** Erstellen (Todos, Tagesansicht, Notizbaum im Wurzelordner).
|
- **Rechtsklick auf freie Fläche:** Erstellen (Todos, Tagesansicht, Notizbaum im Wurzelordner).
|
||||||
- **Rechtsklick auf Ordner:** Notiz oder Unterordner darin erstellen, Umbenennen, Löschen.
|
- **Rechtsklick auf Ordner:** Notiz oder Unterordner darin erstellen, Umbenennen, Löschen.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Clutter from 'gi://Clutter';
|
import Clutter from 'gi://Clutter';
|
||||||
|
import GLib from 'gi://GLib';
|
||||||
import GObject from 'gi://GObject';
|
import GObject from 'gi://GObject';
|
||||||
import Pango from 'gi://Pango';
|
import Pango from 'gi://Pango';
|
||||||
import St from 'gi://St';
|
import St from 'gi://St';
|
||||||
@@ -7,7 +8,8 @@ import * as D from './dates.js';
|
|||||||
import {editTodo, todoMenu, todoRow, todoTitle} from './todos.js';
|
import {editTodo, todoMenu, todoRow, todoTitle} from './todos.js';
|
||||||
import {button, contextMenu, dropdown, openDatePicker, openTimePicker, Popover, scrollBox, textButton} from './widgets.js';
|
import {button, contextMenu, dropdown, openDatePicker, openTimePicker, Popover, scrollBox, textButton} from './widgets.js';
|
||||||
|
|
||||||
const FIRST_VISIBLE_HOUR = 7;
|
// Rote Linie für die aktuelle Uhrzeit wandert einmal pro Minute
|
||||||
|
const NOW_LINE_SECONDS = 60;
|
||||||
const MONTH_CELL_ENTRIES = 2;
|
const MONTH_CELL_ENTRIES = 2;
|
||||||
const ALLDAY_LANE_HEIGHT = 20;
|
const ALLDAY_LANE_HEIGHT = 20;
|
||||||
|
|
||||||
@@ -155,10 +157,13 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
this._cursor = D.today();
|
this._cursor = D.today();
|
||||||
this._drag = null;
|
this._drag = null;
|
||||||
this._slots = [];
|
this._slots = [];
|
||||||
|
this._weekScroll = null;
|
||||||
|
this._nowLineId = null;
|
||||||
|
|
||||||
this._buildHeader();
|
this._buildHeader();
|
||||||
this._body = new St.Bin({x_expand: true, y_expand: true, x_align: Clutter.ActorAlign.FILL, y_align: Clutter.ActorAlign.FILL});
|
this._body = new St.Bin({x_expand: true, y_expand: true, x_align: Clutter.ActorAlign.FILL, y_align: Clutter.ActorAlign.FILL});
|
||||||
this.add_child(this._body);
|
this.add_child(this._body);
|
||||||
|
this.connect('destroy', () => this._stopNowLine());
|
||||||
|
|
||||||
store.onChange(() => this._render());
|
store.onChange(() => this._render());
|
||||||
this._render();
|
this._render();
|
||||||
@@ -204,6 +209,10 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
for (const [view, b] of Object.entries(this._viewButtons))
|
for (const [view, b] of Object.entries(this._viewButtons))
|
||||||
b.checked = view === this._view;
|
b.checked = view === this._view;
|
||||||
|
|
||||||
|
// Scrollposition der Woche über den Neuaufbau retten, sonst springt die Ansicht nach oben
|
||||||
|
const keepScroll = this._view === 'week' && this._weekScroll ? this._weekScroll.vadjustment.value : null;
|
||||||
|
this._stopNowLine();
|
||||||
|
this._weekScroll = null;
|
||||||
this._slots = [];
|
this._slots = [];
|
||||||
this._alldaySlots = [];
|
this._alldaySlots = [];
|
||||||
this._alldayBlocks = [];
|
this._alldayBlocks = [];
|
||||||
@@ -215,7 +224,7 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
} else if (this._view === 'week') {
|
} else if (this._view === 'week') {
|
||||||
const days = D.weekDays(this._cursor);
|
const days = D.weekDays(this._cursor);
|
||||||
this._title.text = `${D.formatDayMonth(days[0])} – ${D.formatDateInput(days[6])}`;
|
this._title.text = `${D.formatDayMonth(days[0])} – ${D.formatDateInput(days[6])}`;
|
||||||
content = this._weekView(days);
|
content = this._weekView(days, keepScroll);
|
||||||
} else {
|
} else {
|
||||||
this._title.text = D.formatDate(this._cursor);
|
this._title.text = D.formatDate(this._cursor);
|
||||||
content = this._dayView(this._cursor);
|
content = this._dayView(this._cursor);
|
||||||
@@ -299,7 +308,7 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
|
|
||||||
// ---- Woche ----
|
// ---- Woche ----
|
||||||
|
|
||||||
_weekView(days) {
|
_weekView(days, keepScroll) {
|
||||||
const box = new St.BoxLayout({vertical: true, x_expand: true, y_expand: true});
|
const box = new St.BoxLayout({vertical: true, x_expand: true, y_expand: true});
|
||||||
const today = D.today();
|
const today = D.today();
|
||||||
this._weekDays = days;
|
this._weekDays = days;
|
||||||
@@ -357,6 +366,10 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
container.add_child(overlay);
|
container.add_child(overlay);
|
||||||
wrap.add_child(container);
|
wrap.add_child(container);
|
||||||
this._weekRows = rows;
|
this._weekRows = rows;
|
||||||
|
this._weekScroll = scroll;
|
||||||
|
this._nowLine = new St.Widget({style_class: 'week-now-line', visible: false});
|
||||||
|
overlay.add_child(this._nowLine);
|
||||||
|
this._todayIndex = days.indexOf(D.today());
|
||||||
for (let hour = 0; hour < 24; hour++)
|
for (let hour = 0; hour < 24; hour++)
|
||||||
rows.add_child(this._weekRow(`${pad(hour)}:00`, days.map((day, i) => this._slot(i, day, hour))));
|
rows.add_child(this._weekRow(`${pad(hour)}:00`, days.map((day, i) => this._slot(i, day, hour))));
|
||||||
this._blocks = [];
|
this._blocks = [];
|
||||||
@@ -371,31 +384,73 @@ class CalendarPanel extends St.BoxLayout {
|
|||||||
this._blocks.push(item);
|
this._blocks.push(item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
rows.connect('notify::allocation', () => this._placeBlocks());
|
// Die rote Linie liegt über den Blöcken
|
||||||
|
overlay.set_child_above_sibling(this._nowLine, null);
|
||||||
|
rows.connect('notify::allocation', () => {
|
||||||
|
this._placeBlocks();
|
||||||
|
this._placeNowLine();
|
||||||
|
});
|
||||||
box.add_child(scroll);
|
box.add_child(scroll);
|
||||||
|
this._startNowLine();
|
||||||
|
|
||||||
// Nach dem ersten Layout auf den Morgen scrollen.
|
// Nach dem ersten Layout: alte Position wiederherstellen, sonst die aktuelle Uhrzeit in die Mitte
|
||||||
const adjustment = scroll.vadjustment;
|
const adjustment = scroll.vadjustment;
|
||||||
const id = adjustment.connect('changed', () => {
|
const id = adjustment.connect('changed', () => {
|
||||||
if (adjustment.upper <= adjustment.page_size)
|
if (adjustment.upper <= adjustment.page_size)
|
||||||
return;
|
return;
|
||||||
adjustment.value = FIRST_VISIBLE_HOUR * this._rowPitch();
|
const now = new Date();
|
||||||
|
const nowY = (now.getHours() * 60 + now.getMinutes()) / 60 * this._rowPitch();
|
||||||
|
const target = keepScroll ?? nowY - adjustment.page_size / 2;
|
||||||
|
adjustment.value = Math.max(0, Math.min(target, adjustment.upper - adjustment.page_size));
|
||||||
adjustment.disconnect(id);
|
adjustment.disconnect(id);
|
||||||
});
|
});
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rote Linie an der aktuellen Uhrzeit in der Spalte von heute.
|
||||||
|
_placeNowLine() {
|
||||||
|
if (!this._nowLine || this._todayIndex < 0) {
|
||||||
|
this._nowLine?.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cells = this._weekRows.get_child_at_index(0).get_child_at_index(1);
|
||||||
|
const cell = cells.get_child_at_index(this._todayIndex);
|
||||||
|
const now = new Date();
|
||||||
|
const y = (now.getHours() * 60 + now.getMinutes()) / 60 * this._rowPitch();
|
||||||
|
this._nowLine.set_position(Math.round(cells.x + cell.x), Math.round(y) - 1);
|
||||||
|
this._nowLine.set_size(cell.width, 2);
|
||||||
|
this._nowLine.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
_startNowLine() {
|
||||||
|
this._nowLineId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, NOW_LINE_SECONDS, () => {
|
||||||
|
this._placeNowLine();
|
||||||
|
return GLib.SOURCE_CONTINUE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopNowLine() {
|
||||||
|
if (this._nowLineId) {
|
||||||
|
GLib.source_remove(this._nowLineId);
|
||||||
|
this._nowLineId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ein Terminblock: Zeit und Titel, Klick bearbeitet, Rechtsklick öffnet das Menü.
|
// Ein Terminblock: Zeit und Titel, Klick bearbeitet, Rechtsklick öffnet das Menü.
|
||||||
_block(event, day) {
|
_block(event, day) {
|
||||||
const inner = new St.BoxLayout({vertical: true, x_expand: true, y_expand: true, y_align: Clutter.ActorAlign.START});
|
const inner = new St.BoxLayout({vertical: true, x_expand: true, y_expand: true, y_align: Clutter.ActorAlign.START});
|
||||||
inner.add_child(new St.Label({text: day === event.date ? event.start : '…', style_class: 'week-block-time'}));
|
inner.add_child(new St.Label({text: day === event.date ? event.start : '…', style_class: 'week-block-time'}));
|
||||||
|
// Titel läuft über mehrere Zeilen, was nicht in den Block passt, wird unten abgeschnitten
|
||||||
const title = new St.Label({text: event.title, style_class: 'week-block-title', x_expand: true});
|
const title = new St.Label({text: event.title, style_class: 'week-block-title', x_expand: true});
|
||||||
title.clutter_text.ellipsize = Pango.EllipsizeMode.END;
|
title.clutter_text.line_wrap = true;
|
||||||
|
title.clutter_text.line_wrap_mode = Pango.WrapMode.WORD_CHAR;
|
||||||
|
title.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
|
||||||
inner.add_child(title);
|
inner.add_child(title);
|
||||||
const block = new St.Button({
|
const block = new St.Button({
|
||||||
style_class: 'week-block',
|
style_class: 'week-block',
|
||||||
child: inner,
|
child: inner,
|
||||||
can_focus: true,
|
can_focus: true,
|
||||||
|
clip_to_allocation: true,
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||||
});
|
});
|
||||||
block.connect('clicked', (_b, mouseButton) => {
|
block.connect('clicked', (_b, mouseButton) => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import St from 'gi://St';
|
|||||||
import {renderMarkdown} from './markdown.js';
|
import {renderMarkdown} from './markdown.js';
|
||||||
import {contextMenu, multilineEntry, Popover, scrollBox, textButton} from './widgets.js';
|
import {contextMenu, multilineEntry, Popover, scrollBox, textButton} from './widgets.js';
|
||||||
|
|
||||||
const AUTOSAVE_SECONDS = 3;
|
const AUTOSAVE_SECONDS = 5;
|
||||||
|
|
||||||
export const NotesPanel = GObject.registerClass(
|
export const NotesPanel = GObject.registerClass(
|
||||||
class NotesPanel extends St.BoxLayout {
|
class NotesPanel extends St.BoxLayout {
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
}
|
}
|
||||||
.week-block:hover, .week-block:focus { background-color: rgba(233, 103, 46, 1); }
|
.week-block:hover, .week-block:focus { background-color: rgba(233, 103, 46, 1); }
|
||||||
.week-block-time { font-size: 7.5pt; color: rgba(255, 255, 255, 0.85); }
|
.week-block-time { font-size: 7.5pt; color: rgba(255, 255, 255, 0.85); }
|
||||||
|
.week-now-line { background-color: #ff3b30; }
|
||||||
.week-block-title { font-size: 8.5pt; font-weight: bold; color: white; }
|
.week-block-title { font-size: 8.5pt; font-weight: bold; color: white; }
|
||||||
|
|
||||||
/* Tag */
|
/* Tag */
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ rclickb() { $IN rclick $(val "bottom($1).join(' ')"); sleep 0.3; }
|
|||||||
type_() { $IN type "$1"; sleep 0.2; }
|
type_() { $IN type "$1"; sleep 0.2; }
|
||||||
key() { $IN key "$1"; sleep 0.3; }
|
key() { $IN key "$1"; sleep 0.3; }
|
||||||
shot() { "$DIR/shot.sh" "$SHOTS/$1.png" >/dev/null; }
|
shot() { "$DIR/shot.sh" "$SHOTS/$1.png" >/dev/null; }
|
||||||
|
# Wochenraster auf eine Stunde scrollen, wie ein Nutzer mit dem Mausrad. Die Ansicht startet sonst bei der aktuellen Uhrzeit.
|
||||||
|
weekscroll() { "$E" "$PRE cal._weekScroll.vadjustment.value = $1 * cal._rowPitch(); 'ok'" >/dev/null; sleep 0.3; }
|
||||||
check() {
|
check() {
|
||||||
local name=$1 actual=$2 expected=$3
|
local name=$1 actual=$2 expected=$3
|
||||||
if [ "$actual" == "$expected" ]; then
|
if [ "$actual" == "$expected" ]; then
|
||||||
@@ -60,6 +62,9 @@ check "Rechte Spalte füllt den Rest, Abstand wie außen" "$(val '(r => [r.x - (
|
|||||||
echo "=== Woche: Termin per Drag"
|
echo "=== Woche: Termin per Drag"
|
||||||
click 'cal._viewButtons.week'
|
click 'cal._viewButtons.week'
|
||||||
check "Wochenansicht" "$(val 'cal._view')" "week"
|
check "Wochenansicht" "$(val 'cal._view')" "week"
|
||||||
|
check "Aktuelle Uhrzeit mittig" "$(val '(a => { const n = new Date(); const y = (n.getHours() * 60 + n.getMinutes()) / 60 * cal._rowPitch(); return Math.abs(a.value + a.page_size / 2 - y) < 30 || a.value === 0 || a.value >= a.upper - a.page_size - 1; })(cal._weekScroll.vadjustment)')" "true"
|
||||||
|
check "Rote Linie in der Spalte von heute" "$(val '(l => l.visible + " " + (Math.abs(l.get_transformed_position()[0] - cal._slots[cal._todayIndex][0].get_transformed_position()[0]) <= 1))(cal._nowLine)')" "true true"
|
||||||
|
weekscroll 7
|
||||||
$IN drag $(xy 'cal._slots[4][10]') $(xy 'cal._slots[4][12]'); sleep 0.3
|
$IN drag $(xy 'cal._slots[4][10]') $(xy 'cal._slots[4][12]'); sleep 0.3
|
||||||
check "Popover offen" "$(val 'grabbed()?.style_class')" "desktop-popover form"
|
check "Popover offen" "$(val 'grabbed()?.style_class')" "desktop-popover form"
|
||||||
check "Zeitraum im Popover" "$(val '["Fr, 18.09.2026 ▾", "10:00 ▾", "13:00 ▾"].map(t => find(grabbed(), t) ? "ja" : "nein").join(" ")')" "ja ja ja"
|
check "Zeitraum im Popover" "$(val '["Fr, 18.09.2026 ▾", "10:00 ▾", "13:00 ▾"].map(t => find(grabbed(), t) ? "ja" : "nein").join(" ")')" "ja ja ja"
|
||||||
@@ -71,6 +76,8 @@ check "Termin gespeichert" "$(val 'JSON.stringify((({title, date, start, end, en
|
|||||||
'{"title":"Sport","date":"2026-09-18","start":"10:00","end":"13:00","endDate":null}'
|
'{"title":"Sport","date":"2026-09-18","start":"10:00","end":"13:00","endDate":null}'
|
||||||
check "Popover zu, Markierung weg" "$(val '[grabbed() ? "grab" : "frei", cal._slots[4].filter(s => s.has_style_class_name("selecting")).length].join(" ")')" "frei 0"
|
check "Popover zu, Markierung weg" "$(val '[grabbed() ? "grab" : "frei", cal._slots[4].filter(s => s.has_style_class_name("selecting")).length].join(" ")')" "frei 0"
|
||||||
check "Ein Block über drei Stunden" "$(val '(b => b.length + " " + Math.round(b[0].block.height / cal._rowPitch()))(cal._blocks.filter(b => b.event.title === "Sport"))')" "1 3"
|
check "Ein Block über drei Stunden" "$(val '(b => b.length + " " + Math.round(b[0].block.height / cal._rowPitch()))(cal._blocks.filter(b => b.event.title === "Sport"))')" "1 3"
|
||||||
|
check "Titel läuft über mehrere Zeilen" "$(val '(b => b.block.get_child().get_child_at_index(1).clutter_text.get_layout().get_line_count() > 1)(cal._blocks.find(b => b.event.title === "Sehr langer Termintitel der abgeschnitten wird"))')" "true"
|
||||||
|
weekscroll 3
|
||||||
shot "02-week"
|
shot "02-week"
|
||||||
|
|
||||||
echo "=== Woche: Termin bearbeiten, Escape, Löschen per Rechtsklick"
|
echo "=== Woche: Termin bearbeiten, Escape, Löschen per Rechtsklick"
|
||||||
@@ -82,6 +89,7 @@ rclick 'cal._blocks.find(b => b.event.title === "Sport").block'
|
|||||||
check "Kontextmenü offen" "$(val 'labels(grabbed()).join("|")')" "Löschen"
|
check "Kontextmenü offen" "$(val 'labels(grabbed()).join("|")')" "Löschen"
|
||||||
shot "03-context-menu"
|
shot "03-context-menu"
|
||||||
click 'find(grabbed(), "Löschen")'
|
click 'find(grabbed(), "Löschen")'
|
||||||
|
check "Scrollposition bleibt nach dem Löschen" "$(val 'Math.round(cal._weekScroll.vadjustment.value / cal._rowPitch())')" "3"
|
||||||
check "Termin gelöscht (Tombstone bleibt)" "$(val 'store.events.filter(e => e.title === "Sport").map(e => e.deleted).join(",") + " " + store.eventsOn("2026-09-18").filter(e => e.title === "Sport").length')" "true 0"
|
check "Termin gelöscht (Tombstone bleibt)" "$(val 'store.events.filter(e => e.title === "Sport").map(e => e.deleted).join(",") + " " + store.eventsOn("2026-09-18").filter(e => e.title === "Sport").length')" "true 0"
|
||||||
|
|
||||||
echo "=== Woche: ganztägiger Termin, Klick daneben schließt"
|
echo "=== Woche: ganztägiger Termin, Klick daneben schließt"
|
||||||
@@ -135,7 +143,7 @@ check "Notiz-Datei angelegt" "$(val 'GLib.file_test(store.notesDir + "/Testnotiz
|
|||||||
check "Editor offen mit Fokus" "$(val '[notes._editing, notes._editScroll.visible, global.stage.get_key_focus() === notes._editor.clutter_text].join(" ")')" "true true true"
|
check "Editor offen mit Fokus" "$(val '[notes._editing, notes._editScroll.visible, global.stage.get_key_focus() === notes._editor.clutter_text].join(" ")')" "true true true"
|
||||||
type_ "# Hallo"; key Return; key Return; type_ "Erste **Notiz**"
|
type_ "# Hallo"; key Return; key Return; type_ "Erste **Notiz**"
|
||||||
shot "06-inline-editor"
|
shot "06-inline-editor"
|
||||||
sleep 4
|
sleep 6
|
||||||
check "Autosave nach ein paar Sekunden" "$(val '[notes._editing, JSON.stringify(read(store.notesDir + "/Testnotiz.md"))].join(" ")')" 'true "# Hallo\n\nErste **Notiz**"'
|
check "Autosave nach ein paar Sekunden" "$(val '[notes._editing, JSON.stringify(read(store.notesDir + "/Testnotiz.md"))].join(" ")')" 'true "# Hallo\n\nErste **Notiz**"'
|
||||||
click 'cal._viewButtons.month'
|
click 'cal._viewButtons.month'
|
||||||
check "Fokusverlust beendet den Editor, Anzeige gerendert" "$(val '[notes._editing, notes._viewScroll.visible, notes._content.text].join("|")')" "false|true|Hallo
|
check "Fokusverlust beendet den Editor, Anzeige gerendert" "$(val '[notes._editing, notes._viewScroll.visible, notes._content.text].join("|")')" "false|true|Hallo
|
||||||
@@ -189,6 +197,7 @@ check "Ordner gewählt zeigt nichts" "$(val '[notes._selected.type, JSON.stringi
|
|||||||
|
|
||||||
echo "=== Woche: Rechtsklick, Termin ohne Ende, mehrtägig"
|
echo "=== Woche: Rechtsklick, Termin ohne Ende, mehrtägig"
|
||||||
click 'cal._viewButtons.week'
|
click 'cal._viewButtons.week'
|
||||||
|
weekscroll 7
|
||||||
rclick 'cal._slots[1][9]'
|
rclick 'cal._slots[1][9]'
|
||||||
check "Rechtsklick Stundenzelle" "$(val 'labels(grabbed()).join("|")')" "Termin erstellen|Todo erstellen"
|
check "Rechtsklick Stundenzelle" "$(val 'labels(grabbed()).join("|")')" "Termin erstellen|Todo erstellen"
|
||||||
click 'find(grabbed(), "Todo erstellen")'
|
click 'find(grabbed(), "Todo erstellen")'
|
||||||
|
|||||||
Reference in New Issue
Block a user