diff --git a/materials_library_vx/__init__.py b/materials_library_vx/__init__.py
index 01157def6da8069169cf70ef0aecb6fc19a206e2..17e3934e64860bd63820b0c01803984f6568c36d 100644
--- a/materials_library_vx/__init__.py
+++ b/materials_library_vx/__init__.py
@@ -19,16 +19,16 @@
 # #####END GPL LICENSE BLOCK #####
 
 bl_info = {
-  "name": "Material Library",
-  "author": "Mackraken (mackraken2023@hotmail.com)",
-  "version": (0, 5, 8),
-  "blender": (2, 80, 0),
-  "location": "Properties > Material",
-  "description": "Material Library VX",
-  "warning": "",
-  "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/matlib-vx",
-  "tracker_url": "",
-  "category": "Material"}
+    "name": "Material Library",
+    "author": "Mackraken (mackraken2023@hotmail.com)",
+    "version": (0, 5, 8),
+    "blender": (2, 80, 0),
+    "location": "Properties > Material",
+    "description": "Material Library VX",
+    "warning": "",
+    "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/matlib-vx",
+    "tracker_url": "",
+    "category": "Material"}
 
 
 import bpy
@@ -52,100 +52,100 @@ dev = False
 matlib_path = os.path.dirname(__file__)
 
 if dev:
-  print (30*"-")
-  matlib_path = r"D:\Blender Foundation\Blender\2.72\scripts\addons\matlib"
+    print (30*"-")
+    matlib_path = r"D:\Blender Foundation\Blender\2.72\scripts\addons\matlib"
 
 ##debug print variables
 def dd(*args, dodir=False):
-  if dev:
-    if dodir:
-      print(dir(*args))
-    print(*args)
+    if dev:
+        if dodir:
+            print(dir(*args))
+        print(*args)
 
 #Regular Functions
 def winpath(path):
-  return path.replace("\\", "\\\\")
+    return path.replace("\\", "\\\\")
 
 def update_search_index(self, context):
-  search = self.search
-  for i, it in enumerate(self.materials):
-    if it.name==search:
-      self.mat_index = i
-      break
+    search = self.search
+    for i, it in enumerate(self.materials):
+        if it.name==search:
+            self.mat_index = i
+            break
 
 def check_path(path):
-  #isabs sometimes returns true on relpaths
-  if path and os.path.exists(path) and os.path.isfile(path) and os.path.isabs(path):
-    try:
-      if bpy.data.filepath and bpy.path.relpath(bpy.data.filepath) == bpy.path.relpath(path):
-        return False
-    except:
-      pass
-      #paths are on different drives. No problem then
-    return True
-  return False
+    #isabs sometimes returns true on relpaths
+    if path and os.path.exists(path) and os.path.isfile(path) and os.path.isabs(path):
+        try:
+            if bpy.data.filepath and bpy.path.relpath(bpy.data.filepath) == bpy.path.relpath(path):
+                return False
+        except:
+            pass
+            #paths are on different drives. No problem then
+        return True
+    return False
 
 def update_lib_index(self, context):
-  self.load_library()
+    self.load_library()
 
 def update_cat_index(self, context):
-  dd("cat index:", self.current_category, self.filter)
+    dd("cat index:", self.current_category, self.filter)
 
-  if self.filter:
-    self.filter = True
+    if self.filter:
+        self.filter = True
 
 
 def update_filter(self, context):
 
-  dd("filter:", self.filter, self.cat_index, self.current_category)
-#  index = self.cat_index
-#
-#  if self.filter:
-#    cat = self.current_category
-#  else:
-#    cat = ""
-#
-#  self.current_library.filter = cat
-  self.update_list()
+    dd("filter:", self.filter, self.cat_index, self.current_category)
+    #  index = self.cat_index
+    #
+    #  if self.filter:
+    #    cat = self.current_category
+    #  else:
+    #    cat = ""
+    #
+    #  self.current_library.filter = cat
+    self.update_list()
 
 def check_index(collection, index):
-  count = len(collection)
-  return count>0 and index<count and index>=0
+    count = len(collection)
+    return count>0 and index<count and index>=0
 
 def send_command(cmd, output="sendmat.py"):
     bin = winpath(bpy.app.binary_path)
-    scriptpath = winpath(os.path.join(matlib_path, output))
+    scriptpath = winpath(os.path.join(bpy.app.tempdir, output))
 
     with open(scriptpath, "w") as f:
-      f.write(cmd)
+        f.write(cmd)
 
     import subprocess
 
     if output == "createlib.py":
-      code = subprocess.call([bin, "-b", "-P", scriptpath])
+        code = subprocess.call([bin, "-b", "-P", scriptpath])
     else:
-      libpath = winpath(bpy.context.scene.matlib.current_library.path)
-      code = subprocess.call([bin, "-b", libpath, "-P", scriptpath])
+        libpath = winpath(bpy.context.scene.matlib.current_library.path)
+        code = subprocess.call([bin, "-b", libpath, "-P", scriptpath])
 
     #code returns 0 if ok, 1 if not
     return abs(code-1)
 
 def list_materials(path, sort=False):
-  list = []
-  with bpy.data.libraries.load(path) as (data_from, data_to):
-    for mat in data_from.materials:
-      list.append(mat)
+    list = []
+    with bpy.data.libraries.load(path) as (data_from, data_to):
+        for mat in data_from.materials:
+            list.append(mat)
 
-  if sort: list = sorted(list)
-  return list
+    if sort: list = sorted(list)
+    return list
 
 #category properties (none atm)
 class EmptyGroup(PropertyGroup):
-  pass
+    pass
 # bpy.utils.register_class(EmptyGroup)
 
 class matlibMaterials(PropertyGroup):
-  category: StringProperty()
+    category: StringProperty()
 # bpy.utils.register_class(matlibMaterials)
 
 #bpy.types.Scene.matlib_categories = CollectionProperty(type=EmptyGroup)
@@ -153,17 +153,17 @@ class matlibMaterials(PropertyGroup):
 ### CATEGORIES
 class Categories():
 
-  #cats = bpy.context.scene.matlib.categories
+    #cats = bpy.context.scene.matlib.categories
 
-  def __init__(self, cats):
-    self.cats = cats
+    def __init__(self, cats):
+        self.cats = cats
 
-  def save(self):
-    scn = bpy.context.scene
-    cats = set([cat.name for cat in self.cats])
-    libpath = bpy.context.scene.matlib.current_library.path
+    def save(self):
+        scn = bpy.context.scene
+        cats = set([cat.name for cat in self.cats])
+        libpath = bpy.context.scene.matlib.current_library.path
 
-    cmd = """
+        cmd = """
 print(30*"+")
 import bpy
 if not hasattr(bpy.context.scene, "matlib_categories"):
@@ -175,19 +175,19 @@ cats = bpy.context.scene.matlib_categories
 for cat in cats:
   cats.remove(0)
 """
-    for cat in cats:
-      cmd += """
+        for cat in cats:
+            cmd += """
 cat = cats.add()
 cat.name = "%s" """ % cat.capitalize()
-    cmd +='''
+        cmd +='''
 bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % winpath(libpath)
 
-    return send_command(cmd, "save_categories.py")
+        return send_command(cmd, "save_categories.py")
 
-  def read(self, pull=True):
-    #mandar a imprimir el listado
-    catfile = winpath(os.path.join(matlib_path, "categories.txt"))
-    cmd = """
+    def read(self, pull=True):
+        #mandar a imprimir el listado
+        catfile = winpath(os.path.join(matlib_path, "categories.txt"))
+        cmd = """
 import bpy, json
 class EmptyProps(bpy.types.PropertyGroup):
   pass
