diff --git a/src/components/AudioCell.vue b/src/components/AudioCell.vue
index 17fa418f03..c515547309 100644
--- a/src/components/AudioCell.vue
+++ b/src/components/AudioCell.vue
@@ -7,6 +7,13 @@
size="sm"
class="absolute active-arrow"
/>
+
+ {{ textLineNumberIndex }}
+
{
}
};
+// 行番号を表示するかどうか
+const showTextLineNumber = computed(() => store.state.showTextLineNumber);
+// 行番号
+const textLineNumberIndex = computed(
+ () => audioKeys.value.indexOf(props.audioKey) + 1
+);
+// 行番号の幅: 2桁はデフォで入るように, 3桁以上は1remずつ広げる
+const textLineNumberWidth = computed(() => {
+ const indexDigits = String(audioKeys.value.length).length;
+ if (indexDigits <= 2) return "1.5rem";
+ return `${indexDigits - 0.5}rem`;
+});
+
// 上下に移動
const audioKeys = computed(() => store.state.audioKeys);
const moveUpCell = (e?: KeyboardEvent) => {
@@ -275,6 +295,21 @@ const isMultipleEngine = computed(() => store.state.engineIds.length > 1);
height: 2rem;
}
+ .line-number {
+ height: 2rem;
+ width: v-bind(textLineNumberWidth);
+ line-height: 2rem;
+ margin-right: -0.3rem;
+ opacity: 0.6;
+ text-align: right;
+ color: colors.$display;
+ &.active {
+ opacity: 1;
+ font-weight: bold;
+ color: colors.$primary-light;
+ }
+ }
+
.q-input {
:deep(.q-field__control) {
height: 2rem;
diff --git a/src/components/SettingDialog.vue b/src/components/SettingDialog.vue
index 336cdf32d9..e01a5d7556 100644
--- a/src/components/SettingDialog.vue
+++ b/src/components/SettingDialog.vue
@@ -527,6 +527,28 @@
]"
/>
+
+ 行番号の表示
+
+
+
+ テキスト欄の左側に行番号を表示します。
+
+
+
+
+
+
+
@@ -823,6 +845,7 @@ const activePointScrollModeOptions: Record<
const experimentalSetting = computed(() => store.state.experimentalSetting);
+// 外観
const currentThemeNameComputed = computed({
get: () => store.state.themeSetting.currentTheme,
set: (currentTheme: string) => {
@@ -838,6 +861,18 @@ const availableThemeNameComputed = computed(() => {
});
});
+const editorFont = computed(() => store.state.editorFont);
+const changeEditorFont = (editorFont: EditorFontType) => {
+ store.dispatch("SET_EDITOR_FONT", { editorFont });
+};
+
+const showTextLineNumber = computed(() => store.state.showTextLineNumber);
+const changeShowTextLineNumber = (showTextLineNumber: boolean) => {
+ store.dispatch("SET_SHOW_TEXT_LINE_NUMBER", {
+ showTextLineNumber,
+ });
+};
+
const currentAudioOutputDeviceComputed = computed<{
key: string;
label: string;
@@ -1042,11 +1077,6 @@ const changeSplitTextWhenPaste = (
store.dispatch("SET_SPLIT_TEXT_WHEN_PASTE", { splitTextWhenPaste });
};
-const editorFont = computed(() => store.state.editorFont);
-const changeEditorFont = (editorFont: EditorFontType) => {
- store.dispatch("SET_EDITOR_FONT", { editorFont });
-};
-
const showsFilePatternEditDialog = ref(false);
const selectedEngineIdRaw = ref(undefined);
diff --git a/src/store/setting.ts b/src/store/setting.ts
index e9e0df87ce..a463d00074 100644
--- a/src/store/setting.ts
+++ b/src/store/setting.ts
@@ -40,6 +40,7 @@ export const settingStoreState: SettingStoreState = {
availableThemes: [],
},
editorFont: "default",
+ showTextLineNumber: false,
acceptRetrieveTelemetry: "Unconfirmed",
experimentalSetting: {
enablePreset: false,
@@ -82,6 +83,12 @@ export const settingStore = createPartialStore({
});
}
+ dispatch("SET_SHOW_TEXT_LINE_NUMBER", {
+ showTextLineNumber: await window.electron.getSetting(
+ "showTextLineNumber"
+ ),
+ });
+
dispatch("SET_ACCEPT_RETRIEVE_TELEMETRY", {
acceptRetrieveTelemetry: await window.electron.getSetting(
"acceptRetrieveTelemetry"
@@ -252,6 +259,18 @@ export const settingStore = createPartialStore({
},
},
+ SET_SHOW_TEXT_LINE_NUMBER: {
+ mutation(state, { showTextLineNumber }) {
+ state.showTextLineNumber = showTextLineNumber;
+ },
+ action({ commit }, { showTextLineNumber }) {
+ window.electron.setSetting("showTextLineNumber", showTextLineNumber);
+ commit("SET_SHOW_TEXT_LINE_NUMBER", {
+ showTextLineNumber,
+ });
+ },
+ },
+
SET_ACCEPT_RETRIEVE_TELEMETRY: {
mutation(state, { acceptRetrieveTelemetry }) {
state.acceptRetrieveTelemetry = acceptRetrieveTelemetry;
diff --git a/src/store/type.ts b/src/store/type.ts
index 88034e8c27..1833f467ac 100644
--- a/src/store/type.ts
+++ b/src/store/type.ts
@@ -998,6 +998,7 @@ export type SettingStoreState = {
engineManifests: Record;
themeSetting: ThemeSetting;
editorFont: EditorFontType;
+ showTextLineNumber: boolean;
acceptRetrieveTelemetry: AcceptRetrieveTelemetryStatus;
experimentalSetting: ExperimentalSetting;
splitTextWhenPaste: SplitTextWhenPasteType;
@@ -1036,6 +1037,11 @@ export type SettingStoreTypes = {
action(payload: { editorFont: EditorFontType }): void;
};
+ SET_SHOW_TEXT_LINE_NUMBER: {
+ mutation: { showTextLineNumber: boolean };
+ action(payload: { showTextLineNumber: boolean }): void;
+ };
+
SET_ACCEPT_RETRIEVE_TELEMETRY: {
mutation: { acceptRetrieveTelemetry: AcceptRetrieveTelemetryStatus };
action(payload: {
diff --git a/src/type/preload.ts b/src/type/preload.ts
index 71ff3df43f..5337b79ccd 100644
--- a/src/type/preload.ts
+++ b/src/type/preload.ts
@@ -568,6 +568,7 @@ export const electronStoreSchema = z
defaultPresetKeys: z.record(voiceIdSchema, presetKeySchema).default({}),
currentTheme: z.string().default("Default"),
editorFont: z.enum(["default", "os"]).default("default"),
+ showTextLineNumber: z.boolean().default(false),
experimentalSetting: experimentalSettingSchema.passthrough().default({}),
acceptRetrieveTelemetry: z
.enum(["Unconfirmed", "Accepted", "Refused"])
diff --git a/tests/unit/store/Vuex.spec.ts b/tests/unit/store/Vuex.spec.ts
index da9b166298..bbd54c9333 100644
--- a/tests/unit/store/Vuex.spec.ts
+++ b/tests/unit/store/Vuex.spec.ts
@@ -75,6 +75,7 @@ describe("store/vuex.js test", () => {
availableThemes: [],
},
editorFont: "default",
+ showTextLineNumber: false,
isPinned: false,
isFullscreen: false,
presetItems: {},
@@ -241,6 +242,7 @@ describe("store/vuex.js test", () => {
store.state.experimentalSetting.enableInterrogativeUpspeak,
false
);
+ assert.equal(store.state.showTextLineNumber, false);
assert.propertyVal(
store.state.splitterPosition,
"audioDetailPaneHeight",