<reponame>MKlimenko/aTools_python3
'''
========================================================================================================================
Author: <NAME>
www.alancamilo.com
Modified: <NAME>

Requirements: aTools Package

------------------------------------------------------------------------------------------------------------------------
To install aTools, please follow the instructions in the file how_to_install.txt

------------------------------------------------------------------------------------------------------------------------
To unistall aTools, go to menu (the last button on the right), Uninstall

========================================================================================================================
''' 

import importlib
import sys
import urllib.request, urllib.error, urllib.parse
import shutil
import zipfile
import os
import webbrowser

from maya import cmds
from maya import mel
from maya import OpenMaya
from maya import OpenMayaAnim
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods      import uiMod
from aTools.commonMods      import utilMod
from aTools.commonMods      import animMod
from aTools.commonMods      import commandsMod
from aTools.commonMods      import aToolsMod
from aTools                 import setup
from aTools.generalTools    import hotkeys;                     importlib.reload(hotkeys)
from aTools.generalTools    import tumbleOnObjects;             importlib.reload(tumbleOnObjects)
from aTools.animTools       import animationCrashRecovery;      importlib.reload(animationCrashRecovery)
from aTools.animTools       import framePlaybackRange;          importlib.reload(framePlaybackRange)
from aTools.animTools       import jumpToSelectedKey;           importlib.reload(jumpToSelectedKey)
    


animationCrashRecovery  = animationCrashRecovery.AnimationCrashRecovery()
tumbleOnObjects         = tumbleOnObjects.TumbleOnObjects()

versionInfoPath     = "%sversion_info.txt"%aToolsMod.getaToolsPath(inScriptsFolder=False)
versionInfoContents = utilMod.readFile(versionInfoPath)
VERSION             = versionInfoContents[0].split(" ")[-1].replace("\n", "")
WHATISNEW           = "".join(versionInfoContents[1:])
KEYSLIST            = ["Up", "Down", "Left", "Right", "", "Page_Up", "Page_Down", "Home", "End", "Insert", "", "Return", "Space", "", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]
SITE_URL            = "http://camiloalan.wix.com/atoolswebsite"
ATOOLS_FOLDER       = "http://www.trickorscript.com/aTools/"
UPDATE_URL          = "%slatest_version.txt"%ATOOLS_FOLDER
DOWNLOAD_URL        = "%saTools.zip"%ATOOLS_FOLDER
lastUsedVersion     = aToolsMod.loadInfoWithUser("userPrefs", "lastUsedVersion")
HELP_URL            = "http://camiloalan.wix.com/atoolswebsite#!help/cjg9"
DONATE_URL          = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RQLT89A239K6"




PREFS = [{  "name":"tumbleOnObjects",
            "command":"tumbleOnObjects.switch(onOff)",
            "default":True
        },{ "name":"autoFramePlaybackRange",
            "command":"framePlaybackRange.toggleframePlaybackRange(onOff)",
            "default":False
        },{ "name":"autoJumpToSelectedKey",
            "command":"jumpToSelectedKey.togglejumpToSelectedKey(onOff)",
            "default":False
        },{ "name":"autoSmartSnapKeys",
            "command":"self.autoSmartSnapKeys.switch(onOff)",
            "default":False
        },{ "name":"animationCrashRecovery",
            "command":"animationCrashRecovery.switch(onOff)",
            "default":True
        },{ "name":"selectionCounter",
            "command":"self.selectionCounter.switch(onOff)",
            "default":True
        },{ "name":"autoSave",
            "command":"cmds.autoSave(enable=onOff)",
            "default":cmds.autoSave(query=True, enable=True)
        },{ "name":"topWaveform",
            "command":"commandsMod.topWaveform(onOff)",
            "default":True
        },{ "name":"playbackAllViews",
            "command":"onOff = 'all' if onOff else 'active'; cmds.playbackOptions(view=onOff)",
            "default":True
        },{ "name":"displayAffected",
            "command":"cmds.displayAffected(onOff)",
            "default":False
        },{ "name":"undoQueue",
            "command":"if onOff: cmds.undoInfo( state=True, infinity=False, length=300)",
            "default":True
        },{ "name":"scrubbingUndo",
            "command":"commandsMod.scrubbingUndo(onOff)",
            "default":True
        },{ "name":"zoomTowardsCenter",
            "command":"cmds.dollyCtx('dollyContext', edit=True, dollyTowardsCenter=onOff)",
            "default":cmds.dollyCtx('dollyContext', query=True, dollyTowardsCenter=True)
        },{ "name":"cycleCheck",
            "command":"cmds.cycleCheck(evaluation=onOff)",
            "default":cmds.cycleCheck(query=True, evaluation=True)
        }]    