@@ -203,61 +203,61 @@ for cat in bpy.context.scene.matlib_categories:
 with open("%s", "w") as f:
   f.write(json.dumps(cats, sort_keys=True, indent=4))
 """ % catfile
-    if pull: send_command(cmd)
+        if pull: send_command(cmd)
 
-    #leer el fichero
-    with open(catfile, "r") as f:
-      cats = json.loads(f.read())
+        #leer el fichero
+        with open(catfile, "r") as f:
+            cats = json.loads(f.read())
 
-    dd(cats)
+        dd(cats)
 
-#    #refrescar categorias
-#    for cat in self.cats:
-#      self.cats.remove(0)
-#
-#    for cat in cats:
-#      item = self.cats.add()
-#      item.name = cat
-#
-    return cats
-
-  def view(self):
-    for cat in self.cats:
-      dd(cat.name)
-
-  def add(self, name):
-    if name and name not in [item.name for item in self.cats]:
-      name = name.strip().capitalize()
-      item = self.cats.add()
-      item.name = name
-      if self.save():
-        dd(name, "added")
-        return True
-    else:
-      dd("duplicated?")
+        #    #refrescar categorias
+        #    for cat in self.cats:
+        #      self.cats.remove(0)
+        #
+        #    for cat in cats:
+        #      item = self.cats.add()
+        #      item.name = cat
+        #
+        return cats
+
+    def view(self):
+        for cat in self.cats:
+            dd(cat.name)
+
+    def add(self, name):
+        if name and name not in [item.name for item in self.cats]:
+            name = name.strip().capitalize()
+            item = self.cats.add()
+            item.name = name
+            if self.save():
+                dd(name, "added")
+                return True
+        else:
+            dd("duplicated?")
 
-  def remove(self, index):
-    self.cats.remove(index)
-    self.save()
+    def remove(self, index):
+        self.cats.remove(index)
+        self.save()
 
 class Library():
 
-  def __init__(self, matlib_path, name):
-    self.name = name
-    self.path = os.path.join(matlib_path, name)
-#  @property
-#  def default(self):
-#    return self.name == default_library
+    def __init__(self, matlib_path, name):
+        self.name = name
+        self.path = os.path.join(matlib_path, name)
+    #  @property
+    #  def default(self):
+    #    return self.name == default_library
 
-  @property
-  def shortname(self):
-#    if self.default:
-#      return "Default Library"
-    return bpy.path.display_name(self.name).title()
+    @property
+    def shortname(self):
+        #    if self.default:
+        #      return "Default Library"
+        return bpy.path.display_name(self.name).title()
 
 
-  def __repr__(self):
-    return str(type(self).__name__) + "('" + self.name + "')"
+    def __repr__(self):
+        return str(type(self).__name__) + "('" + self.name + "')"
 
 #bpy.utils.register_class(Library)
 
@@ -280,184 +280,184 @@ libraries = []
 ### MATLIB CLASS
 class matlibProperties(PropertyGroup):
 
-  #MATLIB PROPERTIES
-
-  #libraries are read from the xml
-  lib_index: IntProperty(min = -1, default = 2, update=update_lib_index)
-  all_materials: CollectionProperty(type = matlibMaterials)
-  materials: CollectionProperty(type = matlibMaterials)
-  mat_index: IntProperty(min = -1, default = -1)
-  categories: CollectionProperty(type = EmptyGroup)
-  cat_index: IntProperty(min = -1, default = -1, update=update_cat_index)
-  search: StringProperty(name="Search", description="Find By Name", update=update_search_index)
-
-  #MATLIB OPTIONS
-  #link: import material linked
-  #force import:
-  #   if disable it wont import a material if its present in the scene,(avoid duplicates)
-  #   instead it will apply the scene material rather than importing the same one from the library
-  #filter: enable or disable category filter
-  #last selected: store the last selected object to regain focus when apply a material.
-  #hide_search: Hides Search Field
-  link: BoolProperty(name = "Linked", description="Link the material", default = False)
-  force_import: BoolProperty(name = "Force Import", description="Use Scene Materials by default", default = False)
-  filter: BoolProperty(name = "Filter",description="Filter Categories", default = False, update=update_filter)
-  show_prefs: BoolProperty(name = "show_prefs", description="Preferences", default = False)
-  last_selected: StringProperty(name="Last Selected")
-  hide_search: BoolProperty(name="Hide Search", description="Use Blender Search Only")
-  #import_file = StringProperty("Import File", subtype="FILE_PATH")
-  #path = os.path.dirname(path)
-  #Development only
-
-  @property
-  def libraries(self):
-    global libraries
-    return libraries
-
-  @property
-  def current_library(self):
-    if check_index(libraries, self.lib_index):
-      return libraries[self.lib_index]
-  @property
-  def active_material(self):
-    if check_index(self.materials, self.mat_index):
-      return self.materials[self.mat_index]
-
-  def reload(self):
-    dd("loading libraries")
-
-    if self.current_library:
-      self.load_library()
-    elif self.lib_index == -1 and len(libraries):
-      self.lib_index = 0
-
-
-  def add_library(self, path, setEnabled = False):
-    #sanitize path
-    ext = os.path.extsep + "blend"
-    if not path.endswith(ext):
-      path += ext
-
-    if check_path(path):
-#      if path == default_library:
-#        return 'ERROR', "Cannot add default library."
-      #if path in [lib.path for lib in self.libraries]:
-      return 'ERROR', "Library already exists."
-    else:
-      dd("Can't find " + path)
-      #create file
-      cmd = '''
+    #MATLIB PROPERTIES
+
+    #libraries are read from the xml
+    lib_index: IntProperty(min = -1, default = 2, update=update_lib_index)
+    all_materials: CollectionProperty(type = matlibMaterials)
+    materials: CollectionProperty(type = matlibMaterials)
+    mat_index: IntProperty(min = -1, default = -1)
+    categories: CollectionProperty(type = EmptyGroup)
+    cat_index: IntProperty(min = -1, default = -1, update=update_cat_index)
+    search: StringProperty(name="Search", description="Find By Name", update=update_search_index)
+
+    #MATLIB OPTIONS
+    #link: import material linked
+    #force import:
+    #   if disable it wont import a material if its present in the scene,(avoid duplicates)
+    #   instead it will apply the scene material rather than importing the same one from the library
+    #filter: enable or disable category filter
+    #last selected: store the last selected object to regain focus when apply a material.
+    #hide_search: Hides Search Field
+    link: BoolProperty(name = "Linked", description="Link the material", default = False)
+    force_import: BoolProperty(name = "Force Import", description="Use Scene Materials by default", default = False)
+    filter: BoolProperty(name = "Filter",description="Filter Categories", default = False, update=update_filter)
+    show_prefs: BoolProperty(name = "show_prefs", description="Preferences", default = False)
+    last_selected: StringProperty(name="Last Selected")
+    hide_search: BoolProperty(name="Hide Search", description="Use Blender Search Only")
+    #import_file = StringProperty("Import File", subtype="FILE_PATH")
+    #path = os.path.dirname(path)
+    #Development only
+
+    @property
+    def libraries(self):
+        global libraries
+        return libraries
+
+    @property
+    def current_library(self):
+        if check_index(libraries, self.lib_index):
+            return libraries[self.lib_index]
+
+    @property
+    def active_material(self):
+        if check_index(self.materials, self.mat_index):
+            return self.materials[self.mat_index]
+
+    def reload(self):
+        dd("loading libraries")
+        if self.current_library:
+            self.load_library()
+        elif self.lib_index == -1 and len(libraries):
+            self.lib_index = 0
+
+
+    def add_library(self, path, setEnabled = False):
+        #sanitize path
+        ext = os.path.extsep + "blend"
+        if not path.endswith(ext):
+            path += ext
+
+        if check_path(path):
+            #      if path == default_library:
+            #        return 'ERROR', "Cannot add default library."
+            #if path in [lib.path for lib in self.libraries]:
+            return 'ERROR', "Library already exists."
+        else:
+            dd("Can't find " + path)
+            #create file
+            cmd = '''
 import bpy
 bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % winpath(path)
-      if not (send_command(cmd, "createlib.py")):
-        return 'ERROR', "There was an error creating the file. Make sure you run Blender with admin rights."
+            if not (send_command(cmd, "createlib.py")):
+                return 'ERROR', "There was an error creating the file. Make sure you run Blender with admin rights."
 
-      #self.libraries = sorted(self.libraries, key=lambda lib: sortlibs(lib))
-      dd("adding library", path)
-      global libraries
-      libraries = get_libraries()
-      return "INFO", "Library added"
+            #self.libraries = sorted(self.libraries, key=lambda lib: sortlibs(lib))
+            dd("adding library", path)
+            global libraries
+            libraries = get_libraries()
+            return "INFO", "Library added"
 
-  def load_library(self):
-    self.empty_list(True)
-    if not self.current_library:
-      return 'ERROR', "Library not found!."
+    def load_library(self):
+        self.empty_list(True)
+        if not self.current_library:
+            return 'ERROR', "Library not found!."
 
-    path = self.current_library.path
+        path = self.current_library.path
 
-    dd("loading library", self.lib_index, path)
+        dd("loading library", self.lib_index, path)
 
-    if check_path(path):
-      self.filter = False
-      self.cat_index = -1
+        if check_path(path):
+            self.filter = False
+            self.cat_index = -1
 
-      categories = Categories(self.categories)
-      self.cats = categories.read(True)
-      self.load_categories()
+            categories = Categories(self.categories)
+            self.cats = categories.read(True)
+            self.load_categories()
 
-      for mat in self.all_materials:
-        self.all_materials.remove(0)
+            for mat in self.all_materials:
+                self.all_materials.remove(0)
 
-      for mat in list_materials(self.current_library.path, True):
-        item = self.all_materials.add()
-        item.name = mat
-        for cat in self.cats:
-          if mat in cat[1]:
-            item.category = cat[0]
-            break
+            for mat in list_materials(self.current_library.path, True):
+                item = self.all_materials.add()
+                item.name = mat
+                for cat in self.cats:
+                    if mat in cat[1]:
+                        item.category = cat[0]
+                        break
 
-      self.update_list()
-    else:
-      return 'ERROR', "Library not found!."
-
-  def update_list(self):
-    ### THIS HAS TO SORT
-    self.empty_list()
-    if self.current_library:
-      current_category = self.current_category
-      #sorteditems = sorted(self.all_materials, key=lambda x: x.name)
-      for mat in self.all_materials:
-        #print(current_category, mat.category)
-        if not self.filter or (self.filter and mat.category == current_category) or current_category == "":
-          item = self.materials.add()
-          item.name = mat.name
-          item.category = mat.category
-
-  def empty_list(self, cats = False):
-    #self.mat_index = -1
-    for it in self.materials:
-      self.materials.remove(0)
-
-    if cats:
-      for c in self.categories:
-        self.categories.remove(0)
-
-  ### CATEGORIES
-  @property
-  def current_category(self):
-    #print(self.mat_index)
-    if check_index(self.categories, self.cat_index):
-      return self.categories[self.cat_index].name
-    return ""
-
-  def load_categories(self):
-
-    for c in self.categories:
-      self.categories.remove(0)
-
-    for c in self.cats:
-      cat = self.categories.add()
-      cat.name = c[0]
-
-  def add_category(self, name):
-    if name:
-      name = name.strip().title()
-      dd("add category", name)
-      categories = Categories(self.categories)
-
-      categories.add(name)
-
-#      if lib:
-#        cat = xml.find("category", name, lib, create = True)
-#        self.load_categories()
-#      else:
-#        return 'ERROR', "Library not found"
-  def remove_category(self):
-    dd("removing category", self.current_category)
-    categories = Categories(self.categories)
-    categories.remove(self.cat_index)
-
-  def set_category(self):
-    mat = self.active_material
-    #dd(lib, mat, self.current_category)
-    if mat:
-      #set mat to category
-      if self.cat_index>-1:
-        dd(self.current_category)
-        cat = self.current_category
-        if cat == self.all_materials[self.mat_index].category:
-          return
-        cmd = """
+            self.update_list()
+        else:
+            return 'ERROR', "Library not found!."
+
+    def update_list(self):
+        ### THIS HAS TO SORT
+        self.empty_list()
+        if self.current_library:
+            current_category = self.current_category
+            #sorteditems = sorted(self.all_materials, key=lambda x: x.name)
+            for mat in self.all_materials:
+                #print(current_category, mat.category)
+                if not self.filter or (self.filter and mat.category == current_category) or current_category == "":
+                    item = self.materials.add()
+                    item.name = mat.name
+                    item.category = mat.category
+
+    def empty_list(self, cats = False):
+        #self.mat_index = -1
+        for it in self.materials:
+            self.materials.remove(0)
+
+        if cats:
+            for c in self.categories:
+                self.categories.remove(0)
+
+    ### CATEGORIES
+    @property
+    def current_category(self):
+        #print(self.mat_index)
+        if check_index(self.categories, self.cat_index):
+            return self.categories[self.cat_index].name
+        return ""
+
+    def load_categories(self):
+
+        for c in self.categories:
+            self.categories.remove(0)
+
+        for c in self.cats:
+            cat = self.categories.add()
+            cat.name = c[0]
+
+    def add_category(self, name):
+        if name:
+            name = name.strip().title()
+            dd("add category", name)
+            categories = Categories(self.categories)
+
+            categories.add(name)
+
+    #      if lib:
+    #        cat = xml.find("category", name, lib, create = True)
+    #        self.load_categories()
+    #      else:
+    #        return 'ERROR', "Library not found"
+    def remove_category(self):
+        dd("removing category", self.current_category)
+        categories = Categories(self.categories)
+        categories.remove(self.cat_index)
+
+    def set_category(self):
+        mat = self.active_material
+        #dd(lib, mat, self.current_category)
+        if mat:
+            #set mat to category
+            if self.cat_index>-1:
+                dd(self.current_category)
+                cat = self.current_category
+                if cat == self.all_materials[self.mat_index].category:
+                    return
+                cmd = """
 import bpy
 try:
   mat = bpy.data.materials['%s']
@@ -467,205 +467,205 @@ if mat:
   mat['category'] = "%s"
   bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)
 """ % (mat.name, cat, winpath(self.current_library.path))
