File: frigcal-products/unzipped/frigcal-main.py
#====================================================================================
# Main Frigcal run logic (run alone or from GUI frigcal-launcher.pyw)
#====================================================================================
# [3.0] split off from frigcal.py to here and add imports to fix circular import;
# if all in frigcal.py, program worked, but frigcal.py code was imported/run twice
# [3.0] on Android, remove '#' and use your quoted unzip path for explorer opens+shortcuts
#import os; os.chdir('/sdcard/Download/Frigcal--source')
import searchcals_dialog # import first, to trigger a _nested_ frigcal.py import
from frigcal import * # use now-complete figcal.py, (imports searchcals_dialog)
from tkinter.messagebox import showinfo
def main(prototype=PROTO): # prototype now fully deprecated
if RunningOnWindows:
"""
---------------------------------------------------------------------------
[3.0] auto deblur tkinter GUIs, wheter run by python.exe or standalone exe;
this must be run before creating any UI components in the calling process;
also done in tools scripts that are built as standalone executables;
an older and limited alternative to the Kivy PPUS app code adopted ahead:
from ctypes import windll
windll.shcore.SetProcessDpiAwareness(2) # 2=per monitor, 1=main monitor
https://github.com/kivy/kivy/pull/7299
https://learning-python.com/post-release-updates.html#win10blurryguis
https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context
---------------------------------------------------------------------------
"""
from ctypes import windll, c_int64
windll.user32.SetProcessDpiAwarenessContext(c_int64(-4)) # per monitor aware v2
try:
icsfiletools.init_default_ics_file() # if none on first run (or bad path)
icsfiletools.parse_ics_files() # makes CalendarsTable, EventsTable
except:
startuperror( # [1.5] GUI popup, not console only
'Error while loading calendar.\n\n'
'Check your "icspath" setting in frigcal_configs.py first. '
"Then check your calendar folder's permissions, and your "
"calendar data's validity.\n\n"
'Python exception text follows:\n\n%s\n%s'
% (sys.exc_info()[0], sys.exc_info()[1]))
else:
# [2.0] make sentinel file in cwd to signal
# launcher to close (if run), ignore errors
try:
open('.frigcal-is-active', 'w').close()
except:
pass
# the normal bit
root = Tk()
main = MonthWindow(root)
if hasattr(sys, 'frozen') and RunningOnWindows:
#--------------------------------------------------------------------
# [3.0] yes, must tell PyInstaller splash screen to close, after
# the main window is built. The ss might be a custom thing here,
# but PyInstaller standalones have no control during unzip time.
#--------------------------------------------------------------------
import pyi_splash
pyi_splash.close()
# [2.0] on macOS, customize app-wide automatic top-of-display menu
# [3.0] added Edit menu to this for easy access to emojis on macOS
fixAppleMenuBar(window=root,
appname=PROGRAM,
helpaction=lambda: webbrowser.open(HELPFILE),
# [3.0] About != Help
aboutaction=lambda:
showinfo(f'About {PROGRAM}',
f'{PROGRAM} version {VERSION}\n'
'See Help for more info'),
quitaction=main.onQuit) # app-wide quit: save/ask
if RunningOnMacOS:
#--------------------------------------------------------------------
# [2.0] required on Mac OS X (only), else the checkbuttons in the
# main window are not displayed in Aqua (blue) active-window style
# until users click another window and click this program's window;
#
# this is a bug in AS's Mac Tk 8.5 -- it's not present in other Tk
# ports, and IDLE search dialogs have the same issue; for reasons
# TBD, it's enough to use just the lift() below for frigcal when
# it is run from a command line, but the full bit here is required
# when run by mac pylaucher on a click; ditto for pymailgui, but
# mergeall requires all 3 steps in both contexts (it's special?...);
# caveat: can still lose active style on iconify and common dialogs;
#
# UPDATE: focus is now restored after common dialog closes by a
# focus_force(), and on deiconifies (unhides) by catching Dock
# clicks and running the heinous hack copied from mergeall below;
#--------------------------------------------------------------------
# fix tk focus loss on startup
root.withdraw()
root.lift()
root.after_idle(root.deiconify)
# fix tk focus loss on deiconify
def onReopen():
#print(root.state()) # always normal
root.lift()
root.update()
temp = Toplevel()
temp.lower()
temp.destroy()
root.createcommand('::tk::mac::ReopenApplication', onReopen)
root.mainloop()
# [2.0] clean up sentinel file on exit,
# else it's deleted on next launcher run
try:
os.remove('.frigcal-is-active')
except:
pass
if __name__ == '__main__':
main()