class GeneralTools_Gui(uiMod.BaseSubUI):
        
    def createLayout(self):     
       
        mainLayout = cmds.rowLayout(numberOfColumns=6, parent=self.parentLayout)
        
        #manipulator orientation
        #cmds.iconTextButton("manipOrientButton", style='textOnly',  label='-', h=self.hb, annotation="Selected objects", command=updateManipOrient)  
        #launchManipOrient()
        
        self.autoSmartSnapKeys       = AutoSmartSnapKeys()
        self.selectionCounter        = SelectionCounter()
          
        #selection        
        cmds.iconTextButton("selectionCounterButton", style='textOnly', font="smallPlainLabelFont", label='0', h=self.hb, annotation="Selected objects")  
        cmds.popupMenu("selectionCounterButtonMenu", button=1, postMenuCommand=self.selectionCounter.populateMenu)      
        
        #animation crash recovery
        cmds.image("animationCrashRecoveryLed", w=14, h=14, annotation="Test")  
                
        #menu
        cmds.iconTextButton(style='iconOnly',   w=self.wb, h=self.hb, image= uiMod.getImagePath("aTools"), highlightImage= uiMod.getImagePath("aTools copy"), annotation="aTools Menu")
        self.popUpaToolsMenu()
         
        self.update = Update()
        self.update.about = self.about
        self.update.checkUpdates(self, mainLayout)
     
        # set default config and startup scripts
        self.setDefaultConfig() 
        
    # end createLayout
    
    def popUpaToolsMenu(self):
        cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 1), button=1)
        cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 3), button=3)
                    
    def populateaToolsMenu(self, menu, button, *args):
        
        #print menu
        #print button
        #menu = menu[0]
        
        uiMod.clearMenuItems(menu)

        subMenu = cmds.menuItem("animBotMenu", subMenu=True, label='animBot - the new aTools' , tearOff=True, parent=menu)
        cmds.menuItem("shelfButtonMenu",          label="Install animBot",    command=installAnimBot,    parent=subMenu)
        cmds.menuItem(                            label="Watch Launch Video", command=watchLaunchVideo,  parent=subMenu)
        cmds.menuItem(                            label="Join the Community", command=joinTheCommunity,  parent=subMenu)

        cmds.menuItem(divider=True, parent=menu)

        shortPrefs =    PREFS[:4]
        for loopPref in shortPrefs:
            name    = loopPref["name"]
            cmds.menuItem('%sMenu'%name, label=utilMod.toTitle(name), command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=menu)
        
        #ANIMATION CRASH RECOVERY      
        animationCrashRecoveryPref =    PREFS[4]
        cmds.menuItem("animationCrashRecoveryMenu", label='Animation Crash Recovery' , command=lambda *args: self.setPref(animationCrashRecoveryPref["name"]), checkBox=self.getPref(animationCrashRecoveryPref["name"]), parent=menu)
        cmds.menuItem(optionBox=True, command=animationCrashRecovery.optionBoxWindow, parent=menu)
        
        cmds.menuItem(divider=True, parent=menu)
        
        subMenu = cmds.menuItem("prefsMenu", subMenu=True, label='Preferences' , tearOff=True, parent=menu)
        
        self.commandsAndHotkeys      = CommandsAndHotkeys()
        cmds.menuItem(label="Commands and Hotkeys",         command=self.commandsAndHotkeys.openGui, parent=subMenu)
        cmds.menuItem(divider=True, parent=subMenu)
        shortPrefs =    PREFS[5:]
        for loopPref in shortPrefs:
            name    = loopPref["name"]
            cmds.menuItem('%sMenu'%name,            label=utilMod.toTitle(name),        command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=subMenu)
        
        cmds.menuItem(divider=True, parent=subMenu)
        cmds.menuItem("loadDefaultsMenu",          label="Load Defaults",     command=self.loadDefaultPrefs, parent=subMenu)
        
        cmds.menuItem("shelfButtonMenu",          label="Create Toggle on Shelf",           command=shelfButton, parent=menu)
        cmds.menuItem(                            label="Refresh", command=refreshATools, parent=menu)
        cmds.menuItem(                            label="Uninstall", command=self.uninstall, parent=menu)
        cmds.menuItem( divider=True )
        cmds.menuItem(                            label="Help", command=self.help, parent=menu)
        cmds.menuItem(                            label="About", command=self.about, parent=menu)
        

    def setPref(self, pref, init=False, default=False):
        
        for loopPref in PREFS:
            name    = loopPref["name"]
            if pref == name:
                command = loopPref["command"]
                if init: 
                    onOff   = self.getPref(pref)
                elif default:
                    onOff   = self.getDefPref(pref)
                    cmds.menuItem("%sMenu"%name, edit=True, checkBox=onOff)
                    aToolsMod.saveInfoWithUser("userPrefs", name, "", True) 
                else:
                    onOff   = cmds.menuItem("%sMenu"%name, query=True, checkBox=True)
                    aToolsMod.saveInfoWithUser("userPrefs", pref, onOff)
                    
                exec(command)
            
                
    
       
    
    def getPref(self, pref):
        r = aToolsMod.loadInfoWithUser("userPrefs", pref)
        if r == None: 
            default = self.getDefPref(pref)
            r = default 
            
        return r
    
    
    def getDefPref(self, pref):
        for loopPref in PREFS:
            name    = loopPref["name"]
            if pref == name:
                default = loopPref["default"]
                return default
    
    def loadDefaultPrefs(self, *args):
        for loopPref in PREFS:
            name    = loopPref["name"]
            self.setPref(name, False, True)     
        
    def setDefaultConfig(self):
        
        #STATIC PREFS
        # tumble config
        #cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0, autoOrthoConstrain=False, orthoLock=False)
        cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0)
        cmds.dollyCtx( 'dollyContext', edit=True, alternateContext=True, scale=1.0, localDolly=True, centerOfInterestDolly=False)
        #timeline ticks display
        G.playBackSliderPython  = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
        cmds.timeControl(G.playBackSliderPython, edit=True, showKeys="mainChannelBox", showKeysCombined=True, animLayerFilterOptions="active") 
        #tickDrawSpecial Color
        cmds.displayRGBColor('timeSliderTickDrawSpecial',1,1,.4)
        
        
        
        #CUSTOMIZABLE PREFS
        for loopPref in PREFS:
            name    = loopPref["name"]
            self.setPref(name, True)
    
    def uninstall(self, *args):
        message = "Are you sure you want to uninstall aTools?"
        confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='No', cancelButton='No', dismissString='No' )
    
        if confirm == 'Yes':      
        
            from aTools.animTools.animBar import animBarUI; importlib.reload(animBarUI)
            #aToolsPath          = aToolsMod.getaToolsPath(2) 
            aToolsFolder        = aToolsMod.getaToolsPath() 
             
            #if aToolsPath in sys.path: sys.path.remove(aToolsPath)
            
            G.deferredManager.sendToQueue(G.aToolsBar.delWindows, 1, "uninstall_delWindows") 
            G.deferredManager.sendToQueue(lambda *args:setup.install('', True), 1, "uninstall_install")
             
            #delete files
            if os.path.isdir(aToolsFolder): shutil.rmtree(aToolsFolder)
            
            cmds.warning("Uninstall complete! If you want to install aTools in the future, go to %s."%SITE_URL)
    
    
    def help(self, *args):
        webbrowser.open_new_tab(HELP_URL)
        
    def about(self, warnUpdate=None, *args):
        
        winName     = "aboutWindow"
        title       = "About" if not warnUpdate else "aTools has been updated!"
        if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
        window      = cmds.window( winName, title=title)
        form        = cmds.formLayout(numberOfDivisions=100)
        pos         = 10
        minWidth    = 300.0
        
        # Creating Elements
        object = cmds.image(image= uiMod.getImagePath("aTools_big"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        object = cmds.text( label="aTools - Version %s"%VERSION, font="boldLabelFont")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        pos += 30
        object = cmds.text( label="More info:")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"%s\">aTools website</a>"%SITE_URL, hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================
        pos += 15
        object = cmds.text( label="Author: <NAME>")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"http://www.alancamilo.com/\">www.alancamilo.com</a>", hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================        pos += 15
        pos += 15
        object = cmds.text( label="Adaped: <NAME>")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"https://github.com/MKlimenko/\">My GitHub</a>", hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================
        
        
        minWidth    = 550.0
        w           = 210
        object      = cmds.text( label="Do you like aTools?", w=w)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-50), ( object, 'right', 10)] )
        #=========================================        
        object = cmds.iconTextButton(label="Buy Me a Beer!", style="iconAndTextVertical", bgc=(.3,.3,.3), h=45, w=w, command=lambda *args: webbrowser.open_new_tab(DONATE_URL), image= uiMod.getImagePath("beer"), highlightImage= uiMod.getImagePath("beer copy"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-30), ( object, 'right', 10)] )
        object = cmds.text( label="I really appreciate\nthe support!", w=w)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos+20), ( object, 'right', 10)] )
        

        if warnUpdate:
            pos += 40
            object = cmds.text( label="aTools has been updated to version %s. What is new?"%VERSION, align="left")
            cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
            pos -= 20

            # open bit link - next big thing
            #webbrowser.open('http://bit.ly/2inAinL', new=0, autoraise=True)

        #=========================================
        pos += 40
        object = cmds.text( label=WHATISNEW, align="left")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        #=========================================
        
        for x in range(WHATISNEW.count("\n")):
            pos += 13
        pos += 25
        
        
        
        cmds.setParent( '..' )
        cmds.showWindow( window )
        
        whatsNewWidth   = cmds.text(object, query=True, width=True) + 15
        
        wid = whatsNewWidth if whatsNewWidth > minWidth else minWidth 
        cmds.window( winName, edit=True, widthHeight=(wid, pos))
        


    
    