-        if send_command(cmd):
-          self.all_materials[self.mat_index].category = cat
-          mat.category = cat
+                if send_command(cmd):
+                    self.all_materials[self.mat_index].category = cat
+                    mat.category = cat
+                else:
+                    return "WARNING", "There was an error."
+
+            #        catnode = xml.find("category", self.current_category, lib, True)
+            #        matnode = xml.find("material", mat.name, lib)
+            #        if matnode:
+            #          catnode.appendChild(matnode)
+            #        else:
+            #          matnode = xml.find("material", mat.name, catnode, True)
+            #        xml.save()
+            #        mat.category = cat
+            #        self.current_library.materials[self.mat_index].category = cat
+            #remove mat from any category
+            else:
+                mat.category = ""
+                self.all_materials[self.mat_index].category = ""
         else:
-          return "WARNING", "There was an error."
-
-#        catnode = xml.find("category", self.current_category, lib, True)
-#        matnode = xml.find("material", mat.name, lib)
-#        if matnode:
-#          catnode.appendChild(matnode)
-#        else:
-#          matnode = xml.find("material", mat.name, catnode, True)
-#        xml.save()
-#        mat.category = cat
-#        self.current_library.materials[self.mat_index].category = cat
-      #remove mat from any category
-      else:
-        mat.category = ""
-        self.all_materials[self.mat_index].category = ""
-    else:
-      return "WARNING", "Select a material"
+            return "WARNING", "Select a material"
 
