Skip to content

Commit 808aedd

Browse files
authored
Pre1.0_2
1 parent 78e3aec commit 808aedd

File tree

11 files changed

+934
-2
lines changed

11 files changed

+934
-2
lines changed

ROOT/softwares/ACOS_console/ACOS_console.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ def exit_function():
139139
globals()["main_inputter"].grid(row=0, column=1, sticky="w")
140140
globals()["inputter_frame"].pack(fill=tk.X)
141141

142+
elif user_command.lower().startswith("help"):
143+
for line in """Help :
144+
- 'dir' : Shows the content of the current directory.
145+
- 'cd <relative path>' : Changes the current directory to the specified relative path.
146+
- 'cls' : Clears the screen.""".split("\n"):
147+
display(line.replace("\t", ""))
148+
142149
else:
143150
display("Unknown command : " + user_command, color="red")
144151

ROOT/softwares/IdeaGlue/IdeaGlue.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import tkinter as tk
33
import os
44
from functools import partial
5+
from PIL import Image, ImageTk
56

67
app_icon = "ACOS_IdeaGlue.png"
78
software_name = "Idea glue"
@@ -33,6 +34,7 @@ def on_app_launch(frame:tk.Frame, width:int=default_size[0], height:int=default_
3334

3435
# Inserting the content
3536
globals()["main_textarea"].insert(1.0, textarea_content)
37+
globals()["main_textarea"].bind("<KeyPress>", partial(display_status_icon, frame, False))
3638

3739
# Placing the textarea
3840
globals()["main_textarea"].place(
@@ -54,15 +56,40 @@ def on_resize(frame, event):
5456
height = frame.winfo_height()
5557
)
5658

57-
def save_content(frame:tk.Tk):
59+
def display_status_icon(frame, saved:bool=True, event=None):
60+
os.chdir(os.path.dirname(os.path.realpath(__file__)))
61+
icon_size = 16
62+
63+
globals()["status_icon_TkImage"] = ImageTk.PhotoImage(
64+
Image.open(
65+
("Not" if saved is False else "") + "Saved.png"
66+
).resize((icon_size, icon_size))
67+
)
68+
globals()["status_icon"] = tk.Label(
69+
frame,
70+
image = globals()["status_icon_TkImage"],
71+
bg = "#d8ad02"
72+
)
73+
globals()["status_icon"].place(
74+
x = frame.winfo_width() - icon_size,
75+
y = frame.winfo_height() - icon_size
76+
)
77+
globals()["status_icon"].bind("<Button-1>", partial(save_content, frame))
78+
79+
os.chdir("../../../")
80+
81+
82+
def save_content(frame:tk.Tk, event=None):
5883
"""
5984
Function to save the textarea content
6085
"""
6186

6287
textarea_file = open("ROOT/" + software_api.REGISTRY["USERS_FOLDER"] + "/" \
6388
+ software_api.current_user + "/.ideaglue_content", "w")
64-
textarea_file.write(globals()["main_textarea"].get(1.0, tk.END))
89+
textarea_file.write(globals()["main_textarea"].get(1.0, tk.END)[:-1])
6590
textarea_file.close()
6691

92+
display_status_icon(frame, True)
93+
6794
frame.after(3000, save_content, frame)
6895

ROOT/softwares/IdeaGlue/NotSaved.png

1.93 KB
Loading

ROOT/softwares/IdeaGlue/Saved.png

1.12 KB
Loading
44.6 KB
Loading
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
from .. import software_api
2+
from cefpython3 import cefpython as cef
3+
import ctypes
4+
5+
try:
6+
import tkinter as tk
7+
except ImportError:
8+
import Tkinter as tk
9+
import sys
10+
import os
11+
import platform
12+
import logging as _logging
13+
import requests
14+
15+
app_icon = "Excel.png"
16+
software_name = "Microsoft Excel"
17+
software_dir = "MicrosoftExcel"
18+
is_GUI = True
19+
min_size = (800, 440)
20+
max_size = None
21+
default_size = (900, 640)
22+
23+
# Fix for PyCharm hints warnings
24+
WindowUtils = cef.WindowUtils()
25+
26+
# Platforms
27+
WINDOWS = (platform.system() == "Windows")
28+
LINUX = (platform.system() == "Linux")
29+
MAC = (platform.system() == "Darwin")
30+
31+
# Globals
32+
logger = _logging.getLogger("tkinter_.py")
33+
34+
# Constants
35+
# Tk 8.5 doesn't support png images
36+
IMAGE_EXT = ".png" if tk.TkVersion > 8.5 else ".gif"
37+
38+
def test_connection():
39+
url = "http://www.google.com"
40+
timeout = 5
41+
try:
42+
request = requests.get(url, timeout=timeout)
43+
return True
44+
except (requests.ConnectionError, requests.Timeout):
45+
return False
46+
47+
def on_app_launch(frame:tk.Frame, width:int=900, height:int=640):
48+
# Testing if connection
49+
if test_connection() is True:
50+
if "no_connection_title" in globals():
51+
globals()["no_connection_title"].pack_forget()
52+
globals()["no_connection_title"].destroy()
53+
globals()["no_connection_subtitle"].pack_forget()
54+
globals()["no_connection_subtitle"].destroy()
55+
56+
logger.setLevel(_logging.CRITICAL)
57+
stream_handler = _logging.StreamHandler()
58+
formatter = _logging.Formatter("[%(filename)s] %(message)s")
59+
stream_handler.setFormatter(formatter)
60+
logger.addHandler(stream_handler)
61+
logger.info("CEF Python {ver}".format(ver=cef.__version__))
62+
logger.info("Python {ver} {arch}".format(
63+
ver=platform.python_version(), arch=platform.architecture()[0]))
64+
logger.info("Tk {ver}".format(ver=tk.Tcl().eval('info patchlevel')))
65+
assert cef.__version__ >= "55.3", "CEF Python v55.3+ required to run this"
66+
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
67+
# Tk must be initialized before CEF otherwise fatal error (Issue #306)
68+
app = MainFrame(frame)
69+
settings = {}
70+
if MAC:
71+
settings["external_message_pump"] = True
72+
cef.Initialize(settings=settings)
73+
else:
74+
if not "no_connection_title" in globals():
75+
globals()["no_connection_title"] = tk.Label(
76+
frame,
77+
text = "Oh No !",
78+
font = ("Impact", 22)
79+
)
80+
globals()["no_connection_title"].pack()
81+
globals()["no_connection_subtitle"] = tk.Label(
82+
frame,
83+
text = "Sounds like no connection is available...",
84+
font = ("Impact", 14)
85+
)
86+
globals()["no_connection_subtitle"].pack()
87+
# Testing again
88+
frame.after(5000, on_app_launch, frame, width, height)
89+
90+
class MainFrame(tk.Frame):
91+
def __init__(self, frame):
92+
self.browser_frame = None
93+
self.frame = frame
94+
95+
# Root
96+
tk.Grid.rowconfigure(frame, 0, weight=1)
97+
tk.Grid.columnconfigure(frame, 0, weight=1)
98+
99+
# MainFrame
100+
tk.Frame.__init__(self, frame)
101+
self.master.bind("<Configure>", self.on_frame_configure)
102+
self.setup_icon()
103+
self.bind("<Configure>", self.on_configure)
104+
self.bind("<FocusIn>", self.on_focus_in)
105+
self.bind("<FocusOut>", self.on_focus_out)
106+
107+
# BrowserFrame
108+
self.browser_frame = BrowserFrame(self)
109+
self.browser_frame.grid(row=1, column=0,
110+
sticky=(tk.N + tk.S + tk.E + tk.W))
111+
tk.Grid.rowconfigure(self, 1, weight=1)
112+
tk.Grid.columnconfigure(self, 0, weight=1)
113+
114+
# Pack MainFrame
115+
self.pack(fill=tk.BOTH, expand=tk.YES)
116+
117+
def on_frame_configure(self, _):
118+
logger.debug("MainFrame.on_frame_configure")
119+
if self.browser_frame:
120+
self.browser_frame.on_frame_configure()
121+
122+
def on_configure(self, event):
123+
logger.debug("MainFrame.on_configure")
124+
if self.browser_frame:
125+
width = event.width
126+
height = event.height
127+
self.browser_frame.on_mainframe_configure(width, height)
128+
129+
def on_focus_in(self, _):
130+
logger.debug("MainFrame.on_focus_in")
131+
132+
def on_focus_out(self, _):
133+
logger.debug("MainFrame.on_focus_out")
134+
135+
def get_browser(self):
136+
if self.browser_frame:
137+
return self.browser_frame.browser
138+
return None
139+
140+
def get_browser_frame(self):
141+
if self.browser_frame:
142+
return self.browser_frame
143+
return None
144+
145+
def setup_icon(self):
146+
resources = os.path.join(os.path.dirname(__file__), "resources")
147+
icon_path = os.path.join(resources, "tkinter" + IMAGE_EXT)
148+
if os.path.exists(icon_path):
149+
self.icon = tk.PhotoImage(file=icon_path)
150+
# noinspection PyProtectedMember
151+
self.master.call("wm", "iconphoto", self.master._w, self.icon)
152+
153+
class BrowserFrame(tk.Frame):
154+
155+
def __init__(self, mainframe, navigation_bar=None):
156+
self.navigation_bar = navigation_bar
157+
self.closing = False
158+
self.browser = None
159+
tk.Frame.__init__(self, mainframe)
160+
self.mainframe = mainframe
161+
self.bind("<FocusIn>", self.on_focus_in)
162+
self.bind("<FocusOut>", self.on_focus_out)
163+
self.bind("<Configure>", self.on_configure)
164+
"""For focus problems see Issue #255 and Issue #535. """
165+
self.focus_set()
166+
167+
def embed_browser(self):
168+
window_info = cef.WindowInfo()
169+
rect = [0, 0, self.winfo_width(), self.winfo_height()]
170+
window_info.SetAsChild(self.get_window_handle(), rect)
171+
self.browser = cef.CreateBrowserSync(window_info,
172+
url="https://www.office.com/launch/excel")
173+
assert self.browser
174+
self.browser.SetClientHandler(LifespanHandler(self))
175+
self.browser.SetClientHandler(LoadHandler(self))
176+
self.browser.SetClientHandler(FocusHandler(self))
177+
self.message_loop_work()
178+
179+
def get_window_handle(self):
180+
if MAC:
181+
# Do not use self.winfo_id() on Mac, because of these issues:
182+
# 1. Window id sometimes has an invalid negative value (Issue #308).
183+
# 2. Even with valid window id it crashes during the call to NSView.setAutoresizingMask:
184+
# https://github.com/cztomczak/cefpython/issues/309#issuecomment-661094466
185+
#
186+
# To fix it using PyObjC package to obtain window handle. If you change structure of windows then you
187+
# need to do modifications here as well.
188+
#
189+
# There is still one issue with this solution. Sometimes there is more than one window, for example when application
190+
# didn't close cleanly last time Python displays an NSAlert window asking whether to Reopen that window. In such
191+
# case app will crash and you will see in console:
192+
# > Fatal Python error: PyEval_RestoreThread: NULL tstate
193+
# > zsh: abort python tkinter_.py
194+
# Error messages related to this: https://github.com/cztomczak/cefpython/issues/441
195+
#
196+
# There is yet another issue that might be related as well:
197+
# https://github.com/cztomczak/cefpython/issues/583
198+
199+
# noinspection PyUnresolvedReferences
200+
from AppKit import NSApp
201+
# noinspection PyUnresolvedReferences
202+
import objc
203+
logger.info("winfo_id={}".format(self.winfo_id()))
204+
# noinspection PyUnresolvedReferences
205+
content_view = objc.pyobjc_id(NSApp.windows()[-1].contentView())
206+
logger.info("content_view={}".format(content_view))
207+
return content_view
208+
elif self.winfo_id() > 0:
209+
return self.winfo_id()
210+
else:
211+
raise Exception("Couldn't obtain window handle")
212+
213+
def message_loop_work(self):
214+
cef.MessageLoopWork()
215+
self.after(10, self.message_loop_work)
216+
217+
def on_configure(self, _):
218+
if not self.browser:
219+
self.embed_browser()
220+
221+
def on_frame_configure(self):
222+
# Root <Configure> event will be called when top window is moved
223+
if self.browser:
224+
self.browser.NotifyMoveOrResizeStarted()
225+
226+
def on_mainframe_configure(self, width, height):
227+
if self.browser:
228+
if WINDOWS:
229+
ctypes.windll.user32.SetWindowPos(
230+
self.browser.GetWindowHandle(), 0,
231+
0, 0, width, height, 0x0002)
232+
elif LINUX:
233+
self.browser.SetBounds(0, 0, width, height)
234+
self.browser.NotifyMoveOrResizeStarted()
235+
236+
def on_focus_in(self, _):
237+
logger.debug("BrowserFrame.on_focus_in")
238+
if self.browser:
239+
self.browser.SetFocus(True)
240+
241+
def on_focus_out(self, _):
242+
logger.debug("BrowserFrame.on_focus_out")
243+
"""For focus problems see Issue #255 and Issue #535. """
244+
if LINUX and self.browser:
245+
self.browser.SetFocus(False)
246+
247+
def on_frame_close(self):
248+
logger.info("BrowserFrame.on_frame_close")
249+
if self.browser:
250+
logger.debug("CloseBrowser")
251+
self.browser.CloseBrowser(True)
252+
self.clear_browser_references()
253+
cef.Shutdown()
254+
255+
def clear_browser_references(self):
256+
# Clear browser references that you keep anywhere in your
257+
# code. All references must be cleared for CEF to shutdown cleanly.
258+
self.browser = None
259+
260+
class LifespanHandler(object):
261+
262+
def __init__(self, tkFrame):
263+
self.tkFrame = tkFrame
264+
265+
def OnBeforeClose(self, browser, **_):
266+
logger.debug("LifespanHandler.OnBeforeClose")
267+
#self.tkFrame.quit()
268+
269+
class LoadHandler(object):
270+
271+
def __init__(self, browser_frame):
272+
self.browser_frame = browser_frame
273+
274+
def OnLoadStart(self, browser, **_):
275+
pass
276+
277+
class FocusHandler(object):
278+
"""For focus problems see Issue #255 and Issue #535. """
279+
280+
def __init__(self, browser_frame):
281+
self.browser_frame = browser_frame
282+
283+
def OnTakeFocus(self, next_component, **_):
284+
logger.debug("FocusHandler.OnTakeFocus, next={next}"
285+
.format(next=next_component))
286+
287+
def OnSetFocus(self, source, **_):
288+
logger.debug("FocusHandler.OnSetFocus, source={source}"
289+
.format(source=source))
290+
if LINUX:
291+
return False
292+
else:
293+
return True
294+
295+
def OnGotFocus(self, **_):
296+
logger.debug("FocusHandler.OnGotFocus")
297+
if LINUX:
298+
self.browser_frame.focus_set()

0 commit comments

Comments
 (0)