mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-11-01 13:13:21 -07:00
Merge branch 'release/v8.26'
This commit is contained in:
commit
f3d56ffb20
85 changed files with 2280 additions and 1793 deletions
146
.github/workflows/ci.yml
vendored
146
.github/workflows/ci.yml
vendored
|
@ -1,117 +1,45 @@
|
||||||
name: Continuous Integration
|
name: Continuous Integration
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: [develop]
|
||||||
- develop
|
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [develop]
|
branches: [develop]
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
workflow_call:
|
||||||
jobs:
|
jobs:
|
||||||
build-windows:
|
build:
|
||||||
name: Build Windows x64
|
strategy:
|
||||||
runs-on: windows-2019
|
matrix:
|
||||||
|
include:
|
||||||
|
- name : Windows x64
|
||||||
|
os: windows-2019
|
||||||
|
runtime: win-x64
|
||||||
|
- name : Windows ARM64
|
||||||
|
os: windows-2019
|
||||||
|
runtime: win-arm64
|
||||||
|
- name : macOS (Intel)
|
||||||
|
os: macos-13
|
||||||
|
runtime: osx-x64
|
||||||
|
- name : macOS (Apple Silicon)
|
||||||
|
os: macos-latest
|
||||||
|
runtime: osx-arm64
|
||||||
|
- name : Linux
|
||||||
|
os: ubuntu-20.04
|
||||||
|
runtime: linux-x64
|
||||||
|
- name : Linux (arm64)
|
||||||
|
os: ubuntu-20.04
|
||||||
|
runtime: linux-arm64
|
||||||
|
name: Build ${{ matrix.name }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup .NET
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.0.x
|
|
||||||
- name: Build
|
|
||||||
run: dotnet build -c Release
|
|
||||||
- name: Publish
|
|
||||||
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r win-x64
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: sourcegit.win-x64
|
|
||||||
path: publish
|
|
||||||
build-macos-intel:
|
|
||||||
name: Build macOS (Intel)
|
|
||||||
runs-on: macos-13
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup .NET
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.0.x
|
|
||||||
- name: Build
|
|
||||||
run: dotnet build -c Release
|
|
||||||
- name: Publish
|
|
||||||
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r osx-x64
|
|
||||||
- name: Packing Program
|
|
||||||
run: tar -cvf sourcegit.osx-x64.tar -C publish/ .
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: sourcegit.osx-x64
|
|
||||||
path: sourcegit.osx-x64.tar
|
|
||||||
build-macos-arm64:
|
|
||||||
name: Build macOS (Apple Silicon)
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup .NET
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.0.x
|
|
||||||
- name: Build
|
|
||||||
run: dotnet build -c Release
|
|
||||||
- name: Publish
|
|
||||||
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r osx-arm64
|
|
||||||
- name: Packing Program
|
|
||||||
run: tar -cvf sourcegit.osx-arm64.tar -C publish/ .
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: sourcegit.osx-arm64
|
|
||||||
path: sourcegit.osx-arm64.tar
|
|
||||||
build-linux:
|
|
||||||
name: Build Linux
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup .NET
|
|
||||||
uses: actions/setup-dotnet@v4
|
|
||||||
with:
|
|
||||||
dotnet-version: 8.0.x
|
|
||||||
- name: Build
|
|
||||||
run: dotnet build -c Release
|
|
||||||
- name: Publish
|
|
||||||
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r linux-x64
|
|
||||||
- name: Rename Executable File
|
|
||||||
run: mv publish/SourceGit publish/sourcegit
|
|
||||||
- name: Packing Program
|
|
||||||
run: tar -cvf sourcegit.linux-x64.tar -C publish/ .
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: sourcegit.linux-x64
|
|
||||||
path: sourcegit.linux-x64.tar
|
|
||||||
build-linux-arm64:
|
|
||||||
name: Build Linux (arm64)
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout sources
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.x
|
||||||
- name: Configure arm64 packages
|
- name: Configure arm64 packages
|
||||||
|
if: ${{ matrix.runtime == 'linux-arm64' }}
|
||||||
run: |
|
run: |
|
||||||
sudo dpkg --add-architecture arm64
|
sudo dpkg --add-architecture arm64
|
||||||
echo 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ focal main restricted
|
echo 'deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ focal main restricted
|
||||||
|
@ -121,19 +49,25 @@ jobs:
|
||||||
sudo sed -i -e 's/^deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
|
sudo sed -i -e 's/^deb http/deb [arch=amd64] http/g' /etc/apt/sources.list
|
||||||
sudo sed -i -e 's/^deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
|
sudo sed -i -e 's/^deb mirror/deb [arch=amd64] mirror/g' /etc/apt/sources.list
|
||||||
- name: Install cross-compiling dependencies
|
- name: Install cross-compiling dependencies
|
||||||
|
if: ${{ matrix.runtime == 'linux-arm64' }}
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install clang llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64
|
sudo apt-get install clang llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64
|
||||||
- name: Build
|
- name: Build
|
||||||
run: dotnet build -c Release
|
run: dotnet build -c Release
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r linux-arm64
|
run: dotnet publish src/SourceGit.csproj -c Release -o publish -r ${{ matrix.runtime }}
|
||||||
- name: Rename Executable File
|
- name: Rename executable file
|
||||||
|
if: ${{ startsWith(matrix.runtime, 'linux-') }}
|
||||||
run: mv publish/SourceGit publish/sourcegit
|
run: mv publish/SourceGit publish/sourcegit
|
||||||
- name: Packing Program
|
- name: Tar artifact
|
||||||
run: tar -cvf sourcegit.linux-arm64.tar -C publish/ .
|
if: ${{ startsWith(matrix.runtime, 'linux-') }}
|
||||||
- name: Upload Artifact
|
run: |
|
||||||
|
tar -cvf "sourcegit.${{ matrix.runtime }}.tar" -C publish .
|
||||||
|
rm -r publish/*
|
||||||
|
mv "sourcegit.${{ matrix.runtime }}.tar" publish
|
||||||
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: sourcegit.linux-arm64
|
name: sourcegit.${{ matrix.runtime }}
|
||||||
path: sourcegit.linux-arm64.tar
|
path: publish
|
||||||
|
|
98
.github/workflows/package.yml
vendored
Normal file
98
.github/workflows/package.yml
vendored
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
name: Package
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: Source Git package version
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
uses: ./.github/workflows/ci.yml
|
||||||
|
windows-portable:
|
||||||
|
name: Package portable Windows app
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
runtime: [win-x64, win-arm64]
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Download build
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: sourcegit.${{ matrix.runtime }}
|
||||||
|
path: build/SourceGit
|
||||||
|
- name: Package
|
||||||
|
env:
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
RUNTIME: ${{ matrix.runtime }}
|
||||||
|
run: ./build/scripts/package.windows-portable.sh
|
||||||
|
- name: Upload package artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: package.${{ matrix.runtime }}
|
||||||
|
path: build/sourcegit_*.zip
|
||||||
|
osx-app:
|
||||||
|
name: Package OSX app
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
runtime: [osx-x64, osx-arm64]
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Download build
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: sourcegit.${{ matrix.runtime }}
|
||||||
|
path: build/SourceGit
|
||||||
|
- name: Package
|
||||||
|
env:
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
RUNTIME: ${{ matrix.runtime }}
|
||||||
|
run: ./build/scripts/package.osx-app.sh
|
||||||
|
- name: Upload package artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: package.${{ matrix.runtime }}
|
||||||
|
path: build/sourcegit_*.zip
|
||||||
|
linux:
|
||||||
|
name: Package Linux
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
runtime: [linux-x64, linux-arm64]
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Download package dependencies
|
||||||
|
run: |
|
||||||
|
sudo add-apt-repository universe
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install desktop-file-utils rpm libfuse2
|
||||||
|
- name: Download build
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: sourcegit.${{ matrix.runtime }}
|
||||||
|
path: build
|
||||||
|
- name: Package
|
||||||
|
env:
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
RUNTIME: ${{ matrix.runtime }}
|
||||||
|
run: |
|
||||||
|
mkdir build/SourceGit
|
||||||
|
tar -xf "build/sourcegit.${{ matrix.runtime }}.tar" -C build/SourceGit
|
||||||
|
./build/scripts/package.linux.sh
|
||||||
|
- name: Upload package artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: package.${{ matrix.runtime }}
|
||||||
|
path: |
|
||||||
|
build/sourcegit-*.AppImage
|
||||||
|
build/sourcegit_*.deb
|
||||||
|
build/sourcegit-*.rpm
|
49
.github/workflows/release.yml
vendored
Normal file
49
.github/workflows/release.yml
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
name: Release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
jobs:
|
||||||
|
version:
|
||||||
|
name: Prepare version string
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.version.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Output version string
|
||||||
|
id: version
|
||||||
|
env:
|
||||||
|
TAG: ${{ github.ref_name }}
|
||||||
|
run: echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"
|
||||||
|
package:
|
||||||
|
needs: version
|
||||||
|
name: Package
|
||||||
|
uses: ./.github/workflows/package.yml
|
||||||
|
with:
|
||||||
|
version: ${{ needs.version.outputs.version }}
|
||||||
|
release:
|
||||||
|
needs: [version, package]
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Create release
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAG: ${{ github.ref_name }}
|
||||||
|
run: gh release create "$TAG" -t "Release ${TAG#v}" --notes-from-tag
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: package.*
|
||||||
|
path: packages
|
||||||
|
merge-multiple: true
|
||||||
|
- name: Upload assets
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAG: ${{ github.ref_name }}
|
||||||
|
VERSION: ${{ needs.version.outputs.version }}
|
||||||
|
run: gh release upload "$TAG" packages/*
|
41
README.md
41
README.md
|
@ -35,6 +35,7 @@ Opensource Git GUI client.
|
||||||
* Git LFS
|
* Git LFS
|
||||||
* Issue Link
|
* Issue Link
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
|
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
|
||||||
|
|
||||||
## How to Use
|
## How to Use
|
||||||
|
@ -46,11 +47,14 @@ You can download the latest stable from [Releases](https://github.com/sourcegit-
|
||||||
This software creates a folder `$"{System.Environment.SpecialFolder.ApplicationData}/SourceGit"`, which is platform-dependent, to store user settings, downloaded avatars and crash logs.
|
This software creates a folder `$"{System.Environment.SpecialFolder.ApplicationData}/SourceGit"`, which is platform-dependent, to store user settings, downloaded avatars and crash logs.
|
||||||
|
|
||||||
| OS | PATH |
|
| OS | PATH |
|
||||||
|---------|-------------------------------------------------|
|
|---------|-----------------------------------------------------|
|
||||||
| Windows | `C:\Users\USER_NAME\AppData\Roaming\SourceGit` |
|
| Windows | `C:\Users\USER_NAME\AppData\Roaming\SourceGit` |
|
||||||
| Linux | `${HOME}/.config/SourceGit` |
|
| Linux | `${HOME}/.config/SourceGit` or `${HOME}/.sourcegit` |
|
||||||
| macOS | `${HOME}/Library/Application Support/SourceGit` |
|
| macOS | `${HOME}/Library/Application Support/SourceGit` |
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> You can open the app data dir from the main menu.
|
||||||
|
|
||||||
For **Windows** users:
|
For **Windows** users:
|
||||||
|
|
||||||
* **MSYS Git is NOT supported**. Please use official [Git for Windows](https://git-scm.com/download/win) instead.
|
* **MSYS Git is NOT supported**. Please use official [Git for Windows](https://git-scm.com/download/win) instead.
|
||||||
|
@ -58,7 +62,8 @@ For **Windows** users:
|
||||||
```shell
|
```shell
|
||||||
winget install SourceGit
|
winget install SourceGit
|
||||||
```
|
```
|
||||||
> `winget` will install this software as a commandline tool. You need run `SourceGit` from console or `Win+R` at the first time. Then you can add it to the taskbar.
|
> [!NOTE]
|
||||||
|
> `winget` will install this software as a commandline tool. You need run `SourceGit` from console or `Win+R` at the first time. Then you can add it to the taskbar.
|
||||||
* You can install the latest stable by `scoope` with follow commands:
|
* You can install the latest stable by `scoope` with follow commands:
|
||||||
```shell
|
```shell
|
||||||
scoop bucket add extras
|
scoop bucket add extras
|
||||||
|
@ -84,17 +89,27 @@ For **Linux** users:
|
||||||
|
|
||||||
This app supports open repository in external tools listed in the table below.
|
This app supports open repository in external tools listed in the table below.
|
||||||
|
|
||||||
| Tool | Windows | macOS | Linux | Environment Variable |
|
| Tool | Windows | macOS | Linux | KEY IN `external_editors.json` |
|
||||||
|-------------------------------|---------|-------|-------|----------------------|
|
|-------------------------------|---------|-------|-------|--------------------------------|
|
||||||
| Visual Studio Code | YES | YES | YES | VSCODE_PATH |
|
| Visual Studio Code | YES | YES | YES | VSCODE |
|
||||||
| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS_PATH |
|
| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS |
|
||||||
| VSCodium | YES | YES | YES | VSCODIUM_PATH |
|
| VSCodium | YES | YES | YES | VSCODIUM |
|
||||||
| JetBrains Fleet | YES | YES | YES | FLEET_PATH |
|
| JetBrains Fleet | YES | YES | YES | FLEET |
|
||||||
| Sublime Text | YES | YES | YES | SUBLIME_TEXT_PATH |
|
| Sublime Text | YES | YES | YES | SUBLIME_TEXT |
|
||||||
|
|
||||||
* You can set the given environment variable for special tool if it can NOT be found by this app automatically.
|
> [!NOTE]
|
||||||
* Installing `JetBrains Toolbox` will help this app to find other JetBrains tools installed on your device.
|
> This app will try to find those tools based on some pre-defined or expected locations automatically. If you are using one portable version of these tools, it will not be detected by this app.
|
||||||
* On macOS, you may need to use `launchctl setenv` to make sure the app can read these environment variables.
|
> To solve this problem you can add a file named `external_editors.json` in app data dir and provide the path directly. For example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tools": {
|
||||||
|
"VSCODE": "D:\\VSCode\\Code.exe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This app also supports a lot of `JetBrains` IDEs, installing `JetBrains Toolbox` will help this app to find them.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,6 @@ MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGit", "src\SourceGit.csproj", "{2091C34D-4A17-4375-BEF3-4D60BE8113E4}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SourceGit", "src\SourceGit.csproj", "{2091C34D-4A17-4375-BEF3-4D60BE8113E4}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{773082AC-D9C8-4186-8521-4B6A7BEE6158}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{773082AC-D9C8-4186-8521-4B6A7BEE6158}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
build\build.linux.sh = build\build.linux.sh
|
|
||||||
build\build.osx.command = build\build.osx.command
|
|
||||||
build\build.windows.ps1 = build\build.windows.ps1
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resources", "resources", "{FD384607-ED99-47B7-AF31-FB245841BC92}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resources", "resources", "{FD384607-ED99-47B7-AF31-FB245841BC92}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -19,6 +14,8 @@ EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67B6D05F-A000-40BA-ADB4-C9065F880D7B}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67B6D05F-A000-40BA-ADB4-C9065F880D7B}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.github\workflows\ci.yml = .github\workflows\ci.yml
|
.github\workflows\ci.yml = .github\workflows\ci.yml
|
||||||
|
.github\workflows\package.yml = .github\workflows\package.yml
|
||||||
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}"
|
||||||
|
@ -77,13 +74,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SPECS", "SPECS", "{7802CD7A
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "appimage", "appimage", "{5D125DD9-B48A-491F-B2FB-D7830D74C4DC}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "appimage", "appimage", "{5D125DD9-B48A-491F-B2FB-D7830D74C4DC}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
build\resources\appimage\publish-appimage = build\resources\appimage\publish-appimage
|
|
||||||
build\resources\appimage\publish-appimage.conf = build\resources\appimage\publish-appimage.conf
|
|
||||||
build\resources\appimage\runtime-x86_64 = build\resources\appimage\runtime-x86_64
|
|
||||||
build\resources\appimage\sourcegit.appdata.xml = build\resources\appimage\sourcegit.appdata.xml
|
build\resources\appimage\sourcegit.appdata.xml = build\resources\appimage\sourcegit.appdata.xml
|
||||||
build\resources\appimage\sourcegit.png = build\resources\appimage\sourcegit.png
|
build\resources\appimage\sourcegit.png = build\resources\appimage\sourcegit.png
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{C54D4001-9940-477C-A0B6-E795ED0A3209}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
build\scripts\package.linux.sh = build\scripts\package.linux.sh
|
||||||
|
build\scripts\package.osx-app.sh = build\scripts\package.osx-app.sh
|
||||||
|
build\scripts\package.windows-portable.sh = build\scripts\package.windows-portable.sh
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -114,6 +115,7 @@ Global
|
||||||
{9BA0B044-0CC9-46F8-B551-204F149BF45D} = {FD384607-ED99-47B7-AF31-FB245841BC92}
|
{9BA0B044-0CC9-46F8-B551-204F149BF45D} = {FD384607-ED99-47B7-AF31-FB245841BC92}
|
||||||
{7802CD7A-591B-4EDD-96F8-9BF3F61692E4} = {9BA0B044-0CC9-46F8-B551-204F149BF45D}
|
{7802CD7A-591B-4EDD-96F8-9BF3F61692E4} = {9BA0B044-0CC9-46F8-B551-204F149BF45D}
|
||||||
{5D125DD9-B48A-491F-B2FB-D7830D74C4DC} = {FD384607-ED99-47B7-AF31-FB245841BC92}
|
{5D125DD9-B48A-491F-B2FB-D7830D74C4DC} = {FD384607-ED99-47B7-AF31-FB245841BC92}
|
||||||
|
{C54D4001-9940-477C-A0B6-E795ED0A3209} = {773082AC-D9C8-4186-8521-4B6A7BEE6158}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {7FF1B9C6-B5BF-4A50-949F-4B407A0E31C9}
|
SolutionGuid = {7FF1B9C6-B5BF-4A50-949F-4B407A0E31C9}
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
8.25
|
8.26
|
|
@ -1,32 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
version=`cat ../VERSION`
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
rm -rf SourceGit *.tar.gz resources/deb/opt *.deb *.rpm *.AppImage
|
|
||||||
|
|
||||||
# Generic AppImage
|
|
||||||
cd resources/appimage
|
|
||||||
./publish-appimage -y -o sourcegit-${version}.linux.x86_64.AppImage
|
|
||||||
|
|
||||||
# Move to build dir
|
|
||||||
mv AppImages/sourcegit-${version}.linux.x86_64.AppImage ../../
|
|
||||||
mv AppImages/AppDir/usr/bin ../../SourceGit
|
|
||||||
cd ../../
|
|
||||||
|
|
||||||
# Debain/Ubuntu package
|
|
||||||
mkdir -p resources/deb/opt/sourcegit/
|
|
||||||
mkdir -p resources/deb/usr/share/applications
|
|
||||||
mkdir -p resources/deb/usr/share/icons
|
|
||||||
cp -f SourceGit/* resources/deb/opt/sourcegit/
|
|
||||||
cp -r resources/_common/applications resources/deb/usr/share/
|
|
||||||
cp -r resources/_common/icons resources/deb/usr/share/
|
|
||||||
chmod +x -R resources/deb/opt/sourcegit
|
|
||||||
sed -i "2s/.*/Version: ${version}/g" resources/deb/DEBIAN/control
|
|
||||||
dpkg-deb --build resources/deb ./sourcegit_${version}-1_amd64.deb
|
|
||||||
|
|
||||||
# Redhat/CentOS/Fedora package
|
|
||||||
rpmbuild -bb --target=x86_64 resources/rpm/SPECS/build.spec --define "_topdir `pwd`/resources/rpm" --define "_version ${version}"
|
|
||||||
mv resources/rpm/RPMS/x86_64/sourcegit-${version}-1.x86_64.rpm .
|
|
||||||
|
|
||||||
rm -rf SourceGit
|
|
|
@ -1,21 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
version=`cat ../VERSION`
|
|
||||||
|
|
||||||
rm -rf SourceGit.app *.zip
|
|
||||||
|
|
||||||
mkdir -p SourceGit.app/Contents/Resources
|
|
||||||
cp resources/app/App.icns SourceGit.app/Contents/Resources/App.icns
|
|
||||||
sed "s/SOURCE_GIT_VERSION/${version}/g" resources/app/App.plist > SourceGit.app/Contents/Info.plist
|
|
||||||
|
|
||||||
mkdir -p SourceGit.app/Contents/MacOS
|
|
||||||
dotnet publish ../src/SourceGit.csproj -c Release -r osx-arm64 -o SourceGit.app/Contents/MacOS
|
|
||||||
zip sourcegit_${version}.osx-arm64.zip -r SourceGit.app -x "*/*\.dsym/*"
|
|
||||||
|
|
||||||
rm -rf SourceGit.app/Contents/MacOS
|
|
||||||
|
|
||||||
mkdir -p SourceGit.app/Contents/MacOS
|
|
||||||
dotnet publish ../src/SourceGit.csproj -c Release -r osx-x64 -o SourceGit.app/Contents/MacOS
|
|
||||||
zip sourcegit_${version}.osx-x64.zip -r SourceGit.app -x "*/*\.dsym/*"
|
|
||||||
|
|
||||||
rm -rf SourceGit.app
|
|
|
@ -1,23 +0,0 @@
|
||||||
$version = Get-Content ..\VERSION
|
|
||||||
|
|
||||||
if (Test-Path SourceGit) {
|
|
||||||
Remove-Item SourceGit -Recurse -Force
|
|
||||||
}
|
|
||||||
|
|
||||||
Remove-Item *.zip -Force
|
|
||||||
|
|
||||||
dotnet publish ..\src\SourceGit.csproj -c Release -r win-arm64 -o SourceGit
|
|
||||||
|
|
||||||
Remove-Item SourceGit\*.pdb -Force
|
|
||||||
|
|
||||||
Compress-Archive -Path SourceGit -DestinationPath "sourcegit_$version.win-arm64.zip"
|
|
||||||
|
|
||||||
if (Test-Path SourceGit) {
|
|
||||||
Remove-Item SourceGit -Recurse -Force
|
|
||||||
}
|
|
||||||
|
|
||||||
dotnet publish ..\src\SourceGit.csproj -c Release -r win-x64 -o SourceGit
|
|
||||||
|
|
||||||
Remove-Item SourceGit\*.pdb -Force
|
|
||||||
|
|
||||||
Compress-Archive -Path SourceGit -DestinationPath "sourcegit_$version.win-x64.zip"
|
|
|
@ -1,708 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
################################################################################
|
|
||||||
# PROJECT : Publish-AppImage for .NET
|
|
||||||
# WEBPAGE : https://github.com/kuiperzone/Publish-AppImage
|
|
||||||
# COPYRIGHT : Andy Thomas 2021-2023
|
|
||||||
# LICENSE : MIT
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# CONSTANTS
|
|
||||||
###############################
|
|
||||||
|
|
||||||
declare -r _SCRIPT_VERSION="1.3.1"
|
|
||||||
declare -r _SCRIPT_TITLE="Publish-AppImage for .NET"
|
|
||||||
declare -r _SCRIPT_IMPL_MIN=1
|
|
||||||
declare -r _SCRIPT_IMPL_MAX=1
|
|
||||||
declare -r _SCRIPT_COPYRIGHT="Copyright 2023 Andy Thomas"
|
|
||||||
declare -r _SCRIPT_WEBSITE="https://github.com/kuiperzone/Publish-AppImage"
|
|
||||||
|
|
||||||
declare -r _SCRIPT_NAME="publish-appimage"
|
|
||||||
declare -r _DEFAULT_CONF="${_SCRIPT_NAME}.conf"
|
|
||||||
|
|
||||||
declare -r _APPIMAGE_KIND="appimage"
|
|
||||||
declare -r _ZIP_KIND="zip"
|
|
||||||
declare -r _DOTNET_NONE="null"
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# FUNCTIONS
|
|
||||||
###############################
|
|
||||||
|
|
||||||
function assert_result
|
|
||||||
{
|
|
||||||
local _ret=$?
|
|
||||||
|
|
||||||
if [ ${_ret} -ne 0 ]; then
|
|
||||||
echo
|
|
||||||
exit ${_ret}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function exec_or_die
|
|
||||||
{
|
|
||||||
echo "${1}"
|
|
||||||
eval "${1}"
|
|
||||||
assert_result
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensure_directory
|
|
||||||
{
|
|
||||||
local _path="${1}"
|
|
||||||
|
|
||||||
if [ ! -d "${_path}" ]; then
|
|
||||||
mkdir -p "${_path}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove_path
|
|
||||||
{
|
|
||||||
local _path="${1}"
|
|
||||||
|
|
||||||
if [ -d "${_path}" ]; then
|
|
||||||
rm -rf "${_path}"
|
|
||||||
assert_result
|
|
||||||
elif [ -f "${_path}" ]; then
|
|
||||||
rm -f "${_path}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_mandatory
|
|
||||||
{
|
|
||||||
local _name="${1}"
|
|
||||||
local _value="${2}"
|
|
||||||
|
|
||||||
if [ "${_value}" == "" ]; then
|
|
||||||
echo "${_name} undefined in: ${_conf_arg_value}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function assert_opt_file
|
|
||||||
{
|
|
||||||
local _name="${1}"
|
|
||||||
local _value="${2}"
|
|
||||||
|
|
||||||
if [ "${_value}" != "" ] && [ ! -f "${_value}" ]; then
|
|
||||||
echo "File not found: ${_value}"
|
|
||||||
|
|
||||||
if [ "${_name}" != "" ]; then
|
|
||||||
echo "See ${_name} in: ${_conf_arg_value}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# HANDLE ARGUMENTS
|
|
||||||
###############################
|
|
||||||
|
|
||||||
# Specify conf file
|
|
||||||
declare -r _CONF_ARG="f"
|
|
||||||
declare -r _CONF_ARG_NAME="conf"
|
|
||||||
_conf_arg_value="${_DEFAULT_CONF}"
|
|
||||||
_arg_syntax=":${_CONF_ARG}:"
|
|
||||||
|
|
||||||
# Runtime ID
|
|
||||||
declare -r _RID_ARG="r"
|
|
||||||
declare -r _RID_ARG_NAME="runtime"
|
|
||||||
_rid_arg_value="linux-x64"
|
|
||||||
_arg_syntax="${_arg_syntax}${_RID_ARG}:"
|
|
||||||
|
|
||||||
# Package kind
|
|
||||||
declare -r _KIND_ARG="k"
|
|
||||||
declare -r _KIND_ARG_NAME="kind"
|
|
||||||
declare -l _kind_arg_value="${_APPIMAGE_KIND}"
|
|
||||||
_arg_syntax="${_arg_syntax}${_KIND_ARG}:"
|
|
||||||
|
|
||||||
# Run app
|
|
||||||
declare -r _RUNAPP_ARG="u"
|
|
||||||
declare -r _RUNAPP_ARG_NAME="run"
|
|
||||||
_runapp_arg_value=false
|
|
||||||
_arg_syntax="${_arg_syntax}${_RUNAPP_ARG}"
|
|
||||||
|
|
||||||
# Verbose
|
|
||||||
declare -r _VERBOSE_ARG="b"
|
|
||||||
declare -r _VERBOSE_ARG_NAME="verbose"
|
|
||||||
_verbose_arg_value=false
|
|
||||||
_arg_syntax="${_arg_syntax}${_VERBOSE_ARG}"
|
|
||||||
|
|
||||||
# Skip yes (no prompt)
|
|
||||||
declare -r _SKIPYES_ARG="y"
|
|
||||||
declare -r _SKIPYES_ARG_NAME="skip-yes"
|
|
||||||
_skipyes_arg_value=false
|
|
||||||
_arg_syntax="${_arg_syntax}${_SKIPYES_ARG}"
|
|
||||||
|
|
||||||
# Output name
|
|
||||||
declare -r _OUTPUT_ARG="o"
|
|
||||||
declare -r _OUTPUT_ARG_NAME="output"
|
|
||||||
_output_arg_value=""
|
|
||||||
_arg_syntax="${_arg_syntax}${_OUTPUT_ARG}:"
|
|
||||||
|
|
||||||
# Show version
|
|
||||||
declare -r _VERSION_ARG="v"
|
|
||||||
declare -r _VERSION_ARG_NAME="version"
|
|
||||||
_version_arg_value=false
|
|
||||||
_arg_syntax="${_arg_syntax}${_VERSION_ARG}"
|
|
||||||
|
|
||||||
# Show help
|
|
||||||
declare -r _HELP_ARG="h"
|
|
||||||
declare -r _HELP_ARG_NAME="help"
|
|
||||||
_help_arg_value=false
|
|
||||||
_arg_syntax="${_arg_syntax}${_HELP_ARG}"
|
|
||||||
|
|
||||||
_exit_help=0
|
|
||||||
|
|
||||||
# Transform long options to short ones
|
|
||||||
for arg in "${@}"; do
|
|
||||||
shift
|
|
||||||
case "${arg}" in
|
|
||||||
("--${_CONF_ARG_NAME}") set -- "$@" "-${_CONF_ARG}" ;;
|
|
||||||
("--${_RID_ARG_NAME}") set -- "$@" "-${_RID_ARG}" ;;
|
|
||||||
("--${_KIND_ARG_NAME}") set -- "$@" "-${_KIND_ARG}" ;;
|
|
||||||
("--${_RUNAPP_NAME}") set -- "$@" "-${_RUNAPP_ARG}" ;;
|
|
||||||
("--${_VERBOSE_ARG_NAME}") set -- "$@" "-${_VERBOSE_ARG}" ;;
|
|
||||||
("--${_SKIPYES_ARG_NAME}") set -- "$@" "-${_SKIPYES_ARG}" ;;
|
|
||||||
("--${_OUTPUT_ARG_NAME}") set -- "$@" "-${_OUTPUT_ARG}" ;;
|
|
||||||
("--${_VERSION_ARG_NAME}") set -- "$@" "-${_VERSION_ARG}" ;;
|
|
||||||
("--${_HELP_ARG_NAME}") set -- "$@" "-${_HELP_ARG}" ;;
|
|
||||||
("--"*)
|
|
||||||
echo "Illegal argument: ${arg}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
_exit_help=1
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
(*) set -- "$@" "${arg}" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ ${_exit_help} == 0 ]; then
|
|
||||||
# Read arguments
|
|
||||||
while getopts ${_arg_syntax} arg; do
|
|
||||||
case "${arg}" in
|
|
||||||
(${_CONF_ARG}) _conf_arg_value="${OPTARG}" ;;
|
|
||||||
(${_RID_ARG}) _rid_arg_value="${OPTARG}" ;;
|
|
||||||
(${_KIND_ARG}) _kind_arg_value="${OPTARG}" ;;
|
|
||||||
(${_RUNAPP_ARG}) _runapp_arg_value=true ;;
|
|
||||||
(${_VERBOSE_ARG}) _verbose_arg_value=true ;;
|
|
||||||
(${_SKIPYES_ARG}) _skipyes_arg_value=true ;;
|
|
||||||
(${_OUTPUT_ARG}) _output_arg_value="${OPTARG}" ;;
|
|
||||||
(${_VERSION_ARG}) _version_arg_value=true ;;
|
|
||||||
(${_HELP_ARG}) _help_arg_value=true ;;
|
|
||||||
(*)
|
|
||||||
echo "Illegal argument"
|
|
||||||
echo
|
|
||||||
|
|
||||||
_exit_help=1
|
|
||||||
break
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle and help and version
|
|
||||||
if [ ${_help_arg_value} == true ] || [ $_exit_help != 0 ]; then
|
|
||||||
|
|
||||||
_indent=" "
|
|
||||||
echo "Usage:"
|
|
||||||
echo "${_indent}${_SCRIPT_NAME} [-flags] [-option-n value-n]"
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "Help Options:"
|
|
||||||
echo "${_indent}-${_HELP_ARG}, --${_HELP_ARG_NAME}"
|
|
||||||
echo "${_indent}Show help information flag."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_VERSION_ARG}, --${_VERSION_ARG_NAME}"
|
|
||||||
echo "${_indent}Show version and about information flag."
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "Build Options:"
|
|
||||||
echo "${_indent}-${_CONF_ARG}, --${_CONF_ARG_NAME} value"
|
|
||||||
echo "${_indent}Specifies the conf file. Defaults to ${_SCRIPT_NAME}.conf."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_RID_ARG}, --${_RID_ARG_NAME} value"
|
|
||||||
echo "${_indent}Dotnet publish runtime identifier. Valid examples include:"
|
|
||||||
echo "${_indent}linux-x64 and linux-arm64. Default is linux-x64 if unspecified."
|
|
||||||
echo "${_indent}See also: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog"
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_KIND_ARG}, --${_KIND_ARG_NAME} value"
|
|
||||||
echo "${_indent}Package output kind. Value must be one of: ${_APPIMAGE_KIND} or ${_ZIP_KIND}."
|
|
||||||
echo "${_indent}Default is ${_APPIMAGE_KIND} if unspecified."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_VERBOSE_ARG}, --${_VERBOSE_ARG_NAME}"
|
|
||||||
echo "${_indent}Verbose review info output flag."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_RUNAPP_ARG}, --${_RUNAPP_ARG_NAME}"
|
|
||||||
echo "${_indent}Run the application after successful build flag."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_SKIPYES_ARG}, --${_SKIPYES_ARG_NAME}"
|
|
||||||
echo "${_indent}Skip confirmation prompt flag (assumes yes)."
|
|
||||||
echo
|
|
||||||
echo "${_indent}-${_OUTPUT_ARG}, --${_OUTPUT_ARG_NAME}"
|
|
||||||
echo "${_indent}Explicit final output filename (excluding directory part)."
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "Example:"
|
|
||||||
echo "${_indent}${_SCRIPT_NAME} -${_RID_ARG} linux-arm64"
|
|
||||||
echo
|
|
||||||
|
|
||||||
exit $_exit_help
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${_version_arg_value} == true ]; then
|
|
||||||
echo
|
|
||||||
echo "${_SCRIPT_TITLE}, ${_SCRIPT_VERSION}"
|
|
||||||
echo "${_SCRIPT_COPYRIGHT}"
|
|
||||||
echo "${_SCRIPT_WEBSITE}"
|
|
||||||
echo
|
|
||||||
echo "MIT License"
|
|
||||||
echo
|
|
||||||
echo "Permission is hereby granted, free of charge, to any person obtaining a copy"
|
|
||||||
echo "of this software and associated documentation files (the "Software"), to deal"
|
|
||||||
echo "in the Software without restriction, including without limitation the rights"
|
|
||||||
echo "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell"
|
|
||||||
echo "copies of the Software, and to permit persons to whom the Software is"
|
|
||||||
echo "furnished to do so, subject to the following conditions:"
|
|
||||||
echo
|
|
||||||
echo "The above copyright notice and this permission notice shall be included in all"
|
|
||||||
echo "copies or substantial portions of the Software."
|
|
||||||
echo
|
|
||||||
echo "THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR"
|
|
||||||
echo "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,"
|
|
||||||
echo "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE"
|
|
||||||
echo "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER"
|
|
||||||
echo "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,"
|
|
||||||
echo "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE"
|
|
||||||
echo "SOFTWARE."
|
|
||||||
echo
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# SOURCE & WORKING
|
|
||||||
###############################
|
|
||||||
|
|
||||||
# Export these now as may be
|
|
||||||
# useful in an advanced config file
|
|
||||||
export DOTNET_RID="${_rid_arg_value}"
|
|
||||||
export PKG_KIND="${_kind_arg_value}"
|
|
||||||
export ISO_DATE=`date +"%Y-%m-%d"`
|
|
||||||
|
|
||||||
if [ ! -f "${_conf_arg_value}" ]; then
|
|
||||||
echo "Configuration file not found: ${_conf_arg_value}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Export contents to any post publish command
|
|
||||||
set -a
|
|
||||||
|
|
||||||
# Source local to PWD
|
|
||||||
source "${_conf_arg_value}"
|
|
||||||
set +a
|
|
||||||
|
|
||||||
# For AppImage tool and backward compatibility
|
|
||||||
export VERSION="${APP_VERSION}"
|
|
||||||
|
|
||||||
|
|
||||||
# Then change PWD to conf file
|
|
||||||
cd "$(dirname "${_conf_arg_value}")"
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# SANITY
|
|
||||||
###############################
|
|
||||||
|
|
||||||
if (( ${CONF_IMPL_VERSION} < ${_SCRIPT_IMPL_MIN} )) || (( ${CONF_IMPL_VERSION} > ${_SCRIPT_IMPL_MAX} )); then
|
|
||||||
echo "Configuration format version ${_SCRIPT_IMPL_VERSION} not compatible"
|
|
||||||
echo "Older conf file but newer ${_SCRIPT_NAME} implementation?"
|
|
||||||
echo "Update from: ${_SCRIPT_WEBSITE}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
assert_mandatory "APP_MAIN" "${APP_MAIN}"
|
|
||||||
assert_mandatory "APP_ID" "${APP_ID}"
|
|
||||||
assert_mandatory "APP_ICON_SRC" "${APP_ICON_SRC}"
|
|
||||||
assert_mandatory "DE_NAME" "${DE_NAME}"
|
|
||||||
assert_mandatory "DE_CATEGORIES" "${DE_CATEGORIES}"
|
|
||||||
assert_mandatory "PKG_OUTPUT_DIR" "${PKG_OUTPUT_DIR}"
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
assert_mandatory "APPIMAGETOOL_COMMAND" "${APPIMAGETOOL_COMMAND}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
assert_opt_file "APP_ICON_SRC" "${APP_ICON_SRC}"
|
|
||||||
assert_opt_file "APP_XML_SRC" "${APP_XML_SRC}"
|
|
||||||
|
|
||||||
if [ "${DE_TERMINAL_FLAG}" != "true" ] && [ "${DE_TERMINAL_FLAG}" != "false" ]; then
|
|
||||||
echo "DE_TERMINAL_FLAG invalid value: ${DE_TERMINAL_FLAG}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${DOTNET_PROJECT_PATH}" == "${_DOTNET_NONE}" ] && [ "${POST_PUBLISH}" == "" ]; then
|
|
||||||
echo "No publish or build operation defined (nothing will be built)"
|
|
||||||
echo "See DOTNET_PROJECT_PATH and POST_PUBLISH in: ${_conf_arg_value}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${DOTNET_PROJECT_PATH}" != "" ] && [ "${DOTNET_PROJECT_PATH}" != "${_DOTNET_NONE}" ] &&
|
|
||||||
[ ! -f "${DOTNET_PROJECT_PATH}" ] && [ ! -d "${DOTNET_PROJECT_PATH}" ]; then
|
|
||||||
echo "DOTNET_PROJECT_PATH path not found: ${DOTNET_PROJECT_PATH}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" != "${_APPIMAGE_KIND}" ] && [ "${_kind_arg_value}" != "${_ZIP_KIND}" ]; then
|
|
||||||
echo "Invalid argument value: ${_kind_arg_value}"
|
|
||||||
echo "Use one of: ${_APPIMAGE_KIND} or ${_ZIP_KIND}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Detect if publish for windows
|
|
||||||
_exec_ext=""
|
|
||||||
declare -l _tw="${_rid_arg_value}"
|
|
||||||
|
|
||||||
if [[ "${_tw}" == "win"* ]]; then
|
|
||||||
|
|
||||||
# May use this in future
|
|
||||||
_exec_ext=".exe"
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
echo "Invalid AppImage payload"
|
|
||||||
echo "Looks like a windows binary to be packaged as AppImage."
|
|
||||||
echo "Use --${_KIND_ARG_NAME} ${_ZIP_KIND} instead."
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# VARIABLES
|
|
||||||
###############################
|
|
||||||
|
|
||||||
# Abbreviate RID where it maps well to arch
|
|
||||||
if [ "${_rid_arg_value}" == "linux-x64" ]; then
|
|
||||||
_file_out_arch="-x86_64"
|
|
||||||
elif [ "${_rid_arg_value}" == "linux-arm64" ]; then
|
|
||||||
_file_out_arch="-aarch64"
|
|
||||||
else
|
|
||||||
# Otherwise use RID itself
|
|
||||||
_file_out_arch="-${_rid_arg_value}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# APPDIR LOCATIONS
|
|
||||||
export APPDIR_ROOT="${PKG_OUTPUT_DIR}/AppDir"
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
# AppImage
|
|
||||||
export APPDIR_USR="${APPDIR_ROOT}/usr"
|
|
||||||
export APPDIR_BIN="${APPDIR_ROOT}/usr/bin"
|
|
||||||
export APPDIR_SHARE="${APPDIR_ROOT}/usr/share"
|
|
||||||
|
|
||||||
_local_run="usr/bin/${APP_MAIN}${_exec_ext}"
|
|
||||||
else
|
|
||||||
# Simple zip
|
|
||||||
export APPDIR_USR=""
|
|
||||||
export APPDIR_BIN="${APPDIR_ROOT}"
|
|
||||||
export APPDIR_SHARE="${APPDIR_ROOT}"
|
|
||||||
|
|
||||||
_local_run="${APP_MAIN}${_exec_ext}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export APPRUN_TARGET="${APPDIR_BIN}/${APP_MAIN}${_exec_ext}"
|
|
||||||
|
|
||||||
|
|
||||||
# DOTNET PUBLISH
|
|
||||||
if [ "${DOTNET_PROJECT_PATH}" != "${_DOTNET_NONE}" ]; then
|
|
||||||
|
|
||||||
_publish_cmd="dotnet publish"
|
|
||||||
|
|
||||||
if [ "${DOTNET_PROJECT_PATH}" != "" ] && [ "${DOTNET_PROJECT_PATH}" != "." ]; then
|
|
||||||
_publish_cmd="${_publish_cmd} \"${DOTNET_PROJECT_PATH}\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
_publish_cmd="${_publish_cmd} -r ${_rid_arg_value}"
|
|
||||||
|
|
||||||
if [ "${APP_VERSION}" != "" ]; then
|
|
||||||
_publish_cmd="${_publish_cmd} -p:Version=${APP_VERSION}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${DOTNET_PUBLISH_ARGS}" != "" ]; then
|
|
||||||
_publish_cmd="${_publish_cmd} ${DOTNET_PUBLISH_ARGS}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_publish_cmd="${_publish_cmd} -o \"${APPDIR_BIN}\""
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# PACKAGE OUTPUT
|
|
||||||
if [ $PKG_VERSION_FLAG == true ] && [ "${APP_VERSION}" != "" ]; then
|
|
||||||
_version_out="-${APP_VERSION}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
|
|
||||||
# AppImageTool
|
|
||||||
if [ "${_output_arg_value}" != "" ]; then
|
|
||||||
_package_out="${PKG_OUTPUT_DIR}/${_output_arg_value}"
|
|
||||||
else
|
|
||||||
_package_out="${PKG_OUTPUT_DIR}/${APP_MAIN}${_version_out}${_file_out_arch}${PKG_APPIMAGE_SUFFIX}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_package_cmd="${APPIMAGETOOL_COMMAND}"
|
|
||||||
|
|
||||||
if [ "${PKG_APPIMAGE_ARGS}" != "" ]; then
|
|
||||||
_package_cmd="${_package_cmd} ${PKG_APPIMAGE_ARGS}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_package_cmd="${_package_cmd} \"${APPDIR_ROOT}\" \"${_package_out}\""
|
|
||||||
|
|
||||||
if [ ${_runapp_arg_value} == true ]; then
|
|
||||||
_packrun_cmd="${_package_out}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
# Simple zip
|
|
||||||
if [ "${_output_arg_value}" != "" ]; then
|
|
||||||
_package_out="${PKG_OUTPUT_DIR}/${_output_arg_value}"
|
|
||||||
else
|
|
||||||
_package_out="${PKG_OUTPUT_DIR}/${APP_MAIN}${_version_out}${_file_out_arch}.zip"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_package_cmd="(cd \"${APPDIR_ROOT}\" && zip -r \"${PWD}/${_package_out}\" ./)"
|
|
||||||
|
|
||||||
if [ ${_runapp_arg_value} == true ]; then
|
|
||||||
_packrun_cmd="${APPRUN_TARGET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# DESKTOP ENTRY & APPDATA
|
|
||||||
###############################
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
|
|
||||||
_desktop="[Desktop Entry]\n"
|
|
||||||
_desktop="${_desktop}Type=Application\n"
|
|
||||||
_desktop="${_desktop}Name=${DE_NAME}\n"
|
|
||||||
_desktop="${_desktop}Exec=AppRun\n"
|
|
||||||
_desktop="${_desktop}Terminal=${DE_TERMINAL_FLAG}\n"
|
|
||||||
_desktop="${_desktop}Categories=${DE_CATEGORIES}\n"
|
|
||||||
|
|
||||||
# Follow app-id
|
|
||||||
_desktop="${_desktop}Icon=${APP_ID}\n"
|
|
||||||
|
|
||||||
if [ "${DE_COMMENT}" != "" ]; then
|
|
||||||
_desktop="${_desktop}Comment=${DE_COMMENT}\n"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${DE_KEYWORDS}" != "" ]; then
|
|
||||||
_desktop="${_desktop}Keywords=${DE_KEYWORDS}\n"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_desktop="${_desktop}${DE_EXTEND}\n"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Load appdata.xml
|
|
||||||
if [ "${APP_XML_SRC}" != "" ]; then
|
|
||||||
|
|
||||||
if command -v envsubst &> /dev/null; then
|
|
||||||
_appxml=$(envsubst <"${APP_XML_SRC}")
|
|
||||||
else
|
|
||||||
_appxml=$(<"${APP_XML_SRC}")
|
|
||||||
echo "WARNING: Variable substitution not available for: ${APP_XML_SRC}"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# DISPLAY & CONFIRM
|
|
||||||
###############################
|
|
||||||
|
|
||||||
echo "${_SCRIPT_TITLE}, ${_SCRIPT_VERSION}"
|
|
||||||
echo "${_SCRIPT_COPYRIGHT}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "APP_MAIN: ${APP_MAIN}"
|
|
||||||
echo "APP_ID: ${APP_ID}"
|
|
||||||
echo "APP_VERSION: ${APP_VERSION}"
|
|
||||||
echo "OUTPUT: ${_package_out}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ "${_desktop}" != "" ]; then
|
|
||||||
echo -e "${_desktop}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ${_verbose_arg_value} == true ] && [ "${_appxml}" != "" ]; then
|
|
||||||
echo -e "${_appxml}\n"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Build Commands:"
|
|
||||||
|
|
||||||
if [ "${_publish_cmd}" != "" ]; then
|
|
||||||
echo
|
|
||||||
echo "${_publish_cmd}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${POST_PUBLISH}" != "" ]; then
|
|
||||||
echo
|
|
||||||
echo "${POST_PUBLISH}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "${_package_cmd}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Prompt
|
|
||||||
if [ $_skipyes_arg_value == false ]; then
|
|
||||||
|
|
||||||
echo
|
|
||||||
read -p "Build now [N/y]? " prompt
|
|
||||||
|
|
||||||
if [ "${prompt}" != "y" ] && [ "${prompt}" != "Y" ]; then
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Continue
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
###############################
|
|
||||||
# PUBLISH & BUILD
|
|
||||||
###############################
|
|
||||||
|
|
||||||
# Clean and ensure directoy exists
|
|
||||||
ensure_directory "${PKG_OUTPUT_DIR}"
|
|
||||||
remove_path "${APPDIR_ROOT}"
|
|
||||||
remove_path "${_package_out}"
|
|
||||||
|
|
||||||
# Create AppDir structure
|
|
||||||
ensure_directory "${APPDIR_BIN}"
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" != "${_ZIP_KIND}" ]; then
|
|
||||||
# We also create usr/share/icons, as some packages require this.
|
|
||||||
# See: https://github.com/kuiperzone/Publish-AppImage/issues/7
|
|
||||||
ensure_directory "${APPDIR_SHARE}/icons"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Publish dotnet
|
|
||||||
if [ "${_publish_cmd}" != "" ]; then
|
|
||||||
exec_or_die "${_publish_cmd}"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Post-publish
|
|
||||||
if [ "${POST_PUBLISH}" != "" ]; then
|
|
||||||
|
|
||||||
exec_or_die "${POST_PUBLISH}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Application file must exist!
|
|
||||||
if [ ! -f "${APPRUN_TARGET}" ]; then
|
|
||||||
echo "Expected application file not found: ${APPRUN_TARGET}"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${_kind_arg_value}" == "${_APPIMAGE_KIND}" ]; then
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Create desktop
|
|
||||||
if [ "${_desktop}" != "" ]; then
|
|
||||||
_file="${APPDIR_ROOT}/${APP_ID}.desktop"
|
|
||||||
echo "Creating: ${_file}"
|
|
||||||
echo -e "${_desktop}" > "${_file}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${_appxml}" != "" ]; then
|
|
||||||
_dir="${APPDIR_SHARE}/metainfo"
|
|
||||||
_file="${_dir}/${APP_ID}.appdata.xml"
|
|
||||||
echo "Creating: ${_file}"
|
|
||||||
ensure_directory "${_dir}"
|
|
||||||
echo -e "${_appxml}" > "${_file}"
|
|
||||||
assert_result
|
|
||||||
|
|
||||||
if [ "${_desktop}" != "" ]; then
|
|
||||||
# Copy of desktop under "applications"
|
|
||||||
# Needed for launchable in appinfo.xml (if used)
|
|
||||||
# See https://github.com/AppImage/AppImageKit/issues/603
|
|
||||||
_dir="${APPDIR_SHARE}/applications"
|
|
||||||
_file="${_dir}/${APP_ID}.desktop"
|
|
||||||
echo "Creating: ${_file}"
|
|
||||||
ensure_directory "${_dir}"
|
|
||||||
echo -e "${_desktop}" > "${_file}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy icon
|
|
||||||
if [ "${APP_ICON_SRC}" != "" ]; then
|
|
||||||
|
|
||||||
_icon_ext="${APP_ICON_SRC##*.}"
|
|
||||||
|
|
||||||
if [ "${_icon_ext}" != "" ]; then
|
|
||||||
_icon_ext=".${_icon_ext}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
_temp="${APPDIR_ROOT}/${APP_ID}${_icon_ext}"
|
|
||||||
echo "Creating: ${_temp}"
|
|
||||||
|
|
||||||
cp "${APP_ICON_SRC}" "${_temp}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
|
|
||||||
# AppRun
|
|
||||||
_temp="${APPDIR_ROOT}/AppRun"
|
|
||||||
|
|
||||||
if [ ! -f "${_temp}" ]; then
|
|
||||||
|
|
||||||
echo "Creating: ${_temp}"
|
|
||||||
ln -s "${_local_run}" "${_temp}"
|
|
||||||
assert_result
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build package
|
|
||||||
echo
|
|
||||||
exec_or_die "${_package_cmd}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "OUTPUT OK: ${_package_out}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if [ "${_packrun_cmd}" != "" ]; then
|
|
||||||
echo "RUNNING ..."
|
|
||||||
exec_or_die "${_packrun_cmd}"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
|
@ -1,140 +0,0 @@
|
||||||
################################################################################
|
|
||||||
# BASH FORMAT CONFIG: Publish-AppImage for .NET
|
|
||||||
# WEBPAGE : https://kuiper.zone/publish-appimage-dotnet/
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Application
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Mandatory application (file) name. This must be the base name of the main
|
|
||||||
# runnable file to be created by the publish/build process. It should NOT
|
|
||||||
# include any directory part or extension, i.e. do not append ".exe" or ".dll"
|
|
||||||
# for dotnet. Example: "MyApp"
|
|
||||||
APP_MAIN="sourcegit"
|
|
||||||
|
|
||||||
# Mandatory application ID in reverse DNS form, i.e. "tld.my-domain.MyApp".
|
|
||||||
# Exclude any ".desktop" post-fix. Note that reverse DNS form is necessary
|
|
||||||
# for compatibility with Freedesktop.org metadata.
|
|
||||||
APP_ID="com.sourcegit-scm.SourceGit"
|
|
||||||
|
|
||||||
# Mandatory icon source file relative to this file (appimagetool seems to
|
|
||||||
# require this). Use .svg or .png only. PNG should be one of standard sizes,
|
|
||||||
# i.e, 128x128 or 256x256 pixels. Example: "Assets/app.svg"
|
|
||||||
APP_ICON_SRC="sourcegit.png"
|
|
||||||
|
|
||||||
# Optional Freedesktop.org metadata source file relative to this file. It is not essential
|
|
||||||
# (leave empty) but will be used by appimagetool for repository information if provided.
|
|
||||||
# See for information: https://docs.appimage.org/packaging-guide/optional/appstream.html
|
|
||||||
# NB. The file may embed bash variables defined in this file and those listed below
|
|
||||||
# (these will be substituted during the build). Examples include: "<id>${APP_ID}</id>"
|
|
||||||
# and "<release version="${APP_VERSION}" date="${ISO_DATE}">".
|
|
||||||
# $ISO_DATE : date of build, i.e. "2021-10-29",
|
|
||||||
# $APP_VERSION : application version (if provided),
|
|
||||||
# Example: "Assets/appdata.xml".
|
|
||||||
APP_XML_SRC="sourcegit.appdata.xml"
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Desktop Entry
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Mandatory friendly name of the application.
|
|
||||||
DE_NAME="SourceGit"
|
|
||||||
|
|
||||||
# Mandatory category(ies), separated with semicolon, in which the entry should be
|
|
||||||
# shown. See https://specifications.freedesktop.org/menu-spec/latest/apa.html
|
|
||||||
# Examples: "Development", "Graphics", "Network", "Utility" etc.
|
|
||||||
DE_CATEGORIES="Utility"
|
|
||||||
|
|
||||||
# Optional short comment text (single line).
|
|
||||||
# Example: "Perform calculations"
|
|
||||||
DE_COMMENT="Open-source GUI client for git users"
|
|
||||||
|
|
||||||
# Optional keywords, separated with semicolon. Values are not meant for
|
|
||||||
# display and should not be redundant with the value of DE_NAME.
|
|
||||||
DE_KEYWORDS=""
|
|
||||||
|
|
||||||
# Flag indicating whether the program runs in a terminal window. Use true or false only.
|
|
||||||
DE_TERMINAL_FLAG=false
|
|
||||||
|
|
||||||
# Optional name-value text to be appended to the Desktop Entry file, thus providing
|
|
||||||
# additional metadata. Name-values should not be redundant with values above and
|
|
||||||
# are to be terminated with new line ("\n").
|
|
||||||
# Example: "Comment[fr]=Effectue des calculs compliqués\nMimeType=image/x-foo"
|
|
||||||
DE_EXTEND=""
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Dotnet Publish
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Optional path relative to this file in which to find the dotnet project (.csproj)
|
|
||||||
# or solution (.sln) file, or the directory containing it. If empty (default), a single
|
|
||||||
# project or solution file is expected under the same directory as this file.
|
|
||||||
# IMPORTANT. If set to "null", dotnet publish is disabled (it is NOT called). Instead,
|
|
||||||
# only POST_PUBLISH is called. Example: "Source/MyProject"
|
|
||||||
DOTNET_PROJECT_PATH="../../../src/SourceGit.csproj"
|
|
||||||
|
|
||||||
# Optional arguments suppled to "dotnet publish". Do NOT include "-r" (runtime) or version here as they will
|
|
||||||
# be added (see also $APP_VERSION). Typically you want as a minimum: "-c Release --self-contained true".
|
|
||||||
# Additional useful arguments include:
|
|
||||||
# "-p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:TrimMode=link"
|
|
||||||
# Refer: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish
|
|
||||||
DOTNET_PUBLISH_ARGS="-c Release -p:DebugType=None -p:DebugSymbols=false"
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# POST-PUBLISH
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Optional post-publish or standalone build command. The value could, for example, copy
|
|
||||||
# additional files into the "bin" directory. The working directory will be the location
|
|
||||||
# of this file. The value is mandatory if DOTNET_PROJECT_PATH equals "null". In
|
|
||||||
# addition to variables in this file, the following variables are exported prior:
|
|
||||||
# $ISO_DATE : date of build, i.e. "2021-10-29",
|
|
||||||
# $APP_VERSION : application version (if provided),
|
|
||||||
# $DOTNET_RID : dotnet runtime identifier string provided at command line (i.e. "linux-x64),
|
|
||||||
# $PKG_KIND : package kind (i.e. "appimage", "zip") provided at command line.
|
|
||||||
# $APPDIR_ROOT : AppImage build directory root (i.e. "AppImages/AppDir").
|
|
||||||
# $APPDIR_USR : AppImage user directory under root (i.e. "AppImages/AppDir/usr").
|
|
||||||
# $APPDIR_BIN : AppImage bin directory under root (i.e. "AppImages/AppDir/usr/bin").
|
|
||||||
# $APPRUN_TARGET : The expected target executable file (i.e. "AppImages/AppDir/usr/bin/app-name").
|
|
||||||
# Example: "Assets/post-publish.sh"
|
|
||||||
POST_PUBLISH="mv AppImages/AppDir/usr/bin/SourceGit AppImages/AppDir/usr/bin/sourcegit; rm -f AppImages/AppDir/usr/bin/*.dbg"
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Package Output
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# Additional arguments for use with appimagetool. See appimagetool --help.
|
|
||||||
# Default is empty. Example: "--sign"
|
|
||||||
PKG_APPIMAGE_ARGS="--runtime-file=runtime-x86_64"
|
|
||||||
|
|
||||||
# Mandatory output directory relative to this file. It will be created if it does not
|
|
||||||
# exist. It will contain the final package file and temporary AppDir. Default: "AppImages".
|
|
||||||
PKG_OUTPUT_DIR="AppImages"
|
|
||||||
|
|
||||||
# Boolean which sets whether to include the application version in the filename of the final
|
|
||||||
# output package (i.e. "HelloWorld-1.2.3-x86_64.AppImage"). It is ignored if $APP_VERSION is
|
|
||||||
# empty or the "output" command arg is specified. Default and recommended: false.
|
|
||||||
PKG_VERSION_FLAG=false
|
|
||||||
|
|
||||||
# Optional AppImage output filename extension. It is ignored if generating a zip file, or if
|
|
||||||
# the "output" command arg is specified. Default and recommended: ".AppImage".
|
|
||||||
PKG_APPIMAGE_SUFFIX=".AppImage"
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Advanced Other
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# The appimagetool command. Default is "appimagetool" which is expected to be found
|
|
||||||
# in the $PATH. If the tool is not in path or has different name, a full path can be given,
|
|
||||||
# example: "/home/user/Apps/appimagetool-x86_64.AppImage"
|
|
||||||
APPIMAGETOOL_COMMAND="appimagetool"
|
|
||||||
|
|
||||||
# Internal use only. Used for compatibility between conf and script. Do not modify.
|
|
||||||
CONF_IMPL_VERSION=1
|
|
Binary file not shown.
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<component type="desktop-application">
|
<component type="desktop-application">
|
||||||
<id>com.sourcegit-scm.SourceGit</id>
|
<id>com.sourcegit_scm.SourceGit</id>
|
||||||
<metadata_license>MIT</metadata_license>
|
<metadata_license>MIT</metadata_license>
|
||||||
<project_license>MIT</project_license>
|
<project_license>MIT</project_license>
|
||||||
<name>SourceGit</name>
|
<name>SourceGit</name>
|
||||||
|
@ -8,8 +8,9 @@
|
||||||
<description>
|
<description>
|
||||||
<p>Open-source GUI client for git users</p>
|
<p>Open-source GUI client for git users</p>
|
||||||
</description>
|
</description>
|
||||||
<launchable type="desktop-id">com.sourcegit-scm.SourceGit.desktop</launchable>
|
<url type="homepage">https://github.com/sourcegit-scm/sourcegit</url>
|
||||||
|
<launchable type="desktop-id">com.sourcegit_scm.SourceGit.desktop</launchable>
|
||||||
<provides>
|
<provides>
|
||||||
<id>com.sourcegit-scm.SourceGit.desktop</id>
|
<id>com.sourcegit_scm.SourceGit.desktop</id>
|
||||||
</provides>
|
</provides>
|
||||||
</component>
|
</component>
|
|
@ -1,5 +1,5 @@
|
||||||
Package: sourcegit
|
Package: sourcegit
|
||||||
Version: 8.18
|
Version: 8.23
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Depends: libx11-6, libice6, libsm6
|
Depends: libx11-6, libice6, libsm6
|
||||||
Architecture: amd64
|
Architecture: amd64
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!bin/sh
|
|
||||||
|
|
||||||
echo 'Create link on /usr/bin'
|
|
||||||
ln -s /opt/sourcegit/sourcegit /usr/bin/sourcegit
|
|
||||||
exit 0
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!bin/sh
|
|
||||||
|
|
||||||
rm -f /usr/bin/sourcegit
|
|
||||||
exit 0
|
|
|
@ -14,24 +14,23 @@ Requires: libSM.so.6
|
||||||
Open-source & Free Git Gui Client
|
Open-source & Free Git Gui Client
|
||||||
|
|
||||||
%install
|
%install
|
||||||
mkdir -p $RPM_BUILD_ROOT/opt/sourcegit
|
mkdir -p %{buildroot}/opt/sourcegit
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/share/applications
|
mkdir -p %{buildroot}/%{_bindir}
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/share/icons
|
mkdir -p %{buildroot}/usr/share/applications
|
||||||
cp -r ../../_common/applications $RPM_BUILD_ROOT/usr/share/
|
mkdir -p %{buildroot}/usr/share/icons
|
||||||
cp -r ../../_common/icons $RPM_BUILD_ROOT/usr/share/
|
cp -f ../../../SourceGit/* %{buildroot}/opt/sourcegit/
|
||||||
cp -f ../../../SourceGit/* $RPM_BUILD_ROOT/opt/sourcegit/
|
ln -sf ../../opt/sourcegit/sourcegit %{buildroot}/%{_bindir}
|
||||||
chmod 755 -R $RPM_BUILD_ROOT/opt/sourcegit
|
cp -r ../../_common/applications %{buildroot}/%{_datadir}
|
||||||
chmod 755 $RPM_BUILD_ROOT/usr/share/applications/sourcegit.desktop
|
cp -r ../../_common/icons %{buildroot}/%{_datadir}
|
||||||
|
chmod 755 -R %{buildroot}/opt/sourcegit
|
||||||
|
chmod 755 %{buildroot}/%{_datadir}/applications/sourcegit.desktop
|
||||||
|
|
||||||
%files
|
%files
|
||||||
/opt/sourcegit
|
%dir /opt/sourcegit/
|
||||||
/usr/share
|
/opt/sourcegit/*
|
||||||
|
/usr/share/applications/sourcegit.desktop
|
||||||
%post
|
/usr/share/icons/*
|
||||||
ln -s /opt/sourcegit/sourcegit /usr/bin/sourcegit
|
%{_bindir}/sourcegit
|
||||||
|
|
||||||
%postun
|
|
||||||
rm -f /usr/bin/sourcegit
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
# skip
|
# skip
|
70
build/scripts/package.linux.sh
Executable file
70
build/scripts/package.linux.sh
Executable file
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "Provide the version as environment variable VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$RUNTIME" ]; then
|
||||||
|
echo "Provide the runtime as environment variable RUNTIME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
arch=
|
||||||
|
appimage_arch=
|
||||||
|
target=
|
||||||
|
case "$RUNTIME" in
|
||||||
|
linux-x64)
|
||||||
|
arch=amd64
|
||||||
|
appimage_arch=x86_64
|
||||||
|
target=x86_64;;
|
||||||
|
linux-arm64)
|
||||||
|
arch=arm64
|
||||||
|
appimage_arch=arm_aarch64
|
||||||
|
target=aarch64;;
|
||||||
|
*)
|
||||||
|
echo "Unknown runtime $RUNTIME"
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
APPIMAGETOOL_URL=https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
if [ ! -f "appimagetool" ]; then
|
||||||
|
curl -o appimagetool -L "$APPIMAGETOOL_URL"
|
||||||
|
chmod +x appimagetool
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f SourceGit/*.dbg
|
||||||
|
|
||||||
|
mkdir -p SourceGit.AppDir/opt
|
||||||
|
mkdir -p SourceGit.AppDir/usr/share/metainfo
|
||||||
|
mkdir -p SourceGit.AppDir/usr/share/applications
|
||||||
|
|
||||||
|
cp -r SourceGit SourceGit.AppDir/opt/sourcegit
|
||||||
|
desktop-file-install resources/_common/applications/sourcegit.desktop --dir SourceGit.AppDir/usr/share/applications \
|
||||||
|
--set-icon com.sourcegit_scm.SourceGit --set-key=Exec --set-value=AppRun
|
||||||
|
mv SourceGit.AppDir/usr/share/applications/{sourcegit,com.sourcegit_scm.SourceGit}.desktop
|
||||||
|
cp resources/appimage/sourcegit.png SourceGit.AppDir/com.sourcegit_scm.SourceGit.png
|
||||||
|
ln -rsf SourceGit.AppDir/opt/sourcegit/sourcegit SourceGit.AppDir/AppRun
|
||||||
|
ln -rsf SourceGit.AppDir/usr/share/applications/com.sourcegit_scm.SourceGit.desktop SourceGit.AppDir
|
||||||
|
cp resources/appimage/sourcegit.appdata.xml SourceGit.AppDir/usr/share/metainfo/com.sourcegit_scm.SourceGit.appdata.xml
|
||||||
|
|
||||||
|
ARCH="$appimage_arch" ./appimagetool -v SourceGit.AppDir "sourcegit-$VERSION.linux.$arch.AppImage"
|
||||||
|
|
||||||
|
mkdir -p resources/deb/opt/sourcegit/
|
||||||
|
mkdir -p resources/deb/usr/bin
|
||||||
|
mkdir -p resources/deb/usr/share/applications
|
||||||
|
mkdir -p resources/deb/usr/share/icons
|
||||||
|
cp -f SourceGit/* resources/deb/opt/sourcegit
|
||||||
|
ln -sf ../../opt/sourcegit/sourcegit resources/deb/usr/bin
|
||||||
|
cp -r resources/_common/applications resources/deb/usr/share
|
||||||
|
cp -r resources/_common/icons resources/deb/usr/share
|
||||||
|
sed -i -e "s/^Version:.*/Version: $VERSION/" -e "s/^Architecture:.*/Architecture: $arch/" resources/deb/DEBIAN/control
|
||||||
|
dpkg-deb --root-owner-group --build resources/deb "sourcegit_$VERSION-1_$arch.deb"
|
||||||
|
|
||||||
|
rpmbuild -bb --target="$target" resources/rpm/SPECS/build.spec --define "_topdir $(pwd)/resources/rpm" --define "_version $VERSION"
|
||||||
|
mv "resources/rpm/RPMS/$target/sourcegit-$VERSION-1.$target.rpm" ./
|
22
build/scripts/package.osx-app.sh
Executable file
22
build/scripts/package.osx-app.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "Provide the version as environment variable VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$RUNTIME" ]; then
|
||||||
|
echo "Provide the runtime as environment variable RUNTIME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
mkdir -p SourceGit.app/Contents/Resources
|
||||||
|
mv SourceGit SourceGit.app/Contents/MacOS
|
||||||
|
cp resources/app/App.icns SourceGit.app/Contents/Resources/App.icns
|
||||||
|
sed "s/SOURCE_GIT_VERSION/$VERSION/g" resources/app/App.plist > SourceGit.app/Contents/Info.plist
|
||||||
|
|
||||||
|
zip "sourcegit_$VERSION.$RUNTIME.zip" -r SourceGit.app -x "*/*\.dsym/*"
|
19
build/scripts/package.windows-portable.sh
Executable file
19
build/scripts/package.windows-portable.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "Provide the version as environment variable VERSION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$RUNTIME" ]; then
|
||||||
|
echo "Provide the runtime as environment variable RUNTIME"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd build
|
||||||
|
|
||||||
|
rm -rf SourceGit/*.pdb
|
||||||
|
|
||||||
|
zip "sourcegit_$VERSION.$RUNTIME.zip" -r SourceGit
|
|
@ -58,6 +58,7 @@ namespace SourceGit
|
||||||
typeof(GridLengthConverter),
|
typeof(GridLengthConverter),
|
||||||
]
|
]
|
||||||
)]
|
)]
|
||||||
|
[JsonSerializable(typeof(Models.ExternalToolPaths))]
|
||||||
[JsonSerializable(typeof(Models.InteractiveRebaseJobCollection))]
|
[JsonSerializable(typeof(Models.InteractiveRebaseJobCollection))]
|
||||||
[JsonSerializable(typeof(Models.JetBrainsState))]
|
[JsonSerializable(typeof(Models.JetBrainsState))]
|
||||||
[JsonSerializable(typeof(Models.ThemeOverrides))]
|
[JsonSerializable(typeof(Models.ThemeOverrides))]
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<NativeMenuItem Header="{DynamicResource Text.SelfUpdate}" Command="{x:Static s:App.CheckForUpdateCommand}"/>
|
<NativeMenuItem Header="{DynamicResource Text.SelfUpdate}" Command="{x:Static s:App.CheckForUpdateCommand}"/>
|
||||||
<NativeMenuItemSeparator/>
|
<NativeMenuItemSeparator/>
|
||||||
<NativeMenuItem Header="{DynamicResource Text.Preference}" Command="{x:Static s:App.OpenPreferenceCommand}" Gesture="⌘+,"/>
|
<NativeMenuItem Header="{DynamicResource Text.Preference}" Command="{x:Static s:App.OpenPreferenceCommand}" Gesture="⌘+,"/>
|
||||||
|
<NativeMenuItem Header="{DynamicResource Text.OpenAppDataDir}" Command="{x:Static s:App.OpenAppDataDirCommand}"/>
|
||||||
<NativeMenuItemSeparator/>
|
<NativeMenuItemSeparator/>
|
||||||
<NativeMenuItem Header="{DynamicResource Text.Quit}" Command="{x:Static s:App.QuitCommand}" Gesture="⌘+Q"/>
|
<NativeMenuItem Header="{DynamicResource Text.Quit}" Command="{x:Static s:App.QuitCommand}" Gesture="⌘+Q"/>
|
||||||
</NativeMenu>
|
</NativeMenu>
|
||||||
|
|
|
@ -44,6 +44,8 @@ namespace SourceGit
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
Native.OS.SetupDataDir();
|
||||||
|
|
||||||
AppDomain.CurrentDomain.UnhandledException += (_, e) =>
|
AppDomain.CurrentDomain.UnhandledException += (_, e) =>
|
||||||
{
|
{
|
||||||
LogException(e.ExceptionObject as Exception);
|
LogException(e.ExceptionObject as Exception);
|
||||||
|
@ -107,6 +109,11 @@ namespace SourceGit
|
||||||
dialog.ShowDialog(toplevel);
|
dialog.ShowDialog(toplevel);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public static readonly SimpleCommand OpenAppDataDirCommand = new SimpleCommand(() =>
|
||||||
|
{
|
||||||
|
Native.OS.OpenInFileManager(Native.OS.DataDir);
|
||||||
|
});
|
||||||
|
|
||||||
public static readonly SimpleCommand OpenAboutCommand = new SimpleCommand(() =>
|
public static readonly SimpleCommand OpenAboutCommand = new SimpleCommand(() =>
|
||||||
{
|
{
|
||||||
var toplevel = GetTopLevel() as Window;
|
var toplevel = GetTopLevel() as Window;
|
||||||
|
@ -521,6 +528,8 @@ namespace SourceGit
|
||||||
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
|
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
Native.OS.SetupEnternalTools();
|
Native.OS.SetupEnternalTools();
|
||||||
|
Models.AvatarManager.Instance.Start();
|
||||||
|
Models.AutoFetchManager.Instance.Start();
|
||||||
|
|
||||||
string startupRepo = null;
|
string startupRepo = null;
|
||||||
if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0]))
|
if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0]))
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
public class Commit : Command
|
public class Commit : Command
|
||||||
{
|
{
|
||||||
public Commit(string repo, string message, bool autoStage, bool amend, bool allowEmpty = false)
|
public Commit(string repo, string message, bool amend, bool allowEmpty = false)
|
||||||
{
|
{
|
||||||
var file = Path.GetTempFileName();
|
var file = Path.GetTempFileName();
|
||||||
File.WriteAllText(file, message);
|
File.WriteAllText(file, message);
|
||||||
|
@ -13,8 +13,6 @@ namespace SourceGit.Commands
|
||||||
Context = repo;
|
Context = repo;
|
||||||
TraitErrorAsOutput = true;
|
TraitErrorAsOutput = true;
|
||||||
Args = $"commit --file=\"{file}\"";
|
Args = $"commit --file=\"{file}\"";
|
||||||
if (autoStage)
|
|
||||||
Args += " --all";
|
|
||||||
if (amend)
|
if (amend)
|
||||||
Args += " --amend --no-edit";
|
Args += " --amend --no-edit";
|
||||||
if (allowEmpty)
|
if (allowEmpty)
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SourceGit.Commands
|
namespace SourceGit.Commands
|
||||||
{
|
{
|
||||||
|
@ -26,7 +23,7 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
Args += remote;
|
Args += remote;
|
||||||
|
|
||||||
AutoFetch.MarkFetched(repo);
|
Models.AutoFetchManager.Instance.MarkFetched(repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
|
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
|
||||||
|
@ -46,110 +43,4 @@ namespace SourceGit.Commands
|
||||||
|
|
||||||
private readonly Action<string> _outputHandler;
|
private readonly Action<string> _outputHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoFetch
|
|
||||||
{
|
|
||||||
public static bool IsEnabled
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
} = false;
|
|
||||||
|
|
||||||
public static int Interval
|
|
||||||
{
|
|
||||||
get => _interval;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value < 1)
|
|
||||||
return;
|
|
||||||
_interval = value;
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
foreach (var job in _jobs)
|
|
||||||
{
|
|
||||||
job.Value.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(_interval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Job
|
|
||||||
{
|
|
||||||
public Fetch Cmd = null;
|
|
||||||
public DateTime NextRunTimepoint = DateTime.MinValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
static AutoFetch()
|
|
||||||
{
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (!IsEnabled)
|
|
||||||
{
|
|
||||||
Thread.Sleep(10000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var now = DateTime.Now;
|
|
||||||
var uptodate = new List<Job>();
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
foreach (var job in _jobs)
|
|
||||||
{
|
|
||||||
if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0)
|
|
||||||
{
|
|
||||||
uptodate.Add(job.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var job in uptodate)
|
|
||||||
{
|
|
||||||
job.Cmd.Exec();
|
|
||||||
job.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.Sleep(2000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddRepository(string repo)
|
|
||||||
{
|
|
||||||
var job = new Job
|
|
||||||
{
|
|
||||||
Cmd = new Fetch(repo, "--all", true, false, null) { RaiseError = false },
|
|
||||||
NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval)),
|
|
||||||
};
|
|
||||||
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_jobs[repo] = job;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveRepository(string repo)
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
_jobs.Remove(repo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MarkFetched(string repo)
|
|
||||||
{
|
|
||||||
lock (_lock)
|
|
||||||
{
|
|
||||||
if (_jobs.TryGetValue(repo, out var value))
|
|
||||||
{
|
|
||||||
value.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, Job> _jobs = new Dictionary<string, Job>();
|
|
||||||
private static readonly object _lock = new object();
|
|
||||||
private static int _interval = 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
120
src/Models/AutoFetchManager.cs
Normal file
120
src/Models/AutoFetchManager.cs
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SourceGit.Models
|
||||||
|
{
|
||||||
|
public class AutoFetchManager
|
||||||
|
{
|
||||||
|
public static AutoFetchManager Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
_instance = new AutoFetchManager();
|
||||||
|
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Job
|
||||||
|
{
|
||||||
|
public Commands.Fetch Cmd = null;
|
||||||
|
public DateTime NextRunTimepoint = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEnabled
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = false;
|
||||||
|
|
||||||
|
public int Interval
|
||||||
|
{
|
||||||
|
get => _interval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_interval = Math.Max(1, value);
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
foreach (var job in _jobs)
|
||||||
|
job.Value.NextRunTimepoint = DateTime.Now.AddMinutes(_interval * 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AutoFetchManager _instance = null;
|
||||||
|
private Dictionary<string, Job> _jobs = new Dictionary<string, Job>();
|
||||||
|
private object _lock = new object();
|
||||||
|
private int _interval = 10;
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!IsEnabled)
|
||||||
|
{
|
||||||
|
Thread.Sleep(10000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var uptodate = new List<Job>();
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
foreach (var job in _jobs)
|
||||||
|
{
|
||||||
|
if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0)
|
||||||
|
uptodate.Add(job.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var job in uptodate)
|
||||||
|
{
|
||||||
|
job.Cmd.Exec();
|
||||||
|
job.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once FunctionNeverReturns
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRepository(string repo)
|
||||||
|
{
|
||||||
|
var job = new Job
|
||||||
|
{
|
||||||
|
Cmd = new Commands.Fetch(repo, "--all", true, false, null) { RaiseError = false },
|
||||||
|
NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval)),
|
||||||
|
};
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_jobs[repo] = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRepository(string repo)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_jobs.Remove(repo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkFetched(string repo)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (_jobs.TryGetValue(repo, out var value))
|
||||||
|
value.NextRunTimepoint = DateTime.Now.AddMinutes(Interval * 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,15 +20,31 @@ namespace SourceGit.Models
|
||||||
void OnAvatarResourceChanged(string email);
|
void OnAvatarResourceChanged(string email);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class AvatarManager
|
public partial class AvatarManager
|
||||||
{
|
{
|
||||||
public static string SelectedServer
|
public static AvatarManager Instance
|
||||||
{
|
{
|
||||||
get;
|
get
|
||||||
set;
|
{
|
||||||
} = "https://www.gravatar.com/avatar/";
|
if (_instance == null)
|
||||||
|
_instance = new AvatarManager();
|
||||||
|
|
||||||
static AvatarManager()
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AvatarManager _instance = null;
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
|
||||||
|
private static partial Regex REG_GITHUB_USER_EMAIL();
|
||||||
|
|
||||||
|
private object _synclock = new object();
|
||||||
|
private string _storePath;
|
||||||
|
private List<IAvatarHost> _avatars = new List<IAvatarHost>();
|
||||||
|
private Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
|
||||||
|
private HashSet<string> _requesting = new HashSet<string>();
|
||||||
|
|
||||||
|
public void Start()
|
||||||
{
|
{
|
||||||
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
|
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
|
||||||
if (!Directory.Exists(_storePath))
|
if (!Directory.Exists(_storePath))
|
||||||
|
@ -62,7 +78,7 @@ namespace SourceGit.Models
|
||||||
var matchGithubUser = REG_GITHUB_USER_EMAIL().Match(email);
|
var matchGithubUser = REG_GITHUB_USER_EMAIL().Match(email);
|
||||||
var url = matchGithubUser.Success ?
|
var url = matchGithubUser.Success ?
|
||||||
$"https://avatars.githubusercontent.com/{matchGithubUser.Groups[2].Value}" :
|
$"https://avatars.githubusercontent.com/{matchGithubUser.Groups[2].Value}" :
|
||||||
$"{SelectedServer}{md5}?d=404";
|
$"https://www.gravatar.com/avatar/{md5}?d=404";
|
||||||
|
|
||||||
var localFile = Path.Combine(_storePath, md5);
|
var localFile = Path.Combine(_storePath, md5);
|
||||||
var img = null as Bitmap;
|
var img = null as Bitmap;
|
||||||
|
@ -105,20 +121,22 @@ namespace SourceGit.Models
|
||||||
NotifyResourceChanged(email);
|
NotifyResourceChanged(email);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once FunctionNeverReturns
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Subscribe(IAvatarHost host)
|
public void Subscribe(IAvatarHost host)
|
||||||
{
|
{
|
||||||
_avatars.Add(host);
|
_avatars.Add(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unsubscribe(IAvatarHost host)
|
public void Unsubscribe(IAvatarHost host)
|
||||||
{
|
{
|
||||||
_avatars.Remove(host);
|
_avatars.Remove(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap Request(string email, bool forceRefetch)
|
public Bitmap Request(string email, bool forceRefetch)
|
||||||
{
|
{
|
||||||
if (forceRefetch)
|
if (forceRefetch)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +185,7 @@ namespace SourceGit.Models
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetEmailHash(string email)
|
private string GetEmailHash(string email)
|
||||||
{
|
{
|
||||||
var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim();
|
var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim();
|
||||||
var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered));
|
var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered));
|
||||||
|
@ -177,21 +195,12 @@ namespace SourceGit.Models
|
||||||
return builder.ToString();
|
return builder.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void NotifyResourceChanged(string email)
|
private void NotifyResourceChanged(string email)
|
||||||
{
|
{
|
||||||
foreach (var avatar in _avatars)
|
foreach (var avatar in _avatars)
|
||||||
{
|
{
|
||||||
avatar.OnAvatarResourceChanged(email);
|
avatar.OnAvatarResourceChanged(email);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly object _synclock = new object();
|
|
||||||
private static readonly string _storePath;
|
|
||||||
private static readonly List<IAvatarHost> _avatars = new List<IAvatarHost>();
|
|
||||||
private static readonly Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
|
|
||||||
private static readonly HashSet<string> _requesting = new HashSet<string>();
|
|
||||||
|
|
||||||
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
|
|
||||||
private static partial Regex REG_GITHUB_USER_EMAIL();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
8
src/Models/CommitLink.cs
Normal file
8
src/Models/CommitLink.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace SourceGit.Models
|
||||||
|
{
|
||||||
|
public class CommitLink
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = null;
|
||||||
|
public string URLPrefix { get; set; } = null;
|
||||||
|
}
|
||||||
|
}
|
22
src/Models/CommitTemplate.cs
Normal file
22
src/Models/CommitTemplate.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
|
namespace SourceGit.Models
|
||||||
|
{
|
||||||
|
public class CommitTemplate : ObservableObject
|
||||||
|
{
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set => SetProperty(ref _name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Content
|
||||||
|
{
|
||||||
|
get => _content;
|
||||||
|
set => SetProperty(ref _content, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _name = string.Empty;
|
||||||
|
private string _content = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,8 +19,8 @@ namespace SourceGit.Models
|
||||||
public class TextInlineRange
|
public class TextInlineRange
|
||||||
{
|
{
|
||||||
public int Start { get; set; }
|
public int Start { get; set; }
|
||||||
public int Count { get; set; }
|
public int End { get; set; }
|
||||||
public TextInlineRange(int p, int n) { Start = p; Count = n; }
|
public TextInlineRange(int p, int n) { Start = p; End = p + n - 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TextDiffLine
|
public class TextDiffLine
|
||||||
|
|
|
@ -79,6 +79,12 @@ namespace SourceGit.Models
|
||||||
public string LaunchCommand { get; set; }
|
public string LaunchCommand { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ExternalToolPaths
|
||||||
|
{
|
||||||
|
[JsonPropertyName("tools")]
|
||||||
|
public Dictionary<string, string> Tools { get; set; } = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
public class ExternalToolsFinder
|
public class ExternalToolsFinder
|
||||||
{
|
{
|
||||||
public List<ExternalTool> Founded
|
public List<ExternalTool> Founded
|
||||||
|
@ -87,42 +93,60 @@ namespace SourceGit.Models
|
||||||
private set;
|
private set;
|
||||||
} = new List<ExternalTool>();
|
} = new List<ExternalTool>();
|
||||||
|
|
||||||
public void TryAdd(string name, string icon, string args, string env, Func<string> finder)
|
public ExternalToolsFinder()
|
||||||
{
|
{
|
||||||
var path = Environment.GetEnvironmentVariable(env);
|
var customPathsConfig = Path.Combine(Native.OS.DataDir, "external_editors.json");
|
||||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
try
|
||||||
{
|
{
|
||||||
path = finder();
|
if (File.Exists(customPathsConfig))
|
||||||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
_customPaths = JsonSerializer.Deserialize(File.ReadAllText(customPathsConfig), JsonCodeGen.Default.ExternalToolPaths);
|
||||||
return;
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_customPaths == null)
|
||||||
|
_customPaths = new ExternalToolPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TryAdd(string name, string icon, string args, string key, Func<string> finder)
|
||||||
|
{
|
||||||
|
if (_customPaths.Tools.TryGetValue(key, out var customPath) && File.Exists(customPath))
|
||||||
|
{
|
||||||
|
Founded.Add(new ExternalTool(name, icon, customPath, args));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var path = finder();
|
||||||
|
if (!string.IsNullOrEmpty(path) && File.Exists(path))
|
||||||
Founded.Add(new ExternalTool(name, icon, path, args));
|
Founded.Add(new ExternalTool(name, icon, path, args));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void VSCode(Func<string> platformFinder)
|
public void VSCode(Func<string> platformFinder)
|
||||||
{
|
{
|
||||||
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE_PATH", platformFinder);
|
TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE", platformFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void VSCodeInsiders(Func<string> platformFinder)
|
public void VSCodeInsiders(Func<string> platformFinder)
|
||||||
{
|
{
|
||||||
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS_PATH", platformFinder);
|
TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS", platformFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void VSCodium(Func<string> platformFinder)
|
public void VSCodium(Func<string> platformFinder)
|
||||||
{
|
{
|
||||||
TryAdd("VSCodium", "codium", "\"{0}\"", "VSCODIUM_PATH", platformFinder);
|
TryAdd("VSCodium", "codium", "\"{0}\"", "VSCODIUM", platformFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Fleet(Func<string> platformFinder)
|
public void Fleet(Func<string> platformFinder)
|
||||||
{
|
{
|
||||||
TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET_PATH", platformFinder);
|
TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET", platformFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SublimeText(Func<string> platformFinder)
|
public void SublimeText(Func<string> platformFinder)
|
||||||
{
|
{
|
||||||
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT_PATH", platformFinder);
|
TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT", platformFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FindJetBrainsFromToolbox(Func<string> platformFinder)
|
public void FindJetBrainsFromToolbox(Func<string> platformFinder)
|
||||||
|
@ -146,5 +170,7 @@ namespace SourceGit.Models
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExternalToolPaths _customPaths = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using Avalonia.Controls.Documents;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
|
@ -10,6 +10,7 @@ namespace SourceGit.Models
|
||||||
public int Start { get; set; } = 0;
|
public int Start { get; set; } = 0;
|
||||||
public int Length { get; set; } = 0;
|
public int Length { get; set; } = 0;
|
||||||
public string URL { get; set; } = "";
|
public string URL { get; set; } = "";
|
||||||
|
public Run Link { get; set; } = null;
|
||||||
|
|
||||||
public bool Intersect(int start, int length)
|
public bool Intersect(int start, int length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,10 +58,12 @@ namespace SourceGit.Models
|
||||||
|
|
||||||
if (URL.StartsWith("http", StringComparison.Ordinal))
|
if (URL.StartsWith("http", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
if (URL.EndsWith(".git"))
|
// Try to remove the user before host and `.git` extension.
|
||||||
url = URL.Substring(0, URL.Length - 4);
|
var uri = new Uri(URL.EndsWith(".git", StringComparison.Ordinal) ? URL.Substring(0, URL.Length - 4) : URL);
|
||||||
|
if (uri.Port != 80 && uri.Port != 443)
|
||||||
|
url = $"{uri.Scheme}://{uri.Host}:{uri.Port}{uri.LocalPath}";
|
||||||
else
|
else
|
||||||
url = URL;
|
url = $"{uri.Scheme}://{uri.Host}{uri.LocalPath}";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,12 @@ namespace SourceGit.Models
|
||||||
set;
|
set;
|
||||||
} = new AvaloniaList<string>();
|
} = new AvaloniaList<string>();
|
||||||
|
|
||||||
|
public AvaloniaList<CommitTemplate> CommitTemplates
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
} = new AvaloniaList<CommitTemplate>();
|
||||||
|
|
||||||
public AvaloniaList<string> CommitMessages
|
public AvaloniaList<string> CommitMessages
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
|
|
|
@ -1,24 +1,102 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
|
using Avalonia.Platform;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
|
|
||||||
using AvaloniaEdit;
|
using AvaloniaEdit;
|
||||||
using AvaloniaEdit.TextMate;
|
using AvaloniaEdit.TextMate;
|
||||||
|
|
||||||
using TextMateSharp.Grammars;
|
using TextMateSharp.Grammars;
|
||||||
|
using TextMateSharp.Internal.Grammars.Reader;
|
||||||
|
using TextMateSharp.Internal.Types;
|
||||||
|
using TextMateSharp.Registry;
|
||||||
|
using TextMateSharp.Themes;
|
||||||
|
|
||||||
namespace SourceGit.Models
|
namespace SourceGit.Models
|
||||||
{
|
{
|
||||||
|
public class RegistryOptionsWrapper : IRegistryOptions
|
||||||
|
{
|
||||||
|
public RegistryOptionsWrapper(ThemeName defaultTheme)
|
||||||
|
{
|
||||||
|
_backend = new RegistryOptions(defaultTheme);
|
||||||
|
_extraGrammars = new List<IRawGrammar>();
|
||||||
|
|
||||||
|
string[] extraGrammarFiles = ["toml.json"];
|
||||||
|
foreach (var file in extraGrammarFiles)
|
||||||
|
{
|
||||||
|
var asset = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/Grammars/{file}",
|
||||||
|
UriKind.RelativeOrAbsolute));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var grammar = GrammarReader.ReadGrammarSync(new StreamReader(asset));
|
||||||
|
_extraGrammars.Add(grammar);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme GetTheme(string scopeName)
|
||||||
|
{
|
||||||
|
return _backend.GetTheme(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawGrammar GetGrammar(string scopeName)
|
||||||
|
{
|
||||||
|
var grammar = _extraGrammars.Find(x => x.GetScopeName().Equals(scopeName, StringComparison.Ordinal));
|
||||||
|
return grammar ?? _backend.GetGrammar(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICollection<string> GetInjections(string scopeName)
|
||||||
|
{
|
||||||
|
return _backend.GetInjections(scopeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme GetDefaultTheme()
|
||||||
|
{
|
||||||
|
return _backend.GetDefaultTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRawTheme LoadTheme(ThemeName name)
|
||||||
|
{
|
||||||
|
return _backend.LoadTheme(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetScopeByFileName(string filename)
|
||||||
|
{
|
||||||
|
var extension = Path.GetExtension(filename);
|
||||||
|
var grammar = _extraGrammars.Find(x => x.GetScopeName().EndsWith(extension, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (grammar != null)
|
||||||
|
return grammar.GetScopeName();
|
||||||
|
|
||||||
|
if (extension == ".h")
|
||||||
|
extension = ".cpp";
|
||||||
|
else if (extension == ".resx" || extension == ".plist" || extension == ".manifest")
|
||||||
|
extension = ".xml";
|
||||||
|
else if (extension == ".command")
|
||||||
|
extension = ".sh";
|
||||||
|
|
||||||
|
return _backend.GetScopeByExtension(extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly RegistryOptions _backend;
|
||||||
|
private readonly List<IRawGrammar> _extraGrammars;
|
||||||
|
}
|
||||||
|
|
||||||
public static class TextMateHelper
|
public static class TextMateHelper
|
||||||
{
|
{
|
||||||
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
public static TextMate.Installation CreateForEditor(TextEditor editor)
|
||||||
{
|
{
|
||||||
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
||||||
return editor.InstallTextMate(new RegistryOptions(ThemeName.DarkPlus));
|
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.DarkPlus));
|
||||||
|
|
||||||
return editor.InstallTextMate(new RegistryOptions(ThemeName.LightPlus));
|
return editor.InstallTextMate(new RegistryOptionsWrapper(ThemeName.LightPlus));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetThemeByApp(TextMate.Installation installation)
|
public static void SetThemeByApp(TextMate.Installation installation)
|
||||||
|
@ -26,26 +104,18 @@ namespace SourceGit.Models
|
||||||
if (installation == null)
|
if (installation == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (installation.RegistryOptions is RegistryOptions reg)
|
if (installation.RegistryOptions is RegistryOptionsWrapper reg)
|
||||||
{
|
{
|
||||||
if (Application.Current?.ActualThemeVariant == ThemeVariant.Dark)
|
var isDark = Application.Current?.ActualThemeVariant == ThemeVariant.Dark;
|
||||||
installation.SetTheme(reg.LoadTheme(ThemeName.DarkPlus));
|
installation.SetTheme(reg.LoadTheme(isDark ? ThemeName.DarkPlus : ThemeName.LightPlus));
|
||||||
else
|
|
||||||
installation.SetTheme(reg.LoadTheme(ThemeName.LightPlus));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetGrammarByFileName(TextMate.Installation installation, string filePath)
|
public static void SetGrammarByFileName(TextMate.Installation installation, string filePath)
|
||||||
{
|
{
|
||||||
if (installation is { RegistryOptions: RegistryOptions reg })
|
if (installation is { RegistryOptions: RegistryOptionsWrapper reg })
|
||||||
{
|
{
|
||||||
var ext = Path.GetExtension(filePath);
|
installation.SetGrammar(reg.GetScopeByFileName(filePath));
|
||||||
if (ext == ".h")
|
|
||||||
ext = ".cpp";
|
|
||||||
else if (ext == ".resx" || ext == ".plist")
|
|
||||||
ext = ".xml";
|
|
||||||
|
|
||||||
installation.SetGrammar(reg.GetScopeByExtension(ext));
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Dialogs;
|
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace SourceGit.Native
|
namespace SourceGit.Native
|
||||||
|
@ -47,9 +46,6 @@ namespace SourceGit.Native
|
||||||
{
|
{
|
||||||
EnableIme = true,
|
EnableIme = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Free-desktop file picker has an extra black background panel.
|
|
||||||
builder.UseManagedSystemDialogs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string FindGitExecutable()
|
public string FindGitExecutable()
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace SourceGit.Native
|
||||||
{
|
{
|
||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Process.Start("open", path);
|
Process.Start("open", $"\"{path}\"");
|
||||||
}
|
}
|
||||||
else if (File.Exists(path))
|
else if (File.Exists(path))
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,9 +21,9 @@ namespace SourceGit.Native
|
||||||
void OpenWithDefaultEditor(string file);
|
void OpenWithDefaultEditor(string file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly string DataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SourceGit");
|
public static string DataDir { get; private set; } = string.Empty;
|
||||||
public static string GitExecutable { get; set; } = string.Empty;
|
public static string GitExecutable { get; set; } = string.Empty;
|
||||||
public static List<Models.ExternalTool> ExternalTools { get; set; } = new List<Models.ExternalTool>();
|
public static List<Models.ExternalTool> ExternalTools { get; set; } = [];
|
||||||
|
|
||||||
static OS()
|
static OS()
|
||||||
{
|
{
|
||||||
|
@ -70,10 +70,19 @@ namespace SourceGit.Native
|
||||||
|
|
||||||
public static void SetupApp(AppBuilder builder)
|
public static void SetupApp(AppBuilder builder)
|
||||||
{
|
{
|
||||||
|
_backend.SetupApp(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetupDataDir()
|
||||||
|
{
|
||||||
|
var osAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||||
|
if (string.IsNullOrEmpty(osAppDataDir))
|
||||||
|
DataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".sourcegit");
|
||||||
|
else
|
||||||
|
DataDir = Path.Combine(osAppDataDir, "SourceGit");
|
||||||
|
|
||||||
if (!Directory.Exists(DataDir))
|
if (!Directory.Exists(DataDir))
|
||||||
Directory.CreateDirectory(DataDir);
|
Directory.CreateDirectory(DataDir);
|
||||||
|
|
||||||
_backend.SetupApp(builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetupEnternalTools()
|
public static void SetupEnternalTools()
|
||||||
|
|
343
src/Resources/Grammars/toml.json
Normal file
343
src/Resources/Grammars/toml.json
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scopeName": "source.toml",
|
||||||
|
"uuid": "8b4e5008-c50d-11ea-a91b-54ee75aeeb97",
|
||||||
|
"information_for_contributors": [
|
||||||
|
"Originally was maintained by aster (galaster@foxmail.com). This notice is only kept here for the record, please don't send e-mails about bugs and other issues."
|
||||||
|
],
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#commentDirective"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#table"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"comment": {
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "comment.line.number-sign.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.definition.comment.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"comment": "Comments",
|
||||||
|
"match": "\\s*((#).*)$"
|
||||||
|
},
|
||||||
|
"commentDirective": {
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "meta.preprocessor.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.definition.meta.preprocessor.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"comment": "Comments",
|
||||||
|
"match": "\\s*((#):.*)$"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "meta.table.toml",
|
||||||
|
"match": "^\\s*(\\[)\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(\\])",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.table.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "punctuation.definition.table.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "meta.array.table.toml",
|
||||||
|
"match": "^\\s*(\\[\\[)\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(\\]\\])",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.table.toml"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.array.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"name": "punctuation.definition.array.table.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "(\\{)",
|
||||||
|
"end": "(\\})",
|
||||||
|
"name": "meta.table.inline.toml",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.table.inline.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"entryBegin": {
|
||||||
|
"name": "meta.entry.toml",
|
||||||
|
"match": "\\s*((?:(?:(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+'))\\s*\\.?\\s*)+)\\s*(=)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "(?:[A-Za-z0-9_+-]+)|(?:\"[^\"]+\")|(?:'[^']+')",
|
||||||
|
"name": "support.type.property-name.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\.",
|
||||||
|
"name": "punctuation.separator.dot.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"name": "punctuation.eq.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "string.quoted.triple.basic.block.toml",
|
||||||
|
"begin": "\"\"\"",
|
||||||
|
"end": "\"\"\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "\\\\([btnfr\"\\\\\\n/ ]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})",
|
||||||
|
"name": "constant.character.escape.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\\\[^btnfr/\"\\\\\\n]",
|
||||||
|
"name": "invalid.illegal.escape.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.single.basic.line.toml",
|
||||||
|
"begin": "\"",
|
||||||
|
"end": "\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": "\\\\([btnfr\"\\\\\\n/ ]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})",
|
||||||
|
"name": "constant.character.escape.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "\\\\[^btnfr/\"\\\\\\n]",
|
||||||
|
"name": "invalid.illegal.escape.toml"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.triple.literal.block.toml",
|
||||||
|
"begin": "'''",
|
||||||
|
"end": "'''"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "string.quoted.single.literal.line.toml",
|
||||||
|
"begin": "'",
|
||||||
|
"end": "'"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.other.time.datetime.offset.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"match": "(?<!\\w)(\\d{4}\\-\\d{2}\\-\\d{2}[T| ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[\\+\\-]\\d{2}:\\d{2}))(?!\\w)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.other.time.datetime.local.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"match": "(\\d{4}\\-\\d{2}\\-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.other.time.date.toml",
|
||||||
|
"match": "\\d{4}\\-\\d{2}\\-\\d{2}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "constant.other.time.time.toml",
|
||||||
|
"match": "\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(true|false)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.language.boolean.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?(0|([1-9](([0-9]|_[0-9])+)?))(?:(?:\\.([0-9]+))?[eE][\\+\\-]?[1-9]_?[0-9]*|(?:\\.[0-9_]*)))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.float.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)((?:[\\+\\-]?(0|([1-9](([0-9]|_[0-9])+)?))))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.integer.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?inf)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.inf.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)([\\+\\-]?nan)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.nan.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)((?:0x(([0-9a-fA-F](([0-9a-fA-F]|_[0-9a-fA-F])+)?))))(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.hex.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(0o[0-7](_?[0-7])*)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.oct.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": "(?<!\\w)(0b[01](_?[01])*)(?!\\w)",
|
||||||
|
"captures": {
|
||||||
|
"1": {
|
||||||
|
"name": "constant.numeric.bin.toml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "meta.array.toml",
|
||||||
|
"begin": "(?<!\\w)(\\[)\\s*",
|
||||||
|
"end": "\\s*(\\])(?!\\w)",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.array.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.array.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"begin": "(\\{)",
|
||||||
|
"end": "(\\})",
|
||||||
|
"name": "meta.table.inline.toml",
|
||||||
|
"beginCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"endCaptures": {
|
||||||
|
"1": {
|
||||||
|
"name": "punctuation.definition.table.inline.toml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"include": "#comment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"match": ",",
|
||||||
|
"name": "punctuation.separator.table.inline.toml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#entryBegin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": "#value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
<StreamGeometry x:Key="Icons.Clear">M512 57c251 0 455 204 455 455S763 967 512 967 57 763 57 512 261 57 512 57zm181 274c-11-11-29-11-40 0L512 472 371 331c-11-11-29-11-40 0-11 11-11 29 0 40L471 512 331 653c-11 11-11 29 0 40 11 11 29 11 40 0l141-141 141 141c11 11 29 11 40 0 11-11 11-29 0-40L552 512l141-141c11-11 11-29 0-40z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Clear">M512 57c251 0 455 204 455 455S763 967 512 967 57 763 57 512 261 57 512 57zm181 274c-11-11-29-11-40 0L512 472 371 331c-11-11-29-11-40 0-11 11-11 29 0 40L471 512 331 653c-11 11-11 29 0 40 11 11 29 11 40 0l141-141 141 141c11 11 29 11 40 0 11-11 11-29 0-40L552 512l141-141c11-11 11-29 0-40z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Clean">M797 829a49 49 0 1049 49 49 49 0 00-49-49zm147-114A49 49 0 10992 764a49 49 0 00-49-49zM928 861a49 49 0 1049 49A49 49 0 00928 861zm-5-586L992 205 851 64l-71 71a67 67 0 00-94 0l235 235a67 67 0 000-94zm-853 128a32 32 0 00-32 50 1291 1291 0 0075 112L288 552c20 0 25 21 8 37l-93 86a1282 1282 0 00120 114l100-32c19-6 28 15 14 34l-40 55c26 19 53 36 82 53a89 89 0 00115-20 1391 1391 0 00256-485l-188-188s-306 224-595 198z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Clean">M797 829a49 49 0 1049 49 49 49 0 00-49-49zm147-114A49 49 0 10992 764a49 49 0 00-49-49zM928 861a49 49 0 1049 49A49 49 0 00928 861zm-5-586L992 205 851 64l-71 71a67 67 0 00-94 0l235 235a67 67 0 000-94zm-853 128a32 32 0 00-32 50 1291 1291 0 0075 112L288 552c20 0 25 21 8 37l-93 86a1282 1282 0 00120 114l100-32c19-6 28 15 14 34l-40 55c26 19 53 36 82 53a89 89 0 00115-20 1391 1391 0 00256-485l-188-188s-306 224-595 198z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Clone">M1280 704c0 141-115 256-256 256H288C129 960 0 831 0 672c0-126 80-232 192-272A327 327 0 01192 384c0-177 143-320 320-320 119 0 222 64 277 160C820 204 857 192 896 192c106 0 192 86 192 192 0 24-5 48-13 69C1192 477 1280 580 1280 704zm-493-128H656V352c0-18-14-32-32-32h-96c-18 0-32 14-32 32v224h-131c-29 0-43 34-23 55l211 211c12 12 33 12 45 0l211-211c20-20 6-55-23-55z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Clone">M1280 704c0 141-115 256-256 256H288C129 960 0 831 0 672c0-126 80-232 192-272A327 327 0 01192 384c0-177 143-320 320-320 119 0 222 64 277 160C820 204 857 192 896 192c106 0 192 86 192 192 0 24-5 48-13 69C1192 477 1280 580 1280 704zm-493-128H656V352c0-18-14-32-32-32h-96c-18 0-32 14-32 32v224h-131c-29 0-43 34-23 55l211 211c12 12 33 12 45 0l211-211c20-20 6-55-23-55z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="Icons.Code">M853 102H171C133 102 102 133 102 171v683C102 891 133 922 171 922h683C891 922 922 891 922 853V171C922 133 891 102 853 102zM390 600l-48 48L205 512l137-137 48 48L301 512l88 88zM465 819l-66-18L559 205l66 18L465 819zm218-171L634 600 723 512l-88-88 48-48L819 512 683 649z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Commit">M796 471A292 292 0 00512 256a293 293 0 00-284 215H0v144h228A293 293 0 00512 832a291 291 0 00284-217H1024V471h-228M512 688A146 146 0 01366 544A145 145 0 01512 400c80 0 146 63 146 144A146 146 0 01512 688</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Commit">M796 471A292 292 0 00512 256a293 293 0 00-284 215H0v144h228A293 293 0 00512 832a291 291 0 00284-217H1024V471h-228M512 688A146 146 0 01366 544A145 145 0 01512 400c80 0 146 63 146 144A146 146 0 01512 688</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Compare">M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Compare">M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Conflict">M608 0q48 0 88 23t63 63 23 87v70h55q35 0 67 14t57 38 38 57 14 67V831q0 34-14 66t-38 57-57 38-67 13H426q-34 0-66-13t-57-38-38-57-14-66v-70h-56q-34 0-66-14t-57-38-38-57-13-67V174q0-47 23-87T109 23 196 0h412m175 244H426q-46 0-86 22T278 328t-26 85v348H608q47 0 86-22t63-62 25-85l1-348m-269 318q18 0 31 13t13 31-13 31-31 13-31-13-13-31 13-31 31-13m0-212q13 0 22 9t11 22v125q0 14-9 23t-22 10-23-7-11-22l-1-126q0-13 10-23t23-10z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Conflict">M608 0q48 0 88 23t63 63 23 87v70h55q35 0 67 14t57 38 38 57 14 67V831q0 34-14 66t-38 57-57 38-67 13H426q-34 0-66-13t-57-38-38-57-14-66v-70h-56q-34 0-66-14t-57-38-38-57-13-67V174q0-47 23-87T109 23 196 0h412m175 244H426q-46 0-86 22T278 328t-26 85v348H608q47 0 86-22t63-62 25-85l1-348m-269 318q18 0 31 13t13 31-13 31-31 13-31-13-13-31 13-31 31-13m0-212q13 0 22 9t11 22v125q0 14-9 23t-22 10-23-7-11-22l-1-126q0-13 10-23t23-10z</StreamGeometry>
|
||||||
|
@ -33,6 +34,7 @@
|
||||||
<StreamGeometry x:Key="Icons.Fetch">M1024 896v128H0V704h128v192h768V704h128v192zM576 555 811 320 896 405l-384 384-384-384L213 320 448 555V0h128v555z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Fetch">M1024 896v128H0V704h128v192h768V704h128v192zM576 555 811 320 896 405l-384 384-384-384L213 320 448 555V0h128v555z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.File">M959 320H960v640A64 64 0 01896 1024H192A64 64 0 01128 960V64A64 64 0 01192 0H640v321h320L959 320zM320 544c0 17 14 32 32 32h384A32 32 0 00768 544c0-17-14-32-32-32H352A32 32 0 00320 544zm0 128c0 17 14 32 32 32h384a32 32 0 0032-32c0-17-14-32-32-32H352a32 32 0 00-32 32zm0 128c0 17 14 32 32 32h384a32 32 0 0032-32c0-17-14-32-32-32H352a32 32 0 00-32 32z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.File">M959 320H960v640A64 64 0 01896 1024H192A64 64 0 01128 960V64A64 64 0 01192 0H640v321h320L959 320zM320 544c0 17 14 32 32 32h384A32 32 0 00768 544c0-17-14-32-32-32H352A32 32 0 00320 544zm0 128c0 17 14 32 32 32h384a32 32 0 0032-32c0-17-14-32-32-32H352a32 32 0 00-32 32zm0 128c0 17 14 32 32 32h384a32 32 0 0032-32c0-17-14-32-32-32H352a32 32 0 00-32 32z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.File.Add">M683 85l213 213v598a42 42 0 01-42 42H170A43 43 0 01128 896V128C128 104 147 85 170 85H683zm-213 384H341v85h128v128h85v-128h128v-85h-128V341h-85v128z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.File.Add">M683 85l213 213v598a42 42 0 01-42 42H170A43 43 0 01128 896V128C128 104 147 85 170 85H683zm-213 384H341v85h128v128h85v-128h128v-85h-128V341h-85v128z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="Icons.File.Checkout">M949 727l-217-231a33 33 0 00-48 0 33 33 0 000 48l157 172H389a35 35 0 00-35 35c0 19 16 34 35 34h452l-160 179a34 34 0 005 54c14 10 33 7 45-5l219-237a33 33 0 000-49zM719 196h131c-24-91-95-160-185-185v131c0 27 25 54 54 54zM129 846l1-747s-7-37 36-33h359v52s-7 76 32 133a191 191 0 00146 84h91v126h66v-191H719a126 126 0 01-127-127V0H155c-51 0-91 40-91 91v767c0 51 40 91 91 91h193v-66H155c0-0-26 4-26-36z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.File.Ignore">M416 832H128V128h384v192C512 355 541 384 576 384L768 384v32c0 19 13 32 32 32S832 435 832 416v-64c0-6 0-19-6-25l-256-256c-6-6-19-6-25-6H128A64 64 0 0064 128v704C64 867 93 896 129 896h288c19 0 32-13 32-32S435 832 416 832zM576 172 722 320H576V172zM736 512C614 512 512 614 512 736S614 960 736 960s224-102 224-224S858 512 736 512zM576 736C576 646 646 576 736 576c32 0 58 6 83 26l-218 218c-19-26-26-51-26-83zm160 160c-32 0-64-13-96-32l224-224c19 26 32 58 32 96 0 90-70 160-160 160z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.File.Ignore">M416 832H128V128h384v192C512 355 541 384 576 384L768 384v32c0 19 13 32 32 32S832 435 832 416v-64c0-6 0-19-6-25l-256-256c-6-6-19-6-25-6H128A64 64 0 0064 128v704C64 867 93 896 129 896h288c19 0 32-13 32-32S435 832 416 832zM576 172 722 320H576V172zM736 512C614 512 512 614 512 736S614 960 736 960s224-102 224-224S858 512 736 512zM576 736C576 646 646 576 736 576c32 0 58 6 83 26l-218 218c-19-26-26-51-26-83zm160 160c-32 0-64-13-96-32l224-224c19 26 32 58 32 96 0 90-70 160-160 160z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.File.Remove">M896 320c0-19-6-32-19-45l-192-192c-13-13-26-19-45-19H192c-38 0-64 26-64 64v768c0 38 26 64 64 64h640c38 0 64-26 64-64V320zm-256 384H384c-19 0-32-13-32-32s13-32 32-32h256c19 0 32 13 32 32s-13 32-32 32zm166-384H640V128l192 192h-26z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.File.Remove">M896 320c0-19-6-32-19-45l-192-192c-13-13-26-19-45-19H192c-38 0-64 26-64 64v768c0 38 26 64 64 64h640c38 0 64-26 64-64V320zm-256 384H384c-19 0-32-13-32-32s13-32 32-32h256c19 0 32 13 32 32s-13 32-32 32zm166-384H640V128l192 192h-26z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Filter">M599 425 599 657 425 832 425 425 192 192 832 192Z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Filter">M599 425 599 657 425 832 425 425 192 192 832 192Z</StreamGeometry>
|
||||||
|
@ -59,6 +61,7 @@
|
||||||
<StreamGeometry x:Key="Icons.LFS">M40 9 15 23 15 31 9 28 9 20 34 5 24 0 0 14 0 34 25 48 25 28 49 14zM26 29 26 48 49 34 49 15z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.LFS">M40 9 15 23 15 31 9 28 9 20 34 5 24 0 0 14 0 34 25 48 25 28 49 14zM26 29 26 48 49 34 49 15z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Lines.Incr">M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l132 0 0-128 64 0 0 128 132 0 0 64-132 0 0 128-64 0 0-128-132 0Z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Lines.Incr">M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l132 0 0-128 64 0 0 128 132 0 0 64-132 0 0 128-64 0 0-128-132 0Z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Lines.Decr">M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l328 0 0 64-328 0Z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Lines.Decr">M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l328 0 0 64-328 0Z</StreamGeometry>
|
||||||
|
<StreamGeometry x:Key="Icons.Link">M 968 418 l -95 94 c -59 59 -146 71 -218 37 L 874 331 a 64 64 0 0 0 0 -90 L 783 150 a 64 64 0 0 0 -90 0 L 475 368 c -34 -71 -22 -159 37 -218 l 94 -94 c 75 -75 196 -75 271 0 l 90 90 c 75 75 75 196 0 271 z M 332 693 a 64 64 0 0 1 0 -90 l 271 -271 c 25 -25 65 -25 90 0 s 25 65 0 90 L 422 693 a 64 64 0 0 1 -90 0 z M 151 783 l 90 90 a 64 64 0 0 0 90 0 l 218 -218 c 34 71 22 159 -37 218 l -86 94 a 192 192 0 0 1 -271 0 l -98 -98 a 192 192 0 0 1 0 -271 l 94 -86 c 59 -59 146 -71 218 -37 L 151 693 a 64 64 0 0 0 0 90 z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.List">M0 33h1024v160H0zM0 432h1024v160H0zM0 831h1024v160H0z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.List">M0 33h1024v160H0zM0 432h1024v160H0zM0 831h1024v160H0z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Loading">M512 0C233 0 7 223 0 500C6 258 190 64 416 64c230 0 416 200 416 448c0 53 43 96 96 96s96-43 96-96c0-283-229-512-512-512zm0 1023c279 0 505-223 512-500c-6 242-190 436-416 436c-230 0-416-200-416-448c0-53-43-96-96-96s-96 43-96 96c0 283 229 512 512 512z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Loading">M512 0C233 0 7 223 0 500C6 258 190 64 416 64c230 0 416 200 416 448c0 53 43 96 96 96s96-43 96-96c0-283-229-512-512-512zm0 1023c279 0 505-223 512-500c-6 242-190 436-416 436c-230 0-416-200-416-448c0-53-43-96-96-96s-96 43-96 96c0 283 229 512 512 512z</StreamGeometry>
|
||||||
<StreamGeometry x:Key="Icons.Local">M976 0h-928A48 48 0 000 48v652a48 48 0 0048 48h416V928H200a48 48 0 000 96h624a48 48 0 000-96H560v-180h416a48 48 0 0048-48V48A48 48 0 00976 0zM928 652H96V96h832v556z</StreamGeometry>
|
<StreamGeometry x:Key="Icons.Local">M976 0h-928A48 48 0 000 48v652a48 48 0 0048 48h416V928H200a48 48 0 000 96h624a48 48 0 000-96H560v-180h416a48 48 0 0048-48V48A48 48 0 00976 0zM928 652H96V96h832v556z</StreamGeometry>
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
<x:String x:Key="Text.About.Menu" xml:space="preserve">Über SourceGit</x:String>
|
<x:String x:Key="Text.About.Menu" xml:space="preserve">Über SourceGit</x:String>
|
||||||
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Erstellt mit </x:String>
|
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Erstellt mit </x:String>
|
||||||
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
|
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
|
||||||
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Text Editor von </x:String>
|
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Texteditor von </x:String>
|
||||||
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Monospace-Schriftarten von </x:String>
|
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Monospace-Schriftarten von </x:String>
|
||||||
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Quelltext findest du unter </x:String>
|
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Quelltext findest du auf </x:String>
|
||||||
<x:String x:Key="Text.About.SubTitle" xml:space="preserve">Open Source & freier Git GUI Client</x:String>
|
<x:String x:Key="Text.About.SubTitle" xml:space="preserve">Open Source & freier Git GUI Client</x:String>
|
||||||
<x:String x:Key="Text.AddWorktree" xml:space="preserve">Worktree hinzufügen</x:String>
|
<x:String x:Key="Text.AddWorktree" xml:space="preserve">Worktree hinzufügen</x:String>
|
||||||
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">Was auschecken:</x:String>
|
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">Was auschecken:</x:String>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<x:String x:Key="Text.Apply.File.Placeholder" xml:space="preserve">Wähle die anzuwendende .patch-Datei</x:String>
|
<x:String x:Key="Text.Apply.File.Placeholder" xml:space="preserve">Wähle die anzuwendende .patch-Datei</x:String>
|
||||||
<x:String x:Key="Text.Apply.IgnoreWS" xml:space="preserve">Ignoriere Leerzeichenänderungen</x:String>
|
<x:String x:Key="Text.Apply.IgnoreWS" xml:space="preserve">Ignoriere Leerzeichenänderungen</x:String>
|
||||||
<x:String x:Key="Text.Apply.NoWarn" xml:space="preserve">Keine Warnungen</x:String>
|
<x:String x:Key="Text.Apply.NoWarn" xml:space="preserve">Keine Warnungen</x:String>
|
||||||
<x:String x:Key="Text.Apply.NoWarn.Desc" xml:space="preserve">Schaltet die Warnung vor nachgestellte Leerzeichen aus</x:String>
|
<x:String x:Key="Text.Apply.NoWarn.Desc" xml:space="preserve">Keine Warnung vor Leerzeichen am Zeilenende</x:String>
|
||||||
<x:String x:Key="Text.Apply.Title" xml:space="preserve">Patch anwenden</x:String>
|
<x:String x:Key="Text.Apply.Title" xml:space="preserve">Patch anwenden</x:String>
|
||||||
<x:String x:Key="Text.Apply.Warn" xml:space="preserve">Warnen</x:String>
|
<x:String x:Key="Text.Apply.Warn" xml:space="preserve">Warnen</x:String>
|
||||||
<x:String x:Key="Text.Apply.Warn.Desc" xml:space="preserve">Gibt eine Warnung für ein paar solcher Fehler aus, aber wendet es an</x:String>
|
<x:String x:Key="Text.Apply.Warn.Desc" xml:space="preserve">Gibt eine Warnung für ein paar solcher Fehler aus, aber wendet es an</x:String>
|
||||||
|
@ -41,12 +41,12 @@
|
||||||
<x:String x:Key="Text.Archive.Title" xml:space="preserve">Archiv erstellen</x:String>
|
<x:String x:Key="Text.Archive.Title" xml:space="preserve">Archiv erstellen</x:String>
|
||||||
<x:String x:Key="Text.Askpass" xml:space="preserve">SourceGit Askpass</x:String>
|
<x:String x:Key="Text.Askpass" xml:space="preserve">SourceGit Askpass</x:String>
|
||||||
<x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ALS UNVERÄNDERT ANGENOMMENE DATEIEN</x:String>
|
<x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ALS UNVERÄNDERT ANGENOMMENE DATEIEN</x:String>
|
||||||
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE UNVERÄNDERT ANGENOMMENEN DATEIEN GEFUNDEN</x:String>
|
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE ALS UNVERÄNDERT ANGENOMMENEN DATEIEN</x:String>
|
||||||
<x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String>
|
<x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String>
|
||||||
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
||||||
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
|
||||||
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">${0}$ auschecken...</x:String>
|
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auscheken von ${0}$...</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Mit Branch vergleichen</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Mit Branch vergleichen</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
|
||||||
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
|
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
|
||||||
|
@ -166,6 +166,7 @@
|
||||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Art:</x:String>
|
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Art:</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">Mit Anmerkung</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">Mit Anmerkung</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Ohne Anmerkung</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Ohne Anmerkung</x:String>
|
||||||
|
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Halte Strg gedrückt, um direkt auszuführen</x:String>
|
||||||
<x:String x:Key="Text.Cut" xml:space="preserve">Ausschneiden</x:String>
|
<x:String x:Key="Text.Cut" xml:space="preserve">Ausschneiden</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Branch löschen</x:String>
|
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Branch löschen</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
||||||
|
@ -218,7 +219,7 @@
|
||||||
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
|
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
|
||||||
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Alle Remotes fetchen</x:String>
|
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Alle Remotes fetchen</x:String>
|
||||||
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Ohne Tags fetchen</x:String>
|
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Ohne Tags fetchen</x:String>
|
||||||
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Alle toten remote Branches entfernen</x:String>
|
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Alle verwaisten Branches entfernen</x:String>
|
||||||
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remote:</x:String>
|
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remote:</x:String>
|
||||||
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Remote-Änderungen fetchen</x:String>
|
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Remote-Änderungen fetchen</x:String>
|
||||||
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Als unverändert annehmen</x:String>
|
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Als unverändert annehmen</x:String>
|
||||||
|
@ -240,7 +241,7 @@
|
||||||
<x:String x:Key="Text.FileHistory" xml:space="preserve">Datei Historie</x:String>
|
<x:String x:Key="Text.FileHistory" xml:space="preserve">Datei Historie</x:String>
|
||||||
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</x:String>
|
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</x:String>
|
||||||
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
|
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Entwicklungs-Branch:</x:String>
|
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Development-Branch:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
|
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.FeaturePrefix" xml:space="preserve">Feature-Prefix:</x:String>
|
<x:String x:Key="Text.GitFlow.FeaturePrefix" xml:space="preserve">Feature-Prefix:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.FinishFeature" xml:space="preserve">FLOW - Finish Feature</x:String>
|
<x:String x:Key="Text.GitFlow.FinishFeature" xml:space="preserve">FLOW - Finish Feature</x:String>
|
||||||
|
@ -251,7 +252,7 @@
|
||||||
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix-Prefix:</x:String>
|
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix-Prefix:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Git-Flow initialisieren</x:String>
|
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Git-Flow initialisieren</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.KeepBranchAfterFinish" xml:space="preserve">Branch behalten</x:String>
|
<x:String x:Key="Text.GitFlow.KeepBranchAfterFinish" xml:space="preserve">Branch behalten</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.ProductionBranch" xml:space="preserve">Produktions-Branch:</x:String>
|
<x:String x:Key="Text.GitFlow.ProductionBranch" xml:space="preserve">Production-Branch:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.Release" xml:space="preserve">Release:</x:String>
|
<x:String x:Key="Text.GitFlow.Release" xml:space="preserve">Release:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.ReleasePrefix" xml:space="preserve">Release-Prefix:</x:String>
|
<x:String x:Key="Text.GitFlow.ReleasePrefix" xml:space="preserve">Release-Prefix:</x:String>
|
||||||
<x:String x:Key="Text.GitFlow.StartFeature" xml:space="preserve">Feature starten...</x:String>
|
<x:String x:Key="Text.GitFlow.StartFeature" xml:space="preserve">Feature starten...</x:String>
|
||||||
|
@ -286,9 +287,9 @@
|
||||||
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">LFS Objekte pushen</x:String>
|
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">LFS Objekte pushen</x:String>
|
||||||
<x:String x:Key="Text.GitLFS.Push.Tips" xml:space="preserve">Pushe große Dateien in der Warteschlange zum Git LFS Endpunkt</x:String>
|
<x:String x:Key="Text.GitLFS.Push.Tips" xml:space="preserve">Pushe große Dateien in der Warteschlange zum Git LFS Endpunkt</x:String>
|
||||||
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
|
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
|
||||||
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Verfolge '{0}' benannte Dateien</x:String>
|
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Verfolge alle '{0}' Dateien</x:String>
|
||||||
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Verfolge alle *{0} Dateien</x:String>
|
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Verfolge alle *{0} Dateien</x:String>
|
||||||
<x:String x:Key="Text.Histories" xml:space="preserve">Historien</x:String>
|
<x:String x:Key="Text.Histories" xml:space="preserve">Verlauf</x:String>
|
||||||
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Wechsle zwischen horizontalem und vertikalem Layout</x:String>
|
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Wechsle zwischen horizontalem und vertikalem Layout</x:String>
|
||||||
<x:String x:Key="Text.Histories.GraphMode" xml:space="preserve">Wechsle zwischen Kurven- und Konturgraphenmodus</x:String>
|
<x:String x:Key="Text.Histories.GraphMode" xml:space="preserve">Wechsle zwischen Kurven- und Konturgraphenmodus</x:String>
|
||||||
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTOR</x:String>
|
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTOR</x:String>
|
||||||
|
@ -314,9 +315,9 @@
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Ausgewählte Änderungen stagen/unstagen</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Ausgewählte Änderungen stagen/unstagen</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Commit-Suchmodus</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Commit-Suchmodus</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">Wechsle zu 'Änderungen'</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">Wechsle zu 'Änderungen'</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ViewHistories" xml:space="preserve">Wechsle zu 'Historien'</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ViewHistories" xml:space="preserve">Wechsle zu 'Verlauf'</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.Repo.ViewStashes" xml:space="preserve">Wechsle zu 'Stashes'</x:String>
|
<x:String x:Key="Text.Hotkeys.Repo.ViewStashes" xml:space="preserve">Wechsle zu 'Stashes'</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.TextEditor" xml:space="preserve">TEXT EDITOR</x:String>
|
<x:String x:Key="Text.Hotkeys.TextEditor" xml:space="preserve">TEXTEDITOR</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.TextEditor.CloseSearch" xml:space="preserve">Suchpanel schließen</x:String>
|
<x:String x:Key="Text.Hotkeys.TextEditor.CloseSearch" xml:space="preserve">Suchpanel schließen</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.TextEditor.GotoNextMatch" xml:space="preserve">Suche nächste Übereinstimmung</x:String>
|
<x:String x:Key="Text.Hotkeys.TextEditor.GotoNextMatch" xml:space="preserve">Suche nächste Übereinstimmung</x:String>
|
||||||
<x:String x:Key="Text.Hotkeys.TextEditor.GotoPrevMatch" xml:space="preserve">Suche vorherige Übereinstimmung</x:String>
|
<x:String x:Key="Text.Hotkeys.TextEditor.GotoPrevMatch" xml:space="preserve">Suche vorherige Übereinstimmung</x:String>
|
||||||
|
@ -334,8 +335,8 @@
|
||||||
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Interaktiver Rebase</x:String>
|
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Interaktiver Rebase</x:String>
|
||||||
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Ziel Branch:</x:String>
|
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Ziel Branch:</x:String>
|
||||||
<x:String x:Key="Text.InteractiveRebase.On" xml:space="preserve">Auf:</x:String>
|
<x:String x:Key="Text.InteractiveRebase.On" xml:space="preserve">Auf:</x:String>
|
||||||
<x:String x:Key="Text.InteractiveRebase.MoveUp" xml:space="preserve">Hoch schieben</x:String>
|
<x:String x:Key="Text.InteractiveRebase.MoveUp" xml:space="preserve">Hochschieben</x:String>
|
||||||
<x:String x:Key="Text.InteractiveRebase.MoveDown" xml:space="preserve">Runter schieben</x:String>
|
<x:String x:Key="Text.InteractiveRebase.MoveDown" xml:space="preserve">Runterschieben</x:String>
|
||||||
<x:String x:Key="Text.Launcher" xml:space="preserve">Source Git</x:String>
|
<x:String x:Key="Text.Launcher" xml:space="preserve">Source Git</x:String>
|
||||||
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">FEHLER</x:String>
|
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">FEHLER</x:String>
|
||||||
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">INFO</x:String>
|
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">INFO</x:String>
|
||||||
|
@ -347,14 +348,15 @@
|
||||||
<x:String x:Key="Text.Name" xml:space="preserve">Name:</x:String>
|
<x:String x:Key="Text.Name" xml:space="preserve">Name:</x:String>
|
||||||
<x:String x:Key="Text.NotConfigured" xml:space="preserve">Git wurde NICHT konfiguriert. Gehe bitte zuerst in die [Einstellungen] und konfiguriere Git.</x:String>
|
<x:String x:Key="Text.NotConfigured" xml:space="preserve">Git wurde NICHT konfiguriert. Gehe bitte zuerst in die [Einstellungen] und konfiguriere Git.</x:String>
|
||||||
<x:String x:Key="Text.Notice" xml:space="preserve">BENACHRICHTIGUNG</x:String>
|
<x:String x:Key="Text.Notice" xml:space="preserve">BENACHRICHTIGUNG</x:String>
|
||||||
|
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">App-Daten Ordner öffnen</x:String>
|
||||||
<x:String x:Key="Text.OpenFolder" xml:space="preserve">ORDNER AUSWÄHLEN</x:String>
|
<x:String x:Key="Text.OpenFolder" xml:space="preserve">ORDNER AUSWÄHLEN</x:String>
|
||||||
<x:String x:Key="Text.OpenWith" xml:space="preserve">Öffne mit...</x:String>
|
<x:String x:Key="Text.OpenWith" xml:space="preserve">Öffne mit...</x:String>
|
||||||
<x:String x:Key="Text.Optional" xml:space="preserve">Optional.</x:String>
|
<x:String x:Key="Text.Optional" xml:space="preserve">Optional.</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.New" xml:space="preserve">Neue Seite erstellen</x:String>
|
<x:String x:Key="Text.PageTabBar.New" xml:space="preserve">Neue Seite erstellen</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Tab.Bookmark" xml:space="preserve">Lesezeichen</x:String>
|
<x:String x:Key="Text.PageTabBar.Tab.Bookmark" xml:space="preserve">Lesezeichen</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Tab.Close" xml:space="preserve">Tab schließen</x:String>
|
<x:String x:Key="Text.PageTabBar.Tab.Close" xml:space="preserve">Tab schließen</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Tab.CloseOther" xml:space="preserve">Schließe andere Tabs</x:String>
|
<x:String x:Key="Text.PageTabBar.Tab.CloseOther" xml:space="preserve">Andere Tabs schließen</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Tab.CloseRight" xml:space="preserve">Schließe Rechte Tabs</x:String>
|
<x:String x:Key="Text.PageTabBar.Tab.CloseRight" xml:space="preserve">Rechte Tabs schließen</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Tab.CopyPath" xml:space="preserve">Kopiere Repository-Pfad</x:String>
|
<x:String x:Key="Text.PageTabBar.Tab.CopyPath" xml:space="preserve">Kopiere Repository-Pfad</x:String>
|
||||||
<x:String x:Key="Text.PageTabBar.Welcome.Title" xml:space="preserve">Repositories</x:String>
|
<x:String x:Key="Text.PageTabBar.Welcome.Title" xml:space="preserve">Repositories</x:String>
|
||||||
<x:String x:Key="Text.Paste" xml:space="preserve">Einfügen</x:String>
|
<x:String x:Key="Text.Paste" xml:space="preserve">Einfügen</x:String>
|
||||||
|
@ -368,20 +370,19 @@
|
||||||
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">Leztes Jahr</x:String>
|
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">Leztes Jahr</x:String>
|
||||||
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Vor {0} Jahren</x:String>
|
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Vor {0} Jahren</x:String>
|
||||||
<x:String x:Key="Text.Preference" xml:space="preserve">Einstellungen</x:String>
|
<x:String x:Key="Text.Preference" xml:space="preserve">Einstellungen</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">ERSCHEINUNGSBILD</x:String>
|
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">DARSTELLUNG</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Standardschriftart</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Standardschriftart</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Standardschriftgröße</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Standardschriftgröße</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Monospace-Schriftart</x:String>
|
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Monospace-Schriftart</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Verwende nur die Monospace-Schriftart im Text Editor</x:String>
|
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Verwende nur die Monospace-Schriftart im Texteditor</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Design</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Design</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Design-Anpassungen</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Design-Anpassungen</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">ALLGEMEIN</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">ALLGEMEIN</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Avatar Server</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Beim Starten nach Updates suchen</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Sprache</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Sprache</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.RestoreTabs" xml:space="preserve">Zuletzt geöffnete Tabs beim Starten wiederherstellen</x:String>
|
<x:String x:Key="Text.Preference.General.RestoreTabs" xml:space="preserve">Zuletzt geöffnete Tabs beim Starten wiederherstellen</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Commit-Nachricht Hinweislänge</x:String>
|
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Längenvorgabe für Commit-Nachrichten</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.UseFixedTabWidth" xml:space="preserve">Fixe Tab-Breite in Titelleiste</x:String>
|
<x:String x:Key="Text.Preference.General.UseFixedTabWidth" xml:space="preserve">Fixe Tab-Breite in Titelleiste</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.VisibleDiffContextLines" xml:space="preserve">Sichtbare Vergleichskontextzeilen</x:String>
|
<x:String x:Key="Text.Preference.General.VisibleDiffContextLines" xml:space="preserve">Sichtbare Vergleichskontextzeilen</x:String>
|
||||||
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
|
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
|
||||||
|
@ -403,12 +404,12 @@
|
||||||
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Tag-Signierung</x:String>
|
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Tag-Signierung</x:String>
|
||||||
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG Format</x:String>
|
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">GPG Format</x:String>
|
||||||
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">GPG Installationspfad</x:String>
|
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">GPG Installationspfad</x:String>
|
||||||
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Gebe Installationspfad zu installiertem GPG Programm an</x:String>
|
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Installationspfad zum GPG Programm</x:String>
|
||||||
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">Benutzer Signierungsschlüssel</x:String>
|
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">Benutzer Signierungsschlüssel</x:String>
|
||||||
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">GPG Benutzer Signierungsschlüssel</x:String>
|
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">GPG Benutzer Signierungsschlüssel</x:String>
|
||||||
<x:String x:Key="Text.Preference.DiffMerge" xml:space="preserve">DIFF/MERGE TOOL</x:String>
|
<x:String x:Key="Text.Preference.DiffMerge" xml:space="preserve">DIFF/MERGE TOOL</x:String>
|
||||||
<x:String x:Key="Text.Preference.DiffMerge.Path" xml:space="preserve">Installationspfad</x:String>
|
<x:String x:Key="Text.Preference.DiffMerge.Path" xml:space="preserve">Installationspfad</x:String>
|
||||||
<x:String x:Key="Text.Preference.DiffMerge.Path.Placeholder" xml:space="preserve">Gebe Installationspfad zum Diff/Merge Tool an</x:String>
|
<x:String x:Key="Text.Preference.DiffMerge.Path.Placeholder" xml:space="preserve">Installationspfad zum Diff/Merge Tool</x:String>
|
||||||
<x:String x:Key="Text.Preference.DiffMerge.Type" xml:space="preserve">Tool</x:String>
|
<x:String x:Key="Text.Preference.DiffMerge.Type" xml:space="preserve">Tool</x:String>
|
||||||
<x:String x:Key="Text.PruneRemote" xml:space="preserve">Remote löschen</x:String>
|
<x:String x:Key="Text.PruneRemote" xml:space="preserve">Remote löschen</x:String>
|
||||||
<x:String x:Key="Text.PruneRemote.Target" xml:space="preserve">Ziel:</x:String>
|
<x:String x:Key="Text.PruneRemote.Target" xml:space="preserve">Ziel:</x:String>
|
||||||
|
@ -480,7 +481,7 @@
|
||||||
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Aktualisiern</x:String>
|
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Aktualisiern</x:String>
|
||||||
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
|
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
|
||||||
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">REMOTE HINZUFÜGEN</x:String>
|
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">REMOTE HINZUFÜGEN</x:String>
|
||||||
<x:String x:Key="Text.Repository.Resolve" xml:space="preserve">LÖSEN</x:String>
|
<x:String x:Key="Text.Repository.Resolve" xml:space="preserve">KONFLIKTE BEHEBEN</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Commit suchen</x:String>
|
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Commit suchen</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.By" xml:space="preserve">Suche über</x:String>
|
<x:String x:Key="Text.Repository.Search.By" xml:space="preserve">Suche über</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Dateiname</x:String>
|
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Dateiname</x:String>
|
||||||
|
@ -488,6 +489,7 @@
|
||||||
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
|
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Autor & Committer</x:String>
|
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Autor & Committer</x:String>
|
||||||
<x:String x:Key="Text.Repository.SearchBranchTag" xml:space="preserve">Suche Branches & Tags</x:String>
|
<x:String x:Key="Text.Repository.SearchBranchTag" xml:space="preserve">Suche Branches & Tags</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Zeige Tags als Baum</x:String>
|
||||||
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistiken</x:String>
|
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistiken</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULE</x:String>
|
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULE</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">SUBMODUL HINZUFÜGEN</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">SUBMODUL HINZUFÜGEN</x:String>
|
||||||
|
@ -585,16 +587,13 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignoriere nur diese Datei</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignoriere nur diese Datei</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage.Tip" xml:space="preserve">Weise den Befehl an automatisch Dateien zu stagen die verändert und modifiziert wurden, aber für Git unbekannte Dateien sind davon unberührt.</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Du kannst diese Datei jetzt stagen.</x:String>
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Du kannst diese Datei jetzt stagen.</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">STRG + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">STRG + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">KONFLIKTE ERKANNT</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">KONFLIKTE ERKANNT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">DATEI KONFLIKTE GELÖST</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">DATEI KONFLIKTE GELÖST</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">LETZTE COMMIT-NACHRICHTEN</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">NACHRICHTEN HISTORIE</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">GESTAGED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">GESTAGED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">UNSTAGEN</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">UNSTAGEN</x:String>
|
||||||
|
|
|
@ -64,6 +64,8 @@
|
||||||
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Compare</x:String>
|
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Compare</x:String>
|
||||||
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
|
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
|
||||||
<x:String x:Key="Text.Cancel" xml:space="preserve">CANCEL</x:String>
|
<x:String x:Key="Text.Cancel" xml:space="preserve">CANCEL</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">Reset to This Revision</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Reset to Parent Revision</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">CHANGE DISPLAY MODE</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">CHANGE DISPLAY MODE</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Show as File and Dir List</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Show as File and Dir List</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Show as Path List</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Show as Path List</x:String>
|
||||||
|
@ -122,6 +124,9 @@
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Enter commit subject</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Enter commit subject</x:String>
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Description</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Description</x:String>
|
||||||
<x:String x:Key="Text.Configure" xml:space="preserve">Repository Configure</x:String>
|
<x:String x:Key="Text.Configure" xml:space="preserve">Repository Configure</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">COMMIT TEMPLATE</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">Template Name:</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">Template Content:</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Email Address</x:String>
|
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Email Address</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Email address</x:String>
|
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Email address</x:String>
|
||||||
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
|
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
|
||||||
|
@ -163,6 +168,7 @@
|
||||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Kind:</x:String>
|
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Kind:</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">annotated</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">annotated</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">lightweight</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">lightweight</x:String>
|
||||||
|
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Hold Ctrl to start directly</x:String>
|
||||||
<x:String x:Key="Text.Cut" xml:space="preserve">Cut</x:String>
|
<x:String x:Key="Text.Cut" xml:space="preserve">Cut</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Delete Branch</x:String>
|
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Delete Branch</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
||||||
|
@ -194,13 +200,13 @@
|
||||||
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEW</x:String>
|
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEW</x:String>
|
||||||
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Highlighting</x:String>
|
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Highlighting</x:String>
|
||||||
<x:String x:Key="Text.Diff.ToggleWordWrap" xml:space="preserve">Line Word Wrap</x:String>
|
<x:String x:Key="Text.Diff.ToggleWordWrap" xml:space="preserve">Line Word Wrap</x:String>
|
||||||
<x:String x:Key="Text.Diff.UseMerger" xml:space="preserve">Open In Merge Tool</x:String>
|
<x:String x:Key="Text.Diff.UseMerger" xml:space="preserve">Open in Merge Tool</x:String>
|
||||||
<x:String x:Key="Text.Diff.VisualLines.Decr" xml:space="preserve">Decrease Number of Visible Lines</x:String>
|
<x:String x:Key="Text.Diff.VisualLines.Decr" xml:space="preserve">Decrease Number of Visible Lines</x:String>
|
||||||
<x:String x:Key="Text.Diff.VisualLines.Incr" xml:space="preserve">Increase Number of Visible Lines</x:String>
|
<x:String x:Key="Text.Diff.VisualLines.Incr" xml:space="preserve">Increase Number of Visible Lines</x:String>
|
||||||
<x:String x:Key="Text.Diff.Welcome" xml:space="preserve">SELECT FILE TO VIEW CHANGES</x:String>
|
<x:String x:Key="Text.Diff.Welcome" xml:space="preserve">SELECT FILE TO VIEW CHANGES</x:String>
|
||||||
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Show hidden symbols</x:String>
|
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Show hidden symbols</x:String>
|
||||||
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Swap</x:String>
|
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Swap</x:String>
|
||||||
<x:String x:Key="Text.DiffWithMerger" xml:space="preserve">Open In Merge Tool</x:String>
|
<x:String x:Key="Text.DiffWithMerger" xml:space="preserve">Open in Merge Tool</x:String>
|
||||||
<x:String x:Key="Text.Discard" xml:space="preserve">Discard Changes</x:String>
|
<x:String x:Key="Text.Discard" xml:space="preserve">Discard Changes</x:String>
|
||||||
<x:String x:Key="Text.Discard.All" xml:space="preserve">All local changes in working copy.</x:String>
|
<x:String x:Key="Text.Discard.All" xml:space="preserve">All local changes in working copy.</x:String>
|
||||||
<x:String x:Key="Text.Discard.Changes" xml:space="preserve">Changes:</x:String>
|
<x:String x:Key="Text.Discard.Changes" xml:space="preserve">Changes:</x:String>
|
||||||
|
@ -344,6 +350,7 @@
|
||||||
<x:String x:Key="Text.Name" xml:space="preserve">Name:</x:String>
|
<x:String x:Key="Text.Name" xml:space="preserve">Name:</x:String>
|
||||||
<x:String x:Key="Text.NotConfigured" xml:space="preserve">Git has NOT been configured. Please to go [Preference] and configure it first.</x:String>
|
<x:String x:Key="Text.NotConfigured" xml:space="preserve">Git has NOT been configured. Please to go [Preference] and configure it first.</x:String>
|
||||||
<x:String x:Key="Text.Notice" xml:space="preserve">NOTICE</x:String>
|
<x:String x:Key="Text.Notice" xml:space="preserve">NOTICE</x:String>
|
||||||
|
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">Open App Data Dir</x:String>
|
||||||
<x:String x:Key="Text.OpenFolder" xml:space="preserve">SELECT FOLDER</x:String>
|
<x:String x:Key="Text.OpenFolder" xml:space="preserve">SELECT FOLDER</x:String>
|
||||||
<x:String x:Key="Text.OpenWith" xml:space="preserve">Open With...</x:String>
|
<x:String x:Key="Text.OpenWith" xml:space="preserve">Open With...</x:String>
|
||||||
<x:String x:Key="Text.Optional" xml:space="preserve">Optional.</x:String>
|
<x:String x:Key="Text.Optional" xml:space="preserve">Optional.</x:String>
|
||||||
|
@ -373,7 +380,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Theme</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Theme</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Theme Overrides</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Theme Overrides</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">GENERAL</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">GENERAL</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Avatar Server</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Check for updates on startup</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Check for updates on startup</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">History Commits</x:String>
|
||||||
|
@ -583,17 +589,16 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage.Tip" xml:space="preserve">Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected.</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Template/Histories</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">RECENT INPUT MESSAGES</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">MESSAGE HISTORIES</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NO RECENT INPUT MESSAGES</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NO RECENT INPUT MESSAGES</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">NO COMMIT TEMPLATES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">UNSTAGE</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">UNSTAGE</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">UNSTAGE ALL</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">UNSTAGE ALL</x:String>
|
||||||
|
@ -601,6 +606,7 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">STAGE</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">STAGE</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">STAGE ALL</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">STAGE ALL</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VIEW ASSUME UNCHANGED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VIEW ASSUME UNCHANGED</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">Template: ${0}$</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Right-click the selected file(s), and make your choice to resolve conflicts.</x:String>
|
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Right-click the selected file(s), and make your choice to resolve conflicts.</x:String>
|
||||||
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
|
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
|
||||||
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copy Path</x:String>
|
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copy Path</x:String>
|
||||||
|
|
|
@ -67,19 +67,21 @@
|
||||||
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparar Branch</x:String>
|
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparar Branch</x:String>
|
||||||
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
|
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
|
||||||
<x:String x:Key="Text.Cancel" xml:space="preserve">CANCELAR</x:String>
|
<x:String x:Key="Text.Cancel" xml:space="preserve">CANCELAR</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">Resetar para Esta Revisão</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Resetar to Revisão Pai</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ALTERAR MODO DE EXIBIÇÃO</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ALTERAR MODO DE EXIBIÇÃO</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Mostrar como Lista de Arquivos e Diretórios</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Mostrar como Grade</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Mostrar como Lista de Caminhos</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Mostrar como Lista de Caminhos</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Mostrar como Árvore de Sistema de Arquivos</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Mostrar como Árvore de Arquivos do Sistema</x:String>
|
||||||
<x:String x:Key="Text.Checkout" xml:space="preserve">Checar Branch</x:String>
|
<x:String x:Key="Text.Checkout" xml:space="preserve">Checkout Branch</x:String>
|
||||||
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Checar Commit</x:String>
|
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Checkout Commit</x:String>
|
||||||
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado</x:String>
|
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado</x:String>
|
||||||
<x:String x:Key="Text.Checkout.Commit.Target" xml:space="preserve">Commit:</x:String>
|
<x:String x:Key="Text.Checkout.Commit.Target" xml:space="preserve">Commit:</x:String>
|
||||||
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
|
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
|
||||||
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
|
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
|
||||||
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
|
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
|
||||||
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Não Fazer Nada</x:String>
|
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Nada</x:String>
|
||||||
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Guardar & Reaplicar</x:String>
|
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash & Reaplicar</x:String>
|
||||||
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick Este Commit</x:String>
|
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick Este Commit</x:String>
|
||||||
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit:</x:String>
|
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit:</x:String>
|
||||||
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commitar todas as alterações</x:String>
|
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commitar todas as alterações</x:String>
|
||||||
|
@ -100,7 +102,8 @@
|
||||||
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
|
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
|
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Copiar Informações</x:String>
|
<x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Copiar Informações</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">Copiar SHA</x:String><x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Rebase Interativo ${0}$ até Aqui</x:String>
|
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">Copiar SHA</x:String>
|
||||||
|
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Rebase Interativo ${0}$ até Aqui</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase ${0}$ até Aqui</x:String>
|
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase ${0}$ até Aqui</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Resetar ${0}$ até Aqui</x:String>
|
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Resetar ${0}$ até Aqui</x:String>
|
||||||
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Reverter Commit</x:String>
|
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Reverter Commit</x:String>
|
||||||
|
@ -124,8 +127,20 @@
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Insira o assunto do commit</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Insira o assunto do commit</x:String>
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Descrição</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Descrição</x:String>
|
||||||
<x:String x:Key="Text.Configure" xml:space="preserve">Configurar Repositório</x:String>
|
<x:String x:Key="Text.Configure" xml:space="preserve">Configurar Repositório</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">TEMPLATE DE COMMIT</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">Nome do Template:</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">Conteúdo do Template:</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Endereço de Email</x:String>
|
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Endereço de Email</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Endereço de email</x:String>
|
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Endereço de email</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">RASTREADOR DE PROBLEMAS</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Adicionar Regra de Exemplo do Github</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Adicionar Regra de Exemplo do Jira</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">Nova Regra</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">Expressão Regex de Issue:</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">Nome da Regra:</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate" xml:space="preserve">URL de Resultado:</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate.Tip" xml:space="preserve">Por favor, use $1, $2 para acessar os valores de grupos do regex.</x:String>
|
||||||
<x:String x:Key="Text.Configure.Proxy" xml:space="preserve">Proxy HTTP</x:String>
|
<x:String x:Key="Text.Configure.Proxy" xml:space="preserve">Proxy HTTP</x:String>
|
||||||
<x:String x:Key="Text.Configure.Proxy.Placeholder" xml:space="preserve">Proxy HTTP usado por este repositório</x:String>
|
<x:String x:Key="Text.Configure.Proxy.Placeholder" xml:space="preserve">Proxy HTTP usado por este repositório</x:String>
|
||||||
<x:String x:Key="Text.Configure.User" xml:space="preserve">Nome de Usuário</x:String>
|
<x:String x:Key="Text.Configure.User" xml:space="preserve">Nome de Usuário</x:String>
|
||||||
|
@ -156,6 +171,7 @@
|
||||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Tipo:</x:String>
|
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Tipo:</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">anotada</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">anotada</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">leve</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">leve</x:String>
|
||||||
|
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Pressione Ctrl para iniciar diretamente</x:String>
|
||||||
<x:String x:Key="Text.Cut" xml:space="preserve">Recortar</x:String>
|
<x:String x:Key="Text.Cut" xml:space="preserve">Recortar</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Excluir Branch</x:String>
|
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Excluir Branch</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
|
||||||
|
@ -337,6 +353,7 @@
|
||||||
<x:String x:Key="Text.Name" xml:space="preserve">Nome:</x:String>
|
<x:String x:Key="Text.Name" xml:space="preserve">Nome:</x:String>
|
||||||
<x:String x:Key="Text.NotConfigured" xml:space="preserve">O Git NÃO foi configurado. Por favor, vá para [Preferências] e configure primeiro.</x:String>
|
<x:String x:Key="Text.NotConfigured" xml:space="preserve">O Git NÃO foi configurado. Por favor, vá para [Preferências] e configure primeiro.</x:String>
|
||||||
<x:String x:Key="Text.Notice" xml:space="preserve">AVISO</x:String>
|
<x:String x:Key="Text.Notice" xml:space="preserve">AVISO</x:String>
|
||||||
|
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">Abrir Pasta de Dados do Aplicativo</x:String>
|
||||||
<x:String x:Key="Text.OpenFolder" xml:space="preserve">SELECIONAR PASTA</x:String>
|
<x:String x:Key="Text.OpenFolder" xml:space="preserve">SELECIONAR PASTA</x:String>
|
||||||
<x:String x:Key="Text.OpenWith" xml:space="preserve">Abrir Com...</x:String>
|
<x:String x:Key="Text.OpenWith" xml:space="preserve">Abrir Com...</x:String>
|
||||||
<x:String x:Key="Text.Optional" xml:space="preserve">Opcional.</x:String>
|
<x:String x:Key="Text.Optional" xml:space="preserve">Opcional.</x:String>
|
||||||
|
@ -362,10 +379,10 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Fonte Padrão</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Fonte Padrão</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Tamanho da Fonte Padrão</x:String>
|
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Tamanho da Fonte Padrão</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Fonte Monoespaçada</x:String>
|
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Fonte Monoespaçada</x:String>
|
||||||
|
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Usar apenas fonte monoespaçada no editor de texto</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Tema</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Tema</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Sobrescrever Tema</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Sobrescrever Tema</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">Servidor de Avatar</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Verificar atualizações na inicialização</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Verificar atualizações na inicialização</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Idioma</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Idioma</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commits do Histórico</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commits do Histórico</x:String>
|
||||||
|
@ -477,6 +494,7 @@
|
||||||
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
|
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
|
||||||
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Autor & Committer</x:String>
|
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Autor & Committer</x:String>
|
||||||
<x:String x:Key="Text.Repository.SearchBranchTag" xml:space="preserve">Pesquisar Branches & Tags</x:String>
|
<x:String x:Key="Text.Repository.SearchBranchTag" xml:space="preserve">Pesquisar Branches & Tags</x:String>
|
||||||
|
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Mostrar Tags como Árvore</x:String>
|
||||||
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Estatísticas</x:String>
|
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Estatísticas</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMÓDULOS</x:String>
|
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMÓDULOS</x:String>
|
||||||
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADICIONAR SUBMÓDULO</x:String>
|
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADICIONAR SUBMÓDULO</x:String>
|
||||||
|
@ -554,6 +572,7 @@
|
||||||
<x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Submódulo:</x:String>
|
<x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Submódulo:</x:String>
|
||||||
<x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Usar opção --remote</x:String>
|
<x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Usar opção --remote</x:String>
|
||||||
<x:String x:Key="Text.Warn" xml:space="preserve">Aviso</x:String>
|
<x:String x:Key="Text.Warn" xml:space="preserve">Aviso</x:String>
|
||||||
|
<x:String x:Key="Text.Welcome" xml:space="preserve">Página de Boas-vindas</x:String>
|
||||||
<x:String x:Key="Text.Welcome.AddRootFolder" xml:space="preserve">Criar Grupo Raíz</x:String>
|
<x:String x:Key="Text.Welcome.AddRootFolder" xml:space="preserve">Criar Grupo Raíz</x:String>
|
||||||
<x:String x:Key="Text.Welcome.AddSubFolder" xml:space="preserve">Criar Subgrupo</x:String>
|
<x:String x:Key="Text.Welcome.AddSubFolder" xml:space="preserve">Criar Subgrupo</x:String>
|
||||||
<x:String x:Key="Text.Welcome.Clone" xml:space="preserve">Clonar Repositório</x:String>
|
<x:String x:Key="Text.Welcome.Clone" xml:space="preserve">Clonar Repositório</x:String>
|
||||||
|
@ -573,17 +592,16 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar apenas este arquivo</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar apenas este arquivo</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Corrigir</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Corrigir</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage.Tip" xml:space="preserve">Informe ao comando para automaticamente stagear arquivos que foram modificados e excluídos, mas novos arquivos que você não informou ao Git não serão afetados.</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Você pode stagear este arquivo agora.</x:String>
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Você pode stagear este arquivo agora.</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT & PUSH</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Template/Histories</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLITOS DETECTADOS</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLITOS DETECTADOS</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">CONFLITOS DE ARQUIVOS RESOLVIDOS</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">CONFLITOS DE ARQUIVOS RESOLVIDOS</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">MENSAGENS RECENTES DE ENTRADA</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUIR ARQUIVOS NÃO RASTREADOS</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUIR ARQUIVOS NÃO RASTREADOS</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">HISTÓRICO DE MENSAGENS</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NENHUMA MENSAGEM DE ENTRADA RECENTE</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NENHUMA MENSAGEM DE ENTRADA RECENTE</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">NENHUM TEMPLATE DE COMMIT</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">DESSTAGEAR</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">DESSTAGEAR</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">DESSTAGEAR TODOS</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">DESSTAGEAR TODOS</x:String>
|
||||||
|
@ -591,6 +609,7 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">STAGEAR</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">STAGEAR</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">STAGEAR TODOS</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">STAGEAR TODOS</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VER SUPOR NÃO ALTERADO</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VER SUPOR NÃO ALTERADO</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">Template: ${0}$</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos.</x:String>
|
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos.</x:String>
|
||||||
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
|
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
|
||||||
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copiar Caminho</x:String>
|
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copiar Caminho</x:String>
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比较</x:String>
|
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比较</x:String>
|
||||||
<x:String x:Key="Text.Bytes" xml:space="preserve">字节</x:String>
|
<x:String x:Key="Text.Bytes" xml:space="preserve">字节</x:String>
|
||||||
<x:String x:Key="Text.Cancel" xml:space="preserve">取 消</x:String>
|
<x:String x:Key="Text.Cancel" xml:space="preserve">取 消</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">重置文件到该版本</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">重置文件到上一版本</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">切换变更显示模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">切换变更显示模式</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">文件名+路径列表模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">文件名+路径列表模式</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">全路径列表模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">全路径列表模式</x:String>
|
||||||
|
@ -125,6 +127,9 @@
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填写提交信息主题</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填写提交信息主题</x:String>
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">详细描述</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">详细描述</x:String>
|
||||||
<x:String x:Key="Text.Configure" xml:space="preserve">仓库配置</x:String>
|
<x:String x:Key="Text.Configure" xml:space="preserve">仓库配置</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">提交信息模板</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">模板名 :</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">模板内容 :</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email" xml:space="preserve">电子邮箱</x:String>
|
<x:String x:Key="Text.Configure.Email" xml:space="preserve">电子邮箱</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">邮箱地址</x:String>
|
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">邮箱地址</x:String>
|
||||||
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT配置</x:String>
|
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT配置</x:String>
|
||||||
|
@ -166,6 +171,7 @@
|
||||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">类型 :</x:String>
|
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">类型 :</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">附注标签</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">附注标签</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">轻量标签</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">轻量标签</x:String>
|
||||||
|
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住Ctrl键点击将以默认参数运行</x:String>
|
||||||
<x:String x:Key="Text.Cut" xml:space="preserve">剪切</x:String>
|
<x:String x:Key="Text.Cut" xml:space="preserve">剪切</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">删除分支确认</x:String>
|
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">删除分支确认</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 :</x:String>
|
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 :</x:String>
|
||||||
|
@ -347,6 +353,7 @@
|
||||||
<x:String x:Key="Text.Name" xml:space="preserve">名称 :</x:String>
|
<x:String x:Key="Text.Name" xml:space="preserve">名称 :</x:String>
|
||||||
<x:String x:Key="Text.NotConfigured" xml:space="preserve">GIT尚未配置。请打开【偏好设置】配置GIT路径。</x:String>
|
<x:String x:Key="Text.NotConfigured" xml:space="preserve">GIT尚未配置。请打开【偏好设置】配置GIT路径。</x:String>
|
||||||
<x:String x:Key="Text.Notice" xml:space="preserve">系统提示</x:String>
|
<x:String x:Key="Text.Notice" xml:space="preserve">系统提示</x:String>
|
||||||
|
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">浏览应用数据目录</x:String>
|
||||||
<x:String x:Key="Text.OpenFolder" xml:space="preserve">选择文件夹</x:String>
|
<x:String x:Key="Text.OpenFolder" xml:space="preserve">选择文件夹</x:String>
|
||||||
<x:String x:Key="Text.OpenWith" xml:space="preserve">打开文件...</x:String>
|
<x:String x:Key="Text.OpenWith" xml:space="preserve">打开文件...</x:String>
|
||||||
<x:String x:Key="Text.Optional" xml:space="preserve">选填。</x:String>
|
<x:String x:Key="Text.Optional" xml:space="preserve">选填。</x:String>
|
||||||
|
@ -376,7 +383,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主题</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主题</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主题自定义</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主题自定义</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">头像服务</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">启动时检测软件更新</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">启动时检测软件更新</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">显示语言</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">显示语言</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大历史提交数</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大历史提交数</x:String>
|
||||||
|
@ -584,18 +590,17 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自动暂存(--all)</x:String>
|
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自动暂存</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage.Tip" xml:space="preserve">提交前自动将修改过和删除的文件加入暂存区,但新增文件需要手动添加。</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交并推送</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交并推送</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">历史输入/模板</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">检测到冲突</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">检测到冲突</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">文件冲突已解决</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">文件冲突已解决</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">最近输入的提交信息</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">显示未跟踪文件</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">显示未跟踪文件</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">历史提交信息</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">没有提交信息记录</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">没有提交信息记录</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">没有可应用的提交信息模板</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">已暂存</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">已暂存</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">从暂存区移除选中</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">从暂存区移除选中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">从暂存区移除所有</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">从暂存区移除所有</x:String>
|
||||||
|
@ -603,6 +608,7 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">暂存选中</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">暂存选中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">暂存所有</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">暂存所有</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">查看忽略变更文件</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">查看忽略变更文件</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">模板:${0}$</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">请选中冲突文件,打开右键菜单,选择合适的解决方式</x:String>
|
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">请选中冲突文件,打开右键菜单,选择合适的解决方式</x:String>
|
||||||
<x:String x:Key="Text.Worktree" xml:space="preserve">本地工作树</x:String>
|
<x:String x:Key="Text.Worktree" xml:space="preserve">本地工作树</x:String>
|
||||||
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">复制工作树路径</x:String>
|
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">复制工作树路径</x:String>
|
||||||
|
|
|
@ -67,6 +67,8 @@
|
||||||
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比較</x:String>
|
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比較</x:String>
|
||||||
<x:String x:Key="Text.Bytes" xml:space="preserve">位元組</x:String>
|
<x:String x:Key="Text.Bytes" xml:space="preserve">位元組</x:String>
|
||||||
<x:String x:Key="Text.Cancel" xml:space="preserve">取 消</x:String>
|
<x:String x:Key="Text.Cancel" xml:space="preserve">取 消</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">重置檔案到該版本</x:String>
|
||||||
|
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">重置檔案到上一版本</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">切換變更顯示模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">切換變更顯示模式</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">檔名+路徑列表模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">檔名+路徑列表模式</x:String>
|
||||||
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">全路徑列表模式</x:String>
|
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">全路徑列表模式</x:String>
|
||||||
|
@ -125,6 +127,9 @@
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填寫提交信息主題</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">填寫提交信息主題</x:String>
|
||||||
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">詳細描述</x:String>
|
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">詳細描述</x:String>
|
||||||
<x:String x:Key="Text.Configure" xml:space="preserve">倉庫配置</x:String>
|
<x:String x:Key="Text.Configure" xml:space="preserve">倉庫配置</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">提交資訊範本</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">範本名稱 :</x:String>
|
||||||
|
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">範本內容 :</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email" xml:space="preserve">電子郵箱</x:String>
|
<x:String x:Key="Text.Configure.Email" xml:space="preserve">電子郵箱</x:String>
|
||||||
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">郵箱地址</x:String>
|
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">郵箱地址</x:String>
|
||||||
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT配置</x:String>
|
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT配置</x:String>
|
||||||
|
@ -166,6 +171,7 @@
|
||||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">型別 :</x:String>
|
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">型別 :</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">附註標籤</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">附註標籤</x:String>
|
||||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">輕量標籤</x:String>
|
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">輕量標籤</x:String>
|
||||||
|
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住Ctrl鍵點擊將以預設參數運行</x:String>
|
||||||
<x:String x:Key="Text.Cut" xml:space="preserve">剪下</x:String>
|
<x:String x:Key="Text.Cut" xml:space="preserve">剪下</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">刪除分支確認</x:String>
|
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">刪除分支確認</x:String>
|
||||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 :</x:String>
|
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 :</x:String>
|
||||||
|
@ -347,6 +353,7 @@
|
||||||
<x:String x:Key="Text.Name" xml:space="preserve">名稱 :</x:String>
|
<x:String x:Key="Text.Name" xml:space="preserve">名稱 :</x:String>
|
||||||
<x:String x:Key="Text.NotConfigured" xml:space="preserve">GIT尚未配置。請開啟【偏好設定】配置GIT路徑。</x:String>
|
<x:String x:Key="Text.NotConfigured" xml:space="preserve">GIT尚未配置。請開啟【偏好設定】配置GIT路徑。</x:String>
|
||||||
<x:String x:Key="Text.Notice" xml:space="preserve">系統提示</x:String>
|
<x:String x:Key="Text.Notice" xml:space="preserve">系統提示</x:String>
|
||||||
|
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">瀏覽程式資料目錄</x:String>
|
||||||
<x:String x:Key="Text.OpenFolder" xml:space="preserve">選擇資料夾</x:String>
|
<x:String x:Key="Text.OpenFolder" xml:space="preserve">選擇資料夾</x:String>
|
||||||
<x:String x:Key="Text.OpenWith" xml:space="preserve">開啟檔案...</x:String>
|
<x:String x:Key="Text.OpenWith" xml:space="preserve">開啟檔案...</x:String>
|
||||||
<x:String x:Key="Text.Optional" xml:space="preserve">選填。</x:String>
|
<x:String x:Key="Text.Optional" xml:space="preserve">選填。</x:String>
|
||||||
|
@ -376,7 +383,6 @@
|
||||||
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主題</x:String>
|
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">主題</x:String>
|
||||||
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主題自訂</x:String>
|
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">主題自訂</x:String>
|
||||||
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
<x:String x:Key="Text.Preference.General" xml:space="preserve">通用配置</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.AvatarServer" xml:space="preserve">頭像服務</x:String>
|
|
||||||
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">啟動時檢測軟體更新</x:String>
|
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">啟動時檢測軟體更新</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">顯示語言</x:String>
|
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">顯示語言</x:String>
|
||||||
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大歷史提交數</x:String>
|
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">最大歷史提交數</x:String>
|
||||||
|
@ -584,18 +590,17 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String>
|
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補(--amend)</x:String>
|
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補(--amend)</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自動暫存(--all)</x:String>
|
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自動暫存</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.AutoStage.Tip" xml:space="preserve">提交前自動將修改過和刪除的檔案加入暫存區,但新增檔案需要手動添加。</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String>
|
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交併推送</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交併推送</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">歷史輸入/範本</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">CTRL + Enter</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">檢測到衝突</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">檢測到衝突</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">檔案衝突已解決</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">檔案衝突已解決</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.HasCommitHistories" xml:space="preserve">最近輸入的提交資訊</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">顯示未跟蹤檔案</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">顯示未跟蹤檔案</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.MessageHistories" xml:space="preserve">歷史提交資訊</x:String>
|
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">沒有提交資訊記錄</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">沒有提交資訊記錄</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">沒有可應用的提交資訊範本</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">已暫存</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">已暫存</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">從暫存區移除選中</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">從暫存區移除選中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">從暫存區移除所有</x:String>
|
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">從暫存區移除所有</x:String>
|
||||||
|
@ -603,6 +608,7 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">暫存選中</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">暫存選中</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">暫存所有</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">暫存所有</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">檢視忽略變更檔案</x:String>
|
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">檢視忽略變更檔案</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">範本:${0}$</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">請選中衝突檔案,開啟右鍵選單,選擇合適的解決方式</x:String>
|
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">請選中衝突檔案,開啟右鍵選單,選擇合適的解決方式</x:String>
|
||||||
<x:String x:Key="Text.Worktree" xml:space="preserve">本地工作樹</x:String>
|
<x:String x:Key="Text.Worktree" xml:space="preserve">本地工作樹</x:String>
|
||||||
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">拷贝工作樹路徑</x:String>
|
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">拷贝工作樹路徑</x:String>
|
||||||
|
|
|
@ -251,8 +251,12 @@
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}"/>
|
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}"/>
|
||||||
|
<Setter Property="FontFamily" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFont}"/>
|
||||||
<Setter Property="FontSize" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize}"/>
|
<Setter Property="FontSize" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize}"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style Selector="TextBlock.small">
|
||||||
|
<Setter Property="FontSize" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"/>
|
||||||
|
</Style>
|
||||||
<Style Selector="TextBlock.bold">
|
<Style Selector="TextBlock.bold">
|
||||||
<Setter Property="FontWeight" Value="Bold"/>
|
<Setter Property="FontWeight" Value="Bold"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
@ -277,12 +281,9 @@
|
||||||
<Setter Property="FontWeight" Value="Bold"/>
|
<Setter Property="FontWeight" Value="Bold"/>
|
||||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="TextBlock.issue_link">
|
|
||||||
|
<Style Selector="Run.issue_link">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource Brush.Link}"/>
|
<Setter Property="Foreground" Value="{DynamicResource Brush.Link}"/>
|
||||||
<Setter Property="Cursor" Value="Hand"/>
|
|
||||||
</Style>
|
|
||||||
<Style Selector="TextBlock.issue_link:pointerover">
|
|
||||||
<Setter Property="TextDecorations" Value="Underline"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="SelectableTextBlock">
|
<Style Selector="SelectableTextBlock">
|
||||||
|
@ -455,6 +456,21 @@
|
||||||
<Setter Property="Fill" Value="{DynamicResource Brush.FG2}"/>
|
<Setter Property="Fill" Value="{DynamicResource Brush.FG2}"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Button.no_border">
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Button.no_border /template/ ContentPresenter#PART_ContentPresenter">
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Button.no_border:pointerover Path">
|
||||||
|
<Setter Property="Fill" Value="{DynamicResource Brush.Accent}"/>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Button.no_border:pressed">
|
||||||
|
<Setter Property="RenderTransform" Value="scale(1.0)"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Button.flat">
|
<Style Selector="Button.flat">
|
||||||
<Setter Property="BorderThickness" Value="1"/>
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Border2}"/>
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Border2}"/>
|
||||||
|
@ -753,11 +769,10 @@
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="MenuItem">
|
<Style Selector="MenuItem">
|
||||||
<Style.Resources>
|
|
||||||
<ControlTheme x:Key="{x:Type MenuItem}" TargetType="MenuItem">
|
|
||||||
<Setter Property="Height" Value="28"/>
|
<Setter Property="Height" Value="28"/>
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}" />
|
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}" />
|
||||||
|
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Panel>
|
<Panel>
|
||||||
|
@ -769,27 +784,28 @@
|
||||||
CornerRadius="3">
|
CornerRadius="3">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIcon" />
|
<ColumnDefinition Width="28" SharedSizeGroup="MenuItemIcon" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGT" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGT" />
|
||||||
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemChevron" />
|
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemChevron" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Border Grid.Column="0" Width="28">
|
<ContentControl Grid.Column="0"
|
||||||
<ContentControl x:Name="PART_IconPresenter"
|
x:Name="PART_IconPresenter"
|
||||||
Content="{TemplateBinding Icon}"
|
Content="{TemplateBinding Icon}"
|
||||||
IsVisible="False"
|
IsVisible="False"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<ContentPresenter Grid.Column="1"
|
<ContentPresenter Grid.Column="1"
|
||||||
Name="PART_HeaderPresenter"
|
x:Name="PART_HeaderPresenter"
|
||||||
Content="{TemplateBinding Header}"
|
Content="{TemplateBinding Header}"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
ContentTemplate="{TemplateBinding HeaderTemplate}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
RecognizesAccessKey="False"/>
|
RecognizesAccessKey="False"/>
|
||||||
|
|
||||||
<TextBlock x:Name="PART_InputGestureText"
|
<TextBlock x:Name="PART_InputGestureText"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Classes="CaptionTextBlockStyle"
|
Classes="CaptionTextBlockStyle"
|
||||||
|
@ -799,6 +815,7 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
Foreground="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
|
||||||
FontSize="11"/>
|
FontSize="11"/>
|
||||||
|
|
||||||
<Path Name="PART_ChevronPath"
|
<Path Name="PART_ChevronPath"
|
||||||
Width="6"
|
Width="6"
|
||||||
Data="M573 512 215 881c-20 20-20 51 0 61l61 61c20 20 51 20 61 0l461-461c10-10 10-20 10-31s0-20-10-31L338 20C317 0 287 0 276 20L215 82c-20 20-20 51 0 61L573 512z"
|
Data="M573 512 215 881c-20 20-20 51 0 61l61 61c20 20 51 20 61 0l461-461c10-10 10-20 10-31s0-20-10-31L338 20C317 0 287 0 276 20L215 82c-20 20-20 51 0 61L573 512z"
|
||||||
|
@ -867,18 +884,8 @@
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="^:disabled">
|
<Style Selector="^:disabled">
|
||||||
<Style Selector="^ /template/ Border#PART_LayoutRoot">
|
<Setter Property="Opacity" Value="0.65"/>
|
||||||
<Setter Property="Background" Value="{DynamicResource MenuFlyoutItemBackgroundDisabled}" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
</Style>
|
|
||||||
<Style Selector="^ /template/ ContentPresenter#PART_HeaderPresenter">
|
|
||||||
<Setter Property="Foreground" Value="{DynamicResource MenuFlyoutItemForegroundDisabled}" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="^ /template/ TextBlock#PART_InputGestureText">
|
|
||||||
<Setter Property="Foreground" Value="{DynamicResource MenuFlyoutItemKeyboardAcceleratorTextForegroundDisabled}" />
|
|
||||||
</Style>
|
|
||||||
<Style Selector="^ /template/ Path#PART_ChevronPath">
|
|
||||||
<Setter Property="Fill" Value="{DynamicResource MenuFlyoutSubItemChevronDisabled}" />
|
|
||||||
</Style>
|
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="^:empty /template/ Path#PART_ChevronPath">
|
<Style Selector="^:empty /template/ Path#PART_ChevronPath">
|
||||||
|
@ -893,8 +900,6 @@
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
</ControlTheme>
|
|
||||||
</Style.Resources>
|
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="ComboBox">
|
<Style Selector="ComboBox">
|
||||||
|
@ -1324,6 +1329,9 @@
|
||||||
<Style Selector="DataGrid /template/ Rectangle#PART_ColumnHeadersAndRowsSeparator">
|
<Style Selector="DataGrid /template/ Rectangle#PART_ColumnHeadersAndRowsSeparator">
|
||||||
<Setter Property="IsVisible" Value="False"/>
|
<Setter Property="IsVisible" Value="False"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
<Style Selector="DataGridCell">
|
||||||
|
<Setter Property="MinHeight" Value="24"/>
|
||||||
|
</Style>
|
||||||
<Style Selector="DataGridCell:focus /template/ Grid#FocusVisual">
|
<Style Selector="DataGridCell:focus /template/ Grid#FocusVisual">
|
||||||
<Setter Property="IsVisible" Value="False"/>
|
<Setter Property="IsVisible" Value="False"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
|
@ -24,12 +24,13 @@
|
||||||
<PublishAot>true</PublishAot>
|
<PublishAot>true</PublishAot>
|
||||||
<PublishTrimmed>true</PublishTrimmed>
|
<PublishTrimmed>true</PublishTrimmed>
|
||||||
<TrimMode>link</TrimMode>
|
<TrimMode>link</TrimMode>
|
||||||
<OptimizationPreference>Size</OptimizationPreference>
|
<OptimizationPreference>Speed</OptimizationPreference>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="App.ico" />
|
<AvaloniaResource Include="App.ico" />
|
||||||
<AvaloniaResource Include="Resources/Fonts/*" />
|
<AvaloniaResource Include="Resources/Fonts/*" />
|
||||||
|
<AvaloniaResource Include="Resources/Grammars/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/*" />
|
<AvaloniaResource Include="Resources/Images/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/*" />
|
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/*" />
|
||||||
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/JetBrains/*" />
|
<AvaloniaResource Include="Resources/Images/ExternalToolIcons/JetBrains/*" />
|
||||||
|
@ -37,15 +38,16 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="11.0.13" />
|
<PackageReference Include="Avalonia" Version="11.1.3" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.13" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.1.3" />
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.13" />
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.3" />
|
||||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.13" />
|
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.1.3" />
|
||||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.13" Condition="'$(Configuration)' == 'Debug'" />
|
<PackageReference Include="Avalonia.Diagnostics" Version="11.1.3" Condition="'$(Configuration)' == 'Debug'" />
|
||||||
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
|
||||||
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.60" />
|
<PackageReference Include="TextMateSharp" Version="1.0.62" />
|
||||||
|
<PackageReference Include="TextMateSharp.Grammars" Version="1.0.62" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -36,11 +36,6 @@ namespace SourceGit.ViewModels
|
||||||
get => Backend is Models.Branch;
|
get => Backend is Models.Branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string TrackStatus
|
|
||||||
{
|
|
||||||
get => Backend is Models.Branch { IsLocal: true } branch ? branch.TrackStatus.ToString() : string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FontWeight NameFontWeight
|
public FontWeight NameFontWeight
|
||||||
{
|
{
|
||||||
get => Backend is Models.Branch { IsCurrent: true } ? FontWeight.Bold : FontWeight.Regular;
|
get => Backend is Models.Branch { IsCurrent: true } ? FontWeight.Bold : FontWeight.Regular;
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace SourceGit.ViewModels
|
||||||
if (value == null || value.Count != 1)
|
if (value == null || value.Count != 1)
|
||||||
DiffContext = null;
|
DiffContext = null;
|
||||||
else
|
else
|
||||||
DiffContext = new DiffContext(_repo, new Models.DiffOption(_commit, value[0]), _diffContext);
|
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_commit, value[0]), _diffContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,15 +89,35 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _viewRevisionFileContent, value);
|
set => SetProperty(ref _viewRevisionFileContent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AvaloniaList<Models.CommitLink> WebLinks
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
} = new AvaloniaList<Models.CommitLink>();
|
||||||
|
|
||||||
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
||||||
{
|
{
|
||||||
get => _issueTrackerRules;
|
get => _repo.Settings?.IssueTrackerRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommitDetail(string repo, AvaloniaList<Models.IssueTrackerRule> issueTrackerRules)
|
public CommitDetail(Repository repo)
|
||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_issueTrackerRules = issueTrackerRules;
|
|
||||||
|
foreach (var remote in repo.Remotes)
|
||||||
|
{
|
||||||
|
if (remote.TryGetVisitURL(out var url))
|
||||||
|
{
|
||||||
|
if (url.StartsWith("https://github.com/", StringComparison.Ordinal))
|
||||||
|
WebLinks.Add(new Models.CommitLink() { Name = "Github", URLPrefix = $"{url}/commit/" });
|
||||||
|
else if (url.StartsWith("https://gitlab.com/", StringComparison.Ordinal))
|
||||||
|
WebLinks.Add(new Models.CommitLink() { Name = "GitLab", URLPrefix = $"{url}/-/commit/" });
|
||||||
|
else if (url.StartsWith("https://gitee.com/", StringComparison.Ordinal))
|
||||||
|
WebLinks.Add(new Models.CommitLink() { Name = "Gitee", URLPrefix = $"{url}/commit/" });
|
||||||
|
else if (url.StartsWith("https://bitbucket.org/", StringComparison.Ordinal))
|
||||||
|
WebLinks.Add(new Models.CommitLink() { Name = "Bitbucket", URLPrefix = $"{url}/commits/" });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cleanup()
|
public void Cleanup()
|
||||||
|
@ -118,8 +138,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void NavigateTo(string commitSHA)
|
public void NavigateTo(string commitSHA)
|
||||||
{
|
{
|
||||||
var repo = App.FindOpenedRepository(_repo);
|
_repo?.NavigateToCommit(commitSHA);
|
||||||
repo?.NavigateToCommit(commitSHA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearSearchChangeFilter()
|
public void ClearSearchChangeFilter()
|
||||||
|
@ -129,7 +148,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public List<Models.Object> GetRevisionFilesUnderFolder(string parentFolder)
|
public List<Models.Object> GetRevisionFilesUnderFolder(string parentFolder)
|
||||||
{
|
{
|
||||||
return new Commands.QueryRevisionObjects(_repo, _commit.SHA, parentFolder).Result();
|
return new Commands.QueryRevisionObjects(_repo.FullPath, _commit.SHA, parentFolder).Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ViewRevisionFile(Models.Object file)
|
public void ViewRevisionFile(Models.Object file)
|
||||||
|
@ -145,13 +164,13 @@ namespace SourceGit.ViewModels
|
||||||
case Models.ObjectType.Blob:
|
case Models.ObjectType.Blob:
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var isBinary = new Commands.IsBinary(_repo, _commit.SHA, file.Path).Result();
|
var isBinary = new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path).Result();
|
||||||
if (isBinary)
|
if (isBinary)
|
||||||
{
|
{
|
||||||
var ext = Path.GetExtension(file.Path);
|
var ext = Path.GetExtension(file.Path);
|
||||||
if (IMG_EXTS.Contains(ext))
|
if (IMG_EXTS.Contains(ext))
|
||||||
{
|
{
|
||||||
var stream = Commands.QueryFileContent.Run(_repo, _commit.SHA, file.Path);
|
var stream = Commands.QueryFileContent.Run(_repo.FullPath, _commit.SHA, file.Path);
|
||||||
var bitmap = stream.Length > 0 ? new Bitmap(stream) : null;
|
var bitmap = stream.Length > 0 ? new Bitmap(stream) : null;
|
||||||
Dispatcher.UIThread.Invoke(() =>
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
{
|
{
|
||||||
|
@ -160,7 +179,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var size = new Commands.QueryFileSize(_repo, file.Path, _commit.SHA).Result();
|
var size = new Commands.QueryFileSize(_repo.FullPath, file.Path, _commit.SHA).Result();
|
||||||
Dispatcher.UIThread.Invoke(() =>
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
{
|
{
|
||||||
ViewRevisionFileContent = new Models.RevisionBinaryFile() { Size = size };
|
ViewRevisionFileContent = new Models.RevisionBinaryFile() { Size = size };
|
||||||
|
@ -170,7 +189,7 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentStream = Commands.QueryFileContent.Run(_repo, _commit.SHA, file.Path);
|
var contentStream = Commands.QueryFileContent.Run(_repo.FullPath, _commit.SHA, file.Path);
|
||||||
var content = new StreamReader(contentStream).ReadToEnd();
|
var content = new StreamReader(contentStream).ReadToEnd();
|
||||||
var matchLFS = REG_LFS_FORMAT().Match(content);
|
var matchLFS = REG_LFS_FORMAT().Match(content);
|
||||||
if (matchLFS.Success)
|
if (matchLFS.Success)
|
||||||
|
@ -191,7 +210,7 @@ namespace SourceGit.ViewModels
|
||||||
case Models.ObjectType.Commit:
|
case Models.ObjectType.Commit:
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var submoduleRoot = Path.Combine(_repo, file.Path);
|
var submoduleRoot = Path.Combine(_repo.FullPath, file.Path);
|
||||||
var commit = new Commands.QuerySingleCommit(submoduleRoot, file.SHA).Result();
|
var commit = new Commands.QuerySingleCommit(submoduleRoot, file.SHA).Result();
|
||||||
if (commit != null)
|
if (commit != null)
|
||||||
{
|
{
|
||||||
|
@ -237,10 +256,49 @@ namespace SourceGit.ViewModels
|
||||||
var toolPath = Preference.Instance.ExternalMergeToolPath;
|
var toolPath = Preference.Instance.ExternalMergeToolPath;
|
||||||
var opt = new Models.DiffOption(_commit, change);
|
var opt = new Models.DiffOption(_commit, change);
|
||||||
|
|
||||||
Task.Run(() => Commands.MergeTool.OpenForDiff(_repo, toolType, toolPath, opt));
|
Task.Run(() => Commands.MergeTool.OpenForDiff(_repo.FullPath, toolType, toolPath, opt));
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
menu.Items.Add(diffWithMerger);
|
menu.Items.Add(diffWithMerger);
|
||||||
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
|
|
||||||
|
var fullPath = Path.Combine(_repo.FullPath, change.Path);
|
||||||
|
if (File.Exists(fullPath))
|
||||||
|
{
|
||||||
|
var resetToThisRevision = new MenuItem();
|
||||||
|
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||||
|
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||||
|
resetToThisRevision.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}");
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var resetToFirstParent = new MenuItem();
|
||||||
|
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
|
||||||
|
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||||
|
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0 && change.Index != Models.ChangeState.Added && change.Index != Models.ChangeState.Renamed;
|
||||||
|
resetToFirstParent.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1");
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var explore = new MenuItem();
|
||||||
|
explore.Header = App.Text("RevealFile");
|
||||||
|
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
||||||
|
explore.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
Native.OS.OpenInFileManager(fullPath, true);
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
menu.Items.Add(resetToThisRevision);
|
||||||
|
menu.Items.Add(resetToFirstParent);
|
||||||
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
|
menu.Items.Add(explore);
|
||||||
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
|
}
|
||||||
|
|
||||||
if (change.Index != Models.ChangeState.Deleted)
|
if (change.Index != Models.ChangeState.Deleted)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +307,7 @@ namespace SourceGit.ViewModels
|
||||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||||
history.Click += (_, ev) =>
|
history.Click += (_, ev) =>
|
||||||
{
|
{
|
||||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path, _issueTrackerRules) };
|
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path) };
|
||||||
window.Show();
|
window.Show();
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
@ -259,26 +317,13 @@ namespace SourceGit.ViewModels
|
||||||
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
||||||
blame.Click += (_, ev) =>
|
blame.Click += (_, ev) =>
|
||||||
{
|
{
|
||||||
var window = new Views.Blame() { DataContext = new Blame(_repo, change.Path, _commit.SHA) };
|
var window = new Views.Blame() { DataContext = new Blame(_repo.FullPath, change.Path, _commit.SHA) };
|
||||||
window.Show();
|
window.Show();
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var full = Path.GetFullPath(Path.Combine(_repo, change.Path));
|
|
||||||
var explore = new MenuItem();
|
|
||||||
explore.Header = App.Text("RevealFile");
|
|
||||||
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
|
||||||
explore.IsEnabled = File.Exists(full);
|
|
||||||
explore.Click += (_, ev) =>
|
|
||||||
{
|
|
||||||
Native.OS.OpenInFileManager(full, true);
|
|
||||||
ev.Handled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
menu.Items.Add(new MenuItem { Header = "-" });
|
|
||||||
menu.Items.Add(history);
|
menu.Items.Add(history);
|
||||||
menu.Items.Add(blame);
|
menu.Items.Add(blame);
|
||||||
menu.Items.Add(explore);
|
|
||||||
menu.Items.Add(new MenuItem { Header = "-" });
|
menu.Items.Add(new MenuItem { Header = "-" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,34 +352,25 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public ContextMenu CreateRevisionFileContextMenu(Models.Object file)
|
public ContextMenu CreateRevisionFileContextMenu(Models.Object file)
|
||||||
{
|
{
|
||||||
var history = new MenuItem();
|
var fullPath = Path.Combine(_repo.FullPath, file.Path);
|
||||||
history.Header = App.Text("FileHistory");
|
|
||||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
var resetToThisRevision = new MenuItem();
|
||||||
history.Click += (_, ev) =>
|
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
|
||||||
|
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||||
|
resetToThisRevision.IsEnabled = File.Exists(fullPath);
|
||||||
|
resetToThisRevision.Click += (_, ev) =>
|
||||||
{
|
{
|
||||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, file.Path, _issueTrackerRules) };
|
new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}");
|
||||||
window.Show();
|
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var blame = new MenuItem();
|
|
||||||
blame.Header = App.Text("Blame");
|
|
||||||
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
|
||||||
blame.IsEnabled = file.Type == Models.ObjectType.Blob;
|
|
||||||
blame.Click += (_, ev) =>
|
|
||||||
{
|
|
||||||
var window = new Views.Blame() { DataContext = new Blame(_repo, file.Path, _commit.SHA) };
|
|
||||||
window.Show();
|
|
||||||
ev.Handled = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var full = Path.GetFullPath(Path.Combine(_repo, file.Path));
|
|
||||||
var explore = new MenuItem();
|
var explore = new MenuItem();
|
||||||
explore.Header = App.Text("RevealFile");
|
explore.Header = App.Text("RevealFile");
|
||||||
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
explore.Icon = App.CreateMenuIcon("Icons.Explore");
|
||||||
|
explore.IsEnabled = File.Exists(fullPath);
|
||||||
explore.Click += (_, ev) =>
|
explore.Click += (_, ev) =>
|
||||||
{
|
{
|
||||||
Native.OS.OpenInFileManager(full, file.Type == Models.ObjectType.Blob);
|
Native.OS.OpenInFileManager(fullPath, file.Type == Models.ObjectType.Blob);
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -353,12 +389,33 @@ namespace SourceGit.ViewModels
|
||||||
if (selected.Count == 1)
|
if (selected.Count == 1)
|
||||||
{
|
{
|
||||||
var saveTo = Path.Combine(selected[0].Path.LocalPath, Path.GetFileName(file.Path));
|
var saveTo = Path.Combine(selected[0].Path.LocalPath, Path.GetFileName(file.Path));
|
||||||
Commands.SaveRevisionFile.Run(_repo, _commit.SHA, file.Path, saveTo);
|
Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file.Path, saveTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
ev.Handled = true;
|
ev.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var history = new MenuItem();
|
||||||
|
history.Header = App.Text("FileHistory");
|
||||||
|
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||||
|
history.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, file.Path) };
|
||||||
|
window.Show();
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var blame = new MenuItem();
|
||||||
|
blame.Header = App.Text("Blame");
|
||||||
|
blame.Icon = App.CreateMenuIcon("Icons.Blame");
|
||||||
|
blame.IsEnabled = file.Type == Models.ObjectType.Blob;
|
||||||
|
blame.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
var window = new Views.Blame() { DataContext = new Blame(_repo.FullPath, file.Path, _commit.SHA) };
|
||||||
|
window.Show();
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
var copyPath = new MenuItem();
|
var copyPath = new MenuItem();
|
||||||
copyPath.Header = App.Text("CopyPath");
|
copyPath.Header = App.Text("CopyPath");
|
||||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||||
|
@ -378,10 +435,14 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
|
|
||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
menu.Items.Add(history);
|
menu.Items.Add(resetToThisRevision);
|
||||||
menu.Items.Add(blame);
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
menu.Items.Add(explore);
|
menu.Items.Add(explore);
|
||||||
menu.Items.Add(saveAs);
|
menu.Items.Add(saveAs);
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
menu.Items.Add(history);
|
||||||
|
menu.Items.Add(blame);
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
menu.Items.Add(copyPath);
|
menu.Items.Add(copyPath);
|
||||||
menu.Items.Add(copyFileName);
|
menu.Items.Add(copyFileName);
|
||||||
return menu;
|
return menu;
|
||||||
|
@ -406,9 +467,9 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var fullMessage = new Commands.QueryCommitFullMessage(_repo, _commit.SHA).Result();
|
var fullMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).Result();
|
||||||
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
|
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
|
||||||
var cmdChanges = new Commands.CompareRevisions(_repo, parent, _commit.SHA) { Cancel = _cancelToken };
|
var cmdChanges = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { Cancel = _cancelToken };
|
||||||
var changes = cmdChanges.Result();
|
var changes = cmdChanges.Result();
|
||||||
var visible = changes;
|
var visible = changes;
|
||||||
if (!string.IsNullOrWhiteSpace(_searchChangeFilter))
|
if (!string.IsNullOrWhiteSpace(_searchChangeFilter))
|
||||||
|
@ -463,8 +524,7 @@ namespace SourceGit.ViewModels
|
||||||
".ico", ".bmp", ".jpg", ".png", ".jpeg"
|
".ico", ".bmp", ".jpg", ".png", ".jpeg"
|
||||||
};
|
};
|
||||||
|
|
||||||
private string _repo;
|
private Repository _repo = null;
|
||||||
private AvaloniaList<Models.IssueTrackerRule> _issueTrackerRules = null;
|
|
||||||
private int _activePageIndex = 0;
|
private int _activePageIndex = 0;
|
||||||
private Models.Commit _commit = null;
|
private Models.Commit _commit = null;
|
||||||
private string _fullMessage = string.Empty;
|
private string _fullMessage = string.Empty;
|
||||||
|
|
|
@ -93,11 +93,8 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public static ValidationResult ValidateSSHKey(string sshkey, ValidationContext ctx)
|
public static ValidationResult ValidateSSHKey(string sshkey, ValidationContext ctx)
|
||||||
{
|
{
|
||||||
if (ctx.ObjectInstance is EditRemote edit && edit.UseSSH)
|
if (ctx.ObjectInstance is EditRemote { _useSSH: true } && !string.IsNullOrEmpty(sshkey))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(sshkey))
|
|
||||||
return new ValidationResult("SSH private key is required");
|
|
||||||
|
|
||||||
if (!File.Exists(sshkey))
|
if (!File.Exists(sshkey))
|
||||||
return new ValidationResult("Given SSH private key can NOT be found!");
|
return new ValidationResult("Given SSH private key can NOT be found!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Avalonia.Collections;
|
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
|
||||||
namespace SourceGit.ViewModels
|
namespace SourceGit.ViewModels
|
||||||
|
@ -35,7 +33,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DiffContext = new DiffContext(_repo, new Models.DiffOption(value, _file), _diffContext);
|
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(value, _file), _diffContext);
|
||||||
DetailContext.Commit = value;
|
DetailContext.Commit = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,15 +52,15 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _detailContext, value);
|
set => SetProperty(ref _detailContext, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileHistories(string repo, string file, AvaloniaList<Models.IssueTrackerRule> issueTrackerRules)
|
public FileHistories(Repository repo, string file)
|
||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_file = file;
|
_file = file;
|
||||||
_detailContext = new CommitDetail(repo, issueTrackerRules);
|
_detailContext = new CommitDetail(repo);
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var commits = new Commands.QueryCommits(_repo, $"-n 10000 -- \"{file}\"", false).Result();
|
var commits = new Commands.QueryCommits(_repo.FullPath, $"-n 10000 -- \"{file}\"", false).Result();
|
||||||
Dispatcher.UIThread.Invoke(() =>
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
{
|
{
|
||||||
IsLoading = false;
|
IsLoading = false;
|
||||||
|
@ -73,7 +71,7 @@ namespace SourceGit.ViewModels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly string _repo = null;
|
private readonly Repository _repo = null;
|
||||||
private readonly string _file = null;
|
private readonly string _file = null;
|
||||||
private bool _isLoading = true;
|
private bool _isLoading = true;
|
||||||
private List<Models.Commit> _commits = null;
|
private List<Models.Commit> _commits = null;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Avalonia.Collections;
|
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
|
@ -11,6 +10,11 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
public class Histories : ObservableObject
|
public class Histories : ObservableObject
|
||||||
{
|
{
|
||||||
|
public Repository Repo
|
||||||
|
{
|
||||||
|
get => _repo;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsLoading
|
public bool IsLoading
|
||||||
{
|
{
|
||||||
get => _isLoading;
|
get => _isLoading;
|
||||||
|
@ -55,11 +59,6 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _detailContext, value);
|
set => SetProperty(ref _detailContext, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
|
||||||
{
|
|
||||||
get => _repo.Settings.IssueTrackerRules;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Histories(Repository repo)
|
public Histories(Repository repo)
|
||||||
{
|
{
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
|
@ -99,7 +98,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var commitDetail = new CommitDetail(_repo.FullPath, _repo.Settings.IssueTrackerRules);
|
var commitDetail = new CommitDetail(_repo);
|
||||||
commitDetail.Commit = commit;
|
commitDetail.Commit = commit;
|
||||||
DetailContext = commitDetail;
|
DetailContext = commitDetail;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +126,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var commitDetail = new CommitDetail(_repo.FullPath, _repo.Settings.IssueTrackerRules);
|
var commitDetail = new CommitDetail(_repo);
|
||||||
commitDetail.Commit = commit;
|
commitDetail.Commit = commit;
|
||||||
DetailContext = commitDetail;
|
DetailContext = commitDetail;
|
||||||
}
|
}
|
||||||
|
@ -249,7 +248,7 @@ namespace SourceGit.ViewModels
|
||||||
reword.Icon = App.CreateMenuIcon("Icons.Edit");
|
reword.Icon = App.CreateMenuIcon("Icons.Edit");
|
||||||
reword.Click += (_, e) =>
|
reword.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (_repo.WorkingCopyChangesCount > 0)
|
if (_repo.LocalChangesCount > 0)
|
||||||
{
|
{
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
return;
|
return;
|
||||||
|
@ -267,7 +266,7 @@ namespace SourceGit.ViewModels
|
||||||
squash.IsEnabled = commit.Parents.Count == 1;
|
squash.IsEnabled = commit.Parents.Count == 1;
|
||||||
squash.Click += (_, e) =>
|
squash.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (_repo.WorkingCopyChangesCount > 0)
|
if (_repo.LocalChangesCount > 0)
|
||||||
{
|
{
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
return;
|
return;
|
||||||
|
@ -328,7 +327,7 @@ namespace SourceGit.ViewModels
|
||||||
interactiveRebase.IsVisible = current.Head != commit.SHA;
|
interactiveRebase.IsVisible = current.Head != commit.SHA;
|
||||||
interactiveRebase.Click += (_, e) =>
|
interactiveRebase.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (_repo.WorkingCopyChangesCount > 0)
|
if (_repo.LocalChangesCount > 0)
|
||||||
{
|
{
|
||||||
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first.");
|
||||||
return;
|
return;
|
||||||
|
@ -385,7 +384,7 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
menu.Items.Add(compareWithHead);
|
menu.Items.Add(compareWithHead);
|
||||||
|
|
||||||
if (_repo.WorkingCopyChangesCount > 0)
|
if (_repo.LocalChangesCount > 0)
|
||||||
{
|
{
|
||||||
var compareWithWorktree = new MenuItem();
|
var compareWithWorktree = new MenuItem();
|
||||||
compareWithWorktree.Header = App.Text("CommitCM.CompareWithWorktree");
|
compareWithWorktree.Header = App.Text("CommitCM.CompareWithWorktree");
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace SourceGit.ViewModels
|
||||||
Current = current;
|
Current = current;
|
||||||
On = on;
|
On = on;
|
||||||
IsLoading = true;
|
IsLoading = true;
|
||||||
DetailContext = new CommitDetail(repoPath, repo.Settings.IssueTrackerRules);
|
DetailContext = new CommitDetail(repo);
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace SourceGit.ViewModels
|
||||||
var last = Pages[0];
|
var last = Pages[0];
|
||||||
if (last.Data is Repository repo)
|
if (last.Data is Repository repo)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
||||||
repo.Close();
|
repo.Close();
|
||||||
|
|
||||||
last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() };
|
||||||
|
@ -245,7 +245,7 @@ namespace SourceGit.ViewModels
|
||||||
};
|
};
|
||||||
|
|
||||||
repo.Open();
|
repo.Open();
|
||||||
Commands.AutoFetch.AddRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.AddRepository(repo.FullPath);
|
||||||
|
|
||||||
if (page == null)
|
if (page == null)
|
||||||
{
|
{
|
||||||
|
@ -371,7 +371,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
if (page.Data is Repository repo)
|
if (page.Data is Repository repo)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
Models.AutoFetchManager.Instance.RemoveRepository(repo.FullPath);
|
||||||
repo.Close();
|
repo.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,19 +128,6 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _layout, value);
|
set => SetProperty(ref _layout, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string AvatarServer
|
|
||||||
{
|
|
||||||
get => Models.AvatarManager.SelectedServer;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (Models.AvatarManager.SelectedServer != value)
|
|
||||||
{
|
|
||||||
Models.AvatarManager.SelectedServer = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MaxHistoryCommits
|
public int MaxHistoryCommits
|
||||||
{
|
{
|
||||||
get => _maxHistoryCommits;
|
get => _maxHistoryCommits;
|
||||||
|
@ -262,11 +249,9 @@ namespace SourceGit.ViewModels
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Native.OS.SetShell(value))
|
if (Native.OS.SetShell(value))
|
||||||
{
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public string GitDefaultCloneDir
|
public string GitDefaultCloneDir
|
||||||
{
|
{
|
||||||
|
@ -276,12 +261,12 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public bool GitAutoFetch
|
public bool GitAutoFetch
|
||||||
{
|
{
|
||||||
get => Commands.AutoFetch.IsEnabled;
|
get => Models.AutoFetchManager.Instance.IsEnabled;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (Commands.AutoFetch.IsEnabled != value)
|
if (Models.AutoFetchManager.Instance.IsEnabled != value)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.IsEnabled = value;
|
Models.AutoFetchManager.Instance.IsEnabled = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,15 +274,15 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public int? GitAutoFetchInterval
|
public int? GitAutoFetchInterval
|
||||||
{
|
{
|
||||||
get => Commands.AutoFetch.Interval;
|
get => Models.AutoFetchManager.Instance.Interval;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value is null or < 1)
|
if (value is null || value < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Commands.AutoFetch.Interval != value)
|
if (Models.AutoFetchManager.Instance.Interval != value)
|
||||||
{
|
{
|
||||||
Commands.AutoFetch.Interval = (int)value;
|
Models.AutoFetchManager.Instance.Interval = (int)value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,7 +321,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
} = new List<string>();
|
} = [];
|
||||||
|
|
||||||
public int LastActiveTabIdx
|
public int LastActiveTabIdx
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,14 +142,16 @@ namespace SourceGit.ViewModels
|
||||||
private set => SetProperty(ref _submodules, value);
|
private set => SetProperty(ref _submodules, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int WorkingCopyChangesCount
|
public int LocalChangesCount
|
||||||
{
|
{
|
||||||
get => _workingCopy == null ? 0 : _workingCopy.Count;
|
get => _localChangesCount;
|
||||||
|
private set => SetProperty(ref _localChangesCount, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int StashesCount
|
public int StashesCount
|
||||||
{
|
{
|
||||||
get => _stashesPage == null ? 0 : _stashesPage.Stashes.Count;
|
get => _stashesCount;
|
||||||
|
private set => SetProperty(ref _stashesCount, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IncludeUntracked
|
public bool IncludeUntracked
|
||||||
|
@ -350,6 +352,9 @@ namespace SourceGit.ViewModels
|
||||||
_stashesPage = null;
|
_stashesPage = null;
|
||||||
_inProgressContext = null;
|
_inProgressContext = null;
|
||||||
|
|
||||||
|
_localChangesCount = 0;
|
||||||
|
_stashesCount = 0;
|
||||||
|
|
||||||
_remotes.Clear();
|
_remotes.Clear();
|
||||||
_branches.Clear();
|
_branches.Clear();
|
||||||
_localBranchTrees.Clear();
|
_localBranchTrees.Clear();
|
||||||
|
@ -420,7 +425,7 @@ namespace SourceGit.ViewModels
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Fetch()
|
public void Fetch(bool autoStart)
|
||||||
{
|
{
|
||||||
if (!PopupHost.CanCreatePopup())
|
if (!PopupHost.CanCreatePopup())
|
||||||
return;
|
return;
|
||||||
|
@ -431,10 +436,13 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (autoStart)
|
||||||
|
PopupHost.ShowAndStartPopup(new Fetch(this));
|
||||||
|
else
|
||||||
PopupHost.ShowPopup(new Fetch(this));
|
PopupHost.ShowPopup(new Fetch(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Pull()
|
public void Pull(bool autoStart)
|
||||||
{
|
{
|
||||||
if (!PopupHost.CanCreatePopup())
|
if (!PopupHost.CanCreatePopup())
|
||||||
return;
|
return;
|
||||||
|
@ -445,10 +453,13 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (autoStart)
|
||||||
|
PopupHost.ShowAndStartPopup(new Pull(this, null));
|
||||||
|
else
|
||||||
PopupHost.ShowPopup(new Pull(this, null));
|
PopupHost.ShowPopup(new Pull(this, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Push()
|
public void Push(bool autoStart)
|
||||||
{
|
{
|
||||||
if (!PopupHost.CanCreatePopup())
|
if (!PopupHost.CanCreatePopup())
|
||||||
return;
|
return;
|
||||||
|
@ -465,6 +476,9 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (autoStart)
|
||||||
|
PopupHost.ShowAndStartPopup(new Push(this, null));
|
||||||
|
else
|
||||||
PopupHost.ShowPopup(new Push(this, null));
|
PopupHost.ShowPopup(new Push(this, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,15 +621,9 @@ namespace SourceGit.ViewModels
|
||||||
Task.Run(RefreshCommits);
|
Task.Run(RefreshCommits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StashAll()
|
public void StashAll(bool autoStart)
|
||||||
{
|
{
|
||||||
if (PopupHost.CanCreatePopup())
|
_workingCopy?.StashAll(autoStart);
|
||||||
{
|
|
||||||
var changes = new List<Models.Change>();
|
|
||||||
changes.AddRange(_workingCopy.Unstaged);
|
|
||||||
changes.AddRange(_workingCopy.Staged);
|
|
||||||
PopupHost.ShowPopup(new StashChanges(this, changes, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GotoResolve()
|
public void GotoResolve()
|
||||||
|
@ -812,7 +820,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
InProgressContext = inProgress;
|
InProgressContext = inProgress;
|
||||||
HasUnsolvedConflicts = hasUnsolvedConflict;
|
HasUnsolvedConflicts = hasUnsolvedConflict;
|
||||||
OnPropertyChanged(nameof(WorkingCopyChangesCount));
|
LocalChangesCount = changes.Count;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,7 +831,8 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
if (_stashesPage != null)
|
if (_stashesPage != null)
|
||||||
_stashesPage.Stashes = stashes;
|
_stashesPage.Stashes = stashes;
|
||||||
OnPropertyChanged(nameof(StashesCount));
|
|
||||||
|
StashesCount = stashes.Count;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,7 +865,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
if (branch.IsLocal)
|
if (branch.IsLocal)
|
||||||
{
|
{
|
||||||
if (WorkingCopyChangesCount > 0)
|
if (_localChangesCount > 0)
|
||||||
PopupHost.ShowPopup(new Checkout(this, branch.Name));
|
PopupHost.ShowPopup(new Checkout(this, branch.Name));
|
||||||
else
|
else
|
||||||
PopupHost.ShowAndStartPopup(new Checkout(this, branch.Name));
|
PopupHost.ShowAndStartPopup(new Checkout(this, branch.Name));
|
||||||
|
@ -1193,7 +1202,7 @@ namespace SourceGit.ViewModels
|
||||||
var discard = new MenuItem();
|
var discard = new MenuItem();
|
||||||
discard.Header = App.Text("BranchCM.DiscardAll");
|
discard.Header = App.Text("BranchCM.DiscardAll");
|
||||||
discard.Icon = App.CreateMenuIcon("Icons.Undo");
|
discard.Icon = App.CreateMenuIcon("Icons.Undo");
|
||||||
discard.IsEnabled = _workingCopy.Count > 0;
|
discard.IsEnabled = _localChangesCount > 0;
|
||||||
discard.Click += (_, e) =>
|
discard.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
if (PopupHost.CanCreatePopup())
|
if (PopupHost.CanCreatePopup())
|
||||||
|
@ -1297,7 +1306,7 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(merge);
|
menu.Items.Add(merge);
|
||||||
menu.Items.Add(rebase);
|
menu.Items.Add(rebase);
|
||||||
|
|
||||||
if (WorkingCopyChangesCount > 0)
|
if (_localChangesCount > 0)
|
||||||
{
|
{
|
||||||
var compareWithWorktree = new MenuItem();
|
var compareWithWorktree = new MenuItem();
|
||||||
compareWithWorktree.Header = App.Text("BranchCM.CompareWithWorktree");
|
compareWithWorktree.Header = App.Text("BranchCM.CompareWithWorktree");
|
||||||
|
@ -1320,7 +1329,7 @@ namespace SourceGit.ViewModels
|
||||||
var compareWithBranch = CreateMenuItemToCompareBranches(branch);
|
var compareWithBranch = CreateMenuItemToCompareBranches(branch);
|
||||||
if (compareWithBranch != null)
|
if (compareWithBranch != null)
|
||||||
{
|
{
|
||||||
if (WorkingCopyChangesCount == 0)
|
if (_localChangesCount == 0)
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
menu.Items.Add(compareWithBranch);
|
menu.Items.Add(compareWithBranch);
|
||||||
|
@ -1597,7 +1606,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasCompare = false;
|
var hasCompare = false;
|
||||||
if (WorkingCopyChangesCount > 0)
|
if (_localChangesCount > 0)
|
||||||
{
|
{
|
||||||
var compareWithWorktree = new MenuItem();
|
var compareWithWorktree = new MenuItem();
|
||||||
compareWithWorktree.Header = App.Text("BranchCM.CompareWithWorktree");
|
compareWithWorktree.Header = App.Text("BranchCM.CompareWithWorktree");
|
||||||
|
@ -1959,6 +1968,9 @@ namespace SourceGit.ViewModels
|
||||||
private int _selectedViewIndex = 0;
|
private int _selectedViewIndex = 0;
|
||||||
private object _selectedView = null;
|
private object _selectedView = null;
|
||||||
|
|
||||||
|
private int _localChangesCount = 0;
|
||||||
|
private int _stashesCount = 0;
|
||||||
|
|
||||||
private bool _isSearching = false;
|
private bool _isSearching = false;
|
||||||
private bool _isSearchLoadingVisible = false;
|
private bool _isSearchLoadingVisible = false;
|
||||||
private bool _isSearchCommitSuggestionOpen = false;
|
private bool _isSearchCommitSuggestionOpen = false;
|
||||||
|
|
|
@ -42,6 +42,17 @@ namespace SourceGit.ViewModels
|
||||||
set => SetProperty(ref _httpProxy, value);
|
set => SetProperty(ref _httpProxy, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AvaloniaList<Models.CommitTemplate> CommitTemplates
|
||||||
|
{
|
||||||
|
get => _repo.Settings.CommitTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Models.CommitTemplate SelectedCommitTemplate
|
||||||
|
{
|
||||||
|
get => _selectedCommitTemplate;
|
||||||
|
set => SetProperty(ref _selectedCommitTemplate, value);
|
||||||
|
}
|
||||||
|
|
||||||
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
||||||
{
|
{
|
||||||
get => _repo.Settings.IssueTrackerRules;
|
get => _repo.Settings.IssueTrackerRules;
|
||||||
|
@ -77,6 +88,20 @@ namespace SourceGit.ViewModels
|
||||||
HttpProxy = string.Empty;
|
HttpProxy = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddCommitTemplate()
|
||||||
|
{
|
||||||
|
var template = new Models.CommitTemplate() { Name = "New Template" };
|
||||||
|
_repo.Settings.CommitTemplates.Add(template);
|
||||||
|
SelectedCommitTemplate = template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSelectedCommitTemplate()
|
||||||
|
{
|
||||||
|
if (_selectedCommitTemplate != null)
|
||||||
|
_repo.Settings.CommitTemplates.Remove(_selectedCommitTemplate);
|
||||||
|
SelectedCommitTemplate = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddSampleGithubIssueTracker()
|
public void AddSampleGithubIssueTracker()
|
||||||
{
|
{
|
||||||
foreach (var remote in _repo.Remotes)
|
foreach (var remote in _repo.Remotes)
|
||||||
|
@ -106,6 +131,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void RemoveSelectedIssueTracker()
|
public void RemoveSelectedIssueTracker()
|
||||||
{
|
{
|
||||||
|
if (_selectedIssueTrackerRule != null)
|
||||||
_repo.Settings.RemoveIssueTracker(_selectedIssueTrackerRule);
|
_repo.Settings.RemoveIssueTracker(_selectedIssueTrackerRule);
|
||||||
SelectedIssueTrackerRule = null;
|
SelectedIssueTrackerRule = null;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +167,7 @@ namespace SourceGit.ViewModels
|
||||||
private readonly Repository _repo = null;
|
private readonly Repository _repo = null;
|
||||||
private readonly Dictionary<string, string> _cached = null;
|
private readonly Dictionary<string, string> _cached = null;
|
||||||
private string _httpProxy;
|
private string _httpProxy;
|
||||||
|
private Models.CommitTemplate _selectedCommitTemplate = null;
|
||||||
private Models.IssueTrackerRule _selectedIssueTrackerRule = null;
|
private Models.IssueTrackerRule _selectedIssueTrackerRule = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
var succ = new Commands.Commit(_repo.FullPath, _message, false, true, true).Exec();
|
var succ = new Commands.Commit(_repo.FullPath, _message, true, true).Exec();
|
||||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||||
return succ;
|
return succ;
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
var succ = new Commands.Reset(_repo.FullPath, Parent.SHA, "--soft").Exec();
|
var succ = new Commands.Reset(_repo.FullPath, Parent.SHA, "--soft").Exec();
|
||||||
if (succ)
|
if (succ)
|
||||||
succ = new Commands.Commit(_repo.FullPath, _message, false, true).Exec();
|
succ = new Commands.Commit(_repo.FullPath, _message, true).Exec();
|
||||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||||
return succ;
|
return succ;
|
||||||
});
|
});
|
||||||
|
|
|
@ -177,8 +177,6 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count => _count;
|
|
||||||
|
|
||||||
public object DetailContext
|
public object DetailContext
|
||||||
{
|
{
|
||||||
get => _detailContext;
|
get => _detailContext;
|
||||||
|
@ -317,6 +315,17 @@ namespace SourceGit.ViewModels
|
||||||
dialog.ShowDialog(toplevel);
|
dialog.ShowDialog(toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StashAll(bool autoStart)
|
||||||
|
{
|
||||||
|
if (!PopupHost.CanCreatePopup())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (autoStart)
|
||||||
|
PopupHost.ShowAndStartPopup(new StashChanges(_repo, _cached, true));
|
||||||
|
else
|
||||||
|
PopupHost.ShowPopup(new StashChanges(_repo, _cached, true));
|
||||||
|
}
|
||||||
|
|
||||||
public void StageSelected()
|
public void StageSelected()
|
||||||
{
|
{
|
||||||
StageChanges(_selectedUnstaged);
|
StageChanges(_selectedUnstaged);
|
||||||
|
@ -556,7 +565,7 @@ namespace SourceGit.ViewModels
|
||||||
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
history.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||||
history.Click += (_, e) =>
|
history.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo.FullPath, change.Path, _repo.Settings.IssueTrackerRules) };
|
var window = new Views.FileHistories() { DataContext = new FileHistories(_repo, change.Path) };
|
||||||
window.Show();
|
window.Show();
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
|
@ -1118,35 +1127,63 @@ namespace SourceGit.ViewModels
|
||||||
public ContextMenu CreateContextMenuForCommitMessages()
|
public ContextMenu CreateContextMenuForCommitMessages()
|
||||||
{
|
{
|
||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
if (_repo.Settings.CommitMessages.Count == 0)
|
|
||||||
|
var templateCount = _repo.Settings.CommitTemplates.Count;
|
||||||
|
if (templateCount == 0)
|
||||||
{
|
{
|
||||||
var empty = new MenuItem();
|
menu.Items.Add(new MenuItem()
|
||||||
empty.Header = App.Text("WorkingCopy.NoCommitHistories");
|
{
|
||||||
empty.IsEnabled = false;
|
Header = App.Text("WorkingCopy.NoCommitTemplates"),
|
||||||
menu.Items.Add(empty);
|
Icon = App.CreateMenuIcon("Icons.Code"),
|
||||||
return menu;
|
IsEnabled = false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var tip = new MenuItem();
|
|
||||||
tip.Header = App.Text("WorkingCopy.HasCommitHistories");
|
|
||||||
tip.IsEnabled = false;
|
|
||||||
menu.Items.Add(tip);
|
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
|
||||||
|
|
||||||
foreach (var message in _repo.Settings.CommitMessages)
|
|
||||||
{
|
{
|
||||||
var dump = message;
|
for (int i = 0; i < templateCount; i++)
|
||||||
|
{
|
||||||
|
var template = _repo.Settings.CommitTemplates[i];
|
||||||
var item = new MenuItem();
|
var item = new MenuItem();
|
||||||
item.Header = dump;
|
item.Header = new Views.NameHighlightedTextBlock("WorkingCopy.UseCommitTemplate", template.Name);
|
||||||
|
item.Icon = App.CreateMenuIcon("Icons.Code");
|
||||||
item.Click += (_, e) =>
|
item.Click += (_, e) =>
|
||||||
{
|
{
|
||||||
CommitMessage = dump;
|
CommitMessage = template.Content;
|
||||||
|
e.Handled = true;
|
||||||
|
};
|
||||||
|
menu.Items.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
|
var historiesCount = _repo.Settings.CommitMessages.Count;
|
||||||
|
if (historiesCount == 0)
|
||||||
|
{
|
||||||
|
menu.Items.Add(new MenuItem()
|
||||||
|
{
|
||||||
|
Header = App.Text("WorkingCopy.NoCommitHistories"),
|
||||||
|
Icon = App.CreateMenuIcon("Icons.Histories"),
|
||||||
|
IsEnabled = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < historiesCount; i++)
|
||||||
|
{
|
||||||
|
var message = _repo.Settings.CommitMessages[i];
|
||||||
|
var item = new MenuItem();
|
||||||
|
item.Header = message;
|
||||||
|
item.Icon = App.CreateMenuIcon("Icons.Histories");
|
||||||
|
item.Click += (_, e) =>
|
||||||
|
{
|
||||||
|
CommitMessage = message;
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
menu.Items.Add(item);
|
menu.Items.Add(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
@ -1245,9 +1282,10 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var autoStage = AutoStageBeforeCommit;
|
||||||
if (!_useAmend)
|
if (!_useAmend)
|
||||||
{
|
{
|
||||||
if (AutoStageBeforeCommit)
|
if (autoStage)
|
||||||
{
|
{
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
|
@ -1269,26 +1307,28 @@ namespace SourceGit.ViewModels
|
||||||
_repo.Settings.PushCommitMessage(_commitMessage);
|
_repo.Settings.PushCommitMessage(_commitMessage);
|
||||||
_repo.SetWatcherEnabled(false);
|
_repo.SetWatcherEnabled(false);
|
||||||
|
|
||||||
var autoStage = AutoStageBeforeCommit;
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
var succ = new Commands.Commit(_repo.FullPath, _commitMessage, autoStage, _useAmend).Exec();
|
var succ = true;
|
||||||
|
if (autoStage && _unstaged.Count > 0)
|
||||||
|
succ = new Commands.Add(_repo.FullPath).Exec();
|
||||||
|
|
||||||
|
if (succ)
|
||||||
|
succ = new Commands.Commit(_repo.FullPath, _commitMessage, _useAmend).Exec();
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
{
|
{
|
||||||
if (succ)
|
if (succ)
|
||||||
{
|
{
|
||||||
SelectedStaged = [];
|
|
||||||
CommitMessage = string.Empty;
|
CommitMessage = string.Empty;
|
||||||
UseAmend = false;
|
UseAmend = false;
|
||||||
|
|
||||||
if (autoPush)
|
if (autoPush)
|
||||||
{
|
|
||||||
PopupHost.ShowAndStartPopup(new Push(_repo, null));
|
PopupHost.ShowAndStartPopup(new Push(_repo, null));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_repo.MarkWorkingCopyDirtyManually();
|
_repo.MarkWorkingCopyDirtyManually();
|
||||||
_repo.SetWatcherEnabled(true);
|
_repo.SetWatcherEnabled(true);
|
||||||
|
|
||||||
IsCommitting = false;
|
IsCommitting = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace SourceGit.Views
|
||||||
refetch.Click += (_, _) =>
|
refetch.Click += (_, _) =>
|
||||||
{
|
{
|
||||||
if (User != null)
|
if (User != null)
|
||||||
Models.AvatarManager.Request(User.Email, true);
|
Models.AvatarManager.Instance.Request(User.Email, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
ContextMenu = new ContextMenu();
|
ContextMenu = new ContextMenu();
|
||||||
|
@ -54,7 +54,7 @@ namespace SourceGit.Views
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var corner = (float)Math.Max(2, Bounds.Width / 16);
|
var corner = (float)Math.Max(2, Bounds.Width / 16);
|
||||||
var img = Models.AvatarManager.Request(User.Email, false);
|
var img = Models.AvatarManager.Instance.Request(User.Email, false);
|
||||||
if (img != null)
|
if (img != null)
|
||||||
{
|
{
|
||||||
var rect = new Rect(0, 0, Bounds.Width, Bounds.Height);
|
var rect = new Rect(0, 0, Bounds.Width, Bounds.Height);
|
||||||
|
@ -72,21 +72,19 @@ namespace SourceGit.Views
|
||||||
public void OnAvatarResourceChanged(string email)
|
public void OnAvatarResourceChanged(string email)
|
||||||
{
|
{
|
||||||
if (User.Email.Equals(email, StringComparison.Ordinal))
|
if (User.Email.Equals(email, StringComparison.Ordinal))
|
||||||
{
|
|
||||||
InvalidateVisual();
|
InvalidateVisual();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnLoaded(RoutedEventArgs e)
|
protected override void OnLoaded(RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnLoaded(e);
|
base.OnLoaded(e);
|
||||||
Models.AvatarManager.Subscribe(this);
|
Models.AvatarManager.Instance.Subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUnloaded(RoutedEventArgs e)
|
protected override void OnUnloaded(RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnUnloaded(e);
|
base.OnUnloaded(e);
|
||||||
Models.AvatarManager.Unsubscribe(this);
|
Models.AvatarManager.Instance.Unsubscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnUserPropertyChanged(Avatar avatar, AvaloniaPropertyChangedEventArgs e)
|
private static void OnUserPropertyChanged(Avatar avatar, AvaloniaPropertyChangedEventArgs e)
|
||||||
|
|
|
@ -40,6 +40,9 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var lineNumber = line.FirstDocumentLine.LineNumber;
|
var lineNumber = line.FirstDocumentLine.LineNumber;
|
||||||
if (lineNumber > _editor.BlameData.LineInfos.Count)
|
if (lineNumber > _editor.BlameData.LineInfos.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -151,6 +154,9 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var lineNumber = line.FirstDocumentLine.LineNumber;
|
var lineNumber = line.FirstDocumentLine.LineNumber;
|
||||||
if (lineNumber >= _editor.BlameData.LineInfos.Count)
|
if (lineNumber >= _editor.BlameData.LineInfos.Count)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4">
|
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4">
|
||||||
<TextBlock Text="{Binding Base.FriendlyName}" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
<TextBlock Text="{Binding Base.FriendlyName}" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding BaseHead.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" PointerPressed="OnPressedSHA"/>
|
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding BaseHead.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" Cursor="Hand" PointerPressed="OnPressedSHA"/>
|
||||||
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding BaseHead.CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding BaseHead.CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4">
|
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4">
|
||||||
<TextBlock Text="{Binding To.FriendlyName}" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
<TextBlock Text="{Binding To.FriendlyName}" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding ToHead.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" PointerPressed="OnPressedSHA"/>
|
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding ToHead.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" Cursor="Hand" PointerPressed="OnPressedSHA"/>
|
||||||
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding ToHead.CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding ToHead.CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
|
@ -83,20 +83,13 @@
|
||||||
FontWeight="{Binding NameFontWeight}"/>
|
FontWeight="{Binding NameFontWeight}"/>
|
||||||
|
|
||||||
<!-- Tracking status -->
|
<!-- Tracking status -->
|
||||||
<Border Grid.Column="2"
|
<v:BranchTreeNodeTrackStatusPresenter Grid.Column="2"
|
||||||
Margin="8,0"
|
Margin="8,0"
|
||||||
Height="18"
|
|
||||||
CornerRadius="9"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="{DynamicResource Brush.Badge}"
|
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
|
||||||
IsVisible="{Binding TrackStatus, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
|
|
||||||
<TextBlock Classes="primary"
|
|
||||||
FontSize="10"
|
FontSize="10"
|
||||||
HorizontalAlignment="Center"
|
Foreground="{DynamicResource Brush.BadgeFG}"
|
||||||
Margin="9,0"
|
Background="{DynamicResource Brush.Badge}"/>
|
||||||
Text="{Binding TrackStatus}"
|
|
||||||
Foreground="{DynamicResource Brush.BadgeFG}"/>
|
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- Filter Toggle Button -->
|
<!-- Filter Toggle Button -->
|
||||||
<ToggleButton Grid.Column="3"
|
<ToggleButton Grid.Column="3"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
|
@ -104,6 +105,99 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BranchTreeNodeTrackStatusPresenter : Control
|
||||||
|
{
|
||||||
|
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
|
||||||
|
TextBlock.FontFamilyProperty.AddOwner<BranchTreeNodeTrackStatusPresenter>();
|
||||||
|
|
||||||
|
public FontFamily FontFamily
|
||||||
|
{
|
||||||
|
get => GetValue(FontFamilyProperty);
|
||||||
|
set => SetValue(FontFamilyProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<double> FontSizeProperty =
|
||||||
|
TextBlock.FontSizeProperty.AddOwner<BranchTreeNodeTrackStatusPresenter>();
|
||||||
|
|
||||||
|
public double FontSize
|
||||||
|
{
|
||||||
|
get => GetValue(FontSizeProperty);
|
||||||
|
set => SetValue(FontSizeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush> ForegroundProperty =
|
||||||
|
AvaloniaProperty.Register<BranchTreeNodeTrackStatusPresenter, IBrush>(nameof(Foreground), Brushes.White);
|
||||||
|
|
||||||
|
public IBrush Foreground
|
||||||
|
{
|
||||||
|
get => GetValue(ForegroundProperty);
|
||||||
|
set => SetValue(ForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush> BackgroundProperty =
|
||||||
|
AvaloniaProperty.Register<BranchTreeNodeTrackStatusPresenter, IBrush>(nameof(Background), Brushes.White);
|
||||||
|
|
||||||
|
public IBrush Background
|
||||||
|
{
|
||||||
|
get => GetValue(BackgroundProperty);
|
||||||
|
set => SetValue(BackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BranchTreeNodeTrackStatusPresenter()
|
||||||
|
{
|
||||||
|
AffectsMeasure<BranchTreeNodeTrackStatusPresenter>(
|
||||||
|
FontSizeProperty,
|
||||||
|
FontFamilyProperty,
|
||||||
|
ForegroundProperty);
|
||||||
|
|
||||||
|
AffectsRender<BranchTreeNodeTrackStatusPresenter>(
|
||||||
|
ForegroundProperty,
|
||||||
|
BackgroundProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render(DrawingContext context)
|
||||||
|
{
|
||||||
|
base.Render(context);
|
||||||
|
|
||||||
|
if (_label != null)
|
||||||
|
{
|
||||||
|
context.DrawRectangle(Background, null, new RoundedRect(new Rect(0, 0, _label.Width + 18, 18), new CornerRadius(9)));
|
||||||
|
context.DrawText(_label, new Point(9, 9 - _label.Height * 0.5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDataContextChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnDataContextChanged(e);
|
||||||
|
InvalidateMeasure();
|
||||||
|
InvalidateVisual();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
|
{
|
||||||
|
_label = null;
|
||||||
|
|
||||||
|
if (DataContext is ViewModels.BranchTreeNode { Backend: Models.Branch branch })
|
||||||
|
{
|
||||||
|
var status = branch.TrackStatus.ToString();
|
||||||
|
if (!string.IsNullOrEmpty(status))
|
||||||
|
{
|
||||||
|
_label = new FormattedText(
|
||||||
|
status,
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
FlowDirection.LeftToRight,
|
||||||
|
new Typeface(FontFamily),
|
||||||
|
FontSize,
|
||||||
|
Foreground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _label != null ? new Size(_label.Width + 18, 18) : new Size(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FormattedText _label = null;
|
||||||
|
}
|
||||||
|
|
||||||
public partial class BranchTree : UserControl
|
public partial class BranchTree : UserControl
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =
|
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =
|
||||||
|
|
|
@ -54,7 +54,17 @@
|
||||||
<Grid RowDefinitions="24,Auto,Auto,Auto" ColumnDefinitions="96,*">
|
<Grid RowDefinitions="24,Auto,Auto,Auto" ColumnDefinitions="96,*">
|
||||||
<!-- SHA -->
|
<!-- SHA -->
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" />
|
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" />
|
||||||
<SelectableTextBlock Grid.Row="0" Grid.Column="1" Classes="primary" Text="{Binding SHA}" Margin="12,0,0,0" VerticalAlignment="Center"/>
|
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
|
||||||
|
<SelectableTextBlock Classes="primary"
|
||||||
|
Text="{Binding SHA}"
|
||||||
|
Margin="12,0,0,0"
|
||||||
|
VerticalAlignment="Center"/>
|
||||||
|
|
||||||
|
<Button Classes="icon_button" Cursor="Hand" Click="OnOpenWebLink" IsVisible="{Binding #ThisControl.WebLinks, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}">
|
||||||
|
<Path Width="12" Height="12" Data="{StaticResource Icons.Link}" Fill="{DynamicResource Brush.Link}"/>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
|
||||||
<!-- PARENTS -->
|
<!-- PARENTS -->
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Parents}" IsVisible="{Binding Parents.Count, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"/>
|
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Parents}" IsVisible="{Binding Parents.Count, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"/>
|
||||||
|
@ -71,6 +81,7 @@
|
||||||
Text="{Binding Converter={x:Static c:StringConverters.ToShortSHA}}"
|
Text="{Binding Converter={x:Static c:StringConverters.ToShortSHA}}"
|
||||||
Foreground="DarkOrange"
|
Foreground="DarkOrange"
|
||||||
TextDecorations="Underline"
|
TextDecorations="Underline"
|
||||||
|
Cursor="Hand"
|
||||||
Margin="0,0,16,0"
|
Margin="0,0,16,0"
|
||||||
PointerPressed="OnParentSHAPressed"/>
|
PointerPressed="OnParentSHAPressed"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
|
@ -2,20 +2,12 @@ using Avalonia;
|
||||||
using Avalonia.Collections;
|
using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
public partial class CommitBaseInfo : UserControl
|
public partial class CommitBaseInfo : UserControl
|
||||||
{
|
{
|
||||||
public static readonly StyledProperty<bool> CanNavigateProperty =
|
|
||||||
AvaloniaProperty.Register<CommitBaseInfo, bool>(nameof(CanNavigate), true);
|
|
||||||
|
|
||||||
public bool CanNavigate
|
|
||||||
{
|
|
||||||
get => GetValue(CanNavigateProperty);
|
|
||||||
set => SetValue(CanNavigateProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly StyledProperty<string> MessageProperty =
|
public static readonly StyledProperty<string> MessageProperty =
|
||||||
AvaloniaProperty.Register<CommitBaseInfo, string>(nameof(Message), string.Empty);
|
AvaloniaProperty.Register<CommitBaseInfo, string>(nameof(Message), string.Empty);
|
||||||
|
|
||||||
|
@ -25,6 +17,15 @@ namespace SourceGit.Views
|
||||||
set => SetValue(MessageProperty, value);
|
set => SetValue(MessageProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<AvaloniaList<Models.CommitLink>> WebLinksProperty =
|
||||||
|
AvaloniaProperty.Register<CommitBaseInfo, AvaloniaList<Models.CommitLink>>(nameof(WebLinks));
|
||||||
|
|
||||||
|
public AvaloniaList<Models.CommitLink> WebLinks
|
||||||
|
{
|
||||||
|
get => GetValue(WebLinksProperty);
|
||||||
|
set => SetValue(WebLinksProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<AvaloniaList<Models.IssueTrackerRule>> IssueTrackerRulesProperty =
|
public static readonly StyledProperty<AvaloniaList<Models.IssueTrackerRule>> IssueTrackerRulesProperty =
|
||||||
AvaloniaProperty.Register<CommitBaseInfo, AvaloniaList<Models.IssueTrackerRule>>(nameof(IssueTrackerRules));
|
AvaloniaProperty.Register<CommitBaseInfo, AvaloniaList<Models.IssueTrackerRule>>(nameof(IssueTrackerRules));
|
||||||
|
|
||||||
|
@ -39,11 +40,43 @@ namespace SourceGit.Views
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnOpenWebLink(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (DataContext is ViewModels.CommitDetail detail)
|
||||||
|
{
|
||||||
|
var links = WebLinks;
|
||||||
|
if (links.Count > 1)
|
||||||
|
{
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
|
||||||
|
foreach (var link in links)
|
||||||
|
{
|
||||||
|
var url = $"{link.URLPrefix}{detail.Commit.SHA}";
|
||||||
|
var item = new MenuItem() { Header = link.Name };
|
||||||
|
item.Click += (_, ev) =>
|
||||||
|
{
|
||||||
|
Native.OS.OpenBrowser(url);
|
||||||
|
ev.Handled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
menu.Items.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
(sender as Control)?.OpenContextMenu(menu);
|
||||||
|
}
|
||||||
|
else if (links.Count == 1)
|
||||||
|
{
|
||||||
|
var url = $"{links[0].URLPrefix}{detail.Commit.SHA}";
|
||||||
|
Native.OS.OpenBrowser(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnParentSHAPressed(object sender, PointerPressedEventArgs e)
|
private void OnParentSHAPressed(object sender, PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is Control { DataContext: string sha } &&
|
if (DataContext is ViewModels.CommitDetail detail && sender is Control { DataContext: string sha })
|
||||||
DataContext is ViewModels.CommitDetail detail &&
|
|
||||||
CanNavigate)
|
|
||||||
{
|
{
|
||||||
detail.NavigateTo(sha);
|
detail.NavigateTo(sha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
<!-- Base Information -->
|
<!-- Base Information -->
|
||||||
<v:CommitBaseInfo Content="{Binding Commit}"
|
<v:CommitBaseInfo Content="{Binding Commit}"
|
||||||
Message="{Binding FullMessage}"
|
Message="{Binding FullMessage}"
|
||||||
|
WebLinks="{Binding WebLinks}"
|
||||||
IssueTrackerRules="{Binding IssueTrackerRules}"/>
|
IssueTrackerRules="{Binding IssueTrackerRules}"/>
|
||||||
|
|
||||||
<!-- Line -->
|
<!-- Line -->
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Avalonia.Collections;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Documents;
|
using Avalonia.Controls.Documents;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Utilities;
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
|
@ -38,6 +39,8 @@ namespace SourceGit.Views
|
||||||
if (change.Property == MessageProperty || change.Property == IssueTrackerRulesProperty)
|
if (change.Property == MessageProperty || change.Property == IssueTrackerRulesProperty)
|
||||||
{
|
{
|
||||||
Inlines.Clear();
|
Inlines.Clear();
|
||||||
|
_matches = null;
|
||||||
|
ClearHoveredIssueLink();
|
||||||
|
|
||||||
var message = Message;
|
var message = Message;
|
||||||
if (string.IsNullOrEmpty(message))
|
if (string.IsNullOrEmpty(message))
|
||||||
|
@ -61,6 +64,7 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
|
|
||||||
matches.Sort((l, r) => l.Start - r.Start);
|
matches.Sort((l, r) => l.Start - r.Start);
|
||||||
|
_matches = matches;
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
foreach (var match in matches)
|
foreach (var match in matches)
|
||||||
|
@ -68,12 +72,9 @@ namespace SourceGit.Views
|
||||||
if (match.Start > pos)
|
if (match.Start > pos)
|
||||||
Inlines.Add(new Run(message.Substring(pos, match.Start - pos)));
|
Inlines.Add(new Run(message.Substring(pos, match.Start - pos)));
|
||||||
|
|
||||||
var link = new TextBlock();
|
match.Link = new Run(message.Substring(match.Start, match.Length));
|
||||||
link.SetValue(TextProperty, message.Substring(match.Start, match.Length));
|
match.Link.Classes.Add("issue_link");
|
||||||
link.SetValue(ToolTip.TipProperty, match.URL);
|
Inlines.Add(match.Link);
|
||||||
link.Classes.Add("issue_link");
|
|
||||||
link.PointerPressed += OnLinkPointerPressed;
|
|
||||||
Inlines.Add(link);
|
|
||||||
|
|
||||||
pos = match.Start + match.Length;
|
pos = match.Start + match.Length;
|
||||||
}
|
}
|
||||||
|
@ -83,16 +84,71 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLinkPointerPressed(object sender, PointerPressedEventArgs e)
|
protected override void OnPointerMoved(PointerEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is TextBlock text)
|
base.OnPointerMoved(e);
|
||||||
{
|
|
||||||
var tooltip = text.GetValue(ToolTip.TipProperty) as string;
|
|
||||||
if (!string.IsNullOrEmpty(tooltip))
|
|
||||||
Native.OS.OpenBrowser(tooltip);
|
|
||||||
|
|
||||||
|
if (e.Pointer.Captured == null && _matches != null)
|
||||||
|
{
|
||||||
|
var padding = Padding;
|
||||||
|
var point = e.GetPosition(this) - new Point(padding.Left, padding.Top);
|
||||||
|
point = new Point(
|
||||||
|
MathUtilities.Clamp(point.X, 0, Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0)),
|
||||||
|
MathUtilities.Clamp(point.Y, 0, Math.Max(TextLayout.Height, 0)));
|
||||||
|
|
||||||
|
var pos = TextLayout.HitTestPoint(point).TextPosition;
|
||||||
|
foreach (var match in _matches)
|
||||||
|
{
|
||||||
|
if (!match.Intersect(pos, 1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (match == _lastHover)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastHover = match;
|
||||||
|
//_lastHover.Link.Classes.Add("issue_link_hovered");
|
||||||
|
|
||||||
|
SetCurrentValue(CursorProperty, Cursor.Parse("Hand"));
|
||||||
|
ToolTip.SetTip(this, match.URL);
|
||||||
|
ToolTip.SetIsOpen(this, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearHoveredIssueLink();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_lastHover != null)
|
||||||
|
{
|
||||||
|
e.Pointer.Capture(null);
|
||||||
|
Native.OS.OpenBrowser(_lastHover.URL);
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnPointerPressed(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerExited(PointerEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerExited(e);
|
||||||
|
ClearHoveredIssueLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearHoveredIssueLink()
|
||||||
|
{
|
||||||
|
if (_lastHover != null)
|
||||||
|
{
|
||||||
|
ToolTip.SetTip(this, null);
|
||||||
|
SetCurrentValue(CursorProperty, Cursor.Parse("IBeam"));
|
||||||
|
//_lastHover.Link.Classes.Remove("issue_link_hovered");
|
||||||
|
_lastHover = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Models.IssueTrackerMatch> _matches = null;
|
||||||
|
private Models.IssueTrackerMatch _lastHover = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,9 +191,11 @@ namespace SourceGit.Views
|
||||||
requiredWidth += label.Width + 16 /* icon */ + 8 /* label margin */ + 4 /* item right margin */;
|
requiredWidth += label.Width + 16 /* icon */ + 8 /* label margin */ + 4 /* item right margin */;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InvalidateVisual();
|
||||||
return new Size(requiredWidth, 16);
|
return new Size(requiredWidth, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InvalidateVisual();
|
||||||
return new Size(0, 0);
|
return new Size(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,7 @@
|
||||||
<ContentControl.DataTemplates>
|
<ContentControl.DataTemplates>
|
||||||
<DataTemplate DataType="m:RevisionSubmodule">
|
<DataTemplate DataType="m:RevisionSubmodule">
|
||||||
<Border Margin="0,0,0,8" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border1}" Background="{DynamicResource Brush.Window}">
|
<Border Margin="0,0,0,8" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border1}" Background="{DynamicResource Brush.Window}">
|
||||||
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" CanNavigate="False" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ContentControl.DataTemplates>
|
</ContentControl.DataTemplates>
|
||||||
|
@ -190,7 +190,7 @@
|
||||||
<Path Width="16" Height="16" Data="{StaticResource Icons.DoubleDown}" HorizontalAlignment="Center" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
<Path Width="16" Height="16" Data="{StaticResource Icons.DoubleDown}" HorizontalAlignment="Center" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||||||
|
|
||||||
<Border Margin="0,8,0,0" BorderThickness="1" BorderBrush="Green" Background="{DynamicResource Brush.Window}">
|
<Border Margin="0,8,0,0" BorderThickness="1" BorderBrush="Green" Background="{DynamicResource Brush.Window}">
|
||||||
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" CanNavigate="False" Content="{Binding New.Commit}" Message="{Binding New.FullMessage}"/>
|
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" Content="{Binding New.Commit}" Message="{Binding New.FullMessage}"/>
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
|
@ -11,6 +11,7 @@ using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using Avalonia.Utilities;
|
||||||
using Avalonia.VisualTree;
|
using Avalonia.VisualTree;
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
|
@ -185,6 +186,8 @@ namespace SourceGit.Views
|
||||||
if (change.Property == SubjectProperty || change.Property == IssueTrackerRulesProperty)
|
if (change.Property == SubjectProperty || change.Property == IssueTrackerRulesProperty)
|
||||||
{
|
{
|
||||||
Inlines.Clear();
|
Inlines.Clear();
|
||||||
|
_matches = null;
|
||||||
|
ClearHoveredIssueLink();
|
||||||
|
|
||||||
var subject = Subject;
|
var subject = Subject;
|
||||||
if (string.IsNullOrEmpty(subject))
|
if (string.IsNullOrEmpty(subject))
|
||||||
|
@ -208,6 +211,7 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
|
|
||||||
matches.Sort((l, r) => l.Start - r.Start);
|
matches.Sort((l, r) => l.Start - r.Start);
|
||||||
|
_matches = matches;
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
foreach (var match in matches)
|
foreach (var match in matches)
|
||||||
|
@ -215,32 +219,82 @@ namespace SourceGit.Views
|
||||||
if (match.Start > pos)
|
if (match.Start > pos)
|
||||||
Inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
|
Inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
|
||||||
|
|
||||||
var link = new TextBlock();
|
match.Link = new Run(subject.Substring(match.Start, match.Length));
|
||||||
link.SetValue(TextProperty, subject.Substring(match.Start, match.Length));
|
match.Link.Classes.Add("issue_link");
|
||||||
link.SetValue(ToolTip.TipProperty, match.URL);
|
Inlines.Add(match.Link);
|
||||||
link.Classes.Add("issue_link");
|
|
||||||
link.PointerPressed += OnLinkPointerPressed;
|
|
||||||
Inlines.Add(link);
|
|
||||||
|
|
||||||
pos = match.Start + match.Length;
|
pos = match.Start + match.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos < subject.Length)
|
if (pos < subject.Length)
|
||||||
Inlines.Add(new Run(subject.Substring(pos)));
|
Inlines.Add(new Run(subject.Substring(pos)));
|
||||||
|
|
||||||
|
InvalidateTextLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLinkPointerPressed(object sender, PointerPressedEventArgs e)
|
protected override void OnPointerMoved(PointerEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is TextBlock text)
|
base.OnPointerMoved(e);
|
||||||
{
|
|
||||||
var tooltip = text.GetValue(ToolTip.TipProperty) as string;
|
|
||||||
if (!string.IsNullOrEmpty(tooltip))
|
|
||||||
Native.OS.OpenBrowser(tooltip);
|
|
||||||
|
|
||||||
|
if (_matches != null)
|
||||||
|
{
|
||||||
|
var padding = Padding;
|
||||||
|
var point = e.GetPosition(this) - new Point(padding.Left, padding.Top);
|
||||||
|
point = new Point(
|
||||||
|
MathUtilities.Clamp(point.X, 0, Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0)),
|
||||||
|
MathUtilities.Clamp(point.Y, 0, Math.Max(TextLayout.Height, 0)));
|
||||||
|
|
||||||
|
var textPosition = TextLayout.HitTestPoint(point).TextPosition;
|
||||||
|
foreach (var match in _matches)
|
||||||
|
{
|
||||||
|
if (!match.Intersect(textPosition, 1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (match == _lastHover)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_lastHover = match;
|
||||||
|
//_lastHover.Link.Classes.Add("issue_link_hovered");
|
||||||
|
|
||||||
|
SetCurrentValue(CursorProperty, Cursor.Parse("Hand"));
|
||||||
|
ToolTip.SetTip(this, match.URL);
|
||||||
|
ToolTip.SetIsOpen(this, true);
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearHoveredIssueLink();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerPressed(e);
|
||||||
|
|
||||||
|
if (_lastHover != null)
|
||||||
|
Native.OS.OpenBrowser(_lastHover.URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerExited(PointerEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerExited(e);
|
||||||
|
ClearHoveredIssueLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearHoveredIssueLink()
|
||||||
|
{
|
||||||
|
if (_lastHover != null)
|
||||||
|
{
|
||||||
|
ToolTip.SetTip(this, null);
|
||||||
|
SetCurrentValue(CursorProperty, Cursor.Parse("Arrow"));
|
||||||
|
//_lastHover.Link.Classes.Remove("issue_link_hovered");
|
||||||
|
_lastHover = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Models.IssueTrackerMatch> _matches = null;
|
||||||
|
private Models.IssueTrackerMatch _lastHover = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CommitTimeTextBlock : TextBlock
|
public class CommitTimeTextBlock : TextBlock
|
||||||
|
@ -541,6 +595,15 @@ namespace SourceGit.Views
|
||||||
set => SetValue(CurrentBranchProperty, value);
|
set => SetValue(CurrentBranchProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<AvaloniaList<Models.IssueTrackerRule>> IssueTrackerRulesProperty =
|
||||||
|
AvaloniaProperty.Register<Histories, AvaloniaList<Models.IssueTrackerRule>>(nameof(IssueTrackerRules));
|
||||||
|
|
||||||
|
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
||||||
|
{
|
||||||
|
get => GetValue(IssueTrackerRulesProperty);
|
||||||
|
set => SetValue(IssueTrackerRulesProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly StyledProperty<long> NavigationIdProperty =
|
public static readonly StyledProperty<long> NavigationIdProperty =
|
||||||
AvaloniaProperty.Register<Histories, long>(nameof(NavigationId));
|
AvaloniaProperty.Register<Histories, long>(nameof(NavigationId));
|
||||||
|
|
||||||
|
@ -550,16 +613,6 @@ namespace SourceGit.Views
|
||||||
set => SetValue(NavigationIdProperty, value);
|
set => SetValue(NavigationIdProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvaloniaList<Models.IssueTrackerRule> IssueTrackerRules
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (DataContext is ViewModels.Histories histories)
|
|
||||||
return histories.IssueTrackerRules;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Histories()
|
static Histories()
|
||||||
{
|
{
|
||||||
NavigationIdProperty.Changed.AddClassHandler<Histories>((h, _) =>
|
NavigationIdProperty.Changed.AddClassHandler<Histories>((h, _) =>
|
||||||
|
|
|
@ -41,6 +41,11 @@
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Settings}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Settings}"/>
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="{DynamicResource Text.OpenAppDataDir}" Command="{x:Static s:App.OpenAppDataDirCommand}">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Explore}"/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem Header="{DynamicResource Text.Hotkeys}" Command="{x:Static s:App.OpenHotkeysCommand}">
|
<MenuItem Header="{DynamicResource Text.Hotkeys}" Command="{x:Static s:App.OpenHotkeysCommand}">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Hotkeys}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Hotkeys}"/>
|
||||||
|
|
|
@ -20,6 +20,11 @@ namespace SourceGit.Views
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasKeyModifier(KeyModifiers modifier)
|
||||||
|
{
|
||||||
|
return _unhandledModifiers.HasFlag(modifier);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnOpened(EventArgs e)
|
protected override void OnOpened(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnOpened(e);
|
base.OnOpened(e);
|
||||||
|
@ -147,6 +152,27 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnKeyDown(e);
|
base.OnKeyDown(e);
|
||||||
|
|
||||||
|
// Record unhandled key modifers.
|
||||||
|
if (!e.Handled)
|
||||||
|
{
|
||||||
|
_unhandledModifiers = e.KeyModifiers;
|
||||||
|
|
||||||
|
if (!_unhandledModifiers.HasFlag(KeyModifiers.Alt) && (e.Key == Key.LeftAlt || e.Key == Key.RightAlt))
|
||||||
|
_unhandledModifiers |= KeyModifiers.Alt;
|
||||||
|
|
||||||
|
if (!_unhandledModifiers.HasFlag(KeyModifiers.Control) && (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl))
|
||||||
|
_unhandledModifiers |= KeyModifiers.Control;
|
||||||
|
|
||||||
|
if (!_unhandledModifiers.HasFlag(KeyModifiers.Shift) && (e.Key == Key.LeftShift || e.Key == Key.RightShift))
|
||||||
|
_unhandledModifiers |= KeyModifiers.Shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnKeyUp(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnKeyUp(e);
|
||||||
|
_unhandledModifiers = KeyModifiers.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnClosing(WindowClosingEventArgs e)
|
protected override void OnClosing(WindowClosingEventArgs e)
|
||||||
|
@ -178,5 +204,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyModifiers _unhandledModifiers = KeyModifiers.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<TabItem.Header>
|
<TabItem.Header>
|
||||||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
|
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
|
||||||
</TabItem.Header>
|
</TabItem.Header>
|
||||||
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
|
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
|
||||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.Locale}"
|
Text="{DynamicResource Text.Preference.General.Locale}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
|
@ -71,25 +71,10 @@
|
||||||
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/>
|
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.AvatarServer}"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Margin="0,0,16,0"/>
|
|
||||||
<ComboBox Grid.Row="1" Grid.Column="1"
|
|
||||||
MinHeight="28"
|
|
||||||
Padding="8,0"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
SelectedItem="{Binding AvatarServer, Mode=TwoWay}">
|
|
||||||
<ComboBox.Items>
|
|
||||||
<sys:String>https://www.gravatar.com/avatar/</sys:String>
|
|
||||||
<sys:String>https://cravatar.cn/avatar/</sys:String>
|
|
||||||
</ComboBox.Items>
|
|
||||||
</ComboBox>
|
|
||||||
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
|
||||||
Text="{DynamicResource Text.Preference.General.VisibleDiffContextLines}"
|
Text="{DynamicResource Text.Preference.General.VisibleDiffContextLines}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<NumericUpDown Grid.Row="2" Grid.Column="1"
|
<NumericUpDown Grid.Row="1" Grid.Column="1"
|
||||||
Minimum="4" Maximum="10000" Increment="1"
|
Minimum="4" Maximum="10000" Increment="1"
|
||||||
Height="28"
|
Height="28"
|
||||||
Padding="4"
|
Padding="4"
|
||||||
|
@ -98,11 +83,11 @@
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
Value="{Binding DiffViewVisualLineNumbers, Mode=TwoWay}"/>
|
Value="{Binding DiffViewVisualLineNumbers, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0"
|
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.SubjectGuideLength}"
|
Text="{DynamicResource Text.Preference.General.SubjectGuideLength}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<NumericUpDown Grid.Row="3" Grid.Column="1"
|
<NumericUpDown Grid.Row="2" Grid.Column="1"
|
||||||
Minimum="50" Maximum="1000" Increment="1"
|
Minimum="50" Maximum="1000" Increment="1"
|
||||||
Height="28"
|
Height="28"
|
||||||
Padding="4"
|
Padding="4"
|
||||||
|
@ -111,11 +96,11 @@
|
||||||
CornerRadius="3"
|
CornerRadius="3"
|
||||||
Value="{Binding SubjectGuideLength, Mode=TwoWay}"/>
|
Value="{Binding SubjectGuideLength, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0"
|
<TextBlock Grid.Row="3" Grid.Column="0"
|
||||||
Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}"
|
Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="0,0,16,0"/>
|
Margin="0,0,16,0"/>
|
||||||
<Grid Grid.Row="4" Grid.Column="1" ColumnDefinitions="*,64">
|
<Grid Grid.Row="3" Grid.Column="1" ColumnDefinitions="*,64">
|
||||||
<Slider Grid.Column="0"
|
<Slider Grid.Column="0"
|
||||||
Minimum="20000" Maximum="100000"
|
Minimum="20000" Maximum="100000"
|
||||||
TickPlacement="BottomRight" TickFrequency="5000"
|
TickPlacement="BottomRight" TickFrequency="5000"
|
||||||
|
@ -130,16 +115,16 @@
|
||||||
Text="{Binding MaxHistoryCommits}"/>
|
Text="{Binding MaxHistoryCommits}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<CheckBox Grid.Row="5" Grid.Column="1"
|
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||||
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
|
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
|
||||||
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
|
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<CheckBox Grid.Row="6" Grid.Column="1"
|
<CheckBox Grid.Row="5" Grid.Column="1"
|
||||||
Height="32"
|
Height="32"
|
||||||
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
|
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
|
||||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
|
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
|
||||||
|
|
||||||
<CheckBox Grid.Row="7" Grid.Column="1"
|
<CheckBox Grid.Row="6" Grid.Column="1"
|
||||||
Height="32"
|
Height="32"
|
||||||
Content="{DynamicResource Text.Preference.General.Check4UpdatesOnStartup}"
|
Content="{DynamicResource Text.Preference.General.Check4UpdatesOnStartup}"
|
||||||
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=Check4UpdatesOnStartup, Mode=TwoWay}"/>
|
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=Check4UpdatesOnStartup, Mode=TwoWay}"/>
|
||||||
|
|
|
@ -91,15 +91,14 @@
|
||||||
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
|
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
|
||||||
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Changes}"/>
|
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Changes}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.WorkingCopy}"/>
|
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.WorkingCopy}"/>
|
||||||
<Border Grid.Column="2"
|
<v:CounterPresenter Grid.Column="2"
|
||||||
Margin="6,0"
|
Margin="6,0"
|
||||||
Height="18"
|
|
||||||
CornerRadius="9"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="{DynamicResource Brush.Badge}"
|
Count="{Binding LocalChangesCount}"
|
||||||
IsVisible="{Binding WorkingCopyChangesCount, Converter={x:Static c:IntConverters.IsGreaterThanZero}}">
|
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
|
||||||
<TextBlock Classes="primary" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding WorkingCopyChangesCount}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
FontSize="10"
|
||||||
</Border>
|
Foreground="{DynamicResource Brush.BadgeFG}"
|
||||||
|
Background="{DynamicResource Brush.Badge}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ListBoxItem>
|
</ListBoxItem>
|
||||||
|
|
||||||
|
@ -107,15 +106,14 @@
|
||||||
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
|
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
|
||||||
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Stashes}"/>
|
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Stashes}"/>
|
||||||
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.Stashes}"/>
|
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.Stashes}"/>
|
||||||
<Border Grid.Column="2"
|
<v:CounterPresenter Grid.Column="2"
|
||||||
Margin="6,0"
|
Margin="6,0"
|
||||||
Height="18"
|
|
||||||
CornerRadius="9"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="{DynamicResource Brush.Badge}"
|
Count="{Binding StashesCount}"
|
||||||
IsVisible="{Binding StashesCount, Converter={x:Static c:IntConverters.IsGreaterThanZero}}">
|
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
|
||||||
<TextBlock Classes="primary" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding StashesCount}" Foreground="{DynamicResource Brush.BadgeFG}"/>
|
FontSize="10"
|
||||||
</Border>
|
Foreground="{DynamicResource Brush.BadgeFG}"
|
||||||
|
Background="{DynamicResource Brush.Badge}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ListBoxItem>
|
</ListBoxItem>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
|
@ -670,7 +668,8 @@
|
||||||
<ContentControl Grid.Row="2" Content="{Binding SelectedView}">
|
<ContentControl Grid.Row="2" Content="{Binding SelectedView}">
|
||||||
<ContentControl.DataTemplates>
|
<ContentControl.DataTemplates>
|
||||||
<DataTemplate DataType="vm:Histories">
|
<DataTemplate DataType="vm:Histories">
|
||||||
<v:Histories CurrentBranch="{Binding $parent[v:Repository].((vm:Repository)DataContext).CurrentBranch}"
|
<v:Histories CurrentBranch="{Binding Repo.CurrentBranch}"
|
||||||
|
IssueTrackerRules="{Binding Repo.Settings.IssueTrackerRules}"
|
||||||
NavigationId="{Binding NavigationId}"/>
|
NavigationId="{Binding NavigationId}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,109 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.Media;
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
|
public class CounterPresenter : Control
|
||||||
|
{
|
||||||
|
public static readonly StyledProperty<int> CountProperty =
|
||||||
|
AvaloniaProperty.Register<CounterPresenter, int>(nameof(Count), 0);
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get => GetValue(CountProperty);
|
||||||
|
set => SetValue(CountProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
|
||||||
|
TextBlock.FontFamilyProperty.AddOwner<CounterPresenter>();
|
||||||
|
|
||||||
|
public FontFamily FontFamily
|
||||||
|
{
|
||||||
|
get => GetValue(FontFamilyProperty);
|
||||||
|
set => SetValue(FontFamilyProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<double> FontSizeProperty =
|
||||||
|
TextBlock.FontSizeProperty.AddOwner<CounterPresenter>();
|
||||||
|
|
||||||
|
public double FontSize
|
||||||
|
{
|
||||||
|
get => GetValue(FontSizeProperty);
|
||||||
|
set => SetValue(FontSizeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush> ForegroundProperty =
|
||||||
|
AvaloniaProperty.Register<CounterPresenter, IBrush>(nameof(Foreground), Brushes.White);
|
||||||
|
|
||||||
|
public IBrush Foreground
|
||||||
|
{
|
||||||
|
get => GetValue(ForegroundProperty);
|
||||||
|
set => SetValue(ForegroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<IBrush> BackgroundProperty =
|
||||||
|
AvaloniaProperty.Register<CounterPresenter, IBrush>(nameof(Background), Brushes.White);
|
||||||
|
|
||||||
|
public IBrush Background
|
||||||
|
{
|
||||||
|
get => GetValue(BackgroundProperty);
|
||||||
|
set => SetValue(BackgroundProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CounterPresenter()
|
||||||
|
{
|
||||||
|
AffectsMeasure<CounterPresenter>(
|
||||||
|
FontSizeProperty,
|
||||||
|
FontFamilyProperty,
|
||||||
|
ForegroundProperty,
|
||||||
|
CountProperty);
|
||||||
|
|
||||||
|
AffectsRender<CounterPresenter>(
|
||||||
|
ForegroundProperty,
|
||||||
|
BackgroundProperty,
|
||||||
|
CountProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Render(DrawingContext context)
|
||||||
|
{
|
||||||
|
base.Render(context);
|
||||||
|
|
||||||
|
if (_label != null)
|
||||||
|
{
|
||||||
|
context.DrawRectangle(Background, null, new RoundedRect(new Rect(0, 0, _label.Width + 18, 18), new CornerRadius(9)));
|
||||||
|
context.DrawText(_label, new Point(9, 9 - _label.Height * 0.5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
|
{
|
||||||
|
if (Count > 0)
|
||||||
|
{
|
||||||
|
_label = new FormattedText(
|
||||||
|
Count.ToString(),
|
||||||
|
CultureInfo.CurrentCulture,
|
||||||
|
FlowDirection.LeftToRight,
|
||||||
|
new Typeface(FontFamily),
|
||||||
|
FontSize,
|
||||||
|
Foreground);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_label = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _label != null ? new Size(_label.Width + 18, 18) : new Size(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FormattedText _label = null;
|
||||||
|
}
|
||||||
|
|
||||||
public partial class Repository : UserControl
|
public partial class Repository : UserControl
|
||||||
{
|
{
|
||||||
public Repository()
|
public Repository()
|
||||||
|
@ -164,7 +261,7 @@ namespace SourceGit.Views
|
||||||
if (!IsLoaded)
|
if (!IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var leftHeight = LeftSidebarGroups.Bounds.Height - 28.0 * 5;
|
var leftHeight = LeftSidebarGroups.Bounds.Height - 28.0 * 5 - 4;
|
||||||
var localBranchRows = vm.IsLocalBranchGroupExpanded ? LocalBranchTree.Rows.Count : 0;
|
var localBranchRows = vm.IsLocalBranchGroupExpanded ? LocalBranchTree.Rows.Count : 0;
|
||||||
var remoteBranchRows = vm.IsRemoteGroupExpanded ? RemoteBranchTree.Rows.Count : 0;
|
var remoteBranchRows = vm.IsRemoteGroupExpanded ? RemoteBranchTree.Rows.Count : 0;
|
||||||
var desiredBranches = (localBranchRows + remoteBranchRows) * 24.0;
|
var desiredBranches = (localBranchRows + remoteBranchRows) * 24.0;
|
||||||
|
|
|
@ -112,6 +112,91 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem>
|
||||||
|
<TabItem.Header>
|
||||||
|
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.CommitMessageTemplate}"/>
|
||||||
|
</TabItem.Header>
|
||||||
|
|
||||||
|
<Grid ColumnDefinitions="200,*" Height="250" Margin="0,8,0,16">
|
||||||
|
<Border Grid.Column="0"
|
||||||
|
BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}"
|
||||||
|
Background="{DynamicResource Brush.Contents}">
|
||||||
|
<Grid RowDefinitions="*,1,Auto">
|
||||||
|
<ListBox Grid.Row="0"
|
||||||
|
Background="Transparent"
|
||||||
|
ItemsSource="{Binding CommitTemplates}"
|
||||||
|
SelectedItem="{Binding SelectedCommitTemplate, Mode=TwoWay}"
|
||||||
|
SelectionMode="Single">
|
||||||
|
<ListBox.Styles>
|
||||||
|
<Style Selector="ListBoxItem">
|
||||||
|
<Setter Property="MinHeight" Value="0"/>
|
||||||
|
<Setter Property="Height" Value="26"/>
|
||||||
|
<Setter Property="Padding" Value="4,2"/>
|
||||||
|
</Style>
|
||||||
|
</ListBox.Styles>
|
||||||
|
|
||||||
|
<ListBox.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Vertical"/>
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ListBox.ItemsPanel>
|
||||||
|
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate DataType="m:CommitTemplate">
|
||||||
|
<Grid ColumnDefinitions="Auto,*">
|
||||||
|
<Path Grid.Column="0" Width="14" Height="14" Data="{StaticResource Icons.Code}"/>
|
||||||
|
<TextBlock Grid.Column="1" Text="{Binding Name}" Margin="8,0" TextTrimming="CharacterEllipsis"/>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
|
<Rectangle Grid.Row="1" Height="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom"/>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2" Orientation="Horizontal" Background="{DynamicResource Brush.ToolBar}">
|
||||||
|
<Button Classes="icon_button" Command="{Binding AddCommitTemplate}">
|
||||||
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Plus}"/>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Rectangle Width="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Left" VerticalAlignment="Stretch"/>
|
||||||
|
|
||||||
|
<Button Classes="icon_button" Command="{Binding RemoveSelectedCommitTemplate}">
|
||||||
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Window.Minimize}"/>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Rectangle Width="1" Fill="{DynamicResource Brush.Border2}" HorizontalAlignment="Left" VerticalAlignment="Stretch"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ContentControl Grid.Column="1" Margin="16,0,0,0">
|
||||||
|
<ContentControl.Content>
|
||||||
|
<Binding Path="SelectedCommitTemplate">
|
||||||
|
<Binding.TargetNullValue>
|
||||||
|
<Path Width="64" Height="64"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Fill="{DynamicResource Brush.FG2}"
|
||||||
|
Data="{StaticResource Icons.Empty}"/>
|
||||||
|
</Binding.TargetNullValue>
|
||||||
|
</Binding>
|
||||||
|
</ContentControl.Content>
|
||||||
|
|
||||||
|
<ContentControl.DataTemplates>
|
||||||
|
<DataTemplate DataType="m:CommitTemplate">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{DynamicResource Text.Configure.CommitMessageTemplate.Name}"/>
|
||||||
|
<TextBox Margin="0,4,0,0" CornerRadius="3" Height="28" Text="{Binding Name, Mode=TwoWay}"/>
|
||||||
|
|
||||||
|
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.CommitMessageTemplate.Content}"/>
|
||||||
|
<v:CommitMessageTextBox Height="150" Text="{Binding Content, Mode=TwoWay}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ContentControl.DataTemplates>
|
||||||
|
</ContentControl>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
<TabItem>
|
<TabItem>
|
||||||
<TabItem.Header>
|
<TabItem.Header>
|
||||||
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.IssueTracker}"/>
|
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.IssueTracker}"/>
|
||||||
|
|
|
@ -31,19 +31,47 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||||
<Button Classes="icon_button" Width="32" Command="{Binding Fetch}" ToolTip.Tip="{DynamicResource Text.Fetch}">
|
<Button Classes="icon_button" Width="32" Click="Fetch">
|
||||||
|
<ToolTip.Tip>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{DynamicResource Text.Fetch}"/>
|
||||||
|
<TextBlock Classes="small italic" Margin="0,4,0,0" Text="{DynamicResource Text.CtrlClickTip}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ToolTip.Tip>
|
||||||
|
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Fetch}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Fetch}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Command="{Binding Pull}" ToolTip.Tip="{DynamicResource Text.Pull}">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Pull">
|
||||||
|
<ToolTip.Tip>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{DynamicResource Text.Pull}"/>
|
||||||
|
<TextBlock Classes="small italic" Margin="0,4,0,0" Text="{DynamicResource Text.CtrlClickTip}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ToolTip.Tip>
|
||||||
|
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Pull}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Pull}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Command="{Binding Push}" ToolTip.Tip="{DynamicResource Text.Push}">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="Push">
|
||||||
|
<ToolTip.Tip>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{DynamicResource Text.Push}"/>
|
||||||
|
<TextBlock Classes="small italic" Margin="0,4,0,0" Text="{DynamicResource Text.CtrlClickTip}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ToolTip.Tip>
|
||||||
|
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Push}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Push}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Command="{Binding StashAll}" ToolTip.Tip="{DynamicResource Text.Stash}">
|
<Button Classes="icon_button" Width="32" Margin="16,0,0,0" Click="StashAll">
|
||||||
|
<ToolTip.Tip>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock Text="{DynamicResource Text.Stash}"/>
|
||||||
|
<TextBlock Classes="small italic" Margin="0,4,0,0" Text="{DynamicResource Text.CtrlClickTip}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ToolTip.Tip>
|
||||||
|
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.Stashes.Add}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Stashes.Add}"/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.VisualTree;
|
||||||
|
|
||||||
namespace SourceGit.Views
|
namespace SourceGit.Views
|
||||||
{
|
{
|
||||||
|
@ -40,6 +42,34 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Fetch(object _, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var launcher = this.FindAncestorOfType<Launcher>();
|
||||||
|
(DataContext as ViewModels.Repository)?.Fetch(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Pull(object _, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var launcher = this.FindAncestorOfType<Launcher>();
|
||||||
|
(DataContext as ViewModels.Repository)?.Pull(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Push(object _, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var launcher = this.FindAncestorOfType<Launcher>();
|
||||||
|
(DataContext as ViewModels.Repository)?.Push(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StashAll(object _, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var launcher = this.FindAncestorOfType<Launcher>();
|
||||||
|
(DataContext as ViewModels.Repository)?.StashAll(launcher?.HasKeyModifier(KeyModifiers.Control) ?? false);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OpenGitFlowMenu(object sender, RoutedEventArgs e)
|
private void OpenGitFlowMenu(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (DataContext is ViewModels.Repository repo)
|
if (DataContext is ViewModels.Repository repo)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4" IsVisible="{Binding IsCurrentHead}">
|
<Border Grid.Column="2" Background="{DynamicResource Brush.Accent}" CornerRadius="4" IsVisible="{Binding IsCurrentHead}">
|
||||||
<TextBlock Text="HEAD" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
<TextBlock Text="HEAD" Classes="primary" Margin="4,0" Foreground="#FFDDDDDD"/>
|
||||||
</Border>
|
</Border>
|
||||||
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" PointerPressed="OnPressedSHA" />
|
<TextBlock Grid.Column="3" Classes="primary" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0" TextDecorations="Underline" Cursor="Hand" PointerPressed="OnPressedSHA" />
|
||||||
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
<DataTemplate DataType="m:RevisionSubmodule">
|
<DataTemplate DataType="m:RevisionSubmodule">
|
||||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="8,8,8,0">
|
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="8,8,8,0">
|
||||||
<TextBlock Text="{DynamicResource Text.CommitDetail.Files.Submodule}" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Foreground="{DynamicResource Brush.FG2}"/>
|
<TextBlock Text="{DynamicResource Text.CommitDetail.Files.Submodule}" FontSize="18" FontWeight="Bold" HorizontalAlignment="Center" Foreground="{DynamicResource Brush.FG2}"/>
|
||||||
<v:CommitBaseInfo Margin="0,16,0,0" CanNavigate="False" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
<v:CommitBaseInfo Margin="0,16,0,0" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ContentControl.DataTemplates>
|
</ContentControl.DataTemplates>
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace SourceGit.Views
|
||||||
Math.Abs(Height - old.Height) > 0.001 ||
|
Math.Abs(Height - old.Height) > 0.001 ||
|
||||||
StartIdx != old.StartIdx ||
|
StartIdx != old.StartIdx ||
|
||||||
EndIdx != old.EndIdx ||
|
EndIdx != old.EndIdx ||
|
||||||
Combined != Combined ||
|
Combined != old.Combined ||
|
||||||
IsOldSide != IsOldSide;
|
IsOldSide != old.IsOldSide;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,9 @@ namespace SourceGit.Views
|
||||||
var typeface = view.CreateTypeface();
|
var typeface = view.CreateTypeface();
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > lines.Count)
|
if (index > lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -160,7 +163,7 @@ namespace SourceGit.Views
|
||||||
var width = textView.Bounds.Width;
|
var width = textView.Bounds.Width;
|
||||||
foreach (var line in textView.VisualLines)
|
foreach (var line in textView.VisualLines)
|
||||||
{
|
{
|
||||||
if (line.FirstDocumentLine == null)
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
|
@ -172,8 +175,47 @@ namespace SourceGit.Views
|
||||||
if (bg == null)
|
if (bg == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - textView.VerticalOffset;
|
var startY = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop) - textView.VerticalOffset;
|
||||||
drawingContext.DrawRectangle(bg, null, new Rect(0, y, width, line.Height));
|
var endY = line.GetTextLineVisualYPosition(line.TextLines[^1], VisualYPosition.LineBottom) - textView.VerticalOffset;
|
||||||
|
drawingContext.DrawRectangle(bg, null, new Rect(0, startY, width, endY - startY));
|
||||||
|
|
||||||
|
if (info.Highlights.Count > 0)
|
||||||
|
{
|
||||||
|
var highlightBG = info.Type == Models.TextDiffLineType.Added ? _presenter.AddedHighlightBrush : _presenter.DeletedHighlightBrush;
|
||||||
|
var processingIdxStart = 0;
|
||||||
|
var processingIdxEnd = 0;
|
||||||
|
var nextHightlight = 0;
|
||||||
|
|
||||||
|
foreach (var tl in line.TextLines)
|
||||||
|
{
|
||||||
|
processingIdxEnd += tl.Length;
|
||||||
|
|
||||||
|
var y = line.GetTextLineVisualYPosition(tl, VisualYPosition.LineTop) - textView.VerticalOffset;
|
||||||
|
var h = line.GetTextLineVisualYPosition(tl, VisualYPosition.LineBottom) - textView.VerticalOffset - y;
|
||||||
|
|
||||||
|
while (nextHightlight < info.Highlights.Count)
|
||||||
|
{
|
||||||
|
var highlight = info.Highlights[nextHightlight];
|
||||||
|
if (highlight.Start >= processingIdxEnd)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var start = line.GetVisualColumn(highlight.Start < processingIdxStart ? processingIdxStart : highlight.Start);
|
||||||
|
var end = line.GetVisualColumn(highlight.End >= processingIdxEnd ? processingIdxEnd : highlight.End + 1);
|
||||||
|
|
||||||
|
var x = line.GetTextLineVisualXPosition(tl, start) - textView.HorizontalOffset;
|
||||||
|
var w = line.GetTextLineVisualXPosition(tl, end) - textView.HorizontalOffset - x;
|
||||||
|
var rect = new Rect(x, y, w, h);
|
||||||
|
drawingContext.DrawRectangle(highlightBG, null, rect);
|
||||||
|
|
||||||
|
if (highlight.End >= processingIdxEnd)
|
||||||
|
break;
|
||||||
|
|
||||||
|
nextHightlight++;
|
||||||
|
}
|
||||||
|
|
||||||
|
processingIdxStart = processingIdxEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,20 +259,6 @@ namespace SourceGit.Views
|
||||||
v.TextRunProperties.SetForegroundBrush(_presenter.IndicatorForeground);
|
v.TextRunProperties.SetForegroundBrush(_presenter.IndicatorForeground);
|
||||||
v.TextRunProperties.SetTypeface(new Typeface(_presenter.FontFamily, FontStyle.Italic));
|
v.TextRunProperties.SetTypeface(new Typeface(_presenter.FontFamily, FontStyle.Italic));
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.Highlights.Count > 0)
|
|
||||||
{
|
|
||||||
var bg = info.Type == Models.TextDiffLineType.Added ? _presenter.AddedHighlightBrush : _presenter.DeletedHighlightBrush;
|
|
||||||
foreach (var highlight in info.Highlights)
|
|
||||||
{
|
|
||||||
ChangeLinePart(line.Offset + highlight.Start, line.Offset + highlight.Start + highlight.Count, v =>
|
|
||||||
{
|
|
||||||
v.TextRunProperties.SetBackgroundBrush(bg);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +422,7 @@ namespace SourceGit.Views
|
||||||
if (chunk == null || (!chunk.Combined && chunk.IsOldSide != IsOld))
|
if (chunk == null || (!chunk.Combined && chunk.IsOldSide != IsOld))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var color = (Color)this.FindResource("SystemAccentColor");
|
var color = (Color)this.FindResource("SystemAccentColor")!;
|
||||||
var brush = new SolidColorBrush(color, 0.1);
|
var brush = new SolidColorBrush(color, 0.1);
|
||||||
var pen = new Pen(color.ToUInt32());
|
var pen = new Pen(color.ToUInt32());
|
||||||
var rect = new Rect(0, chunk.Y, Bounds.Width, chunk.Height);
|
var rect = new Rect(0, chunk.Y, Bounds.Width, chunk.Height);
|
||||||
|
@ -409,6 +437,7 @@ namespace SourceGit.Views
|
||||||
base.OnLoaded(e);
|
base.OnLoaded(e);
|
||||||
|
|
||||||
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
||||||
|
TextArea.TextView.PointerEntered += OnTextViewPointerEntered;
|
||||||
TextArea.TextView.PointerMoved += OnTextViewPointerMoved;
|
TextArea.TextView.PointerMoved += OnTextViewPointerMoved;
|
||||||
TextArea.TextView.PointerWheelChanged += OnTextViewPointerWheelChanged;
|
TextArea.TextView.PointerWheelChanged += OnTextViewPointerWheelChanged;
|
||||||
|
|
||||||
|
@ -420,6 +449,7 @@ namespace SourceGit.Views
|
||||||
base.OnUnloaded(e);
|
base.OnUnloaded(e);
|
||||||
|
|
||||||
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
||||||
|
TextArea.TextView.PointerEntered -= OnTextViewPointerEntered;
|
||||||
TextArea.TextView.PointerMoved -= OnTextViewPointerMoved;
|
TextArea.TextView.PointerMoved -= OnTextViewPointerMoved;
|
||||||
TextArea.TextView.PointerWheelChanged -= OnTextViewPointerWheelChanged;
|
TextArea.TextView.PointerWheelChanged -= OnTextViewPointerWheelChanged;
|
||||||
|
|
||||||
|
@ -480,6 +510,12 @@ namespace SourceGit.Views
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTextViewPointerEntered(object sender, PointerEventArgs e)
|
||||||
|
{
|
||||||
|
if (EnableChunkSelection && sender is TextView view)
|
||||||
|
UpdateSelectedChunk(e.GetPosition(view).Y + view.VerticalOffset);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTextViewPointerMoved(object sender, PointerEventArgs e)
|
private void OnTextViewPointerMoved(object sender, PointerEventArgs e)
|
||||||
{
|
{
|
||||||
if (EnableChunkSelection && sender is TextView view)
|
if (EnableChunkSelection && sender is TextView view)
|
||||||
|
@ -675,12 +711,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
||||||
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
||||||
if (endIdx < firstLineIdx)
|
if (endIdx < firstLineIdx || startIdx > lastLineIdx)
|
||||||
{
|
|
||||||
TrySetChunk(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (startIdx > lastLineIdx)
|
|
||||||
{
|
{
|
||||||
TrySetChunk(null);
|
TrySetChunk(null);
|
||||||
return;
|
return;
|
||||||
|
@ -711,6 +742,9 @@ namespace SourceGit.Views
|
||||||
var lineIdx = -1;
|
var lineIdx = -1;
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > diff.Lines.Count)
|
if (index > diff.Lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -853,12 +887,7 @@ namespace SourceGit.Views
|
||||||
|
|
||||||
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
var firstLineIdx = view.VisualLines[0].FirstDocumentLine.LineNumber - 1;
|
||||||
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
var lastLineIdx = view.VisualLines[^1].FirstDocumentLine.LineNumber - 1;
|
||||||
if (endIdx < firstLineIdx)
|
if (endIdx < firstLineIdx || startIdx > lastLineIdx)
|
||||||
{
|
|
||||||
TrySetChunk(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (startIdx > lastLineIdx)
|
|
||||||
{
|
{
|
||||||
TrySetChunk(null);
|
TrySetChunk(null);
|
||||||
return;
|
return;
|
||||||
|
@ -895,6 +924,9 @@ namespace SourceGit.Views
|
||||||
var lineIdx = -1;
|
var lineIdx = -1;
|
||||||
foreach (var line in view.VisualLines)
|
foreach (var line in view.VisualLines)
|
||||||
{
|
{
|
||||||
|
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
var index = line.FirstDocumentLine.LineNumber;
|
var index = line.FirstDocumentLine.LineNumber;
|
||||||
if (index > lines.Count)
|
if (index > lines.Count)
|
||||||
break;
|
break;
|
||||||
|
@ -1129,7 +1161,7 @@ namespace SourceGit.Views
|
||||||
SetCurrentValue(SelectedChunkProperty, null);
|
SetCurrentValue(SelectedChunkProperty, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStageChunk(object sender, RoutedEventArgs e)
|
private void OnStageChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
@ -1187,7 +1219,7 @@ namespace SourceGit.Views
|
||||||
repo.SetWatcherEnabled(true);
|
repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUnstageChunk(object sender, RoutedEventArgs e)
|
private void OnUnstageChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
@ -1241,7 +1273,7 @@ namespace SourceGit.Views
|
||||||
repo.SetWatcherEnabled(true);
|
repo.SetWatcherEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDiscardChunk(object sender, RoutedEventArgs e)
|
private void OnDiscardChunk(object _1, RoutedEventArgs _2)
|
||||||
{
|
{
|
||||||
var chunk = SelectedChunk;
|
var chunk = SelectedChunk;
|
||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
|
|
|
@ -175,11 +175,13 @@
|
||||||
<!-- Commit Options -->
|
<!-- Commit Options -->
|
||||||
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,*,Auto,Auto,Auto">
|
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,*,Auto,Auto,Auto">
|
||||||
<Button Grid.Column="0"
|
<Button Grid.Column="0"
|
||||||
Classes="icon_button"
|
Classes="no_border"
|
||||||
Width="14" Height="14"
|
Margin="4,0,0,0" Padding="0"
|
||||||
Click="OnOpenCommitMessagePicker"
|
Click="OnOpenCommitMessagePicker">
|
||||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.MessageHistories}">
|
<Grid ColumnDefinitions="Auto,*">
|
||||||
<Path Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.List}"/>
|
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Menu}"/>
|
||||||
|
<TextBlock Grid.Column="1" Margin="8,0,0,0" Text="{DynamicResource Text.WorkingCopy.CommitMessageHelper}"/>
|
||||||
|
</Grid>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<CheckBox Grid.Column="1"
|
<CheckBox Grid.Column="1"
|
||||||
|
@ -187,8 +189,7 @@
|
||||||
Margin="12,0,0,0"
|
Margin="12,0,0,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
IsChecked="{Binding AutoStageBeforeCommit, Mode=TwoWay}"
|
IsChecked="{Binding AutoStageBeforeCommit, Mode=TwoWay}"
|
||||||
Content="{DynamicResource Text.WorkingCopy.AutoStage}"
|
Content="{DynamicResource Text.WorkingCopy.AutoStage}"/>
|
||||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.AutoStage.Tip}"/>
|
|
||||||
|
|
||||||
<CheckBox Grid.Column="2"
|
<CheckBox Grid.Column="2"
|
||||||
Height="24"
|
Height="24"
|
||||||
|
|
Loading…
Reference in a new issue