-  def get_material(self, name, link=False):
-    with bpy.data.libraries.load(self.current_library.path, link, False) as (data_from, data_to):
-      data_to.materials = [name]
-    if link:
-      print(name + " linked.")
-    else:
-      print(name + " appended.")
-
-  def apply(self, context, preview=False):
-    name = self.active_material.name
-    if not name: return "WARNING", "Select a material from the list."
-
-    linked = self.link or preview
-    force =  self.force_import or linked
-
-    objects = []
-    active = context.object
-    dummy = self.get_dummy(context)
-
-    #setup objects
-    if preview:
-      if context.mode == "EDIT_MESH":
-        return "WARNING", "Can't preview on EDIT MODE"
-      if dummy!= active:
-        self.last_selected = context.object.name
-      context.view_layer.objects.active = dummy
-      objects.append(dummy)
-    #apply
-    else:
-      objects = [obj for obj in context.selected_objects if hasattr(obj.data, "materials")]
-
-    if not objects:
-      return "INFO", "Please select an object"
-
-    if dummy == context.object and not preview:
-      if (len(objects)==1 and dummy.select):
-        return "ERROR", "Apply is disabled for the Material Preview Object"
-      try:
-        last = context.scene.objects[self.last_selected]
-        if last in context.selected_objects:
-          context.view_layer.objects.active = last
+    def get_material(self, name, link=False):
+        with bpy.data.libraries.load(self.current_library.path, link, False) as (data_from, data_to):
+            data_to.materials = [name]
+        if link:
+            print(name + " linked.")
         else:
-          self.last_selected = ""
-      except:
-        context.view_layer.objects.active = None
-    dummy.select_set(False)
-      #objects = context.selected_objects
-
-    material = None
-
-    #mira si hay materiales linkados de la libreria actual
-    for mat in bpy.data.materials:
-      try:
-        samelib = bpy.path.relpath(mat.library.filepath) == bpy.path.relpath(self.current_library.path)
-      except:
-        samelib = False
-
-      if mat.name == name and mat.library and samelib:
-        material = mat
-        dd("encontre linked", name, "no importo nada")
-        break
-
-    if not force:
-      #busca materiales no linkados
-      for mat in bpy.data.materials:
-        if mat.name == name and not mat.library:
-          material = mat
-          dd("encontre no linkado", name, "no importo nada")
-          break
-
-    if not material:
-      #go get it
-      dd("voy a buscarlo")
-      nmats = len(bpy.data.materials)
-
-      self.get_material(name, linked)
-
-      if not self.force_import:
-        try:
-          material = bpy.data.materials[name]
-        except:
-          pass
-
-      if not material:
-        if nmats == len(bpy.data.materials) and not linked:
-          return "ERROR", name + " doesn't exists at library " + str(linked)
+            print(name + " appended.")
+
+    def apply(self, context, preview=False):
+        name = self.active_material.name
+        if not name: return "WARNING", "Select a material from the list."
+
+        linked = self.link or preview
+        force =  self.force_import or linked
+
+        objects = []
+        active = context.object
+        dummy = self.get_dummy(context)
+
+        #setup objects
+        if preview:
+            if context.mode == "EDIT_MESH":
+                return "WARNING", "Can't preview on EDIT MODE"
+            if dummy!= active:
+                self.last_selected = context.object.name
+            context.view_layer.objects.active = dummy
+            objects.append(dummy)
+        #apply
         else:
-          for mat in reversed(bpy.data.materials):
-            if mat.name[0:len(name)] == name:
-              #careful on how blender writes library paths
-              try:
+            objects = [obj for obj in context.selected_objects if hasattr(obj.data, "materials")]
+
+        if not objects:
+            return "INFO", "Please select an object"
+
+        if dummy == context.object and not preview:
+            if (len(objects)==1 and dummy.select):
+                return "ERROR", "Apply is disabled for the Material Preview Object"
+            try:
+                last = context.scene.objects[self.last_selected]
+                if last in context.selected_objects:
+                    context.view_layer.objects.active = last
+                else:
+                    self.last_selected = ""
+            except:
+                context.view_layer.objects.active = None
+        dummy.select_set(False)
+        #objects = context.selected_objects
+
+        material = None
+
+        #mira si hay materiales linkados de la libreria actual
+        for mat in bpy.data.materials:
+            try:
                 samelib = bpy.path.relpath(mat.library.filepath) == bpy.path.relpath(self.current_library.path)
-              except:
+            except:
                 samelib = False
 
-              if linked and mat.library and samelib:
+            if mat.name == name and mat.library and samelib:
                 material = mat
-                dd(name, "importado con link")
+                dd("encontre linked", name, "no importo nada")
                 break
-              else:
-                if not mat.library:
-                  dd(name, "importado sin link")
-                  material = mat
-                  break
-        if material:
-          material.use_fake_user = False
-          material.user_clear()
-
-    print ("Material", material, force)
-
-    #if material:
-    #maybe some test cases doesn't return a material, gotta take care of that
-    #i cannot think of any case like that right now
-    #maybe import linked when the database isnt sync
-    if context.mode == "EDIT_MESH":
-      obj = context.object
-      dd(material)
-      index = -1
-      for i, mat in enumerate(obj.data.materials):
-        if mat == material:
-          index = i
-          break
-
-      if index == -1:
-        obj.data.materials.append(material)
-        index = len(obj.data.materials)-1
-      dd(index)
-      import bmesh
-      bm  = bmesh.from_edit_mesh(obj.data)
-      for f in bm.faces:
-        if f.select:
-          f.material_index = index
 
-    else:
-      for obj in objects:
-        index = obj.active_material_index
-        if index < len(obj.material_slots):
-          obj.material_slots[index].material = None
-          obj.material_slots[index].material = material
+        if not force:
+            #busca materiales no linkados
+            for mat in bpy.data.materials:
+                if mat.name == name and not mat.library:
+                    material = mat
+                    dd("encontre no linkado", name, "no importo nada")
+                    break
+
+        if not material:
+            #go get it
+            dd("voy a buscarlo")
+            nmats = len(bpy.data.materials)
+
+            self.get_material(name, linked)
+
+            if not self.force_import:
+                try:
+                    material = bpy.data.materials[name]
+                except:
+                    pass
+
+            if not material:
+                if nmats == len(bpy.data.materials) and not linked:
+                    return "ERROR", name + " doesn't exists at library " + str(linked)
+                else:
+                    for mat in reversed(bpy.data.materials):
+                        if mat.name[0:len(name)] == name:
+                            #careful on how blender writes library paths
+                            try:
+                                samelib = bpy.path.relpath(mat.library.filepath) == bpy.path.relpath(self.current_library.path)
+                            except:
+                                samelib = False
+
+                            if linked and mat.library and samelib:
+                                material = mat
+                                dd(name, "importado con link")
+                                break
+                            else:
+                                if not mat.library:
+                                    dd(name, "importado sin link")
+                                    material = mat
+                                    break
+                if material:
+                    material.use_fake_user = False
+                    material.user_clear()
+
+        print ("Material", material, force)
+
+        #if material:
+        #maybe some test cases doesn't return a material, gotta take care of that
+        #i cannot think of any case like that right now
+        #maybe import linked when the database isnt sync
+        if context.mode == "EDIT_MESH":
+            obj = context.object
+            dd(material)
+            index = -1
+            for i, mat in enumerate(obj.data.materials):
+                if mat == material:
+                    index = i
+                    break
+
+            if index == -1:
+                obj.data.materials.append(material)
+                index = len(obj.data.materials)-1
+            dd(index)
+            import bmesh
+            bm  = bmesh.from_edit_mesh(obj.data)
+            for f in bm.faces:
+                if f.select:
+                    f.material_index = index
+
         else:
-          obj.data.materials.append(material)
+            for obj in objects:
+                index = obj.active_material_index
+                if index < len(obj.material_slots):
+                    obj.material_slots[index].material = None
+                    obj.material_slots[index].material = material
+                else:
+                    obj.data.materials.append(material)
 