class Update(object):
    
    def __init__(self):
        G.GT_wasUpdated     = G.GT_wasUpdated or None

        
    def tryUpdate(self):
        return True   

    def checkUpdates(self, gui, layout, *args):        

        if self.tryUpdate():     
                        
            if not G.GT_wasUpdated:                
                hasUpdate = self.hasUpdate()
                if hasUpdate != False:
                    cmds.iconTextButton(label="Updating...", style='textOnly', h=gui.hb, parent=layout)
                    cmds.progressBar("aToolsProgressBar", maxValue=100, width=50, parent=layout)
                    
                    if hasUpdate == "offline_update":
                        offlinePath     = aToolsMod.loadInfoWithUser("userPrefs", "offlinePath") 
                        offlineFolder   = offlinePath[0]
                        offlineFilePath = "%s%saTools.zip"%(offlineFolder, os.sep)
                        downloadUrl     = "file:///%s%saTools.zip"%(offlineFolder, os.sep)
                        fileModTime     = os.path.getmtime(offlineFilePath)
                        offline         = [offlineFilePath, fileModTime]
                    else:
                        downloadUrl     = DOWNLOAD_URL
                        offline         = None
            
                    function            = lambda *args:self.updateaTools(downloadUrl, offline)
                    G.deferredManager.sendToQueue(function, 1, "checkUpdates")
                    return                                              

        self.warnUpdate()
        self.warnAnimBot()

    
    def updateaTools(self, downloadUrl, offline=None, *args):
        
        aToolsPath      = aToolsMod.getaToolsPath(2)
        aToolsFolder    = aToolsMod.getaToolsPath()
        oldaToolsFolder = "%saTools.old"%aToolsPath
        tmpZipFile      = "%stmp.zip"%aToolsPath    
            
        #delete temp
        if os.path.isfile(tmpZipFile):     os.remove(tmpZipFile)
        if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)  
        
        output = utilMod.download("aToolsProgressBar", downloadUrl, tmpZipFile)
        
        if not output:
            cmds.warning("Atools - Update failed.")
            return
        
        #rename aTools to old
        if os.path.isdir(aToolsFolder): os.rename(aToolsFolder, oldaToolsFolder)
        #uncompress file
        zfobj = zipfile.ZipFile(tmpZipFile)
        for name in zfobj.namelist():
            uncompressed = zfobj.read(name)        
            # save uncompressed data to disk
            filename  = utilMod.formatPath("%s%s"%(aToolsPath, name))
            
            d         = os.path.dirname(filename)
            
            if not os.path.exists(d): os.makedirs(d)
            if filename.endswith(os.sep): continue
            
            output = open(filename,'wb')
            output.write(uncompressed)
            output.close()
            
        #delete temp
        zfobj.close()
        if os.path.isfile(tmpZipFile):     os.remove(tmpZipFile)
        if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)
        
        setup.install(offline=offline)

        #refresh
        G.GT_wasUpdated = True
        refreshATools()
    
       
    def hasUpdate(self):
        return False
    
    def warnUpdate(self):
            
        if G.GT_wasUpdated:
            G.GT_wasUpdated  = None            
        
        if lastUsedVersion != VERSION:
            aToolsMod.saveInfoWithUser("userPrefs", "lastUsedVersion", VERSION)  
            G.deferredManager.sendToQueue(lambda *args:self.about(warnUpdate=True), 50, "warnUpdate")     

    def warnAnimBot(self):

        try:
            import animBot
        except ImportError:
            pref = aToolsMod.loadInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain")
            if not pref:
                G.deferredManager.sendToQueue(self.atoolsIsRetiring, 50, "warnAnimBot")

    def dontShowAgain(self, onOff):

        aToolsMod.saveInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain", onOff)

    def atoolsIsRetiring(self):

        winName     = "atoolsIsRetiringWindow"
        title       = "aTools is Retiring..."

        if cmds.window(winName, query=True, exists=True):
            cmds.deleteUI(winName)

        window      = cmds.window( winName, title=title)
        form        = cmds.formLayout(numberOfDivisions=100)
        pos         = 10
        minWidth    = 300.0


        # Creating Elements
        object = cmds.text( label="aTools is giving place to animBot, a more robust,\nsmart and intuitive toolset. ", align="left")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 15

        object = cmds.image(image=uiMod.getImagePath("atools_animbot"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 100

        object = cmds.text( label="Three Steps for Full Awesomeness:", fn="boldLabelFont")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.button(label="1) Install animBot and have fun!", bgc=(.3,.3,.3), h=45, w=280, command=installAnimBot)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 45

        object = cmds.button(label="2) Watch the launch video.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 45

        object = cmds.button(label="3) Join the community.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 65

        object = cmds.text(align="left", label="The upgrade will be optional and although aTools\nwon't get feature updates, it will be available forever.\nPlease check the community for information about\nanimBot development progress.")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 80

        object = cmds.text( label="Enjoy!")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.text( label="-Alan")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.checkBox(label="Don't show this again", value=False, changeCommand=self.dontShowAgain)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20


        pos += 10
        cmds.setParent( '..' )
        cmds.showWindow( window )

        cmds.window( winName, edit=True, widthHeight=(minWidth, pos))


class SelectionCounter(object):
    
    def __init__(self):
        self.defaultWidth   = 25
  
    def update(self):
        selectionCount = len(cmds.ls(selection=True))
        
        cmds.iconTextButton("selectionCounterButton", edit=True, label="%s"%selectionCount)
        cmds.iconTextButton("selectionCounterButton", edit=True, w=self.defaultWidth)
            
            
    def populateMenu(self, parent, *args):
        
        menuItens = cmds.popupMenu(parent, query=True, itemArray=True)
        
        if menuItens:
            for loopMenu in menuItens:
                if cmds.menuItem(loopMenu, query=True, exists=True): cmds.deleteUI(loopMenu)
        
        selection = cmds.ls(selection=True)
        selection.sort()
        
        for loopSel in selection:
            cmds.menuItem('%sMenu'%loopSel, label=loopSel, parent=parent, command=lambda x, loopSel=loopSel, *args: self.selectFromMenu(loopSel))
                    
    def selectFromMenu(self, selection):    
        cmds.select(selection)
                
    
    def switch(self, onOff):
           
        utilMod.killScriptJobs("G.selectionCounterScriptJobs")
        cmds.iconTextButton("selectionCounterButton", edit=True, visible=False)
    
        if onOff:
            cmds.iconTextButton("selectionCounterButton", edit=True, visible=True)
            
            G.selectionCounterScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.update )))
        
        self.update()
    


class AutoSmartSnapKeys(object):
    
    def __init__(self):        
        utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")               
    
    def switch(self, onOff):
        
        utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")
                
        if onOff:
            G.autoSmartSnapKeysJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.smartSnapKeys )))
    
    
    def smartSnapKeys(self):
        
        rangeVisible            = cmds.timeControl( G.playBackSliderPython, query=True, rangeVisible=True )
        
        if not rangeVisible: return        
        
        cmds.undoInfo(stateWithoutFlush=False)
        commandsMod.smartSnapKeys()
        cmds.undoInfo(stateWithoutFlush=True)

    
