diff --git a/command_prompt.py b/command_prompt.py index 23342dc..bc9e01a 100644 --- a/command_prompt.py +++ b/command_prompt.py @@ -77,7 +77,7 @@ class Command_prompt(Label): # process command if keycode[1]=="enter": self.insert=False - self.parse_argv() + self.run_command() self.set_text("") # move @@ -246,7 +246,7 @@ class Command_prompt(Label): # check that cursor is in first argument if cursor[0]==1: # complete filesystem path - self.append_text_at_cursor(self.complete_path(self.argv[1],cursor[1])) + self.append_text_at_cursor(self.complete_path(self.argv[cursor[0]],cursor[1])) # complete filesystem path def complete_path(self,base,end): @@ -271,3 +271,72 @@ class Command_prompt(Label): self.app.status_bar.raw_text+=name+" " self.app.status_bar.draw() return os.path.commonprefix(paths)[end:] + + + # run command + def run_command(self): + # parse command line + self.parse_argv() + + # write + if self.argv[0]=="w" or self.argv[0]=="w!" or self.argv[0]=="wq": + if len(self.argv)>2: + self.app.status_bar.set_text("error: could not write to file: too many arguments -- usage: ':w [path to file]'") + return + elif len(self.argv)==1: + if os.path.isfile(self.app.openfile): + self.app.painter.write(self.app.openfile) + else: + self.app.status_bar.set_text("error: no file is open for editing, specify a path") + return + else: + # check that the file is not a directory + if os.path.isdir(self.argv[1]): + self.app.status_bar.set_text("error: '"+self.argv[1]+"' is a directory") + return + # check that file does not already exist + elif self.argv[0]!="w!" and self.argv[1]!= self.app.openfile and os.path.isfile(self.argv[1]): + self.app.status_bar.set_text("error: '"+self.argv[1]+"' already exists (use ':w!' to overwrite)") + return + # check that the containing directory exists + elif len(os.path.dirname(self.argv[1]))>0 and not os.path.isdir(os.path.dirname(self.argv[1])): + self.app.status_bar.set_text("error: could not find directory '"+os.path.dirname(self.argv[1])+"'") + return + # check permissions + elif (len(os.path.dirname(self.argv[1]))>0 and not os.access(os.path.dirname(self.argv[1]),os.W_OK)) or (len(os.path.dirname(self.argv[1]))==0 and not os.access(os.getcwd(),os.W_OK)): + self.app.status_bar.set_text("error: permission denied") + return + else: + self.app.painter.write(self.argv[1]) + + # open file + if self.argv[0]=="e": + if len(self.argv)>2: + self.app.status_bar.set_text("error: could not open file: too many arguments -- usage: ':e '") + return + elif len(self.argv)==1: + self.app.status_bar.set_text("error: could not open file: no argument found -- usage: ':e '") + return + else: + # check that the file is not a directory + if os.path.isdir(self.argv[1]): + self.app.status_bar.set_text("error: '"+self.argv[1]+"' is a directory") + return + # check that the file exists + elif not os.path.isfile(self.argv[1]): + self.app.status_bar.set_text("error: could not find file '"+self.argv[1]+"'") + return + # check permissions + elif not os.access(self.argv[1],os.R_OK): + self.app.status_bar.set_text("error: permission denied") + return + else: + # select openfile + self.app.openfile=self.argv[1] + # read the file + self.app.painter.read(self.argv[1]) + + # quit + if self.argv[0]=="q" or self.argv=="wq": + self.app.stop() + diff --git a/cross.py b/cross.py index 5faa391..c0effaa 100644 --- a/cross.py +++ b/cross.py @@ -310,4 +310,73 @@ class Cross_painter(Widget): return self.check_move(candidate,cross) + # write configuration to file + def write(self,file): + ff=open(file,"w") + for cross in self.crosses: + ff.write("{:05.2f},{:05.2f};{:3.1f},{:3.1f},{:3.1f}\n".format(cross.pos.x,cross.pos.y,cross.color[0],cross.color[1],cross.color[2])) + ff.close() + + # read configuration from file + def read(self,file): + self.crosses=[] + ff=open(file,"r") + + # counter + i=0 + + for line in ff.readlines(): + i+=1 + + # remove newline + line=line[:len(line)-1] + + # ignore comments + if '#' in line: + line=line[:line.find('#')] + # ignore empty lines + if len(line)==0: + continue + + entries=line.split(";") + # skip line if improperly formatted + if len(entries)>2: + print("warning: ignoring line "+str(i)+" in file '"+file+"': more than two ';' spearated entries in '"+line+"'",file=sys.stderr) + continue + + # position + pos_str=entries[0].split(",") + # skip line if improperly formatted + if len(pos_str)!=2: + print("warning: ignoring line "+str(i)+" in file '"+file+"': position '"+entries[0]+"' does not have two components",file=sys.stderr) + continue + try: + pos=Point(float(pos_str[0]),float(pos_str[1])) + except: + print("warning: ignoring line "+str(i)+" in file '"+file+"': position '"+entries[0]+"' cannot be read",file=sys.stderr) + continue + + + # color + color=(0,0,1) + if len(entries)==2: + color_str=entries[1].split(",") + # skip line if improperly formatted + if len(color_str)!=3: + print("warning: ignoring line "+str(i)+" in file '"+file+"': color '"+entries[1]+"' does not have three components",file=sys.stderr) + continue + try: + color=(float(color_str[0]),float(color_str[1]),float(color_str[2])) + except: + print("warning: ignoring line "+str(i)+" in file '"+file+"': color '"+entries[1]+"' cannot be read",file=sys.stderr) + continue + + if self.check_interaction_any(pos,None): + # add to list + self.crosses.append(Cross(pos.x,pos.y,color=color)) + else: + print("warning: ignoring line "+str(i)+" in file '"+file+"': particle overlaps with existing particles",file=sys.stderr) + + ff.close() + self.draw() diff --git a/main.py b/main.py index 189e4d7..4ad1df7 100644 --- a/main.py +++ b/main.py @@ -15,8 +15,14 @@ class Jam_app(App): def build(self): layout=BoxLayout(orientation="vertical") + # the file open for editing + self.openfile="" + + # painter self.painter=Cross_painter(self) + # status bar self.status_bar=Status_bar(self) + # command prompt self.command_prompt=Command_prompt(self) layout.add_widget(self.painter)