-      if not linked:
-        bpy.ops.object.make_local(type="SELECT_OBDATA_MATERIAL")
+            if not linked:
+                bpy.ops.object.make_local(type="SELECT_OBDATA_MATERIAL")
 
-  def add_material(self, mat):
+    def add_material(self, mat):
 
-    if not mat:
-      return 'WARNING', "Select a material from the scene."
+        if not mat:
+            return 'WARNING', "Select a material from the scene."
 
-    name = mat.name
-    thispath = winpath(bpy.data.filepath)
-    libpath = winpath(self.current_library.path)
+        name = mat.name
+        thispath = winpath(bpy.data.filepath)
+        libpath = winpath(self.current_library.path)
 
-    if not thispath:
-      return 'WARNING', "Save this file before export."
+        if not thispath:
+            return 'WARNING', "Save this file before export."
 
-    if not libpath:
-      return 'WARNING', "Library not found!."
+        if not libpath:
+            return 'WARNING', "Library not found!."
 
-    elif bpy.data.is_dirty:
-      bpy.ops.wm.save_mainfile(check_existing=True)
+        elif bpy.data.is_dirty:
+            bpy.ops.wm.save_mainfile(check_existing=True)
 
-    if mat.library:
-      return 'WARNING', 'Cannot export linked materials.'
+        if mat.library:
+            return 'WARNING', 'Cannot export linked materials.'
 
-    dd("adding material", name, libpath)
+        dd("adding material", name, libpath)
 
-    overwrite = ""
-    if name in list_materials(libpath):
-      overwrite = '''
+        overwrite = ""
+        if name in list_materials(libpath):
+            overwrite = '''
 mat = bpy.data.materials["%s"]
 mat.name = "tmp"
 mat.use_fake_user = False
 mat.user_clear()'''  % name
 
-    cmd = '''
+        cmd = '''
 import bpy{0}
 with bpy.data.libraries.load("{1}") as (data_from, data_to):
   data_to.materials = ["{2}"]
@@ -675,88 +675,88 @@ bpy.ops.file.pack_all()
 bpy.ops.wm.save_mainfile(filepath="{3}", check_existing=False, compress=True)
 '''.format(overwrite, thispath, name, libpath)
 
-    if send_command(cmd):
-      #self.load_library()
-      if not overwrite:
-        item = self.all_materials.add()
-        item.name = name
-        if "category" in mat.keys():
-          item.category = mat['category']
-        #reorder all_materials
-        items = sorted([[item.name, item.category] for item in self.all_materials], key = lambda x: x[0])
-
-        self.all_materials.clear()
-        for it in items:
-          item = self.all_materials.add()
-          item.name = it[0]
-          item.category = it[1]
-
-        self.update_list()
-
-      return 'INFO', "Material added."
-    else:
-      print("Save Material Error: Run Blender with administrative privileges.")
-      return 'WARNING', "There was an error saving the material"
-
-  def remove_material(self):
-    name = self.active_material.name
-    libpath = winpath(self.current_library.path)
-    if name and libpath and name in list_materials(libpath):
-      cmd = '''import bpy
+        if send_command(cmd):
+            #self.load_library()
+            if not overwrite:
+                item = self.all_materials.add()
+                item.name = name
+                if "category" in mat.keys():
+                    item.category = mat['category']
+                #reorder all_materials
+                items = sorted([[item.name, item.category] for item in self.all_materials], key = lambda x: x[0])
+
+                self.all_materials.clear()
+                for it in items:
+                    item = self.all_materials.add()
+                    item.name = it[0]
+                    item.category = it[1]
+
+                self.update_list()
+
+            return 'INFO', "Material added."
+        else:
+            print("Save Material Error: Run Blender with administrative privileges.")
+            return 'WARNING', "There was an error saving the material"
+
+    def remove_material(self):
+        name = self.active_material.name
+        libpath = winpath(self.current_library.path)
+        if name and libpath and name in list_materials(libpath):
+            cmd = '''import bpy
 mat = bpy.data.materials["%s"]
 mat.use_fake_user = False
 mat.user_clear()
 bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % (name , libpath)
-      if send_command(cmd, "removemat.py"):
-        self.all_materials.remove(self.mat_index)
-        self.update_list()
-      else:
-        return 'ERROR', "There was an error."
-    return "INFO", name + " removed."
-
-  def get_dummy(self, context):
-    dummy_name = "Material_Preview_Dummy"
-    dummy_mesh = "Material_Preview_Mesh"
-    scn = context.scene
-    try:
-      dummy = scn.objects[dummy_name]
-    except:
-      #create dummy
-      try:
-        me = bpy.data.meshes(dummy_mesh)
-      except:
-        me = bpy.data.meshes.new(dummy_mesh)
-      dummy = bpy.data.objects.new(dummy_name, me)
-      context.collection.objects.link(dummy)
-
-    dummy.hide_set(True)
-    dummy.hide_render = True
-    dummy.hide_select = True
-    return dummy
+            if send_command(cmd, "removemat.py"):
+                self.all_materials.remove(self.mat_index)
+                self.update_list()
+            else:
+                return 'ERROR', "There was an error."
+        return "INFO", name + " removed."
+
+    def get_dummy(self, context):
+        dummy_name = "Material_Preview_Dummy"
+        dummy_mesh = "Material_Preview_Mesh"
+        scn = context.scene
+        try:
+            dummy = scn.objects[dummy_name]
+        except:
+            #create dummy
+            try:
+                me = bpy.data.meshes(dummy_mesh)
+            except:
+                me = bpy.data.meshes.new(dummy_mesh)
+            dummy = bpy.data.objects.new(dummy_name, me)
+            context.collection.objects.link(dummy)
+
+        dummy.hide_set(True)
+        dummy.hide_render = True
+        dummy.hide_select = True
+        return dummy
 
 # bpy.utils.register_class(matlibProperties)
 # Scene.matlib = PointerProperty(type = matlibProperties)
 
 ### MENUS
 class MATLIB_MT_LibsMenu(Menu):
-  bl_label = "Libraries Menu"
+    bl_label = "Libraries Menu"
 
-  def draw(self, context):
-    layout = self.layout
-    libs = libraries
-    #layout.operator("matlib.operator", text="Default Library").cmd="lib-1"
-    for i, lib in enumerate(libs):
-      layout.operator("matlib.operator", text=lib.shortname).cmd="lib"+str(i)
+    def draw(self, context):
+        layout = self.layout
+        libs = libraries
+        #layout.operator("matlib.operator", text="Default Library").cmd="lib-1"
+        for i, lib in enumerate(libs):
+            layout.operator("matlib.operator", text=lib.shortname).cmd="lib"+str(i)
 
 class MATLIB_MT_CatsMenu(Menu):
-  bl_label = "Categories Menu"
+    bl_label = "Categories Menu"
 
-  def draw(self, context):
-    layout = self.layout
-    cats = context.scene.matlib.categories
-    layout.operator("matlib.operator", text="All").cmd="cat-1"
-    for i, cat in enumerate(cats):
-      layout.operator("matlib.operator", text=cat.name).cmd="cat"+str(i)
+    def draw(self, context):
+        layout = self.layout
+        cats = context.scene.matlib.categories
+        layout.operator("matlib.operator", text="All").cmd="cat-1"
+        for i, cat in enumerate(cats):
+            layout.operator("matlib.operator", text=cat.name).cmd="cat"+str(i)
 
 ### OPERATORS
 #class MATLIB_OT_add(Operator):
@@ -775,294 +775,294 @@ class MATLIB_MT_CatsMenu(Menu):
 
 
 class MATLIB_OT_add(Operator):
