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.putPreference('last_run_version', version.getVersion(False))
157 profile.performVersionUpgrade()
158 newVersionDialog.newVersionDialog().Show()
160 # Must happen before the main window is created, in case there are changes
161 # that would affect it (such as machine name changes)
162 if version.isDevVersion():
163 profile.performVersionUpgrade()
165 self.mainWindow = mainWindow.mainWindow()
166 self.destroySplashScreen()
167 self.SetTopWindow(self.mainWindow)
168 self.mainWindow.Show()
169 self.mainWindow.OnDropFiles(self.loadFiles)
170 setFullScreenCapable(self.mainWindow)
172 # Must come after creating the main window
173 if version.isDevVersion():
174 import wx.lib.inspection
175 # Show the WX widget inspection tool
176 #wx.lib.inspection.InspectionTool().Show()
178 if sys.platform.startswith('darwin'):
179 wx.CallAfter(self.StupidMacOSWorkaround)
181 def StupidMacOSWorkaround(self):
182 subprocess.Popen(['osascript', '-e', '''\
183 tell application "System Events"
184 set procName to name of first process whose unix id is %s
186 tell application procName to activate
189 if platform.system() == "Darwin": #Mac magic. Dragons live here. THis sets full screen options.
192 _objc = ctypes.PyDLL(objc._objc.__file__)
194 # PyObject *PyObjCObject_New(id objc_object, int flags, int retain)
195 _objc.PyObjCObject_New.restype = ctypes.py_object
196 _objc.PyObjCObject_New.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
198 def setFullScreenCapable(frame):
199 frameobj = _objc.PyObjCObject_New(frame.GetHandle(), 0, 1)
201 NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7
202 window = frameobj.window()
203 newBehavior = window.collectionBehavior() | NSWindowCollectionBehaviorFullScreenPrimary
204 window.setCollectionBehavior_(newBehavior)
206 def setFullScreenCapable(frame):
210 def setFullScreenCapable(frame):