class CommandsAndHotkeys(object): 
    
    def __init__(self):
        
        self.allColors   = ["yellow", "green", "blue", "purple", "red", "orange", "gray"] 
        self.colorValues = {"yellow":(1,0.97,0.4), 
                            "green" :(0.44,1,0.53), 
                            "blue"  :(0.28,0.6,1), 
                            "purple":(0.640,0.215,0.995), 
                            "red"   :(1,0.4,0.4), 
                            "orange":(1,0.6,0.4), 
                            "gray"  :(0.5,0.5,0.5)}   

        self.reassignCommandsAtStartup()

    def openGui(self, *args):
        
        winName     = "commandsWindow"
        height      = 26
        commands    = []
        names       = [] 
        hotkeysDict = [[]]
        allHotkeys  = hotkeys.getHotkeys()
        totalItems  = sum(len(x) for x in allHotkeys)
        itemsCount  = 0
        aB          = 0
        totalColums = 2
        
        for n, loopHotkey in enumerate(allHotkeys):  
            if itemsCount > (totalItems/totalColums) * (aB+1): 
                aB += 1
                hotkeysDict.append([])        
            itemsCount += len(loopHotkey)
            for loopItem in loopHotkey:
                hotkeysDict[aB].append(loopItem)
                hotkeysDict[aB][-1]["colorValue"] = self.colorValues[self.allColors[n]]
                
        if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
        
        window          = cmds.window( winName, title = "Commands and Hotkeys")    
        mainLayout      = cmds.columnLayout(adjustableColumn=True)
        columnsLayout   = cmds.rowColumnLayout(numberOfColumns=totalColums)
        
        for loopColumn in range(totalColums):
        
            parent = cmds.rowColumnLayout(numberOfColumns=7, columnSpacing=([2,5], [3,3], [4,3], [5,1], [6,5], [7,5]), parent=columnsLayout)
              
            cmds.text(label='Command', h=height)
            cmds.text(label='Ctl', h=height)
            cmds.text(label='Alt', h=height)
            cmds.text(label='Key', h=height)
            cmds.text(label='', h=height)
            cmds.text(label='Set Hotkey', h=height)
            cmds.text(label='Assigned to', align="left", h=height)
        
            for loopIndex, loopCommand in enumerate(hotkeysDict[loopColumn]):  
                
                          
                command = loopCommand["command"]
                name    = loopCommand["name"] 
                key     = loopCommand["hotkey"]
                alt     = loopCommand["alt"]
                ctl     = loopCommand["ctl"]  
                toolTip = loopCommand["toolTip"]  
                color   = loopCommand["colorValue"]
                
                hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name) 
                if hotkeyData != None: 
                    key     = hotkeyData[0]
                    alt     = hotkeyData[1]
                    ctl     = hotkeyData[2]
                
                cmds.button("command%s"%name, label=utilMod.toTitle(name), command=command, annotation=toolTip, h=height, bgc=color, parent=parent)
                cmds.checkBox('ctl%s'%name, label='', value=ctl, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.checkBox('alt%s'%name, label='', value=alt, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.scrollField('key%s'%name, w=80, text=key, keyPressCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.button(label=" ", h=height, parent=parent)
                self.popSpecialHotkeys(name)
                cmds.button(label='>',           command=lambda x, name=name, command=command, *args: self.setHotkey(self.getHotkeyDict([name], [command])), h=height, parent=parent)
                cmds.text("query%s"%name, align="left", label=self.hotkeyCheck(key, ctl, alt), font="plainLabelFont", h=height, parent=parent)
                
                commands.append(command)
                names.append(name)
                
                #cmds.button(label="Set Hotkey", command=lambda *args: getHotkeyDict([name], [command], [key], [alt], [ctl], [cmd]))
                self.updateHotkeyCheck(name)        
                
                
        #cmds.rowLayout(numberOfColumns=2, columnAttach=([1, 'left', 0],[2, 'right', 0]), adjustableColumn=2)
        cmds.button(label="Load Defaults", command=lambda *args: self.loadHotkeys(True), parent=mainLayout)
        cmds.button(label="Set All Hotkeys", command=lambda *args: self.setHotkey(self.getHotkeyDict(names, commands)), parent=mainLayout)
        
        cmds.showWindow( window )
    
    def loadHotkeys(self, defaults=False):
        
        allHotkeys  = hotkeys.getHotkeys()
        hotkeysDict = []
        
        for n, loopHotkey in enumerate(allHotkeys):  
            for loopItem in loopHotkey:
                hotkeysDict.append(loopItem)
                
        
        for loopIndex, loopCommand in enumerate(hotkeysDict):  
            
                      
            command = loopCommand["command"]
            name    = loopCommand["name"] 
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]  
            toolTip = loopCommand["toolTip"]  
            
            if not defaults:
                hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name) 
                if hotkeyData != None: 
                    key     = hotkeyData[0]
                    alt     = hotkeyData[1]
                    ctl     = hotkeyData[2]
            
            
            cmds.checkBox('ctl%s'%name, edit=True, value=ctl)
            cmds.checkBox('alt%s'%name, edit=True, value=alt)
            cmds.scrollField('key%s'%name, edit=True, text=key)
            
            self.updateHotkeyCheck(name)
    
    
    def popSpecialHotkeys(self, name):
        cmds.popupMenu("popSpecialHotkeysMenu", button=1)
        
        
        for loopKey in KEYSLIST:
            if loopKey == "":
                cmds.menuItem( divider=True )
            else:
                cmds.menuItem       ("menu%s"%loopKey, label=str(loopKey), command=lambda x, name=name, loopKey=loopKey, *args: self.typeSpecialKey(name, loopKey))    
        
    
        cmds.setParent( '..', menu=True )
    
    def typeSpecialKey(self, name, text):
        cmds.scrollField("key%s"%name, edit=True, text=text)
        self.updateHotkeyCheck(name)
    
    def getHotkeyDict(self, names, commands):
        
        hotkeysDict = []
        
        for n, loopName in enumerate(names):
            command = commands[n]
            name    = loopName
            key     = cmds.scrollField("key%s"%loopName, query=True, text=True)
            alt     = cmds.checkBox("alt%s"%loopName, query=True, value=True)
            ctl     = cmds.checkBox("ctl%s"%loopName, query=True, value=True)
    
            if len(key) > 1: key = key[0]
            
            hotkeysDict.append({"name":"%s"%name,
                                "command":"%s"%command,
                                "hotkey":"%s"%key,
                                "alt":alt,
                                "ctl":ctl
                                })
            
            
        return hotkeysDict
    
    
    def setHotkey(self, hotkeyDict):
        message = "Are you sure?\n\n"    
        
        #format message
        for loopIndex, loopCommand in enumerate(hotkeyDict):
                
            command = loopCommand["command"]
            name    = loopCommand["name"]
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]
            q       = cmds.text("query%s"%name, query=True, label=True)
            
            commandKeys = ""
            if ctl: commandKeys += "Ctl + "
            if alt: commandKeys += "Alt + "
            
            message += "%s (%s%s)"%(name, commandKeys, key)
            if q != "": message += " is assigned to: %s"%q
            message += "\n"
            
        confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
    
        if confirm == 'Yes':    
            for loopIndex, loopCommand in enumerate(hotkeyDict):
                
                command = loopCommand["command"]
                name    = loopCommand["name"]
                key     = loopCommand["hotkey"]
                alt     = loopCommand["alt"]
                ctl     = loopCommand["ctl"]       
                
                cmds.nameCommand(name, command='python("%s");'%command, annotation=name)
                cmds.hotkey(k=key, alt=alt, ctl=ctl, name=name)
    
                aToolsMod.saveInfoWithUser("hotkeys", name, [key, alt, ctl]) 
                self.updateHotkeyCheck(name)
                
            cmds.savePrefs( hotkeys=True )
           
    
    def hotkeyCheck(self, key, ctl, alt):
        if key != "":
            q = cmds.hotkey(key, query=True, alt=alt, ctl=ctl, name=True)
            if q != None and "NameCom" in q: q = q[7:]
            return q
        else:
            return ""
    

    def updateHotkeyCheck(self, name):

        function = lambda name=name, *args: self.delayedUpdateHotkeyCheck(name)
        G.deferredManager.sendToQueue(function, 1, "updateHotkeyCheck")
                
        
    def delayedUpdateHotkeyCheck(self, name): 
        command = cmds.button("command%s"%name, query=True, label=True)
        key     = cmds.scrollField("key%s"%name, query=True, text=True)
        ctl     = cmds.checkBox("ctl%s"%name, query=True, value=True)
        alt     = cmds.checkBox("alt%s"%name, query=True, value=True) 
        
        
        if len(key) > 1 and key not in KEYSLIST: 
            key = key[0]
            cmds.scrollField("key%s"%name, edit=True, text=key)
        
        
        label = self.hotkeyCheck(key, ctl, alt)
        
        
        if label == None: label = ""
        
        cmds.text("query%s"%name, edit=True, label=label, font="plainLabelFont")    
        if utilMod.toTitle(label) != command: cmds.text("query%s"%name, edit=True, font="boldLabelFont")
        
    
    def reassignCommandsAtStartup(self):
        
        allHotkeys  = hotkeys.getHotkeys()
        hotkeysDict = []
        
        for n, loopHotkey in enumerate(allHotkeys):  
            for loopItem in loopHotkey:
                hotkeysDict.append(loopItem)
                
        
        for loopCommand in hotkeysDict:  
                      
            command = loopCommand["command"]
            name    = loopCommand["name"] 
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]  
            #toolTip = loopCommand["toolTip"]  
            
            label   = self.hotkeyCheck(key, ctl, alt)        
                       
            if label == name: cmds.nameCommand(name, command='python("%s");'%command, annotation=name)



    
    
        

#=========================================================



def shelfButton(*args):
    topShelf        = mel.eval('$nul = $gShelfTopLevel')
    currentShelf    = cmds.tabLayout(topShelf, q=1, st=1)
    command         = "from aTools.animTools.animBar import animBarUI; animBarUI.show('toggle')"
    
    cmds.shelfButton(parent=currentShelf, annotation='aTools ON/OFF', imageOverlayLabel="aTools", i='commandButton.xpm', command=command)
          

def refreshATools(*args): 
    G.deferredManager.sendToQueue(refreshAToolsDef, 1, "refreshATools")
    

def refreshAToolsDef():
    from aTools.animTools.animBar import animBarUI;     importlib.reload(animBarUI)
    animBarUI.show('refresh')


    # animBot

def installAnimBot(*args):
    installFileFolder = os.path.normpath(os.path.dirname(os.path.dirname(__file__)))
    installFilePath = os.path.join(installFileFolder, "animBot Drag'n Drop Install.mel").replace("\\", "/") # fix for windows
    mel.eval("source \"%s\";"%installFilePath)

def watchLaunchVideo(*args):
    webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao")

def joinTheCommunity(*args):
    webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439")

'''
========================================================================================================================
Author: <NAME>
www.alancamilo.com
Modified: <NAME>

Requirements: aTools Package

------------------------------------------------------------------------------------------------------------------------
To install aTools, please follow the instructions in the file how_to_install.txt

------------------------------------------------------------------------------------------------------------------------
To unistall aTools, go to menu (the last button on the right), Uninstall

========================================================================================================================
''' 

import importlib
import sys
import urllib.request, urllib.error, urllib.parse
import shutil
import zipfile
import os
import webbrowser

from maya import cmds
from maya import mel
from maya import OpenMaya
from maya import OpenMayaAnim
from aTools.generalTools.aToolsGlobals import aToolsGlobals as G
from aTools.commonMods      import uiMod
from aTools.commonMods      import utilMod
from aTools.commonMods      import animMod
from aTools.commonMods      import commandsMod
from aTools.commonMods      import aToolsMod
from aTools                 import setup
from aTools.generalTools    import hotkeys;                     importlib.reload(hotkeys)
from aTools.generalTools    import tumbleOnObjects;             importlib.reload(tumbleOnObjects)
from aTools.animTools       import animationCrashRecovery;      importlib.reload(animationCrashRecovery)
from aTools.animTools       import framePlaybackRange;          importlib.reload(framePlaybackRange)
from aTools.animTools       import jumpToSelectedKey;           importlib.reload(jumpToSelectedKey)
    


animationCrashRecovery  = animationCrashRecovery.AnimationCrashRecovery()
tumbleOnObjects         = tumbleOnObjects.TumbleOnObjects()