-  """Add active material to library"""
-  bl_idname = "matlib.add"
-  bl_label = "Add active material"
-
-  @classmethod
-  def poll(cls, context):
-    obj = context.active_object
-    return  obj is not None and obj.active_material is not None
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    success = matlib.add_material(context.object.active_material)
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
-    return {'FINISHED'}
+    """Add active material to library"""
+    bl_idname = "matlib.add"
+    bl_label = "Add active material"
+
+    @classmethod
+    def poll(cls, context):
+        obj = context.active_object
+        return  obj is not None and obj.active_material is not None
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        success = matlib.add_material(context.object.active_material)
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
+        return {'FINISHED'}
 
 class MATLIB_OT_remove(Operator):
-  """Remove material from library"""
-  bl_idname = "matlib.remove"
-  bl_label = "Remove material from library"
-
-  @classmethod
-  def poll(cls, context):
-    matlib = context.scene.matlib
-    return check_index(matlib.materials, matlib.mat_index)
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    success = matlib.remove_material()
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
-    return {'FINISHED'}
+    """Remove material from library"""
+    bl_idname = "matlib.remove"
+    bl_label = "Remove material from library"
+
+    @classmethod
+    def poll(cls, context):
+        matlib = context.scene.matlib
+        return check_index(matlib.materials, matlib.mat_index)
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        success = matlib.remove_material()
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
+        return {'FINISHED'}
 
 class MATLIB_OT_remove(Operator):
-  """Reload library"""
-  bl_idname = "matlib.reload"
-  bl_label = "Reload library"
-
-#  @classmethod
-#  def poll(cls, context):
-#    matlib = context.scene.matlib
-#    index = matlib.mat_index
-#    l = len(matlib.materials)
-#    return l>0 and index >=0 and index < l
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    success = matlib.reload()
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
-    return {'FINISHED'}
+    """Reload library"""
+    bl_idname = "matlib.reload"
+    bl_label = "Reload library"
+
+    #  @classmethod
+    #  def poll(cls, context):
+    #    matlib = context.scene.matlib
+    #    index = matlib.mat_index
+    #    l = len(matlib.materials)
+    #    return l>0 and index >=0 and index < l
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        success = matlib.reload()
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
+        return {'FINISHED'}
 
 
 class MATLIB_OT_apply(Operator):
-  """Apply selected material"""
-  bl_idname = "matlib.apply"
-  bl_label = "Apply material"
-
-  @classmethod
-  def poll(cls, context):
-    matlib = context.scene.matlib
-    index = matlib.mat_index
-    l = len(matlib.materials)
-    obj = context.active_object
-    return l>0 and index >=0 and index < l and obj is not None
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    success = matlib.apply(context, False)
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
-    return {'FINISHED'}
+    """Apply selected material"""
+    bl_idname = "matlib.apply"
+    bl_label = "Apply material"
+
+    @classmethod
+    def poll(cls, context):
+        matlib = context.scene.matlib
+        index = matlib.mat_index
+        l = len(matlib.materials)
+        obj = context.active_object
+        return l>0 and index >=0 and index < l and obj is not None
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        success = matlib.apply(context, False)
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
+        return {'FINISHED'}
 
 
 class MATLIB_OT_preview(Operator):
-  """Preview selected material"""
-  bl_idname = "matlib.preview"
-  bl_label = "Preview selected material"
-
-  @classmethod
-  def poll(cls, context):
-    matlib = context.scene.matlib
-    index = matlib.mat_index
-    l = len(matlib.materials)
-    obj = context.active_object
-    return l>0 and index >=0 and index < l
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    success = matlib.apply(context, True)
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
-    return {'FINISHED'}
+    """Preview selected material"""
+    bl_idname = "matlib.preview"
+    bl_label = "Preview selected material"
+
+    @classmethod
+    def poll(cls, context):
+        matlib = context.scene.matlib
+        index = matlib.mat_index
+        l = len(matlib.materials)
+        obj = context.active_object
+        return l>0 and index >=0 and index < l
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        success = matlib.apply(context, True)
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
+        return {'FINISHED'}
 
 
 class MATLIB_OT_flush(Operator):
-  """Flush unused materials"""
-  bl_idname = "matlib.flush"
-  bl_label = "Flush unused materials"
-
-  @classmethod
-  def poll(cls, context):
-    matlib = context.scene.matlib
-    index = matlib.mat_index
-    l = len(matlib.materials)
-    obj = context.active_object
-    return l>0 and index >=0 and index < l
-
-  def execute(self, context):
-    matlib = context.scene.matlib
-    dummy = matlib.get_dummy(context)
-    if dummy == context.object:
-      try:
-        context.view_layer.objects.active = context.scene.objects[matlib.last_selected]
-      except:
-        pass
-
-    for slot in dummy.material_slots:
-      slot.material = None
-    i=0
-    for mat in bpy.data.materials:
-      if mat.users==0:
-        i+=1
-        print (mat.name, "removed.")
-        bpy.data.materials.remove(mat)
-
-    plural = "" if i == 1 else "s"
-    self.report({'INFO'}, str(i) + " material"+plural+" removed.")
-
-    return {'FINISHED'}
+    """Flush unused materials"""
+    bl_idname = "matlib.flush"
+    bl_label = "Flush unused materials"
+
+    @classmethod
+    def poll(cls, context):
+        matlib = context.scene.matlib
+        index = matlib.mat_index
+        l = len(matlib.materials)
+        obj = context.active_object
+        return l>0 and index >=0 and index < l
+
+    def execute(self, context):
+        matlib = context.scene.matlib
+        dummy = matlib.get_dummy(context)
+        if dummy == context.object:
+            try:
+                context.view_layer.objects.active = context.scene.objects[matlib.last_selected]
+            except:
+                pass
+
+        for slot in dummy.material_slots:
+            slot.material = None
+        i=0
+        for mat in bpy.data.materials:
+            if mat.users==0:
+                i+=1
+                print (mat.name, "removed.")
+                bpy.data.materials.remove(mat)
+
+        plural = "" if i == 1 else "s"
+        self.report({'INFO'}, str(i) + " material"+plural+" removed.")
+
+        return {'FINISHED'}
 
 
 class MATLIB_OT_operator(Operator):
