diff options
Diffstat (limited to 'desktop/modules/git')
| -rw-r--r-- | desktop/modules/git/GitPage.qml | 229 | ||||
| -rw-r--r-- | desktop/modules/git/README.md | 4 |
2 files changed, 131 insertions, 102 deletions
diff --git a/desktop/modules/git/GitPage.qml b/desktop/modules/git/GitPage.qml index c91f050..6edf085 100644 --- a/desktop/modules/git/GitPage.qml +++ b/desktop/modules/git/GitPage.qml @@ -36,6 +36,20 @@ Column { // the page is closed. Not named `gm`, the module's id (it would bind to itself). required property QtObject owner + // The section whose add row is open, and what is typed in it. The text + // lives here rather than in the fields because every reload rebuilds the + // rows, and a failed add should keep what was typed. + property string adding: "" + property string newKey: "" + property string newValue: "" + onAddingChanged: { newKey = ""; newValue = ""; errors = ({}); } + + function add() { + if (page.newKey.trim() === "") return; + page.write(["add", page.adding + "." + page.newKey.trim(), page.newValue], "add", + () => page.adding = ""); + } + function tag(e) { return e.name + "=" + e.value; } // One Process per call, so reads and writes never share one (a running @@ -98,6 +112,94 @@ Column { font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } } + // The add row under a section's heading: key and value. Enter in the key + // moves to the value, Enter there adds, Escape closes the row. + Component { + id: addRow + Column { + spacing: 4 + + Item { + width: parent.width + height: 34 + + Rectangle { + id: keyBox + anchors.left: parent.left + width: parent.width * 0.32 + height: parent.height + radius: 8 + color: Theme.surface + TextInput { + id: keyIn + anchors { fill: parent; leftMargin: 10; rightMargin: 10 } + verticalAlignment: TextInput.AlignVCenter + clip: true + selectByMouse: true + color: Theme.text + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + text: page.newKey + onTextEdited: page.newKey = text + onAccepted: valIn.forceActiveFocus() + Keys.onEscapePressed: page.adding = "" + Component.onCompleted: forceActiveFocus() + Text { + anchors.verticalCenter: parent.verticalCenter + visible: parent.text === "" + text: "key" + color: Theme.subtext + font: parent.font + } + } + } + + Rectangle { + anchors { left: keyBox.right; leftMargin: 8; right: addBtn.left; rightMargin: 8 } + height: parent.height + radius: 8 + color: Theme.surface + TextInput { + id: valIn + anchors { fill: parent; leftMargin: 10; rightMargin: 10 } + verticalAlignment: TextInput.AlignVCenter + clip: true + selectByMouse: true + color: Theme.text + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + text: page.newValue + onTextEdited: page.newValue = text + onAccepted: page.add() + Keys.onEscapePressed: page.adding = "" + Text { + anchors.verticalCenter: parent.verticalCenter + visible: parent.text === "" + text: "value" + color: Theme.subtext + font: parent.font + } + } + } + + Button { + id: addBtn + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + text: "Add" + enabled: page.newKey.trim() !== "" + onClicked: page.add() + } + } + + Text { + width: parent.width + visible: !!page.errors.add + text: page.errors.add ?? "" + wrapMode: Text.Wrap + color: Theme.red + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + } + } + } + Repeater { model: page.entries @@ -110,14 +212,33 @@ Column { spacing: 4 enabled: !page.busy - // A section's heading, above its first row. - Text { + // A section's heading, above its first row, with + to add a key + // to it. git config --add writes into the existing section, so + // the new key lands with its neighbours in the file. + Item { + id: heading visible: row.index === 0 || page.entries[row.index - 1].section !== row.modelData.section - topPadding: 10 - bottomPadding: 2 - text: row.modelData.section - font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true } - color: Theme.text + width: parent.width + height: 40 + + Text { + anchors { left: parent.left; bottom: parent.bottom; bottomMargin: 6 } + text: row.modelData.section + font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true } + color: Theme.text + } + Button { + anchors { right: parent.right; bottom: parent.bottom; bottomMargin: 2 } + text: "+" + onClicked: page.adding = page.adding === row.modelData.section ? "" : row.modelData.section + } + } + + Loader { + width: parent.width + active: heading.visible && page.adding === row.modelData.section + visible: active + sourceComponent: addRow } // An Item with anchors, not a Row: a Row sizes to its children @@ -183,98 +304,4 @@ Column { } } } - - // Add: section.key and a value. The fields clear only when git took it. - Text { - topPadding: 10 - bottomPadding: 2 - text: "Add" - font { family: Theme.fontFamily; pixelSize: Theme.fontSize; bold: true } - color: Theme.text - } - - Item { - width: parent.width - height: 34 - enabled: !page.busy - - Rectangle { - id: newKeyBox - anchors { left: parent.left } - width: parent.width * 0.32 - height: parent.height - radius: 8 - color: Theme.surface - TextInput { - id: newKey - anchors { fill: parent; leftMargin: 10; rightMargin: 10 } - verticalAlignment: TextInput.AlignVCenter - clip: true - selectByMouse: true - color: Theme.text - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } - // Typed text is cleared first, as a row's edit is undone; - // an empty field lets Escape through, to leave the page. - Keys.onEscapePressed: event => { - if (text !== "") text = ""; - else event.accepted = false; - } - Text { - anchors.verticalCenter: parent.verticalCenter - visible: parent.text === "" - text: "section.key" - color: Theme.subtext - font: parent.font - } - } - } - - Rectangle { - anchors { left: newKeyBox.right; leftMargin: 8; right: addBtn.left; rightMargin: 8 } - height: parent.height - radius: 8 - color: Theme.surface - TextInput { - id: newValue - anchors { fill: parent; leftMargin: 10; rightMargin: 10 } - verticalAlignment: TextInput.AlignVCenter - clip: true - selectByMouse: true - color: Theme.text - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } - // Typed text is cleared first, as a row's edit is undone; - // an empty field lets Escape through, to leave the page. - Keys.onEscapePressed: event => { - if (text !== "") text = ""; - else event.accepted = false; - } - onAccepted: if (addBtn.enabled) addBtn.clicked() - Text { - anchors.verticalCenter: parent.verticalCenter - visible: parent.text === "" - text: "value" - color: Theme.subtext - font: parent.font - } - } - } - - Button { - id: addBtn - anchors { right: parent.right; verticalCenter: parent.verticalCenter } - text: "Add" - enabled: newKey.text.trim() !== "" - onClicked: page.write(["add", newKey.text.trim(), newValue.text], "add", - () => { newKey.text = ""; newValue.text = ""; }) - } - } - - Text { - width: parent.width - visible: !!page.errors.add - text: page.errors.add ?? "" - wrapMode: Text.Wrap - color: Theme.red - font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } - } } diff --git a/desktop/modules/git/README.md b/desktop/modules/git/README.md index e5a4370..65f2a8a 100644 --- a/desktop/modules/git/README.md +++ b/desktop/modules/git/README.md @@ -5,7 +5,9 @@ page's "More git settings" button. Back returns to the user page. One row per value, grouped by section in file order, so a key set several times shows several rows. Enter saves a row, Escape undoes an edit, Remove -drops that one value, and the Add row takes `section.key` and a value. +drops that one value, and `+` beside a section's heading adds a key to +that section, where `git config --add` writes it among its neighbours. A +new section is made in the editor. "Edit in editor" opens the file in Sublime Text. `gitcfg` does every read and write, through `git config`, so the file keeps |