versionInfoPath     = "%sversion_info.txt"%aToolsMod.getaToolsPath(inScriptsFolder=False)
versionInfoContents = utilMod.readFile(versionInfoPath)
VERSION             = versionInfoContents[0].split(" ")[-1].replace("\n", "")
WHATISNEW           = "".join(versionInfoContents[1:])
KEYSLIST            = ["Up", "Down", "Left", "Right", "", "Page_Up", "Page_Down", "Home", "End", "Insert", "", "Return", "Space", "", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"]
SITE_URL            = "http://camiloalan.wix.com/atoolswebsite"
ATOOLS_FOLDER       = "http://www.trickorscript.com/aTools/"
UPDATE_URL          = "%slatest_version.txt"%ATOOLS_FOLDER
DOWNLOAD_URL        = "%saTools.zip"%ATOOLS_FOLDER
lastUsedVersion     = aToolsMod.loadInfoWithUser("userPrefs", "lastUsedVersion")
HELP_URL            = "http://camiloalan.wix.com/atoolswebsite#!help/cjg9"
DONATE_URL          = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5RQLT89A239K6"




PREFS = [{  "name":"tumbleOnObjects",
            "command":"tumbleOnObjects.switch(onOff)",
            "default":True
        },{ "name":"autoFramePlaybackRange",
            "command":"framePlaybackRange.toggleframePlaybackRange(onOff)",
            "default":False
        },{ "name":"autoJumpToSelectedKey",
            "command":"jumpToSelectedKey.togglejumpToSelectedKey(onOff)",
            "default":False
        },{ "name":"autoSmartSnapKeys",
            "command":"self.autoSmartSnapKeys.switch(onOff)",
            "default":False
        },{ "name":"animationCrashRecovery",
            "command":"animationCrashRecovery.switch(onOff)",
            "default":True
        },{ "name":"selectionCounter",
            "command":"self.selectionCounter.switch(onOff)",
            "default":True
        },{ "name":"autoSave",
            "command":"cmds.autoSave(enable=onOff)",
            "default":cmds.autoSave(query=True, enable=True)
        },{ "name":"topWaveform",
            "command":"commandsMod.topWaveform(onOff)",
            "default":True
        },{ "name":"playbackAllViews",
            "command":"onOff = 'all' if onOff else 'active'; cmds.playbackOptions(view=onOff)",
            "default":True
        },{ "name":"displayAffected",
            "command":"cmds.displayAffected(onOff)",
            "default":False
        },{ "name":"undoQueue",
            "command":"if onOff: cmds.undoInfo( state=True, infinity=False, length=300)",
            "default":True
        },{ "name":"scrubbingUndo",
            "command":"commandsMod.scrubbingUndo(onOff)",
            "default":True
        },{ "name":"zoomTowardsCenter",
            "command":"cmds.dollyCtx('dollyContext', edit=True, dollyTowardsCenter=onOff)",
            "default":cmds.dollyCtx('dollyContext', query=True, dollyTowardsCenter=True)
        },{ "name":"cycleCheck",
            "command":"cmds.cycleCheck(evaluation=onOff)",
            "default":cmds.cycleCheck(query=True, evaluation=True)
        }]    





class GeneralTools_Gui(uiMod.BaseSubUI):
        
    def createLayout(self):     
       
        mainLayout = cmds.rowLayout(numberOfColumns=6, parent=self.parentLayout)
        
        #manipulator orientation
        #cmds.iconTextButton("manipOrientButton", style='textOnly',  label='-', h=self.hb, annotation="Selected objects", command=updateManipOrient)  
        #launchManipOrient()
        
        self.autoSmartSnapKeys       = AutoSmartSnapKeys()
        self.selectionCounter        = SelectionCounter()
          
        #selection        
        cmds.iconTextButton("selectionCounterButton", style='textOnly', font="smallPlainLabelFont", label='0', h=self.hb, annotation="Selected objects")  
        cmds.popupMenu("selectionCounterButtonMenu", button=1, postMenuCommand=self.selectionCounter.populateMenu)      
        
        #animation crash recovery
        cmds.image("animationCrashRecoveryLed", w=14, h=14, annotation="Test")  
                
        #menu
        cmds.iconTextButton(style='iconOnly',   w=self.wb, h=self.hb, image= uiMod.getImagePath("aTools"), highlightImage= uiMod.getImagePath("aTools copy"), annotation="aTools Menu")
        self.popUpaToolsMenu()
         
        self.update = Update()
        self.update.about = self.about
        self.update.checkUpdates(self, mainLayout)
     
        # set default config and startup scripts
        self.setDefaultConfig() 
        
    # end createLayout
    
    def popUpaToolsMenu(self):
        cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 1), button=1)
        cmds.popupMenu(postMenuCommand=lambda *args:self.populateaToolsMenu(args[0], 3), button=3)
                    
    def populateaToolsMenu(self, menu, button, *args):
        
        #print menu
        #print button
        #menu = menu[0]
        
        uiMod.clearMenuItems(menu)

        subMenu = cmds.menuItem("animBotMenu", subMenu=True, label='animBot - the new aTools' , tearOff=True, parent=menu)
        cmds.menuItem("shelfButtonMenu",          label="Install animBot",    command=installAnimBot,    parent=subMenu)
        cmds.menuItem(                            label="Watch Launch Video", command=watchLaunchVideo,  parent=subMenu)
        cmds.menuItem(                            label="Join the Community", command=joinTheCommunity,  parent=subMenu)

        cmds.menuItem(divider=True, parent=menu)

        shortPrefs =    PREFS[:4]
        for loopPref in shortPrefs:
            name    = loopPref["name"]
            cmds.menuItem('%sMenu'%name, label=utilMod.toTitle(name), command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=menu)
        
        #ANIMATION CRASH RECOVERY      
        animationCrashRecoveryPref =    PREFS[4]
        cmds.menuItem("animationCrashRecoveryMenu", label='Animation Crash Recovery' , command=lambda *args: self.setPref(animationCrashRecoveryPref["name"]), checkBox=self.getPref(animationCrashRecoveryPref["name"]), parent=menu)
        cmds.menuItem(optionBox=True, command=animationCrashRecovery.optionBoxWindow, parent=menu)
        
        cmds.menuItem(divider=True, parent=menu)
        
        subMenu = cmds.menuItem("prefsMenu", subMenu=True, label='Preferences' , tearOff=True, parent=menu)
        
        self.commandsAndHotkeys      = CommandsAndHotkeys()
        cmds.menuItem(label="Commands and Hotkeys",         command=self.commandsAndHotkeys.openGui, parent=subMenu)
        cmds.menuItem(divider=True, parent=subMenu)
        shortPrefs =    PREFS[5:]
        for loopPref in shortPrefs:
            name    = loopPref["name"]
            cmds.menuItem('%sMenu'%name,            label=utilMod.toTitle(name),        command=lambda x, name=name, *args: self.setPref(name), checkBox=self.getPref(name), parent=subMenu)
        
        cmds.menuItem(divider=True, parent=subMenu)
        cmds.menuItem("loadDefaultsMenu",          label="Load Defaults",     command=self.loadDefaultPrefs, parent=subMenu)
        
        cmds.menuItem("shelfButtonMenu",          label="Create Toggle on Shelf",           command=shelfButton, parent=menu)
        cmds.menuItem(                            label="Refresh", command=refreshATools, parent=menu)
        cmds.menuItem(                            label="Uninstall", command=self.uninstall, parent=menu)
        cmds.menuItem( divider=True )
        cmds.menuItem(                            label="Help", command=self.help, parent=menu)
        cmds.menuItem(                            label="About", command=self.about, parent=menu)
        

    def setPref(self, pref, init=False, default=False):
        
        for loopPref in PREFS:
            name    = loopPref["name"]
            if pref == name:
                command = loopPref["command"]
                if init: 
                    onOff   = self.getPref(pref)
                elif default:
                    onOff   = self.getDefPref(pref)
                    cmds.menuItem("%sMenu"%name, edit=True, checkBox=onOff)
                    aToolsMod.saveInfoWithUser("userPrefs", name, "", True) 
                else:
                    onOff   = cmds.menuItem("%sMenu"%name, query=True, checkBox=True)
                    aToolsMod.saveInfoWithUser("userPrefs", pref, onOff)
                    
                exec(command)
            
                
    
       
    
    def getPref(self, pref):
        r = aToolsMod.loadInfoWithUser("userPrefs", pref)
        if r == None: 
            default = self.getDefPref(pref)
            r = default 
            
        return r
    
    
    def getDefPref(self, pref):
        for loopPref in PREFS:
            name    = loopPref["name"]
            if pref == name:
                default = loopPref["default"]
                return default
    
    def loadDefaultPrefs(self, *args):
        for loopPref in PREFS:
            name    = loopPref["name"]
            self.setPref(name, False, True)     
        
    def setDefaultConfig(self):
        
        #STATIC PREFS
        # tumble config
        #cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0, autoOrthoConstrain=False, orthoLock=False)
        cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0)
        cmds.dollyCtx( 'dollyContext', edit=True, alternateContext=True, scale=1.0, localDolly=True, centerOfInterestDolly=False)
        #timeline ticks display
        G.playBackSliderPython  = G.playBackSliderPython or mel.eval('$aTools_playBackSliderPython=$gPlayBackSlider')
        cmds.timeControl(G.playBackSliderPython, edit=True, showKeys="mainChannelBox", showKeysCombined=True, animLayerFilterOptions="active") 
        #tickDrawSpecial Color
        cmds.displayRGBColor('timeSliderTickDrawSpecial',1,1,.4)
        
        
        
        #CUSTOMIZABLE PREFS
        for loopPref in PREFS:
            name    = loopPref["name"]
            self.setPref(name, True)
    
    def uninstall(self, *args):
        message = "Are you sure you want to uninstall aTools?"
        confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='No', cancelButton='No', dismissString='No' )
    
        if confirm == 'Yes':      
        
            from aTools.animTools.animBar import animBarUI; importlib.reload(animBarUI)
            #aToolsPath          = aToolsMod.getaToolsPath(2) 
            aToolsFolder        = aToolsMod.getaToolsPath() 
             
            #if aToolsPath in sys.path: sys.path.remove(aToolsPath)
            
            G.deferredManager.sendToQueue(G.aToolsBar.delWindows, 1, "uninstall_delWindows") 
            G.deferredManager.sendToQueue(lambda *args:setup.install('', True), 1, "uninstall_install")
             
            #delete files
            if os.path.isdir(aToolsFolder): shutil.rmtree(aToolsFolder)
            
            cmds.warning("Uninstall complete! If you want to install aTools in the future, go to %s."%SITE_URL)
    
    
    def help(self, *args):
        webbrowser.open_new_tab(HELP_URL)
        
    def about(self, warnUpdate=None, *args):
        
        winName     = "aboutWindow"
        title       = "About" if not warnUpdate else "aTools has been updated!"
        if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
        window      = cmds.window( winName, title=title)
        form        = cmds.formLayout(numberOfDivisions=100)
        pos         = 10
        minWidth    = 300.0
        
        # Creating Elements
        object = cmds.image(image= uiMod.getImagePath("aTools_big"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        object = cmds.text( label="aTools - Version %s"%VERSION, font="boldLabelFont")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        pos += 30
        object = cmds.text( label="More info:")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"%s\">aTools website</a>"%SITE_URL, hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================
        pos += 15
        object = cmds.text( label="Author: <NAME>")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"http://www.alancamilo.com/\">www.alancamilo.com</a>", hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================        pos += 15
        pos += 15
        object = cmds.text( label="Adaped: <NAME>")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 80)] )
        #=========================================
        object = cmds.text( label="<a href=\"https://github.com/MKlimenko/\">My GitHub</a>", hyperlink=True)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 220)] )
        #=========================================
        
        
        minWidth    = 550.0
        w           = 210
        object      = cmds.text( label="Do you like aTools?", w=w)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-50), ( object, 'right', 10)] )
        #=========================================        
        object = cmds.iconTextButton(label="Buy Me a Beer!", style="iconAndTextVertical", bgc=(.3,.3,.3), h=45, w=w, command=lambda *args: webbrowser.open_new_tab(DONATE_URL), image= uiMod.getImagePath("beer"), highlightImage= uiMod.getImagePath("beer copy"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos-30), ( object, 'right', 10)] )
        object = cmds.text( label="I really appreciate\nthe support!", w=w)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos+20), ( object, 'right', 10)] )
        

        if warnUpdate:
            pos += 40
            object = cmds.text( label="aTools has been updated to version %s. What is new?"%VERSION, align="left")
            cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
            pos -= 20

            # open bit link - next big thing
            #webbrowser.open('http://bit.ly/2inAinL', new=0, autoraise=True)

        #=========================================
        pos += 40
        object = cmds.text( label=WHATISNEW, align="left")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        #=========================================
        
        for x in range(WHATISNEW.count("\n")):
            pos += 13
        pos += 25
        
        
        
        cmds.setParent( '..' )
        cmds.showWindow( window )
        
        whatsNewWidth   = cmds.text(object, query=True, width=True) + 15
        
        wid = whatsNewWidth if whatsNewWidth > minWidth else minWidth 
        cmds.window( winName, edit=True, widthHeight=(wid, pos))
        


    
    

