1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
12 #Only try to import the _core to save import time
18 class CuraApp(wx.App):
19 def __init__(self, files):
20 if platform.system() == "Windows" and not 'PYCHARM_HOSTED' in os.environ:
21 from Cura.util import profile
22 super(CuraApp, self).__init__(redirect=True, filename=os.path.join(profile.getBasePath(), 'output_log.txt'))
24 super(CuraApp, self).__init__(redirect=False)
26 self.mainWindow = None
28 self.loadFiles = files
30 if platform.system() == "Darwin":
31 self.Bind(wx.EVT_ACTIVATE_APP, self.OnActivate)
33 if sys.platform.startswith('win'):
34 #Check for an already running instance, if another instance is running load files in there
35 from Cura.util import version
36 from ctypes import windll
41 portNr = 0xCA00 + sum(map(ord, version.getVersion(False)))
44 other_hwnd = windll.user32.FindWindowA(None, ctypes.c_char_p('Cura - ' + version.getVersion()))
46 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
47 sock.sendto('\0'.join(files), ("127.0.0.1", portNr))
49 windll.user32.SetForegroundWindow(other_hwnd)
54 socketListener = threading.Thread(target=self.Win32SocketListener, args=(portNr,))
55 socketListener.daemon = True
56 socketListener.start()
58 if sys.platform.startswith('darwin'):
59 #Do not show a splashscreen on OSX, as by Apple guidelines
60 self.afterSplashCallback()
62 from Cura.gui import splashScreen
63 self.splash = splashScreen.splashScreen(self.afterSplashCallback)
65 def MacOpenFile(self, path):
67 self.mainWindow.OnDropFiles([path])
68 except Exception as e:
69 warnings.warn("File at {p} cannot be read: {e}".format(p=path, e=str(e)))
71 def MacReopenApp(self, event):
72 self.GetTopWindow().Raise()
74 def MacHideApp(self, event):
75 self.GetTopWindow().Show(False)
80 def MacPrintFile(self, file_path):
83 def OnActivate(self, e):
85 self.GetTopWindow().Raise()
88 def Win32SocketListener(self, port):
91 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
92 sock.bind(("127.0.0.1", port))
94 data, addr = sock.recvfrom(2048)
96 wx.CallAfter(self.mainWindow.OnDropFiles, data.split('\0'))
97 except Exception as e:
98 warnings.warn("File at {p} cannot be read: {e}".format(p=data, e=str(e)))
102 def destroySplashScreen(self):
103 if self.splash is not None:
104 self.splash.Show(False)
105 self.splash.Destroy()
108 def afterSplashCallback(self):
109 #These imports take most of the time and thus should be done after showing the splashscreen
111 from Cura.gui import mainWindow
112 from Cura.gui import configWizard
113 from Cura.gui import newVersionDialog
114 from Cura.util import profile
115 from Cura.util import resources
116 from Cura.util import version
118 resources.setupLocalization(profile.getPreference('language')) # it's important to set up localization at very beginning to install _
120 #If we do not have preferences yet, try to load it from a previous Cura install
121 if profile.getMachineSetting('machine_type') == 'unknown':
123 otherCuraInstalls = profile.getAlternativeBasePaths()
124 for path in otherCuraInstalls[::-1]:
126 print 'Loading old settings from %s' % (path)
127 profile.loadPreferences(os.path.join(path, 'preferences.ini'))
128 profile.loadProfile(os.path.join(path, 'current_profile.ini'))
132 print traceback.print_exc()
135 print traceback.print_exc()
137 #If we haven't run it before, run the configuration wizard.
138 if profile.getMachineSetting('machine_type') == 'unknown':
139 #Check if we need to copy our examples
140 exampleFile = os.path.normpath(os.path.join(resources.resourceBasePath, 'example', 'Rocktopus.stl'))
142 self.loadFiles = [exampleFile]
143 self.destroySplashScreen()
144 configWizard.ConfigWizard()
146 if profile.getPreference('check_for_updates') == 'True':
147 newVersion = version.checkForNewerVersion()
148 if newVersion is not None:
149 self.destroySplashScreen()
150 if wx.MessageBox(_("A new version of Cura is available, would you like to download?"), _("New version available"), wx.YES_NO | wx.ICON_INFORMATION) == wx.YES:
151 webbrowser.open(newVersion)
153 if profile.getMachineSetting('machine_name') == '':
155 if profile.getPreference('last_run_version') != version.getVersion(False):
156 profile.performVersionUpgrade()
158 # Must happen before the main window is created, in case there are changes
159 # that would affect it (such as machine name changes)
160 if version.isDevVersion():
161 profile.performVersionUpgrade()
163 self.mainWindow = mainWindow.mainWindow()
164 self.destroySplashScreen()
165 self.SetTopWindow(self.mainWindow)
166 self.mainWindow.Show()
167 self.mainWindow.OnDropFiles(self.loadFiles)
168 setFullScreenCapable(self.mainWindow)
170 if profile.getPreference('last_run_version') != version.getVersion(False):
171 profile.putPreference('last_run_version', version.getVersion(False))
172 newVersionDialog.newVersionDialog().Show()
174 # Must come after creating the main window
175 #if version.isDevVersion():
176 #import wx.lib.inspection
177 # Show the WX widget inspection tool
178 #wx.lib.inspection.InspectionTool().Show()
180 if sys.platform.startswith('darwin'):
181 wx.CallAfter(self.StupidMacOSWorkaround)
183 def StupidMacOSWorkaround(self):
184 subprocess.Popen(['osascript', '-e', '''\
185 tell application "System Events"
186 set procName to name of first process whose unix id is %s
188 tell application procName to activate
191 if platform.system() == "Darwin": #Mac magic. Dragons live here. THis sets full screen options.
194 _objc = ctypes.PyDLL(objc._objc.__file__)
196 # PyObject *PyObjCObject_New(id objc_object, int flags, int retain)
197 _objc.PyObjCObject_New.restype = ctypes.py_object
198 _objc.PyObjCObject_New.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
200 def setFullScreenCapable(frame):
201 frameobj = _objc.PyObjCObject_New(frame.GetHandle(), 0, 1)
203 NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7
204 window = frameobj.window()
205 newBehavior = window.collectionBehavior() | NSWindowCollectionBehaviorFullScreenPrimary
206 window.setCollectionBehavior_(newBehavior)
208 def setFullScreenCapable(frame):
212 def setFullScreenCapable(frame):