;;; ============================================================
;;; SPIS_TOOLS.lsp — единый загрузчик инструментов СПИС
;;;
;;; AutoCAD 2020 и 2026. Кодировка Windows-1251.
;;;
;;; Папка скриптов определяется АВТОМАТИЧЕСКИ и запоминается:
;;; 1) реестр HKCU\Software\GENPRO\SPIS\ToolsDir
;;; 2) пути поддержки AutoCAD (findfile)
;;; 3) поиск SPIS_TOOLS.lsp в доверенных путях (до 3 уровней)
;;; Найденная папка добавляется в TRUSTEDPATHS (снимает диалог
;;; безопасности) и сохраняется в реестр — второй раз мгновенно.
;;;
;;; Если автопоиск не сработал — команда SPISSETDIR.
;;;
;;; Команды:
;;; SPISSETDIR — указать папку СПИС вручную
;;; SPISRUNSETS — собрать файлы дисциплин (фоном, Python)
;;; SPISATTACHSETS — подключить АР и дисциплины в СПИС
;;; XRLIST XRBIND XRBIND1 XRPATH XRUNBIND XRDETACH
;;; SPISHELP — справка
;;; ============================================================
(vl-load-com)
(setq *SPIS-REG* "HKEY_CURRENT_USER\\Software\\GENPRO\\SPIS")
(setq *SPIS-SUBS* (list "SPIS_RUN_SETS.lsp" "SPIS_SYSTEM_SETS.lsp"
"XRBIND.lsp" "SPISHELP.lsp"))
(setq *SPIS-DIR* nil)
;; ---------- мелкие утилиты ----------
(defun spis:trim (s) (vl-string-right-trim "\\/" s))
(defun spis:split (str sep / pos res)
(setq res nil)
(while (setq pos (vl-string-search sep str))
(setq res (cons (substr str 1 pos) res)
str (substr str (+ pos 1 (strlen sep)))))
(reverse (cons str res)))
;; Есть ли в папке загрузчик?
(defun spis:here-p (dir / full)
(if (and dir (> (strlen dir) 0))
(progn
(setq full (strcat (spis:trim dir) "\\SPIS_TOOLS.lsp"))
(if (findfile full) T nil))
nil))
;; ---------- реестр: запомнить/прочитать папку ----------
(defun spis:reg-get ( / r)
(setq r (vl-catch-all-apply 'vl-registry-read (list *SPIS-REG* "ToolsDir")))
(if (vl-catch-all-error-p r) nil r))
(defun spis:reg-set (dir)
(vl-catch-all-apply 'vl-registry-write (list *SPIS-REG* "ToolsDir" dir)))
;; ---------- добавить папку в TRUSTEDPATHS ----------
(defun spis:ensure-trusted (dir / tp full)
(setq full (strcase (spis:trim dir)))
(setq tp (getvar "TRUSTEDPATHS"))
(if (vl-string-search full (strcase tp))
(princ)
(progn
(setvar "TRUSTEDPATHS" (strcat tp ";" (spis:trim dir)))
(princ (strcat "\n Доверенный путь добавлен: " (spis:trim dir))))))
;; ---------- рекурсивный поиск папки с загрузчиком ----------
(defun spis:scan (dir depth / subs s found r)
(setq found nil)
(if (spis:here-p dir)
(setq found dir)
(if (> depth 0)
(progn
(setq r (vl-catch-all-apply 'vl-directory-files (list dir "*" -1)))
(if (not (vl-catch-all-error-p r))
(foreach s r
(if (and (null found)
(/= s ".") (/= s "..")
(vl-file-directory-p (strcat dir "\\" s)))
(setq found (spis:scan (strcat dir "\\" s) (1- depth)))))))))
found)
;; ---------- корни для поиска: пути поддержки + доверенные ----------
(defun spis:candidate-roots ( / acc)
(setq acc (spis:split (getvar "ACADPREFIX") ";"))
(setq acc (append acc (spis:split (getvar "TRUSTEDPATHS") ";")))
acc)
;; ---------- определить папку ----------
(defun spis:detect ( / d f roots)
(setq d (spis:reg-get)) ;; 1) реестр
(if (not (spis:here-p d)) (setq d nil))
(if (null d) ;; 2) пути поддержки
(if (setq f (findfile "SPIS_TOOLS.lsp"))
(setq d (vl-filename-directory f))))
(if (null d) ;; 3) скан доверенных/поддержки
(progn
(setq roots (spis:candidate-roots))
(foreach r roots
(if (and (null d) (vl-file-directory-p r))
(setq d (spis:scan (spis:trim r) 3))))))
d)
;; ---------- загрузка одного файла по полному пути ----------
(defun spis:load-one (dir fname / full r)
(setq full (strcat (spis:trim dir) "\\" fname))
(if (findfile full)
(progn
(setq r (vl-catch-all-apply 'load (list full)))
(if (vl-catch-all-error-p r)
(princ (strcat "\n [ОШИБКА] " fname ": " (vl-catch-all-error-message r)))
(princ (strcat "\n [OK] " fname))))
(princ (strcat "\n [НЕТ] " fname " — не найден в " dir)))
(princ))
;; ---------- ручная установка папки ----------
(defun c:SPISSETDIR ( / dir)
(setq dir (getstring T "\nПапка с файлами СПИС (например Y:/BIM/Autocad PLUGINS/SPIS): "))
(setq dir (spis:trim (vl-string-translate "/" "\\" dir)))
(cond
((= dir "") (princ "\n Пусто — ничего не изменено."))
((not (spis:here-p dir)) (princ "\n В этой папке нет SPIS_TOOLS.lsp."))
(T
(setq *SPIS-DIR* dir)
(spis:reg-set dir)
(spis:ensure-trusted dir)
(princ (strcat "\n Папка сохранена: " dir))
(princ "\n Перезагрузите SPIS_TOOLS.lsp (APPLOAD) для подключения команд.")))
(princ))
;; ============================================================
;; ЗАГРУЗКА
;; ============================================================
(princ "\n==============================================")
(princ "\n Загрузка инструментов СПИС")
(princ "\n==============================================")
(if (setq *SPIS-DIR* (spis:detect))
(progn
(princ (strcat "\n Папка: " *SPIS-DIR*))
(spis:reg-set *SPIS-DIR*)
(spis:ensure-trusted *SPIS-DIR*)
(foreach f *SPIS-SUBS* (spis:load-one *SPIS-DIR* f))
(princ "\n\n Команды:")
(princ "\n SPISRUNSETS — собрать файлы дисциплин")
(princ "\n SPISATTACHSETS — подключить дисциплины в СПИС")
(princ "\n XRLIST XRBIND XRBIND1 XRPATH XRUNBIND XRDETACH")
(princ "\n SPISHELP — справка")
(princ "\n SPISSETDIR — указать папку вручную"))
(progn
(princ "\n Папка с инструментами не найдена автоматически.")
(princ "\n Выполните команду SPISSETDIR и укажите путь, например:")
(princ "\n Y:/BIM/Autocad PLUGINS/SPIS")))
(princ "\n==============================================")
(princ)
;;; Автозагрузка: APPLOAD -> Содержимое -> Добавить -> SPIS_TOOLS.lsp
;;; либо строка в acaddoc.lsp (путь подставьте свой):
;;; (setvar "TRUSTEDPATHS" (strcat (getvar "TRUSTEDPATHS") ";Y:\\BIM\\Autocad PLUGINS\\SPIS"))
;;; (load "Y:/BIM/Autocad PLUGINS/SPIS/SPIS_TOOLS.lsp")