-  """Add, Remove, Reload, Apply, Preview, Clean Material"""
-  bl_label = "New"
-  bl_idname = "matlib.operator"
-  __doc__ = "Add, Remove, Reload, Apply, Preview, Clean Material"
-
-  category: StringProperty(name="Category")
-  filepath: StringProperty(options={'HIDDEN'})
-  cmd: bpy.props.StringProperty(name="Command", options={'HIDDEN'})
-  filter_glob: StringProperty(default="*.blend", options={'HIDDEN'})
-  @classmethod
-  def poll(cls, context):
-    return context.active_object is not None
-
-  def draw(self, context):
-    layout = self.layout
-    #cmd = LIBRARY_ADD
-    if self.cmd == "LIBRARY_ADD":
-      #layout.label("Select a blend file as library or")
-      #layout.label("Type a name to create a new library.")
-      layout.prop(self, "category", text="Library")
-    elif self.cmd == "FILTER_ADD":
-      layout.prop(self, "category")
-
-  def invoke(self, context, event):
-
-    cmd = self.cmd
-    print("invoke", cmd)
-
-    if cmd == "LIBRARY_ADD":
-      self.filepath = matlib_path + os.path.sep
-      dd("filepath", self.filepath, matlib_path)
-      #context.window_manager.fileselect_add(self)
-      context.window_manager.invoke_props_dialog(self)
-      return {'RUNNING_MODAL'}
-    elif cmd == "FILTER_ADD":
-      context.window_manager.invoke_props_dialog(self)
-      return {'RUNNING_MODAL'}
-    return self.execute(context)
-
-  ### TODO: execute doesn't trigger remove
-  def execute(self, context):
-
-    success = ""
-    matlib = context.scene.matlib
-
-    if self.cmd == "init":
-      print("initialize")
-      return {'FINISHED'}
-
-    #Library Commands
-    if self.cmd[0:3] == "lib":
-      index = int(self.cmd[3::])
-      matlib.lib_index = index
-      #success = matlib.load_library()
-    elif self.cmd == "LIBRARY_ADD":
-      dd("execute lib add")
-      libname = self.category
-      if libname[-6::] != ".blend": libname+= ".blend"
-      libname = os.path.join(matlib_path, libname)
-      print(libname)
-
-      success = matlib.add_library(libname, True)
-      for i, l in enumerate(libraries):
-        if l.name == self.category:
-          matlib.lib_index = i
-          break
-
-    elif self.cmd == "RELOAD":
-      success = matlib.reload()
-
-    if not matlib.current_library:
-      self.report({'ERROR'}, "Select a Library")
-      return {'CANCELLED'}
-
-    if self.cmd == "FILTER_ADD":
-      success = matlib.add_category(self.category)
-      for i, cat in enumerate(matlib.categories):
-        if cat.name == self.category:
-          matlib.cat_index = i
-          break
-
-    elif self.cmd == "FILTER_REMOVE":
-      matlib.remove_category()
-
-    elif self.cmd == "FILTER_SET":
-      success = matlib.set_category()
-
-    elif self.cmd[0:3] == "cat":
-      index = int(self.cmd[3::])
-      matlib.cat_index = index
-
-    #Common Commands
-    elif self.cmd == "ADD":
-      success = matlib.add_material(context.object.active_material)
-
-    elif self.cmd == "REMOVE":
-      success = matlib.remove_material()
-
-
-    elif self.cmd == "APPLY":
-      success = matlib.apply(context)
-
-    elif self.cmd == "PREVIEW":
-      success = matlib.apply(context, True)
-
-    elif self.cmd=="FLUSH":
-      #release dummy materials
-      dummy = matlib.get_dummy(context)
-      if dummy == context.object:
-        try:
-          context.view_layer.objects.active = context.scene.objects[matlib.last_selected]
-        except:
-          pass
-
-      for slot in dummy.material_slots:
-        slot.material = None
-      i=0
-      for mat in bpy.data.materials:
-        if mat.users==0:
-          i+=1
-          print (mat.name, "removed.")
-          bpy.data.materials.remove(mat)
-
-      plural = "s"
-      if i==1:
-        plural = ""
-
-      self.report({'INFO'}, str(i) + " material"+plural+" removed.")
-
-    ### CONVERT
-    elif self.cmd == "CONVERT":
-      return {'FINISHED'}
-      lib = matlib.current_library
-      if lib:
-
-        path = os.path.join(matlib_path, "www")
-        if not os.path.exists(path):
-          os.mkdir(path)
-        path = os.path.join(path, lib.shortname)
-        if not os.path.exists(path):
-          os.mkdir(path)
-
-        path = winpath(path)
-        libpath = winpath(lib.name)
-
-        print(path)
-        print(libpath)
-
-        #decirle a la libreria que cree un fichero blend por cada material que tenga.
-        cmd = """
+    """Add, Remove, Reload, Apply, Preview, Clean Material"""
+    bl_label = "New"
+    bl_idname = "matlib.operator"
+    __doc__ = "Add, Remove, Reload, Apply, Preview, Clean Material"
+
+    category: StringProperty(name="Category")
+    filepath: StringProperty(options={'HIDDEN'})
+    cmd: bpy.props.StringProperty(name="Command", options={'HIDDEN'})
+    filter_glob: StringProperty(default="*.blend", options={'HIDDEN'})
+    @classmethod
+    def poll(cls, context):
+        return context.active_object is not None
+
+    def draw(self, context):
+        layout = self.layout
+        #cmd = LIBRARY_ADD
+        if self.cmd == "LIBRARY_ADD":
+            #layout.label("Select a blend file as library or")
+            #layout.label("Type a name to create a new library.")
+            layout.prop(self, "category", text="Library")
+        elif self.cmd == "FILTER_ADD":
+            layout.prop(self, "category")
+
+    def invoke(self, context, event):
+
+        cmd = self.cmd
+        print("invoke", cmd)
+
+        if cmd == "LIBRARY_ADD":
+            self.filepath = matlib_path + os.path.sep
+            dd("filepath", self.filepath, matlib_path)
+            #context.window_manager.fileselect_add(self)
+            context.window_manager.invoke_props_dialog(self)
+            return {'RUNNING_MODAL'}
+        elif cmd == "FILTER_ADD":
+            context.window_manager.invoke_props_dialog(self)
+            return {'RUNNING_MODAL'}
+        return self.execute(context)
+
+    ### TODO: execute doesn't trigger remove
+    def execute(self, context):
+
+        success = ""
+        matlib = context.scene.matlib
+
+        if self.cmd == "init":
+            print("initialize")
+            return {'FINISHED'}
+
+        #Library Commands
+        if self.cmd[0:3] == "lib":
+            index = int(self.cmd[3::])
+            matlib.lib_index = index
+            #success = matlib.load_library()
+        elif self.cmd == "LIBRARY_ADD":
+            dd("execute lib add")
+            libname = self.category
+            if libname[-6::] != ".blend": libname+= ".blend"
+            libname = os.path.join(matlib_path, libname)
+            print(libname)
+
+            success = matlib.add_library(libname, True)
+            for i, l in enumerate(libraries):
+                if l.name == self.category:
+                    matlib.lib_index = i
+                    break
+
+        elif self.cmd == "RELOAD":
+            success = matlib.reload()
+
+        if not matlib.current_library:
+            self.report({'ERROR'}, "Select a Library")
+            return {'CANCELLED'}
+
+        if self.cmd == "FILTER_ADD":
+            success = matlib.add_category(self.category)
+            for i, cat in enumerate(matlib.categories):
+                if cat.name == self.category:
+                    matlib.cat_index = i
+                    break
+
+        elif self.cmd == "FILTER_REMOVE":
+            matlib.remove_category()
+
+        elif self.cmd == "FILTER_SET":
+            success = matlib.set_category()
+
+        elif self.cmd[0:3] == "cat":
+            index = int(self.cmd[3::])
+            matlib.cat_index = index
+
+        #Common Commands
+        elif self.cmd == "ADD":
+            success = matlib.add_material(context.object.active_material)
+
+        elif self.cmd == "REMOVE":
+            success = matlib.remove_material()
+
+
+        elif self.cmd == "APPLY":
+            success = matlib.apply(context)
+
+        elif self.cmd == "PREVIEW":
+            success = matlib.apply(context, True)
+
+        elif self.cmd=="FLUSH":
+            #release dummy materials
+            dummy = matlib.get_dummy(context)
+            if dummy == context.object:
+                try:
+                    context.view_layer.objects.active = context.scene.objects[matlib.last_selected]
+                except:
+                    pass
+
+            for slot in dummy.material_slots:
+                slot.material = None
+            i=0
+            for mat in bpy.data.materials:
+                if mat.users==0:
+                    i+=1
+                    print (mat.name, "removed.")
+                    bpy.data.materials.remove(mat)
+
+            plural = "s"
+            if i==1:
+                plural = ""
+
+            self.report({'INFO'}, str(i) + " material"+plural+" removed.")
+
+        ### CONVERT
+        elif self.cmd == "CONVERT":
+            return {'FINISHED'}
+            lib = matlib.current_library
+            if lib:
+
+                path = os.path.join(matlib_path, "www")
+                if not os.path.exists(path):
+                    os.mkdir(path)
+                path = os.path.join(path, lib.shortname)
+                if not os.path.exists(path):
+                    os.mkdir(path)
+
+                path = winpath(path)
+                libpath = winpath(lib.name)
+
+                print(path)
+                print(libpath)
+
+                #decirle a la libreria que cree un fichero blend por cada material que tenga.
+                cmd = """
 print(30*"+")
 import bpy, os
 def list_materials():
