99PACKAGE_SETTINGS = "GDL.sublime-settings"
1010DEFAULT_AC_PATH = "C:/Program Files/GRAPHISOFT/ARCHICAD 23"
1111
12- def check_system ():
13- """ Returns the file ending of executables depending on the
14- operating system of the user.
15- """
16- if sys .platform .startswith ('darwin' ): # OSX
17- return "Contents/MacOS/LP_XMLConverter.app/Contents/MacOS/LP_XMLConverter"
18- elif sys .platform .startswith ('win' ): # Windows
19- return "LP_XMLConverter.exe"
20- else :
21- sublime .error_message ("GDL build error: Your OS is not supported." )
22- return
2312
2413def save_all_files ():
25- """ Saves all files open in sublime .
14+ """ Saves all files open in Sublime .
2615 Mimics the 'save on build' behavior of Sublime Text.
2716 """
2817 for window in sublime .windows ():
2918 for view in window .views ():
3019 if view .file_name () and view .is_dirty ():
3120 view .run_command ("save" )
3221
33- def get_project_data (view , invoke ): # invoke is either 'to-hsf' or 'to-gsm'
22+ def get_project_data (view , invoke ):
3423 """ Gets the data of the .sublime-project file.
3524 Returns additional arguments for the commandline operation,
3625 if the user has set any.
3726 """
27+ # invoke options: 'to-hsf' / 'to-gsm' / 'proj_gsm_path'
3828 project_data = view .window ().project_data ()
3929 if not project_data :
4030 sublime .error_message ("You must create a project first! (Project > Save Project As...)" )
@@ -51,25 +41,25 @@ def get_project_data(view, invoke): # invoke is either 'to-hsf' or 'to-gsm'
5141 else :
5242 sublime .error_message ("Something went wrong." )
5343 return
54-
44+
45+ # Future addition. Sadly not working as by now.
5546# class AutocompleteCaps(sublime_plugin.EventListener):
5647# def on_query_completions(self, view, prefix, locations):
5748# return suggestions
58-
59- # go to
60- # http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-lp_xmlconverter-tool
61- # for detailed information
62- class HsfBuildCommand (sublime_plugin .WindowCommand ):
49+
50+
51+ class Builder (sublime_plugin .WindowCommand ):
6352
6453 def run (self , * args , ** kwargs ):
65- self .os = check_system ()
54+ self .lp_conv_path = self .check_system ()
55+ self .pckg_settings = sublime .load_settings (PACKAGE_SETTINGS )
56+ self .AC_path = str (self .pckg_settings .get ("AC_path" , DEFAULT_AC_PATH ))
57+ self .converter = os .path .join (self .AC_path , self .lp_conv_path )
58+
6659 self .view = self .window .active_view ()
6760 if self .view .settings ().get ("auto_save" , True ):
6861 save_all_files ()
6962
70- settings = sublime .load_settings (PACKAGE_SETTINGS )
71- self .AC_path = str (settings .get ("AC_path" , DEFAULT_AC_PATH ))
72-
7363 folders = self .window .folders ()
7464 if len (folders ) <= 0 :
7565 sublime .error_message ("GDL build command error: You must have a project open." )
@@ -82,16 +72,25 @@ def run(self, *args, **kwargs):
8272 self .multipleFolders = True
8373 self .pick_project_folder (folders )
8474
85- def on_done_proj (self ):
86- # this needs to be in its own function, because
87- # the sublime text quick panel works asynchronous
88- self .find_gsm ()
75+ def check_system (self ):
76+ """ Returns the path to the LP_XML converter.
77+ """
78+ if sys .platform .startswith ('darwin' ): # OSX
79+ self .os_win = "false"
80+ return "Contents/MacOS/LP_XMLConverter.app/Contents/MacOS/LP_XMLConverter"
81+ elif sys .platform .startswith ('win' ): # Windows
82+ self .os_win = "true"
83+ return "LP_XMLConverter.exe"
84+ else :
85+ sublime .error_message ("GDL build error: Your OS is not supported." )
86+ return
8987
90- def on_done_file (self ):
91- self .cmdargs = get_project_data (self .view , 'to-hsf' )
92- self .run_hsf ()
88+ def normpath (self , path ):
89+ return '"{}"' .format (os .path .normpath (path ))
9390
9491 def pick_project_folder (self , folders ):
92+ """ Gets called if there are multiple folders in the project.
93+ """
9594 folderNames = []
9695 for folder in folders :
9796 index = folder .rfind ('/' ) + 1
@@ -110,6 +109,31 @@ def select_project(self, select):
110109 self .project_folder = folders [select ]
111110 self .on_done_proj () # go on here
112111
112+ def show_quick_panel (self , options , done ):
113+ """ Shows the Sublime Text quick panel with the invoked options. """
114+ # Sublime Text 3 requires a short timeout between quick panels
115+ sublime .set_timeout (lambda : self .window .show_quick_panel (options , done ), 10 )
116+
117+
118+ # @classmethod
119+ # def is_enabled(self):
120+ # return "/GDL/" in self.window.active_view().settings().get("syntax")
121+
122+
123+ # go to
124+ # http://gdl.graphisoft.com/tips-and-tricks/how-to-use-the-lp_xmlconverter-tool
125+ # for detailed information
126+ class HsfBuildCommand (Builder ):
127+ """ Converts a GSM into human readable GDL scripts. """
128+
129+ def run (self , * args , ** kwargs ):
130+ """ Sublime Text will call this function. """
131+ super ().run (self )
132+
133+ def on_done_proj (self ):
134+ # own function because quick panel is async
135+ self .find_gsm ()
136+
113137 def find_gsm (self ):
114138 self .files = []
115139 # r=root, d=directories, f=files
@@ -127,78 +151,47 @@ def find_gsm(self):
127151 self .file_to_convert = self .files [0 ]
128152 self .on_done_file () # go on here
129153
154+ def on_done_file (self ):
155+ self .cmdargs = get_project_data (self .view , 'to-hsf' )
156+ self .run_hsf ()
157+
130158 def select_gsm (self , select ):
131159 if select < 0 :
132160 return
133161 self .file_to_convert = self .files [select ]
134162 self .on_done_file () # go on here
135-
136- # Sublime Text 3 requires a short timeout between quick panels
137- def show_quick_panel (self , options , done ):
138- sublime .set_timeout (lambda : self .window .show_quick_panel (options , done ), 10 )
139-
163+
140164 def run_hsf (self , ):
141- converter = os .path .join (self .AC_path , self .os )
142- cmd = [converter , "libpart2hsf" , self .cmdargs , self .file_to_convert , self .project_folder ] # cmd, source, dest
165+ """ Invokes the LP_XML converter.
166+ """
167+ self .converter = super ().normpath (self .converter )
168+ self .file_to_convert = super ().normpath (self .file_to_convert )
169+ self .project_folder = super ().normpath (self .project_folder )
170+
171+ cmd = [self .converter , "libpart2hsf" , self .cmdargs , self .file_to_convert , self .project_folder ] # cmd, source, dest
143172 cmd = list (filter (None , cmd )) # filters out the empty cmdargs. otherwise Macs get hiccups. sigh.
144- log .debug ("GDL Command run: " + " " .join (cmd ))
145- execCMD = {"cmd" : cmd }
173+ cmd = " " .join (cmd )
174+
175+ #log.debug("GDL Command run: " + " ".join(cmd))
176+ execCMD = {"shell_cmd" : cmd }
146177
147178 self .window .run_command ("exec" , execCMD )
148179
149180############################################################################
150- class LibpartBuildCommand (sublime_plugin .WindowCommand ):
181+ class LibpartBuildCommand (Builder ):
182+ """ Builds a GSM from the GDL scripts in the project. """
151183
152184 def run (self , * args , ** kwargs ):
153- self .os = check_system ()
154- self .view = self .window .active_view ()
155- if self .view .settings ().get ("auto_save" , True ):
156- save_all_files ()
157-
158- settings = sublime .load_settings (PACKAGE_SETTINGS )
159- self .AC_path = str (settings .get ("AC_path" , DEFAULT_AC_PATH ))
160-
161- folders = self .window .folders ()
162- if len (folders ) <= 0 :
163- sublime .error_message ("GDL build command error: You must have a project open." )
164- else :
165- if len (folders ) == 1 :
166- self .multipleFolders = False
167- self .project_folder = folders [0 ]
168- self .on_done_proj () # go on here
169- else :
170- self .multipleFolders = True
171- self .pick_project_folder (folders )
185+ """ Sublime Text will call this function. """
186+ super ().run (self )
172187
173188 def on_done_proj (self ):
174189 # own function because quick panel is async
175190 self .find_hsf ()
176191
177- def on_done_file (self ):
178- self .gsm_name = self .folder_to_convert + ".gsm"
179- self .cmdargs = get_project_data (self .view , 'to-gsm' )
180- self .run_libpart ()
181-
182- def pick_project_folder (self , folders ):
183- folderNames = []
184- for folder in folders :
185- index = folder .rfind ('/' ) + 1
186- if index > 0 :
187- folderNames .append (folder [index :])
188- else :
189- folderNames .append (folder )
190-
191- # self.sel_proj will be called once, with the index of the selected item
192- self .show_quick_panel (folderNames , self .select_project )
193-
194- def select_project (self , select ):
195- folders = self .window .folders ()
196- if select < 0 : # will be -1 if panel was cancelled
197- return
198- self .project_folder = folders [select ]
199- self .on_done_proj () # go on here
200-
201192 def find_hsf (self ):
193+ """ Finds all possible folders for converting to GSM.
194+ """
202195 self .folders = [fldr for fldr in os .listdir (self .project_folder ) if os .path .isdir (os .path .join (self .project_folder , fldr ))]
203196
204197 if len (self .folders ) <= 0 :
@@ -211,21 +204,56 @@ def find_hsf(self):
211204 self .on_done_file () # go on here
212205
213206 def select_hsf (self , select ):
207+ """ Selects on of the possible of folders of the find_hsf() def.
208+ """
214209 folders = self .folders
215210 if select < 0 : # will be -1 if panel was cancelled
216211 return
217212 self .folder_to_convert = os .path .join (self .project_folder , folders [select ])
218213 self .on_done_file () # go on here
219214
220- # Sublime Text 3 requires a short timeout between quick panels
221- def show_quick_panel (self , options , done ):
222- sublime .set_timeout (lambda : self .window .show_quick_panel (options , done ), 10 )
215+ def on_done_file (self ):
216+ """ Path handling for GSM output.
217+ """
218+ self .global_gsm_path = str (self .pckg_settings .get ("global_gsm_path" , "" ))
219+ self .proj_gsm_path = get_project_data (self .view , 'proj_gsm_path' )
220+
221+ output_path = ""
222+ if self .proj_gsm_path : # project based path takes precedence
223+ if self .proj_gsm_path != "default" :
224+ # only set the path if its not 'default' which mimics the standard behavior
225+ # TODO implement path check here
226+ output_path = self .proj_gsm_path
227+ elif self .global_gsm_path : # otherwise take global path, if set
228+ output_path = self .global_gsm_path
229+
230+ if not output_path :
231+ # default path => not global or proj path is set, or proj path says 'default'
232+ output_path = os .path .dirname (self .folder_to_convert )
233+
234+ gsm_name = os .path .basename (os .path .normpath (self .folder_to_convert )) + ".gsm"
235+ self .gsm_path = os .path .join (output_path , gsm_name )
236+
237+ self .cmdargs = get_project_data (self .view , 'to-gsm' )
238+
239+ self .run_libpart ()
223240
224241 def run_libpart (self ):
225- converter = os .path .join (self .AC_path , self .os )
226- cmd = [converter , "hsf2libpart" , self .cmdargs , self .folder_to_convert , self .gsm_name ] # cmd, source, dest
242+ """ Invokes the LP_XML converter.
243+ """
244+ self .converter = super ().normpath (self .converter )
245+ self .folder_to_convert = super ().normpath (self .folder_to_convert )
246+ self .gsm_path = super ().normpath (self .gsm_path )
247+
248+ cmd = [self .converter , "hsf2libpart" , self .cmdargs , self .folder_to_convert , self .gsm_path ] # cmd, source, dest
227249 cmd = list (filter (None , cmd )) # filters out the empty cmdargs. otherwise Macs get hiccups. sigh.
228- log .debug ("GDL Command run: " + " " .join (cmd ))
229- execCMD = {"cmd" : cmd }
250+ cmd = " " .join (cmd )
251+ # log.debug("GDL Command run: " + cmd)
252+
253+ # if you use `cmd` instead of `shell_cmd` you will get the infamous [Winerror 5]
254+ # see: https://forum.sublimetext.com/t/winerror-5-access-is-denied/
255+ # however, for `shell_cmd` to work we need to pass a string, not a list (!)
256+ execCMD = {"shell_cmd" : cmd }
230257
231258 self .window .run_command ("exec" , execCMD )
259+
0 commit comments