def __init__(self, master): self.holdofftime = config.getint('querytime') + companion.holdoff self.session = companion.Session() self.edsm = edsm.EDSM() self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') elif platform == 'linux2': from PIL import Image, ImageTk icon = ImageTk.PhotoImage(Image.open("EDMarketConnector.png")) self.w.tk.call('wm', 'iconphoto', self.w, '-default', icon) style = ttk.Style() style.theme_use('clam') elif platform == 'darwin': # Default ttk font choice looks bad on El Capitan font = tkFont.Font(family='TkDefaultFont', size=13, weight=tkFont.NORMAL) style = ttk.Style() style.configure('TLabel', font=font) style.configure('TButton', font=font) style.configure('TLabelframe.Label', font=font) style.configure('TCheckbutton', font=font) style.configure('TRadiobutton', font=font) style.configure('TEntry', font=font) frame = ttk.Frame(self.w, name=appname.lower()) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) frame.rowconfigure(4, weight=1) ttk.Label(frame, text=_('Cmdr') + ':').grid(row=0, column=0, sticky=tk.W) # Main window ttk.Label(frame, text=_('System') + ':').grid(row=1, column=0, sticky=tk.W) # Main window ttk.Label(frame, text=_('Station') + ':').grid(row=2, column=0, sticky=tk.W) # Main window self.cmdr = ttk.Label(frame, width=-21) self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.system_url, popup_copy=True) self.station = HyperlinkLabel( frame, url=self.station_url, popup_copy=lambda x: x != self.STATION_UNDOCKED) self.button = ttk.Button( frame, name='update', text=_('Update'), command=self.getandsend, default=tk.ACTIVE, state=tk.DISABLED) # Update button in main window self.status = ttk.Label(frame, name='status', width=-25) self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) self.cmdr.grid(row=0, column=1, sticky=tk.EW) self.system.grid(row=1, column=1, sticky=tk.EW) self.station.grid(row=2, column=1, sticky=tk.EW) self.button.grid(row=3, column=0, columnspan=2, sticky=tk.NSEW) self.status.grid(row=4, column=0, columnspan=2, sticky=tk.EW) for child in frame.winfo_children(): child.grid_configure(padx=5, pady=(platform == 'darwin' and 3 or 2)) menubar = tk.Menu() if platform == 'darwin': from Foundation import NSBundle # https://www.tcl.tk/man/tcl/TkCmd/menu.htm apple_menu = tk.Menu(menubar, name='apple') apple_menu.add_command( label=_("About {APP}").format(APP=applongname), command=lambda: self.w.call('tk::mac::standardAboutPanel' )) # App menu entry on OSX apple_menu.add_command( label=_("Check for Updates..."), command=lambda: self.updater.checkForUpdates()) menubar.add_cascade(menu=apple_menu) self.edit_menu = tk.Menu(menubar, name='edit') self.edit_menu.add_command( label=_('Copy'), accelerator='Command-c', state=tk.DISABLED, command=self.copy) # As in Copy and Paste menubar.add_cascade(label=_('Edit'), menu=self.edit_menu) # Menu title self.w.bind('<Command-c>', self.copy) self.view_menu = tk.Menu(menubar, name='view') self.view_menu.add_command(label=_('Status'), state=tk.DISABLED, command=lambda: stats.StatsDialog( self.w, self.session)) # Menu item menubar.add_cascade(label=_('View'), menu=self.view_menu) # Menu title on OSX window_menu = tk.Menu(menubar, name='window') menubar.add_cascade(label=_('Window'), menu=window_menu) # Menu title on OSX # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.call('set', 'tk::mac::useCompatibilityMetrics', '0') self.w.createcommand( 'tkAboutDialog', lambda: self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand( "::tk::mac::ShowPreferences", lambda: prefs.PreferencesDialog(self.w, self.login)) self.w.createcommand( "::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app else: file_menu = self.view_menu = tk.Menu(menubar, tearoff=tk.FALSE) file_menu.add_command(label=_('Status'), state=tk.DISABLED, command=lambda: stats.StatsDialog( self.w, self.session)) # Menu item file_menu.add_command( label=_("Check for Updates..."), command=lambda: self.updater.checkForUpdates()) file_menu.add_command( label=_("Settings"), command=lambda: prefs.PreferencesDialog( self.w, self.login)) # Item in the File menu on Windows file_menu.add_separator() file_menu.add_command( label=_("Exit"), command=self.onexit) # Item in the File menu on Windows menubar.add_cascade(label=_("File"), menu=file_menu) # Menu title on Windows self.edit_menu = tk.Menu(menubar, tearoff=tk.FALSE) self.edit_menu.add_command( label=_('Copy'), accelerator='Ctrl+C', state=tk.DISABLED, command=self.copy) # As in Copy and Paste menubar.add_cascade(label=_('Edit'), menu=self.edit_menu) # Menu title self.w.bind('<Control-c>', self.copy) self.w.protocol("WM_DELETE_WINDOW", self.onexit) if platform == 'linux2': # Fix up menu to use same styling as everything else (fg, bg, afg, abg) = (style.lookup('TLabel.label', 'foreground'), style.lookup('TLabel.label', 'background'), style.lookup('TButton.label', 'foreground', ['active']), style.lookup('TButton.label', 'background', ['active'])) menubar.configure(fg=fg, bg=bg, activeforeground=afg, activebackground=abg) file_menu.configure(fg=fg, bg=bg, activeforeground=afg, activebackground=abg) self.edit_menu.configure(fg=fg, bg=bg, activeforeground=afg, activebackground=abg) self.w['menu'] = menubar # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match and ( platform != 'darwin' or int(match.group(2)) > 0 ): # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) self.w.update_idletasks() self.w.wait_visibility() (w, h) = (self.w.winfo_width(), self.w.winfo_height()) self.w.minsize(w, h) # Minimum size = initial size if platform != 'linux2': # update_idletasks() doesn't allow for the menubar on Linux self.w.maxsize(-1, h) # Maximum height = initial height # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) self.w.bind_all('<<Quit>>', self.onexit) # user-generated # Install hotkey monitoring self.w.bind_all('<<Invoke>>', self.getandsend) # user-generated hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods')) # Install log monitoring self.w.bind_all('<<Jump>>', self.system_change) # user-generated if (config.getint('output') & config.OUT_LOG_AUTO) and ( config.getint('output') & (config.OUT_LOG_AUTO | config.OUT_LOG_EDSM)): monitor.enable_logging() monitor.start(self.w) # First run if not config.get('username') or not config.get('password'): prefs.PreferencesDialog(self.w, self.login) else: self.login()
def __init__(self, master): self.ser = serial.Serial('/dev/cu.wchusbserial1490') sleep(3) self.holdofftime = config.getint('querytime') + companion.holdoff self.session = companion.Session() self.edsm = edsm.EDSM() self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) plug.load_plugins() if platform != 'darwin': if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') else: from PIL import Image, ImageTk self.w.tk.call( 'wm', 'iconphoto', self.w, '-default', ImageTk.PhotoImage(Image.open("EDMarketConnector.png"))) self.theme_icon = tk.PhotoImage( data= 'R0lGODlhFAAQAMZVAAAAAAEAAAIBAAMBAAQCAAYDAAcDAAkEAAoEAAwGAQ8IARAIAREJARYKABkLARsMASMQASgSAiUUAy0UAjAVAioXBDIWAy4YBC4ZBS8ZBTkZA0EdBDsgBkUfA0MkB00iA1AjA1IlBFQmBE4qCFgoBVkoBFArCF0qBVQtCGUrBGMtBWYtBWA0Cm8xBW8xBm8yBXMzBXU1Bms5C3s1BXs2BXw2BX02BXw4B4A5B3Q/DIJGDYNGDYJHDoNHDYdJDppGCItLD4xLDo5MDo5MD5hSD59VEKdaEbJgErtlE7tlFLxlE8BpFMJpFMNpFMZrFdFxFtl1F995GOB6GOF6GP+LG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAUABAAAAejgACCgiODhoeGBABPPgACj48DA4gAk00cSRUYGZycEogBAE4LCUM8Oj2pOzlQBAKHSBeKlABKBq+DHkS0g0wJiCZFvABHJBuHBSxADFRTUs/PUUsiKhaIKEZBKTM13TU0Nj8IIRqThjJCK8MnFIgKMMMAJRGGAQUvvAIPLocBAjgdPggcKMLAgRi0GjxYyNBBCwjwQoEKQLEiABA3HMU7NOFQIAA7' ) self.theme_minimize = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f,\n 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\n' ) self.theme_close = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x1c, 0x38, 0x38, 0x1c, 0x70, 0x0e,\n 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c,\n 0x1c, 0x38, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00 };\n' ) frame = tk.Frame(self.w, name=appname.lower()) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) self.cmdr_label = tk.Label(frame) self.ship_label = tk.Label(frame) self.system_label = tk.Label(frame) self.station_label = tk.Label(frame) self.cmdr_label.grid(row=1, column=0, sticky=tk.W) self.ship_label.grid(row=2, column=0, sticky=tk.W) self.system_label.grid(row=3, column=0, sticky=tk.W) self.station_label.grid(row=4, column=0, sticky=tk.W) self.cmdr = tk.Label(frame, anchor=tk.W) self.ship = HyperlinkLabel(frame, url=self.shipyard_url) self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.system_url, popup_copy=True) self.station = HyperlinkLabel( frame, url=self.station_url, popup_copy=lambda x: x != self.STATION_UNDOCKED) self.cmdr.grid(row=1, column=1, sticky=tk.EW) self.ship.grid(row=2, column=1, sticky=tk.EW) self.system.grid(row=3, column=1, sticky=tk.EW) self.station.grid(row=4, column=1, sticky=tk.EW) for plugname in plug.PLUGINS: appitem = plug.get_plugin_app(plugname, frame) if appitem: if isinstance(appitem, tuple) and len(appitem) == 2: row = frame.grid_size()[1] appitem[0].grid(row=row, column=0, sticky=tk.W) appitem[1].grid(row=row, column=1, sticky=tk.EW) else: appitem.grid(columnspan=2, sticky=tk.W) self.button = ttk.Button( frame, text=_('Update'), width=28, default=tk.ACTIVE, state=tk.DISABLED) # Update button in main window self.theme_button = tk.Label(frame, width=platform == 'darwin' and 32 or 28, state=tk.DISABLED) self.status = tk.Label(frame, name='status', anchor=tk.W) row = frame.grid_size()[1] self.button.grid(row=row, columnspan=2, sticky=tk.NSEW) self.theme_button.grid(row=row, columnspan=2, sticky=tk.NSEW) theme.register_alternate((self.button, self.theme_button), { 'row': row, 'columnspan': 2, 'sticky': tk.NSEW }) self.status.grid(columnspan=2, sticky=tk.EW) self.button.bind('<Button-1>', self.getandsend) theme.button_bind(self.theme_button, self.getandsend) for child in frame.winfo_children(): child.grid_configure(padx=5, pady=(platform != 'win32' and 2 or 0)) self.menubar = tk.Menu() if platform == 'darwin': # Can't handle (de)iconify if topmost is set, so suppress iconify button # http://wiki.tcl.tk/13428 and p15 of https://developer.apple.com/legacy/library/documentation/Carbon/Conceptual/HandlingWindowsControls/windowscontrols.pdf root.call('tk::unsupported::MacWindowStyle', 'style', root, 'document', 'closeBox horizontalZoom resizable') # https://www.tcl.tk/man/tcl/TkCmd/menu.htm self.system_menu = tk.Menu(self.menubar, name='apple') self.system_menu.add_command( command=lambda: self.w.call('tk::mac::standardAboutPanel')) self.system_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.system_menu) self.file_menu = tk.Menu(self.menubar, name='file') self.file_menu.add_command(command=self.save_raw) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, name='edit') self.edit_menu.add_command(accelerator='Command-c', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.w.bind('<Command-c>', self.copy) self.view_menu = tk.Menu(self.menubar, name='view') self.view_menu.add_command(command=lambda: stats.StatsDialog(self)) self.menubar.add_cascade(menu=self.view_menu) window_menu = tk.Menu(self.menubar, name='window') self.menubar.add_cascade(menu=window_menu) self.w['menu'] = self.menubar # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.call('set', 'tk::mac::useCompatibilityMetrics', '0') self.w.createcommand( 'tkAboutDialog', lambda: self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand( "::tk::mac::ShowPreferences", lambda: prefs.PreferencesDialog(self.w, self.postprefs)) self.w.createcommand( "::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app else: self.file_menu = self.view_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.file_menu.add_command(command=lambda: stats.StatsDialog(self)) self.file_menu.add_command(command=self.save_raw) self.file_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.file_menu.add_command(command=lambda: prefs.PreferencesDialog( self.w, self.postprefs)) self.file_menu.add_separator() self.file_menu.add_command(command=self.onexit) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.edit_menu.add_command(accelerator='Ctrl+C', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) if platform == 'win32': # Must be added after at least one "real" menu entry self.always_ontop = tk.BooleanVar( value=config.getint('always_ontop')) self.system_menu = tk.Menu(self.menubar, name='system', tearoff=tk.FALSE) self.system_menu.add_separator() self.system_menu.add_checkbutton( label=_('Always on top'), variable=self.always_ontop, command=self.ontop_changed) # Appearance setting self.menubar.add_cascade(menu=self.system_menu) self.w.bind('<Control-c>', self.copy) self.w.protocol("WM_DELETE_WINDOW", self.onexit) theme.register( self.menubar ) # menus and children aren't automatically registered theme.register(self.file_menu) theme.register(self.edit_menu) # Alternate title bar and menu for dark theme self.theme_menubar = tk.Frame(frame) self.theme_menubar.columnconfigure(2, weight=1) theme_titlebar = tk.Label(self.theme_menubar, text=applongname, image=self.theme_icon, anchor=tk.W, compound=tk.LEFT) theme_titlebar.grid(columnspan=3, padx=2, sticky=tk.NSEW) self.drag_offset = None theme_titlebar.bind('<Button-1>', self.drag_start) theme_titlebar.bind('<B1-Motion>', self.drag_continue) theme_titlebar.bind('<ButtonRelease-1>', self.drag_end) if platform == 'win32': # Can't work out how to deiconify on Linux theme_minimize = tk.Label(self.theme_menubar, image=self.theme_minimize) theme_minimize.grid(row=0, column=3, padx=2) theme.button_bind(theme_minimize, self.oniconify, image=self.theme_minimize) theme_close = tk.Label(self.theme_menubar, image=self.theme_close) theme_close.grid(row=0, column=4, padx=2) theme.button_bind(theme_close, self.onexit, image=self.theme_close) self.theme_file_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_file_menu.grid(row=1, column=0, padx=5, sticky=tk.W) theme.button_bind( self.theme_file_menu, lambda e: self.file_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_edit_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_edit_menu.grid(row=1, column=1, sticky=tk.W) theme.button_bind( self.theme_edit_menu, lambda e: self.edit_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) theme.register_highlight(theme_titlebar) theme.register( self.theme_minimize) # images aren't automatically registered theme.register(self.theme_close) theme.register_alternate((self.menubar, self.theme_menubar), { 'row': 0, 'columnspan': 2, 'sticky': tk.NSEW }) self.set_labels() # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match: if platform == 'darwin': if int( match.group(2) ) >= 0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) elif platform == 'win32': # Check that the titlebar will be at least partly on screen import ctypes from ctypes.wintypes import POINT # https://msdn.microsoft.com/en-us/library/dd145064 MONITOR_DEFAULTTONULL = 0 if ctypes.windll.user32.MonitorFromPoint( POINT( int(match.group(1)) + 16, int(match.group(2)) + 16), MONITOR_DEFAULTTONULL): self.w.geometry(config.get('geometry')) else: self.w.geometry(config.get('geometry')) self.w.attributes('-topmost', config.getint('always_ontop') and 1 or 0) self.w.resizable(tk.TRUE, tk.FALSE) theme.register(frame) theme.register_highlight(self.ship) theme.register_highlight(self.system) theme.register_highlight(self.station) theme.apply(self.w) self.w.bind("<Map>", self.onmap) # Special handling for overrideredict self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) self.w.bind_all('<<Invoke>>', self.getandsend) # Hotkey monitoring self.w.bind_all('<<JournalEvent>>', self.journal_event) # Journal monitoring self.w.bind_all('<<Quit>>', self.onexit) # Updater # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) # First run if not config.get('username') or not config.get('password'): prefs.PreferencesDialog(self.w, self.postprefs) else: self.login() self.ser.write(b'!0Initialising...\n') self.ser.flush()
def __init__(self, master): self.holdofftime = config.getint('querytime') + companion.holdoff self.session = companion.Session() self.edsm = edsm.EDSM() self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) # Special handling for overrideredict self.w.bind("<Map>", self.onmap) plug.load_plugins() if platform != 'darwin': if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') else: from PIL import Image, ImageTk self.w.tk.call( 'wm', 'iconphoto', self.w, '-default', ImageTk.PhotoImage(Image.open("EDMarketConnector.png"))) self.theme_icon = tk.PhotoImage( data= 'R0lGODlhEAAQAMYAAAAAAAEAAAEBAQICAgQEAwYFBAsHBAoIBgwIBAwIBQ0IBA8JBBAJBBAKBRMMBRkPBhoQBykWCSoWCCoXCTsfCzwfCkAhDEIjDD8kC0AlDEEmC0EmDEcoDk4oDU8pDU4qEFMrD1ktDlotD1ouD1g0EWAyEWU0EV03EmA4EWo2EW03EWQ6Emw4EWo9FGo+E3Y8FH5AFH1IFoBJFo1RGo1SGY1SGpBTGZFTGZJTGZhYG6piHa1kHa5kHbBkHr9uIMt0IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEKAEAALAAAAAAQABAAAAd7gACCg4SFhoeHGCiIhRs5JwMCkpKGGTIFODaaNjc/D4QaMQMAk5MuEIQOO6OFAiscCIQNPQk8NTO4NDofLwayPi0mIMPDLAcqvoIBDiQWkaUCAykKhAsXAoYCHRKEDDAjIyIiIyEEHhHYhAPr7BQlE+mMABXo8oTx9oWBADs=' ) self.theme_minimize = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f,\n 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\n' ) self.theme_close = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x1c, 0x38, 0x38, 0x1c, 0x70, 0x0e,\n 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c,\n 0x1c, 0x38, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00 };\n' ) frame = tk.Frame(self.w, name=appname.lower()) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) self.cmdr_label = tk.Label(frame) self.system_label = tk.Label(frame) self.station_label = tk.Label(frame) self.cmdr_label.grid(row=1, column=0, sticky=tk.W) self.system_label.grid(row=2, column=0, sticky=tk.W) self.station_label.grid(row=3, column=0, sticky=tk.W) self.cmdr = tk.Label(frame, anchor=tk.W) self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.system_url, popup_copy=True) self.station = HyperlinkLabel( frame, url=self.station_url, popup_copy=lambda x: x != self.STATION_UNDOCKED) self.cmdr.grid(row=1, column=1, sticky=tk.EW) self.system.grid(row=2, column=1, sticky=tk.EW) self.station.grid(row=3, column=1, sticky=tk.EW) for plugname in plug.PLUGINS: appitem = plug.get_plugin_app(plugname, frame) if appitem: appitem.grid(columnspan=2, sticky=tk.W) self.button = ttk.Button( frame, text=_('Update'), width=28, command=self.getandsend, default=tk.ACTIVE, state=tk.DISABLED) # Update button in main window self.theme_button = tk.Label(frame, width=platform == 'darwin' and 32 or 28, state=tk.DISABLED) self.status = tk.Label(frame, name='status', anchor=tk.W) row = frame.grid_size()[1] self.button.grid(row=row, columnspan=2, sticky=tk.NSEW) self.theme_button.grid(row=row, columnspan=2, sticky=tk.NSEW) theme.register_alternate((self.button, self.theme_button), { 'row': row, 'columnspan': 2, 'sticky': tk.NSEW }) self.status.grid(columnspan=2, sticky=tk.EW) theme.button_bind(self.theme_button, self.getandsend) self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) for child in frame.winfo_children(): child.grid_configure(padx=5, pady=(platform == 'win32' and 1 or 3)) self.menubar = tk.Menu() if platform == 'darwin': # Can't handle (de)iconify if topmost is set, so suppress iconify button # http://wiki.tcl.tk/13428 and p15 of https://developer.apple.com/legacy/library/documentation/Carbon/Conceptual/HandlingWindowsControls/windowscontrols.pdf root.call('tk::unsupported::MacWindowStyle', 'style', root, 'document', 'closeBox horizontalZoom resizable') # https://www.tcl.tk/man/tcl/TkCmd/menu.htm self.file_menu = tk.Menu(self.menubar, name='apple') self.file_menu.add_command( command=lambda: self.w.call('tk::mac::standardAboutPanel')) self.file_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, name='edit') self.edit_menu.add_command(accelerator='Command-c', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.w.bind('<Command-c>', self.copy) self.view_menu = tk.Menu(self.menubar, name='view') self.view_menu.add_command( state=tk.DISABLED, command=lambda: stats.StatsDialog(self.w, self.session)) self.menubar.add_cascade(menu=self.view_menu) window_menu = tk.Menu(self.menubar, name='window') self.menubar.add_cascade(menu=window_menu) self.w['menu'] = self.menubar # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.call('set', 'tk::mac::useCompatibilityMetrics', '0') self.w.createcommand( 'tkAboutDialog', lambda: self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand( "::tk::mac::ShowPreferences", lambda: prefs.PreferencesDialog(self.w, self.postprefs)) self.w.createcommand( "::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app else: self.file_menu = self.view_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.file_menu.add_command( state=tk.DISABLED, command=lambda: stats.StatsDialog(self.w, self.session)) self.file_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.file_menu.add_command(command=lambda: prefs.PreferencesDialog( self.w, self.postprefs)) self.file_menu.add_separator() self.file_menu.add_command(command=self.onexit) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.edit_menu.add_command(accelerator='Ctrl+C', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) if platform == 'win32': # Must be added after at least one "real" menu entry self.always_ontop = tk.BooleanVar( value=config.getint('always_ontop')) system_menu = tk.Menu(self.menubar, name='system', tearoff=tk.FALSE) system_menu.add_separator() system_menu.add_checkbutton( label=_('Always on top'), variable=self.always_ontop, command=self.ontop_changed) # Appearance setting self.menubar.add_cascade(menu=system_menu) # Gets index 0 self.w.bind('<Control-c>', self.copy) self.w.protocol("WM_DELETE_WINDOW", self.onexit) theme.register( self.menubar ) # menus and children aren't automatically registered theme.register(self.file_menu) theme.register(self.edit_menu) # Alternate title bar and menu for dark theme self.theme_menubar = tk.Frame(frame) self.theme_menubar.columnconfigure(2, weight=1) theme_titlebar = tk.Label(self.theme_menubar, text=applongname, image=self.theme_icon, anchor=tk.W, compound=tk.LEFT) theme_titlebar.grid(columnspan=3, sticky=tk.NSEW) self.drag_offset = None theme_titlebar.bind('<Button-1>', self.drag_start) theme_titlebar.bind('<B1-Motion>', self.drag_continue) theme_titlebar.bind('<ButtonRelease-1>', self.drag_end) if platform == 'win32': # Can't work out how to deiconify on Linux theme_minimize = tk.Label(self.theme_menubar, image=self.theme_minimize) theme_minimize.grid(row=0, column=3) theme.button_bind(theme_minimize, self.oniconify, image=self.theme_minimize) theme_close = tk.Label(self.theme_menubar, image=self.theme_close) theme_close.grid(row=0, column=4) theme.button_bind(theme_close, self.onexit, image=self.theme_close) self.theme_file_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_file_menu.grid(row=1, column=0, padx=5, sticky=tk.W) theme.button_bind( self.theme_file_menu, lambda e: self.file_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_edit_menu = tk.Label(self.theme_menubar, anchor=tk.W) # Menu title self.theme_edit_menu.grid(row=1, column=1, sticky=tk.W) theme.button_bind( self.theme_edit_menu, lambda e: self.edit_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) theme.register_highlight(theme_titlebar) theme.register( self.theme_minimize) # images aren't automatically registered theme.register(self.theme_close) theme.register_alternate((self.menubar, self.theme_menubar), { 'row': 0, 'columnspan': 2, 'sticky': tk.NSEW }) self.set_labels() # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match: if platform == 'darwin': if int( match.group(2) ) >= 0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) elif platform == 'win32': # Check that the titlebar will be at least partly on screen import ctypes from ctypes.wintypes import POINT # https://msdn.microsoft.com/en-us/library/dd145064 MONITOR_DEFAULTTONULL = 0 if ctypes.windll.user32.MonitorFromPoint( POINT( int(match.group(1)) + 16, int(match.group(2)) + 16), MONITOR_DEFAULTTONULL): self.w.geometry(config.get('geometry')) else: self.w.geometry(config.get('geometry')) self.w.attributes('-topmost', config.getint('always_ontop') and 1 or 0) self.w.resizable(tk.TRUE, tk.FALSE) theme.register(frame) theme.register_highlight(self.system) theme.register_highlight(self.station) theme.apply(self.w) # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) self.w.bind_all('<<Quit>>', self.onexit) # user-generated # Install hotkey monitoring self.w.bind_all('<<Invoke>>', self.getandsend) # user-generated hotkeymgr.register(self.w, config.getint('hotkey_code'), config.getint('hotkey_mods')) # Install log monitoring monitor.set_callback(self.system_change) edproxy.set_callback(self.system_change) if (config.getint('output') & config.OUT_LOG_AUTO) and ( config.getint('output') & (config.OUT_LOG_FILE | config.OUT_LOG_EDSM)): monitor.enable_logging() monitor.start(self.w) edproxy.start(self.w) # First run if not config.get('username') or not config.get('password'): prefs.PreferencesDialog(self.w, self.postprefs) else: self.login()
def __init__(self, master): # Start a protocol handler to handle cAPI registration. Requires main window to exist. protocolhandler.start(master) self.holdofftime = config.getint('querytime') + companion.holdoff self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) self.prefsdialog = None plug.load_plugins(master) if platform != 'darwin': if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') else: self.w.tk.call( 'wm', 'iconphoto', self.w, '-default', tk.PhotoImage( file=join(config.respath, 'EDMarketConnector.png'))) self.theme_icon = tk.PhotoImage( data= 'R0lGODlhFAAQAMZQAAoKCQoKCgsKCQwKCQsLCgwLCg4LCQ4LCg0MCg8MCRAMCRANChINCREOChIOChQPChgQChgRCxwTCyYVCSoXCS0YCTkdCTseCT0fCTsjDU0jB0EnDU8lB1ElB1MnCFIoCFMoCEkrDlkqCFwrCGEuCWIuCGQvCFs0D1w1D2wyCG0yCF82D182EHE0CHM0CHQ1CGQ5EHU2CHc3CHs4CH45CIA6CIE7CJdECIdLEolMEohQE5BQE41SFJBTE5lUE5pVE5RXFKNaFKVbFLVjFbZkFrxnFr9oFsNqFsVrF8RsFshtF89xF9NzGNh1GNl2GP+KG////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAEKAH8ALAAAAAAUABAAAAeegAGCgiGDhoeIRDiIjIZGKzmNiAQBQxkRTU6am0tPCJSGShuSAUcLoIIbRYMFra4FAUgQAQCGJz6CDQ67vAFJJBi0hjBBD0w9PMnJOkAiJhaIKEI7HRoc19ceNAolwbWDLD8uAQnl5ga1I9CHEjEBAvDxAoMtFIYCBy+kFDKHAgM3ZtgYSLAGgwkp3pEyBOJCC2ELB31QATGioAoVAwEAOw==' ) self.theme_minimize = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f,\n 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };\n' ) self.theme_close = tk.BitmapImage( data= '#define im_width 16\n#define im_height 16\nstatic unsigned char im_bits[] = {\n 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x1c, 0x38, 0x38, 0x1c, 0x70, 0x0e,\n 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0x70, 0x0e, 0x38, 0x1c,\n 0x1c, 0x38, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00 };\n' ) frame = tk.Frame(self.w, name=appname.lower()) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) self.cmdr_label = tk.Label(frame) self.ship_label = tk.Label(frame) self.system_label = tk.Label(frame) self.station_label = tk.Label(frame) self.cmdr_label.grid(row=1, column=0, sticky=tk.W) self.ship_label.grid(row=2, column=0, sticky=tk.W) self.system_label.grid(row=3, column=0, sticky=tk.W) self.station_label.grid(row=4, column=0, sticky=tk.W) self.cmdr = tk.Label(frame, compound=tk.RIGHT, anchor=tk.W, name='cmdr') self.ship = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.shipyard_url, name='ship') self.system = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.system_url, popup_copy=True, name='system') self.station = HyperlinkLabel(frame, compound=tk.RIGHT, url=self.station_url, name='station') self.cmdr.grid(row=1, column=1, sticky=tk.EW) self.ship.grid(row=2, column=1, sticky=tk.EW) self.system.grid(row=3, column=1, sticky=tk.EW) self.station.grid(row=4, column=1, sticky=tk.EW) for plugin in plug.PLUGINS: appitem = plugin.get_app(frame) if appitem: tk.Frame(frame, highlightthickness=1).grid(columnspan=2, sticky=tk.EW) # separator if isinstance(appitem, tuple) and len(appitem) == 2: row = frame.grid_size()[1] appitem[0].grid(row=row, column=0, sticky=tk.W) appitem[1].grid(row=row, column=1, sticky=tk.EW) else: appitem.grid(columnspan=2, sticky=tk.EW) self.button = ttk.Button( frame, text=_('Update'), width=28, default=tk.ACTIVE, state=tk.DISABLED) # Update button in main window self.theme_button = tk.Label(frame, width=platform == 'darwin' and 32 or 28, state=tk.DISABLED) self.status = tk.Label(frame, name='status', anchor=tk.W) row = frame.grid_size()[1] self.button.grid(row=row, columnspan=2, sticky=tk.NSEW) self.theme_button.grid(row=row, columnspan=2, sticky=tk.NSEW) theme.register_alternate( (self.button, self.theme_button, self.theme_button), { 'row': row, 'columnspan': 2, 'sticky': tk.NSEW }) self.status.grid(columnspan=2, sticky=tk.EW) self.button.bind('<Button-1>', self.getandsend) theme.button_bind(self.theme_button, self.getandsend) for child in frame.winfo_children(): child.grid_configure( padx=5, pady=(platform != 'win32' or isinstance(child, tk.Frame)) and 2 or 0) self.menubar = tk.Menu() if platform == 'darwin': # Can't handle (de)iconify if topmost is set, so suppress iconify button # http://wiki.tcl.tk/13428 and p15 of https://developer.apple.com/legacy/library/documentation/Carbon/Conceptual/HandlingWindowsControls/windowscontrols.pdf root.call('tk::unsupported::MacWindowStyle', 'style', root, 'document', 'closeBox resizable') # https://www.tcl.tk/man/tcl/TkCmd/menu.htm self.system_menu = tk.Menu(self.menubar, name='apple') self.system_menu.add_command( command=lambda: self.w.call('tk::mac::standardAboutPanel')) self.system_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.system_menu) self.file_menu = tk.Menu(self.menubar, name='file') self.file_menu.add_command(command=self.save_raw) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, name='edit') self.edit_menu.add_command(accelerator='Command-c', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.w.bind('<Command-c>', self.copy) self.view_menu = tk.Menu(self.menubar, name='view') self.view_menu.add_command(command=lambda: stats.StatsDialog(self)) self.menubar.add_cascade(menu=self.view_menu) window_menu = tk.Menu(self.menubar, name='window') self.menubar.add_cascade(menu=window_menu) self.help_menu = tk.Menu(self.menubar, name='help') self.w.createcommand("::tk::mac::ShowHelp", self.help_general) self.help_menu.add_command(command=self.help_privacy) self.help_menu.add_command(command=self.help_releases) self.menubar.add_cascade(menu=self.help_menu) self.w['menu'] = self.menubar # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.call('set', 'tk::mac::useCompatibilityMetrics', '0') self.w.createcommand( 'tkAboutDialog', lambda: self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand( "::tk::mac::ShowPreferences", lambda: prefs.PreferencesDialog(self.w, self.postprefs)) self.w.createcommand( "::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app self.w.resizable(tk.FALSE, tk.FALSE) # Can't be only resizable on one axis else: self.file_menu = self.view_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.file_menu.add_command(command=lambda: stats.StatsDialog(self)) self.file_menu.add_command(command=self.save_raw) self.file_menu.add_command(command=lambda: prefs.PreferencesDialog( self.w, self.postprefs)) self.file_menu.add_separator() self.file_menu.add_command(command=self.onexit) self.menubar.add_cascade(menu=self.file_menu) self.edit_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.edit_menu.add_command(accelerator='Ctrl+C', state=tk.DISABLED, command=self.copy) self.menubar.add_cascade(menu=self.edit_menu) self.help_menu = tk.Menu(self.menubar, tearoff=tk.FALSE) self.help_menu.add_command(command=self.help_general) self.help_menu.add_command(command=self.help_privacy) self.help_menu.add_command(command=self.help_releases) self.help_menu.add_command( command=lambda: self.updater.checkForUpdates()) self.menubar.add_cascade(menu=self.help_menu) if platform == 'win32': # Must be added after at least one "real" menu entry self.always_ontop = tk.BooleanVar( value=config.getint('always_ontop')) self.system_menu = tk.Menu(self.menubar, name='system', tearoff=tk.FALSE) self.system_menu.add_separator() self.system_menu.add_checkbutton( label=_('Always on top'), variable=self.always_ontop, command=self.ontop_changed) # Appearance setting self.menubar.add_cascade(menu=self.system_menu) self.w.bind('<Control-c>', self.copy) self.w.protocol("WM_DELETE_WINDOW", self.onexit) theme.register( self.menubar ) # menus and children aren't automatically registered theme.register(self.file_menu) theme.register(self.edit_menu) theme.register(self.help_menu) # Alternate title bar and menu for dark theme self.theme_menubar = tk.Frame(frame) self.theme_menubar.columnconfigure(2, weight=1) theme_titlebar = tk.Label(self.theme_menubar, text=applongname, image=self.theme_icon, cursor='fleur', anchor=tk.W, compound=tk.LEFT) theme_titlebar.grid(columnspan=3, padx=2, sticky=tk.NSEW) self.drag_offset = None theme_titlebar.bind('<Button-1>', self.drag_start) theme_titlebar.bind('<B1-Motion>', self.drag_continue) theme_titlebar.bind('<ButtonRelease-1>', self.drag_end) theme_minimize = tk.Label(self.theme_menubar, image=self.theme_minimize) theme_minimize.grid(row=0, column=3, padx=2) theme.button_bind(theme_minimize, self.oniconify, image=self.theme_minimize) theme_close = tk.Label(self.theme_menubar, image=self.theme_close) theme_close.grid(row=0, column=4, padx=2) theme.button_bind(theme_close, self.onexit, image=self.theme_close) self.theme_file_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_file_menu.grid(row=1, column=0, padx=5, sticky=tk.W) theme.button_bind( self.theme_file_menu, lambda e: self.file_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_edit_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_edit_menu.grid(row=1, column=1, sticky=tk.W) theme.button_bind( self.theme_edit_menu, lambda e: self.edit_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) self.theme_help_menu = tk.Label(self.theme_menubar, anchor=tk.W) self.theme_help_menu.grid(row=1, column=2, sticky=tk.W) theme.button_bind( self.theme_help_menu, lambda e: self.help_menu.tk_popup( e.widget.winfo_rootx(), e.widget.winfo_rooty() + e.widget.winfo_height())) tk.Frame(self.theme_menubar, highlightthickness=1).grid(columnspan=5, padx=5, sticky=tk.EW) theme.register( self.theme_minimize) # images aren't automatically registered theme.register(self.theme_close) self.blank_menubar = tk.Frame(frame) tk.Label(self.blank_menubar).grid() tk.Label(self.blank_menubar).grid() tk.Frame(self.blank_menubar, height=2).grid() theme.register_alternate( (self.menubar, self.theme_menubar, self.blank_menubar), { 'row': 0, 'columnspan': 2, 'sticky': tk.NSEW }) self.w.resizable(tk.TRUE, tk.FALSE) # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match: if platform == 'darwin': if int( match.group(2) ) >= 0: # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) elif platform == 'win32': # Check that the titlebar will be at least partly on screen import ctypes from ctypes.wintypes import POINT # https://msdn.microsoft.com/en-us/library/dd145064 MONITOR_DEFAULTTONULL = 0 if ctypes.windll.user32.MonitorFromPoint( POINT( int(match.group(1)) + 16, int(match.group(2)) + 16), MONITOR_DEFAULTTONULL): self.w.geometry(config.get('geometry')) else: self.w.geometry(config.get('geometry')) self.w.attributes('-topmost', config.getint('always_ontop') and 1 or 0) theme.register(frame) theme.apply(self.w) self.w.bind('<Map>', self.onmap) # Special handling for overrideredict self.w.bind('<Enter>', self.onenter) # Special handling for transparency self.w.bind('<FocusIn>', self.onenter) # " self.w.bind('<Leave>', self.onleave) # " self.w.bind('<FocusOut>', self.onleave) # " self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) self.w.bind_all('<<Invoke>>', self.getandsend) # Hotkey monitoring self.w.bind_all('<<JournalEvent>>', self.journal_event) # Journal monitoring self.w.bind_all('<<DashboardEvent>>', self.dashboard_event) # Dashboard monitoring self.w.bind_all('<<PluginError>>', self.plugin_error) # Statusbar self.w.bind_all('<<CompanionAuthEvent>>', self.auth) # cAPI auth self.w.bind_all('<<Quit>>', self.onexit) # Updater # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) if not getattr(sys, 'frozen', False): self.updater.checkForUpdates( ) # Sparkle / WinSparkle does this automatically for packaged apps try: config.get_password( '') # Prod SecureStorage on Linux to initialise except RuntimeError: pass # Migration from <= 3.30 for username in config.get('fdev_usernames') or []: config.delete_password(username) config.delete('fdev_usernames') config.delete('username') config.delete('password') config.delete('logdir') self.postprefs( False) # Companion login happens in callback from monitor plugins_not_py3_last = config.getint('plugins_not_py3_last') or int( time()) if (plugins_not_py3_last + 86400) < int(time()) and len( plug.PLUGINS_not_py3): import tkMessageBox tkMessageBox.showinfo( 'Plugins Without Python 3.x Support', "One or more of your enabled plugins do not yet have support for Python 3.x. Please see the list on the 'Plugins' tab of 'File' > 'Settings'. You should check if there is an updated version available, else alert the developer that they will need to update the code when EDMC moves to Python 3.x" ) config.set('plugins_not_py3_last', int(time()))
def __init__(self, master): self.holdofftime = config.getint('querytime') + companion.holdoff self.session = companion.Session() self.w = master self.w.title(applongname) self.w.rowconfigure(0, weight=1) self.w.columnconfigure(0, weight=1) if platform == 'win32': self.w.wm_iconbitmap(default='EDMarketConnector.ico') elif platform == 'linux2': from PIL import Image, ImageTk icon = ImageTk.PhotoImage(Image.open("EDMarketConnector.png")) self.w.tk.call('wm', 'iconphoto', self.w, '-default', icon) style = ttk.Style() style.theme_use('clam') frame = ttk.Frame(self.w) frame.grid(sticky=tk.NSEW) frame.columnconfigure(1, weight=1) frame.rowconfigure(4, weight=1) ttk.Label(frame, text="Cmdr:").grid(row=0, column=0, sticky=tk.W) ttk.Label(frame, text="System:").grid(row=1, column=0, sticky=tk.W) ttk.Label(frame, text="Station:").grid(row=2, column=0, sticky=tk.W) self.cmdr = ttk.Label(frame, width=-20) self.system = ttk.Label(frame, width=-20) self.station = ttk.Label(frame, width=-20) self.button = ttk.Button(frame, text='Update', command=self.getandsend, default=tk.ACTIVE, state=tk.DISABLED) self.status = ttk.Label(frame, width=-25) self.w.bind('<Return>', self.getandsend) self.w.bind('<KP_Enter>', self.getandsend) self.cmdr.grid(row=0, column=1, sticky=tk.W) self.system.grid(row=1, column=1, sticky=tk.W) self.station.grid(row=2, column=1, sticky=tk.W) self.button.grid(row=3, column=0, columnspan=2, sticky=tk.NSEW) self.status.grid(row=4, column=0, columnspan=2, sticky=tk.SW) for child in frame.winfo_children(): child.grid_configure(padx=5, pady=(platform == 'darwin' and 3 or 2)) menubar = tk.Menu() if platform == 'darwin': from Foundation import NSBundle # https://www.tcl.tk/man/tcl/TkCmd/menu.htm apple_menu = tk.Menu(menubar, name='apple') apple_menu.add_command( label="About %s" % applongname, command=lambda: self.w.call('tk::mac::standardAboutPanel')) apple_menu.add_command( label="Statistics", command=lambda: stats.StatsDialog(self.w, self.session)) apple_menu.add_command( label="Check for Update", command=lambda: self.updater.checkForUpdates()) menubar.add_cascade(menu=apple_menu) window_menu = tk.Menu(menubar, name='window') menubar.add_cascade(menu=window_menu) # https://www.tcl.tk/man/tcl/TkCmd/tk_mac.htm self.w.createcommand( 'tkAboutDialog', lambda: self.w.call('tk::mac::standardAboutPanel')) self.w.createcommand("::tk::mac::Quit", self.onexit) self.w.createcommand( "::tk::mac::ShowPreferences", lambda: prefs.PreferencesDialog(self.w, self.login)) self.w.createcommand( "::tk::mac::ReopenApplication", self.w.deiconify) # click on app in dock = restore self.w.protocol("WM_DELETE_WINDOW", self.w.withdraw) # close button shouldn't quit app else: file_menu = tk.Menu(menubar, tearoff=tk.FALSE) file_menu.add_command( label="Statistics", command=lambda: stats.StatsDialog(self.w, self.session)) file_menu.add_command( label="Check for Update", command=lambda: self.updater.checkForUpdates()) file_menu.add_command( label="Settings", command=lambda: prefs.PreferencesDialog(self.w, self.login)) file_menu.add_separator() file_menu.add_command(label="Exit", command=self.onexit) menubar.add_cascade(label="File", menu=file_menu) self.w.protocol("WM_DELETE_WINDOW", self.onexit) if platform == 'linux2': # Fix up menu to use same styling as everything else (fg, bg, afg, abg) = (style.lookup('TLabel.label', 'foreground'), style.lookup('TLabel.label', 'background'), style.lookup('TButton.label', 'foreground', ['active']), style.lookup('TButton.label', 'background', ['active'])) menubar.configure(fg=fg, bg=bg, activeforeground=afg, activebackground=abg) file_menu.configure(fg=fg, bg=bg, activeforeground=afg, activebackground=abg) self.w['menu'] = menubar # update geometry if config.get('geometry'): match = re.match('\+([\-\d]+)\+([\-\d]+)', config.get('geometry')) if match and ( platform != 'darwin' or int(match.group(2)) > 0 ): # http://core.tcl.tk/tk/tktview/c84f660833546b1b84e7 self.w.geometry(config.get('geometry')) self.w.update_idletasks() self.w.wait_visibility() (w, h) = (self.w.winfo_width(), self.w.winfo_height()) self.w.minsize(w, h) # Minimum size = initial size if platform != 'linux2': # update_idletasks() doesn't allow for the menubar on Linux self.w.maxsize(-1, h) # Maximum height = initial height # First run if not config.get('username') or not config.get('password'): prefs.PreferencesDialog(self.w, self.login) else: self.login() # Load updater after UI creation (for WinSparkle) import update self.updater = update.Updater(self.w) self.w.bind_all('<<Quit>>', self.onexit) # user-generated