@@ -1103,89 +1103,89 @@ for mat in mats:
   material.use_fake_user = True
   bpy.ops.wm.save_mainfile(filepath = matpath, compress=True, check_existing=False)
 """.format(libpath, path)
-        print(cmd)
-        send_command(cmd, "createlib.py")
+                print(cmd)
+                send_command(cmd, "createlib.py")
 
-    if type(success).__name__ == "tuple":
-      print(success)
-      self.report({success[0]}, success[1])
+        if type(success).__name__ == "tuple":
+            print(success)
+            self.report({success[0]}, success[1])
 
-    return {'FINISHED'}
+        return {'FINISHED'}
 
 
 class MATLIB_PT_vxPanel(Panel):
-  bl_label = "Material Library VX"
-  bl_space_type = "PROPERTIES"
-  bl_region_type = "WINDOW"
-  bl_context = "material"
-
-  @classmethod
-  def poll(self, context):
-    return context.active_object.active_material!=None
-
-  def draw(self, context):
-    layout = self.layout
-    matlib = context.scene.matlib
-
-    #hyper ugly trick but i dont know how to init classes at register time
-#    if matlibProperties.init:
-#      matlibProperties.init = False
-#      matlib.__init__()
-
-    #libraries
-    row = layout.row(align=True)
-    if matlib.current_library:
-      text = matlib.current_library.shortname
-    else:
-      text = "Select a Library"
+    bl_label = "Material Library VX"
+    bl_space_type = "PROPERTIES"
+    bl_region_type = "WINDOW"
+    bl_context = "material"
 
-    row.menu("MATLIB_MT_LibsMenu",text=text)
-    row.operator("matlib.operator", icon="ADD", text="").cmd = "LIBRARY_ADD"
-    if matlib.active_material:
-      row.label(text = matlib.active_material.category)
-    else:
-      row.label(text="")
-#
-#    #search
-    if not matlib.hide_search:
-      row = layout.row(align=True)
-      row.prop_search(matlib, "search", matlib, "materials", text="", icon="VIEWZOOM")
-
-#    #list
-    row = layout.row()
-    row.template_list("UI_UL_list", "  ", matlib, "materials", matlib, "mat_index", rows=6)
-    col = row.column(align=True)
-    row = layout.row()
-
-      #operators
-    col.operator("matlib.operator", icon="ADD", text="").cmd="ADD"
-    col.operator("matlib.operator", icon="REMOVE", text="").cmd="REMOVE"
-    col.operator("matlib.operator", icon="FILE_REFRESH", text="").cmd="RELOAD"
-    col.operator("matlib.operator", icon="MATERIAL", text="").cmd="APPLY"
-    col.operator("matlib.operator", icon="COLOR", text="").cmd="PREVIEW"
-    col.operator("matlib.operator", icon="GHOST_DISABLED", text="").cmd="FLUSH"
-    col.prop(matlib, "show_prefs", icon="MODIFIER", text="")
-
-    #categories
-    row = layout.row(align=True)
-    text = "All"
-    if matlib.current_category: text = matlib.current_category
-    row.menu("MATLIB_MT_CatsMenu",text=text)
-    row.prop(matlib, "filter", icon="FILTER", text="")
-    row.operator("matlib.operator", icon="FILE_PARENT", text="").cmd="FILTER_SET"
-    row.operator("matlib.operator", icon="ADD", text="").cmd="FILTER_ADD"
-    row.operator("matlib.operator", icon="REMOVE", text="").cmd="FILTER_REMOVE"
-
-    #prefs
-    if matlib.show_prefs:
-      row = layout.row()
-      row.prop(matlib, "force_import")
-      row.prop(matlib, "link")
-      row = layout.row()
-      row.prop(matlib, "hide_search")
+    @classmethod
+    def poll(self, context):
+        return context.active_object.active_material!=None
+
+    def draw(self, context):
+        layout = self.layout
+        matlib = context.scene.matlib
+
+        #hyper ugly trick but i dont know how to init classes at register time
+        #    if matlibProperties.init:
+        #      matlibProperties.init = False
+        #      matlib.__init__()
+
+        #libraries
+        row = layout.row(align=True)
+        if matlib.current_library:
+            text = matlib.current_library.shortname
+        else:
+            text = "Select a Library"
+
+        row.menu("MATLIB_MT_LibsMenu",text=text)
+        row.operator("matlib.operator", icon="ADD", text="").cmd = "LIBRARY_ADD"
+        if matlib.active_material:
+            row.label(text = matlib.active_material.category)
+        else:
+            row.label(text="")
+        #
+        #    #search
+        if not matlib.hide_search:
+            row = layout.row(align=True)
+            row.prop_search(matlib, "search", matlib, "materials", text="", icon="VIEWZOOM")
+
+        #    #list
+        row = layout.row()
+        row.template_list("UI_UL_list", "  ", matlib, "materials", matlib, "mat_index", rows=6)
+        col = row.column(align=True)
+        row = layout.row()
+
+        #operators
+        col.operator("matlib.operator", icon="ADD", text="").cmd="ADD"
+        col.operator("matlib.operator", icon="REMOVE", text="").cmd="REMOVE"
+        col.operator("matlib.operator", icon="FILE_REFRESH", text="").cmd="RELOAD"
+        col.operator("matlib.operator", icon="MATERIAL", text="").cmd="APPLY"
+        col.operator("matlib.operator", icon="COLOR", text="").cmd="PREVIEW"
+        col.operator("matlib.operator", icon="GHOST_DISABLED", text="").cmd="FLUSH"
+        col.prop(matlib, "show_prefs", icon="MODIFIER", text="")
+
+        #categories
+        row = layout.row(align=True)
+        text = "All"
+        if matlib.current_category: text = matlib.current_category
+        row.menu("MATLIB_MT_CatsMenu",text=text)
+        row.prop(matlib, "filter", icon="FILTER", text="")
+        row.operator("matlib.operator", icon="FILE_PARENT", text="").cmd="FILTER_SET"
+        row.operator("matlib.operator", icon="ADD", text="").cmd="FILTER_ADD"
+        row.operator("matlib.operator", icon="REMOVE", text="").cmd="FILTER_REMOVE"
+
+        #prefs
+        if matlib.show_prefs:
+            row = layout.row()
+            row.prop(matlib, "force_import")
+            row.prop(matlib, "link")
+            row = layout.row()
+            row.prop(matlib, "hide_search")
 #      row = layout.row(align=True)
-      #row = layout.row()
-      #row.operator("matlib.operator", icon="URL", text="Convert Library").cmd="CONVERT"
+#row = layout.row()
+#row.operator("matlib.operator", icon="URL", text="Convert Library").cmd="CONVERT"
 
 #      row = layout.row()
 #      if (matlib.current_library):
@@ -1217,11 +1217,11 @@ def reload_library(self, context):
 
 class matlibvxPref(AddonPreferences):
     bl_idname = __name__
-
     matlib_path: StringProperty(
         name="Additional Path",
         description="User defined path to .blend libraries files",
         default="",
+        subtype="DIR_PATH",
         update=reload_library
     )
 
@@ -1230,15 +1230,16 @@ class matlibvxPref(AddonPreferences):
         layout.prop(self, "matlib_path")
 
 classes = [
-matlibMaterials,
-EmptyGroup,
-MATLIB_PT_vxPanel, 
-MATLIB_OT_operator,
-MATLIB_MT_LibsMenu, 
-MATLIB_MT_CatsMenu,
-matlibProperties,
+    matlibvxPref,
+    matlibMaterials,
+    EmptyGroup,
+    MATLIB_PT_vxPanel,
+    MATLIB_OT_operator,
+    MATLIB_MT_LibsMenu,
+    MATLIB_MT_CatsMenu,
+    matlibProperties,
 ]
-        
+
 """
 classes = [
 matlibProperties,
@@ -1282,7 +1283,7 @@ def unregister():
     libraries.clear()
     bpy.app.handlers.load_post.remove(refresh_libs)
     for c in classes:
-       bpy.utils.unregister_class(c)
+        bpy.utils.unregister_class(c)
 
 
 if __name__ == "__main__":