class Update(object):
    
    def __init__(self):
        G.GT_wasUpdated     = G.GT_wasUpdated or None

        
    def tryUpdate(self):
        return True   

    def checkUpdates(self, gui, layout, *args):        

        if self.tryUpdate():     
                        
            if not G.GT_wasUpdated:                
                hasUpdate = self.hasUpdate()
                if hasUpdate != False:
                    cmds.iconTextButton(label="Updating...", style='textOnly', h=gui.hb, parent=layout)
                    cmds.progressBar("aToolsProgressBar", maxValue=100, width=50, parent=layout)
                    
                    if hasUpdate == "offline_update":
                        offlinePath     = aToolsMod.loadInfoWithUser("userPrefs", "offlinePath") 
                        offlineFolder   = offlinePath[0]
                        offlineFilePath = "%s%saTools.zip"%(offlineFolder, os.sep)
                        downloadUrl     = "file:///%s%saTools.zip"%(offlineFolder, os.sep)
                        fileModTime     = os.path.getmtime(offlineFilePath)
                        offline         = [offlineFilePath, fileModTime]
                    else:
                        downloadUrl     = DOWNLOAD_URL
                        offline         = None
            
                    function            = lambda *args:self.updateaTools(downloadUrl, offline)
                    G.deferredManager.sendToQueue(function, 1, "checkUpdates")
                    return                                              

        self.warnUpdate()
        self.warnAnimBot()

    
    def updateaTools(self, downloadUrl, offline=None, *args):
        
        aToolsPath      = aToolsMod.getaToolsPath(2)
        aToolsFolder    = aToolsMod.getaToolsPath()
        oldaToolsFolder = "%saTools.old"%aToolsPath
        tmpZipFile      = "%stmp.zip"%aToolsPath    
            
        #delete temp
        if os.path.isfile(tmpZipFile):     os.remove(tmpZipFile)
        if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)  
        
        output = utilMod.download("aToolsProgressBar", downloadUrl, tmpZipFile)
        
        if not output:
            cmds.warning("Atools - Update failed.")
            return
        
        #rename aTools to old
        if os.path.isdir(aToolsFolder): os.rename(aToolsFolder, oldaToolsFolder)
        #uncompress file
        zfobj = zipfile.ZipFile(tmpZipFile)
        for name in zfobj.namelist():
            uncompressed = zfobj.read(name)        
            # save uncompressed data to disk
            filename  = utilMod.formatPath("%s%s"%(aToolsPath, name))
            
            d         = os.path.dirname(filename)
            
            if not os.path.exists(d): os.makedirs(d)
            if filename.endswith(os.sep): continue
            
            output = open(filename,'wb')
            output.write(uncompressed)
            output.close()
            
        #delete temp
        zfobj.close()
        if os.path.isfile(tmpZipFile):     os.remove(tmpZipFile)
        if os.path.isdir(oldaToolsFolder): shutil.rmtree(oldaToolsFolder)
        
        setup.install(offline=offline)

        #refresh
        G.GT_wasUpdated = True
        refreshATools()
    
       
    def hasUpdate(self):
        return False
    
    def warnUpdate(self):
            
        if G.GT_wasUpdated:
            G.GT_wasUpdated  = None            
        
        if lastUsedVersion != VERSION:
            aToolsMod.saveInfoWithUser("userPrefs", "lastUsedVersion", VERSION)  
            G.deferredManager.sendToQueue(lambda *args:self.about(warnUpdate=True), 50, "warnUpdate")     

    def warnAnimBot(self):

        try:
            import animBot
        except ImportError:
            pref = aToolsMod.loadInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain")
            if not pref:
                G.deferredManager.sendToQueue(self.atoolsIsRetiring, 50, "warnAnimBot")

    def dontShowAgain(self, onOff):

        aToolsMod.saveInfoWithUser("userPrefs", "dontShowAnimBotWarningAgain", onOff)

    def atoolsIsRetiring(self):

        winName     = "atoolsIsRetiringWindow"
        title       = "aTools is Retiring..."

        if cmds.window(winName, query=True, exists=True):
            cmds.deleteUI(winName)

        window      = cmds.window( winName, title=title)
        form        = cmds.formLayout(numberOfDivisions=100)
        pos         = 10
        minWidth    = 300.0


        # Creating Elements
        object = cmds.text( label="aTools is giving place to animBot, a more robust,\nsmart and intuitive toolset. ", align="left")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 15

        object = cmds.image(image=uiMod.getImagePath("atools_animbot"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 100

        object = cmds.text( label="Three Steps for Full Awesomeness:", fn="boldLabelFont")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.button(label="1) Install animBot and have fun!", bgc=(.3,.3,.3), h=45, w=280, command=installAnimBot)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 45

        object = cmds.button(label="2) Watch the launch video.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 45

        object = cmds.button(label="3) Join the community.", bgc=(.3,.3,.3), h=45, w=280, command=lambda *args:webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439"))
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 65

        object = cmds.text(align="left", label="The upgrade will be optional and although aTools\nwon't get feature updates, it will be available forever.\nPlease check the community for information about\nanimBot development progress.")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 80

        object = cmds.text( label="Enjoy!")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.text( label="-Alan")
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20

        object = cmds.checkBox(label="Don't show this again", value=False, changeCommand=self.dontShowAgain)
        cmds.formLayout( form, edit=True, attachForm=[( object, 'top', pos), ( object, 'left', 10)] )
        pos += 20


        pos += 10
        cmds.setParent( '..' )
        cmds.showWindow( window )

        cmds.window( winName, edit=True, widthHeight=(minWidth, pos))


class SelectionCounter(object):
    
    def __init__(self):
        self.defaultWidth   = 25
  
    def update(self):
        selectionCount = len(cmds.ls(selection=True))
        
        cmds.iconTextButton("selectionCounterButton", edit=True, label="%s"%selectionCount)
        cmds.iconTextButton("selectionCounterButton", edit=True, w=self.defaultWidth)
            
            
    def populateMenu(self, parent, *args):
        
        menuItens = cmds.popupMenu(parent, query=True, itemArray=True)
        
        if menuItens:
            for loopMenu in menuItens:
                if cmds.menuItem(loopMenu, query=True, exists=True): cmds.deleteUI(loopMenu)
        
        selection = cmds.ls(selection=True)
        selection.sort()
        
        for loopSel in selection:
            cmds.menuItem('%sMenu'%loopSel, label=loopSel, parent=parent, command=lambda x, loopSel=loopSel, *args: self.selectFromMenu(loopSel))
                    
    def selectFromMenu(self, selection):    
        cmds.select(selection)
                
    
    def switch(self, onOff):
           
        utilMod.killScriptJobs("G.selectionCounterScriptJobs")
        cmds.iconTextButton("selectionCounterButton", edit=True, visible=False)
    
        if onOff:
            cmds.iconTextButton("selectionCounterButton", edit=True, visible=True)
            
            G.selectionCounterScriptJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('SelectionChanged', self.update )))
        
        self.update()
    


class AutoSmartSnapKeys(object):
    
    def __init__(self):        
        utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")               
    
    def switch(self, onOff):
        
        utilMod.killScriptJobs("G.autoSmartSnapKeysJobs")
                
        if onOff:
            G.autoSmartSnapKeysJobs.append(cmds.scriptJob(runOnce = False, killWithScene = False, event =('timeChanged', self.smartSnapKeys )))
    
    
    def smartSnapKeys(self):
        
        rangeVisible            = cmds.timeControl( G.playBackSliderPython, query=True, rangeVisible=True )
        
        if not rangeVisible: return        
        
        cmds.undoInfo(stateWithoutFlush=False)
        commandsMod.smartSnapKeys()
        cmds.undoInfo(stateWithoutFlush=True)

    
class CommandsAndHotkeys(object): 
    
    def __init__(self):
        
        self.allColors   = ["yellow", "green", "blue", "purple", "red", "orange", "gray"] 
        self.colorValues = {"yellow":(1,0.97,0.4), 
                            "green" :(0.44,1,0.53), 
                            "blue"  :(0.28,0.6,1), 
                            "purple":(0.640,0.215,0.995), 
                            "red"   :(1,0.4,0.4), 
                            "orange":(1,0.6,0.4), 
                            "gray"  :(0.5,0.5,0.5)}   

        self.reassignCommandsAtStartup()

    def openGui(self, *args):
        
        winName     = "commandsWindow"
        height      = 26
        commands    = []
        names       = [] 
        hotkeysDict = [[]]
        allHotkeys  = hotkeys.getHotkeys()
        totalItems  = sum(len(x) for x in allHotkeys)
        itemsCount  = 0
        aB          = 0
        totalColums = 2
        
        for n, loopHotkey in enumerate(allHotkeys):  
            if itemsCount > (totalItems/totalColums) * (aB+1): 
                aB += 1
                hotkeysDict.append([])        
            itemsCount += len(loopHotkey)
            for loopItem in loopHotkey:
                hotkeysDict[aB].append(loopItem)
                hotkeysDict[aB][-1]["colorValue"] = self.colorValues[self.allColors[n]]
                
        if cmds.window(winName, query=True, exists=True): cmds.deleteUI(winName)
        
        window          = cmds.window( winName, title = "Commands and Hotkeys")    
        mainLayout      = cmds.columnLayout(adjustableColumn=True)
        columnsLayout   = cmds.rowColumnLayout(numberOfColumns=totalColums)
        
        for loopColumn in range(totalColums):
        
            parent = cmds.rowColumnLayout(numberOfColumns=7, columnSpacing=([2,5], [3,3], [4,3], [5,1], [6,5], [7,5]), parent=columnsLayout)
              
            cmds.text(label='Command', h=height)
            cmds.text(label='Ctl', h=height)
            cmds.text(label='Alt', h=height)
            cmds.text(label='Key', h=height)
            cmds.text(label='', h=height)
            cmds.text(label='Set Hotkey', h=height)
            cmds.text(label='Assigned to', align="left", h=height)
        
            for loopIndex, loopCommand in enumerate(hotkeysDict[loopColumn]):  
                
                          
                command = loopCommand["command"]
                name    = loopCommand["name"] 
                key     = loopCommand["hotkey"]
                alt     = loopCommand["alt"]
                ctl     = loopCommand["ctl"]  
                toolTip = loopCommand["toolTip"]  
                color   = loopCommand["colorValue"]
                
                hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name) 
                if hotkeyData != None: 
                    key     = hotkeyData[0]
                    alt     = hotkeyData[1]
                    ctl     = hotkeyData[2]
                
                cmds.button("command%s"%name, label=utilMod.toTitle(name), command=command, annotation=toolTip, h=height, bgc=color, parent=parent)
                cmds.checkBox('ctl%s'%name, label='', value=ctl, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.checkBox('alt%s'%name, label='', value=alt, changeCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.scrollField('key%s'%name, w=80, text=key, keyPressCommand=lambda x, name=name, *args:self.updateHotkeyCheck(name), h=height, parent=parent)
                cmds.button(label=" ", h=height, parent=parent)
                self.popSpecialHotkeys(name)
                cmds.button(label='>',           command=lambda x, name=name, command=command, *args: self.setHotkey(self.getHotkeyDict([name], [command])), h=height, parent=parent)
                cmds.text("query%s"%name, align="left", label=self.hotkeyCheck(key, ctl, alt), font="plainLabelFont", h=height, parent=parent)
                
                commands.append(command)
                names.append(name)
                
                #cmds.button(label="Set Hotkey", command=lambda *args: getHotkeyDict([name], [command], [key], [alt], [ctl], [cmd]))
                self.updateHotkeyCheck(name)        
                
                
        #cmds.rowLayout(numberOfColumns=2, columnAttach=([1, 'left', 0],[2, 'right', 0]), adjustableColumn=2)
        cmds.button(label="Load Defaults", command=lambda *args: self.loadHotkeys(True), parent=mainLayout)
        cmds.button(label="Set All Hotkeys", command=lambda *args: self.setHotkey(self.getHotkeyDict(names, commands)), parent=mainLayout)
        
        cmds.showWindow( window )
    
    def loadHotkeys(self, defaults=False):
        
        allHotkeys  = hotkeys.getHotkeys()
        hotkeysDict = []
        
        for n, loopHotkey in enumerate(allHotkeys):  
            for loopItem in loopHotkey:
                hotkeysDict.append(loopItem)
                
        
        for loopIndex, loopCommand in enumerate(hotkeysDict):  
            
                      
            command = loopCommand["command"]
            name    = loopCommand["name"] 
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]  
            toolTip = loopCommand["toolTip"]  
            
            if not defaults:
                hotkeyData = aToolsMod.loadInfoWithUser("hotkeys", name) 
                if hotkeyData != None: 
                    key     = hotkeyData[0]
                    alt     = hotkeyData[1]
                    ctl     = hotkeyData[2]
            
            
            cmds.checkBox('ctl%s'%name, edit=True, value=ctl)
            cmds.checkBox('alt%s'%name, edit=True, value=alt)
            cmds.scrollField('key%s'%name, edit=True, text=key)
            
            self.updateHotkeyCheck(name)
    
    
    def popSpecialHotkeys(self, name):
        cmds.popupMenu("popSpecialHotkeysMenu", button=1)
        
        
        for loopKey in KEYSLIST:
            if loopKey == "":
                cmds.menuItem( divider=True )
            else:
                cmds.menuItem       ("menu%s"%loopKey, label=str(loopKey), command=lambda x, name=name, loopKey=loopKey, *args: self.typeSpecialKey(name, loopKey))    
        
    
        cmds.setParent( '..', menu=True )
    
    def typeSpecialKey(self, name, text):
        cmds.scrollField("key%s"%name, edit=True, text=text)
        self.updateHotkeyCheck(name)
    
    def getHotkeyDict(self, names, commands):
        
        hotkeysDict = []
        
        for n, loopName in enumerate(names):
            command = commands[n]
            name    = loopName
            key     = cmds.scrollField("key%s"%loopName, query=True, text=True)
            alt     = cmds.checkBox("alt%s"%loopName, query=True, value=True)
            ctl     = cmds.checkBox("ctl%s"%loopName, query=True, value=True)
    
            if len(key) > 1: key = key[0]
            
            hotkeysDict.append({"name":"%s"%name,
                                "command":"%s"%command,
                                "hotkey":"%s"%key,
                                "alt":alt,
                                "ctl":ctl
                                })
            
            
        return hotkeysDict
    
    
    def setHotkey(self, hotkeyDict):
        message = "Are you sure?\n\n"    
        
        #format message
        for loopIndex, loopCommand in enumerate(hotkeyDict):
                
            command = loopCommand["command"]
            name    = loopCommand["name"]
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]
            q       = cmds.text("query%s"%name, query=True, label=True)
            
            commandKeys = ""
            if ctl: commandKeys += "Ctl + "
            if alt: commandKeys += "Alt + "
            
            message += "%s (%s%s)"%(name, commandKeys, key)
            if q != "": message += " is assigned to: %s"%q
            message += "\n"
            
        confirm = cmds.confirmDialog( title='Confirm', message=message, button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
    
        if confirm == 'Yes':    
            for loopIndex, loopCommand in enumerate(hotkeyDict):
                
                command = loopCommand["command"]
                name    = loopCommand["name"]
                key     = loopCommand["hotkey"]
                alt     = loopCommand["alt"]
                ctl     = loopCommand["ctl"]       
                
                cmds.nameCommand(name, command='python("%s");'%command, annotation=name)
                cmds.hotkey(k=key, alt=alt, ctl=ctl, name=name)
    
                aToolsMod.saveInfoWithUser("hotkeys", name, [key, alt, ctl]) 
                self.updateHotkeyCheck(name)
                
            cmds.savePrefs( hotkeys=True )
           
    
    def hotkeyCheck(self, key, ctl, alt):
        if key != "":
            q = cmds.hotkey(key, query=True, alt=alt, ctl=ctl, name=True)
            if q != None and "NameCom" in q: q = q[7:]
            return q
        else:
            return ""
    

    def updateHotkeyCheck(self, name):

        function = lambda name=name, *args: self.delayedUpdateHotkeyCheck(name)
        G.deferredManager.sendToQueue(function, 1, "updateHotkeyCheck")
                
        
    def delayedUpdateHotkeyCheck(self, name): 
        command = cmds.button("command%s"%name, query=True, label=True)
        key     = cmds.scrollField("key%s"%name, query=True, text=True)
        ctl     = cmds.checkBox("ctl%s"%name, query=True, value=True)
        alt     = cmds.checkBox("alt%s"%name, query=True, value=True) 
        
        
        if len(key) > 1 and key not in KEYSLIST: 
            key = key[0]
            cmds.scrollField("key%s"%name, edit=True, text=key)
        
        
        label = self.hotkeyCheck(key, ctl, alt)
        
        
        if label == None: label = ""
        
        cmds.text("query%s"%name, edit=True, label=label, font="plainLabelFont")    
        if utilMod.toTitle(label) != command: cmds.text("query%s"%name, edit=True, font="boldLabelFont")
        
    
    def reassignCommandsAtStartup(self):
        
        allHotkeys  = hotkeys.getHotkeys()
        hotkeysDict = []
        
        for n, loopHotkey in enumerate(allHotkeys):  
            for loopItem in loopHotkey:
                hotkeysDict.append(loopItem)
                
        
        for loopCommand in hotkeysDict:  
                      
            command = loopCommand["command"]
            name    = loopCommand["name"] 
            key     = loopCommand["hotkey"]
            alt     = loopCommand["alt"]
            ctl     = loopCommand["ctl"]  
            #toolTip = loopCommand["toolTip"]  
            
            label   = self.hotkeyCheck(key, ctl, alt)        
                       
            if label == name: cmds.nameCommand(name, command='python("%s");'%command, annotation=name)



    
    
        

#=========================================================



def shelfButton(*args):
    topShelf        = mel.eval('$nul = $gShelfTopLevel')
    currentShelf    = cmds.tabLayout(topShelf, q=1, st=1)
    command         = "from aTools.animTools.animBar import animBarUI; animBarUI.show('toggle')"
    
    cmds.shelfButton(parent=currentShelf, annotation='aTools ON/OFF', imageOverlayLabel="aTools", i='commandButton.xpm', command=command)
          

def refreshATools(*args): 
    G.deferredManager.sendToQueue(refreshAToolsDef, 1, "refreshATools")
    

def refreshAToolsDef():
    from aTools.animTools.animBar import animBarUI;     importlib.reload(animBarUI)
    animBarUI.show('refresh')


    # animBot

def installAnimBot(*args):
    installFileFolder = os.path.normpath(os.path.dirname(os.path.dirname(__file__)))
    installFilePath = os.path.join(installFileFolder, "animBot Drag'n Drop Install.mel").replace("\\", "/") # fix for windows
    mel.eval("source \"%s\";"%installFilePath)

def watchLaunchVideo(*args):
    webbrowser.open_new_tab("https://youtu.be/DezLHqXrDao")

def joinTheCommunity(*args):
    webbrowser.open_new_tab("https://www.facebook.com/groups/1589262684419439")
======================================================================================================================== Author: <NAME> www.alancamilo.com Modified: <NAME>  Requirements: aTools Package  ------------------------------------------------------------------------------------------------------------------------ To install aTools, please follow the instructions in the file how_to_install.txt  ------------------------------------------------------------------------------------------------------------------------ To unistall aTools, go to menu (the last button on the right), Uninstall  ======================================================================================================================== #!help/cjg9" #manipulator orientation #cmds.iconTextButton("manipOrientButton", style='textOnly',  label='-', h=self.hb, annotation="Selected objects", command=updateManipOrient) #launchManipOrient() #selection #animation crash recovery #menu # set default config and startup scripts # end createLayout #print menu #print button #menu = menu[0] #ANIMATION CRASH RECOVERY #STATIC PREFS # tumble config #cmds.tumbleCtx( 'tumbleContext', edit=True, alternateContext=True, tumbleScale=1.0, localTumble=0, autoOrthoConstrain=False, orthoLock=False) #timeline ticks display #tickDrawSpecial Color #CUSTOMIZABLE PREFS #aToolsPath          = aToolsMod.getaToolsPath(2) #if aToolsPath in sys.path: sys.path.remove(aToolsPath) #delete files # Creating Elements #========================================= #========================================= #========================================= #========================================= #=========================================        pos += 15 #========================================= #========================================= #========================================= # open bit link - next big thing #webbrowser.open('http://bit.ly/2inAinL', new=0, autoraise=True) #========================================= #========================================= #delete temp #rename aTools to old #uncompress file # save uncompressed data to disk #delete temp #refresh # Creating Elements #cmds.button(label="Set Hotkey", command=lambda *args: getHotkeyDict([name], [command], [key], [alt], [ctl], [cmd])) #cmds.rowLayout(numberOfColumns=2, columnAttach=([1, 'left', 0],[2, 'right', 0]), adjustableColumn=2) #format message #toolTip = loopCommand["toolTip"] #========================================================= # animBot # fix for windows