forked from actlaboratory/falcon
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
214 lines (190 loc) · 8.04 KB
/
Copy pathapp.py
File metadata and controls
214 lines (190 loc) · 8.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# -*- coding: utf-8 -*-
#Falcon app GUI implementation
#Copyright (C) 2019 Yukio Nozawa <personal@nyanchangames.com>
#Note: All comments except these top lines will be written in Japanese.
import accessible_output2.outputs.auto
import sys
import FalconConfigParser
import gettext
import logging
import os
import wx
import locale
import win32api
import datetime
import UserCommandManager
from logging import getLogger, FileHandler, Formatter
from soundPlayer import pybass
from simpleDialog import *
import constants
import DefaultSettings
import errorCodes
import misc
import workerThreads
from views import main
class falconAppMain(wx.App):
def initialize(self):
"""アプリを初期化する。"""
t=misc.Timer()
self.frozen=hasattr(sys,"frozen")
self.InitLogger()
self.error_sound_handle=None
self.LoadSettings()
wx.DisableAsserts()
try:
if self.config["general"]["locale"]!=None:
locale.setlocale(locale.LC_TIME,self.config["general"]["locale"])
else:
locale.setlocale(locale.LC_TIME)
except:
locale.setlocale(locale.LC_TIME)
self.config["general"]["locale"]=""
self.SetTimeZone()
self.InitTranslation()
self.LoadUserCommandSettings()
self.LoadUserExtentionSettings()
self.InitSound()
self.InitCaches()
workerThreads.Start()
# 起動サウンドの再生
self.PlaySound(self.config["sounds"]["startup"])
# 音声読み上げの準備
reader=self.config["speech"]["reader"]
if(reader=="PCTK"):
self.log.info("use reader 'PCTalker'")
self.speech=accessible_output2.outputs.pc_talker.PCTalker()
elif(reader=="NVDA"):
self.log.info("use reader 'NVDA'")
self.speech=accessible_output2.outputs.nvda.NVDA()
# elif(reader=="SAPI4"):
# self.log.info("use reader 'SAPI4'")
# self.speech=accessible_output2.outputs.sapi4.Sapi4()
elif(reader=="SAPI5"):
self.log.info("use reader 'SAPI5'")
self.speech=accessible_output2.outputs.sapi5.SAPI5()
elif(reader=="AUTO"):
self.log.info("use reader 'AUTO'")
self.speech=accessible_output2.outputs.auto.Auto()
elif(reader=="JAWS"):
self.log.info("use reader 'JAWS'")
self.speech=accessible_output2.outputs.jaws.Jaws()
elif(reader=="CLIPBOARD"):
self.log.info("use reader 'CLIPBOARD'")
self.speech=accessible_output2.outputs.clipboard.Clipboard()
elif(reader=="NOSPEECH"):
self.log.info("use reader 'NOSPEECH'")
self.speech=accessible_output2.outputs.nospeech.NoSpeech()
else:
self.config.set("speech","reader","AUTO")
self.log.warning("Setting missed! speech.reader reset to 'AUTO'")
self.speech=accessible_output2.outputs.auto.Auto()
self.log.debug("finished environment setup (%f seconds from start)" % t.elapsed)
# メインビューを表示
self.hMainView=main.View()
self.hMainView.Initialize()
misc.InitContextMenu(self.hMainView.hFrame.GetHandle())
self.log.debug("Finished mainView setup (%f seconds from start)" % t.elapsed)
return True
def InitLogger(self):
"""ロギング機能を初期化して準備する。"""
self.hLogHandler=FileHandler("falcon.log", mode="w", encoding="UTF-8")
self.hLogHandler.setLevel(logging.DEBUG)
self.hLogFormatter=Formatter("%(name)s - %(levelname)s - %(message)s (%(asctime)s)")
self.hLogHandler.setFormatter(self.hLogFormatter)
self.log=getLogger("falcon")
self.log.setLevel(logging.DEBUG)
self.log.addHandler(self.hLogHandler)
r="executable" if self.frozen else "interpreter"
self.log.info("Starting Falcon as %s!" % r)
def LoadSettings(self):
"""設定ファイルを読み込む。なければデフォルト設定を適用し、設定ファイルを書く。"""
self.config = DefaultSettings.DefaultSettings.get()
self.config.read(constants.SETTING_FILE_NAME)
self.config.write()
def LoadUserCommandSettings(self):
"""お気に入りフォルダと「ここで開く」の設定を読み込む"""
self.favoriteDirectory=UserCommandManager.UserCommandManager(self.config.items("favorite_directories"),self.config.items("favorite_directories_shortcut"),"MOVE_FAVORITE_FOLDER_")
if self.favoriteDirectory.errors:
tmp=_("お気に入りフォルダの設定が不正です。以下の設定を確認してください。\n\n")
for v in self.favoriteDirectory.errors:
tmp+=v+"\n"
dialog(_("エラー"),tmp)
self.openHereCommand=UserCommandManager.UserCommandManager(self.config.items("open_here"),self.config.items("open_here_shortcut"),"MOVE_OPEN_HERE_")
if self.openHereCommand.errors:
tmp=_("「ここで開く」の設定が不正です。以下の設定を確認してください。\n\n")
for v in self.openHereCommand.errors:
tmp+=v+"\n"
dialog(_("エラー"),tmp)
self.userCommandManagers={
self.favoriteDirectory : _("お気に入りディレクトリ"),
self.openHereCommand : _("ここで開く")
}
def LoadUserExtentionSettings(self):
#サポートするドキュメント形式の追加設定
self.documentFormats=set()
documentFormats=self.config["extentions"]["document"].split("/")
err_audio=[]
err_format=[]
for ext in documentFormats:
ext=ext.lower()
if ext in constants.SUPPORTED_AUDIO_FORMATS:
err_audio.append(ext)
if "." in ext:
err_format.append(ext)
else:
self.documentFormats.add(ext)
if err_format:
dialog(_("エラー"),_("以下の拡張子は、利用できない文字を含んでいるため登録できません。\n\n")+str(err_format))
if err_audio:
dialog(_("エラー"),_("以下の拡張子は、既に音声データの拡張子として登録されているため、テキスト形式として登録できません。\n\n")+str(err_audio))
def InitTranslation(self):
"""翻訳を初期化する。"""
self.translator=gettext.translation("messages","locale", languages=[self.config.getstring("general","language","ja-JP",constants.SUPPORTING_LANGUAGE)], fallback=True)
self.translator.install()
def InitSound(self):
"""サウンド再生機能を初期化する。"""
ret=pybass.BASS_Init(-1, 44100, 0, 0, 0)
if ret!=1: self.log.error("BASS sound system could not be initialized.")
def InitCaches(self):
"""起動中に使用するキャッシュデータを初期化する。"""
self.filetypes_cach={}#これほんとに使うかどうか検討中
def GetFrozenStatus(self):
"""コンパイル済みのexeで実行されている場合はTrue、インタプリタで実行されている場合はFalseを帰す。"""
return self.frozen
def say(self,s,interrupt=False):
"""スクリーンリーダーでしゃべらせる。"""
self.speech.speak(s, interrupt=interrupt)
self.speech.braille(s)
def PlaySound(self,path,custom_location=False,volume=-1):
"""サウンドファイルを再生する。"""
if not custom_location: path="fx/"+path
if not os.path.isfile(path):
if path!="":
self.log.error("Sound file '"+path+"' not found.")
return -1
handle=pybass.BASS_StreamCreateFile(False,path,0,0,pybass.BASS_STREAM_AUTOFREE|pybass.BASS_UNICODE)
if handle==0:
self.log.error("Cannot load sound file %s. Error code: %d" % (path, pybass.BASS_ErrorGetCode()))
return -1
#end error
if volume==-1:
volume=self.config.getint("speech","fx_volume",100,0,300)
pybass.BASS_ChannelSetAttribute(handle, pybass.BASS_ATTRIB_VOL, volume/100)
pybass.BASS_ChannelPlay(handle,True)
return handle
def StopSound(self,handle):
pybass.BASS_ChannelStop(handle)
def OnExit(self):
workerThreads.Stop()
return wx.App.OnExit(self)
def SetTimeZone(self):
bias=win32api.GetTimeZoneInformation(True)[1][0]*-1
hours=bias//60
minutes=bias%60
self.timezone=datetime.timezone(datetime.timedelta(hours=hours,minutes=minutes))
def PlayErrorSound(self):
"""例外が発生したときに音を鳴らす。"""
if not self.error_sound_handle:
self.error_sound_handle=pybass.BASS_StreamCreateFile(False,"fx\\internal_error.ogg",0,0,pybass.BASS_STREAM_AUTOFREE|pybass.BASS_UNICODE)
#end load
pybass.BASS_ChannelPlay(self.error_sound_handle,True)