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
117 from distutils.version import LooseVersion
119 resources.setupLocalization(profile.getPreference('language')) # it's important to set up localization at very beginning to install _
121 if LooseVersion(wx.__version__) < LooseVersion('3.0'):
122 wx.MessageBox(_("This version of Cura requires WxPython version 3.0 or newer.\nYour current WxPython version is %s.") % wx.__version__,
123 _("WxPython version is too old"), wx.OK | wx.ICON_ERROR)
126 #If we do not have preferences yet, try to load it from a previous Cura install
127 if profile.getMachineSetting('machine_type') == 'unknown':
129 otherCuraInstalls = profile.getAlternativeBasePaths()
130 for path in otherCuraInstalls[::-1]:
132 print 'Loading old settings from %s' % (path)
133 profile.loadPreferences(os.path.join(path, 'preferences.ini'))
134 profile.loadProfile(os.path.join(path, 'current_profile.ini'))
138 print traceback.print_exc()
141 print traceback.print_exc()
143 #If we haven't run it before, run the configuration wizard.
144 if profile.getMachineSetting('machine_type') == 'unknown':
145 #Check if we need to copy our examples
146 exampleFile = os.path.normpath(os.path.join(resources.resourceBasePath, 'example', 'Rocktopus.stl'))
148 self.loadFiles = [exampleFile]
149 self.destroySplashScreen()
150 configWizard.ConfigWizard()
152 if profile.getPreference('check_for_updates') == 'True':
153 newVersion = version.checkForNewerVersion()
154 if newVersion is not None:
155 self.destroySplashScreen()
156 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:
157 webbrowser.open(newVersion)
159 if profile.getMachineSetting('machine_name') == '':
161 if profile.getPreference('last_run_version') != version.getVersion(False):
162 profile.performVersionUpgrade()
164 # Must happen before the main window is created, in case there are changes
165 # that would affect it (such as machine name changes)
166 if version.isDevVersion():
167 profile.performVersionUpgrade()
169 self.mainWindow = mainWindow.mainWindow()
170 self.destroySplashScreen()
171 self.SetTopWindow(self.mainWindow)
172 self.mainWindow.Show()
173 self.mainWindow.OnDropFiles(self.loadFiles)
174 setFullScreenCapable(self.mainWindow)
176 if profile.getPreference('last_run_version') != version.getVersion(False):
177 profile.putPreference('last_run_version', version.getVersion(False))
178 newVersionDialog.newVersionDialog().Show()
180 # Must come after creating the main window
181 #if version.isDevVersion():
182 #import wx.lib.inspection
183 # Show the WX widget inspection tool
184 #wx.lib.inspection.InspectionTool().Show()
186 if sys.platform.startswith('darwin'):
187 wx.CallAfter(self.StupidMacOSWorkaround)
189 def StupidMacOSWorkaround(self):
190 subprocess.Popen(['osascript', '-e', '''\
191 tell application "System Events"
192 set procName to name of first process whose unix id is %s
194 tell application procName to activate
197 if platform.system() == "Darwin": #Mac magic. Dragons live here. THis sets full screen options.
200 _objc = ctypes.PyDLL(objc._objc.__file__)
202 # PyObject *PyObjCObject_New(id objc_object, int flags, int retain)
203 _objc.PyObjCObject_New.restype = ctypes.py_object
204 _objc.PyObjCObject_New.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
206 def setFullScreenCapable(frame):
207 frameobj = _objc.PyObjCObject_New(frame.GetHandle(), 0, 1)
209 NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7
210 window = frameobj.window()
211 newBehavior = window.collectionBehavior() | NSWindowCollectionBehaviorFullScreenPrimary
212 window.setCollectionBehavior_(newBehavior)
214 def setFullScreenCapable(frame):
218 def setFullScreenCapable(frame):