; 图层状态保存及恢复工具[lxx-____].lsp
; ---------lxx.2001.4

; 保存图层状态[lxx_lass]
; 恢复图层状态[lxx_lasr]
; 清除图层状态[lxx_del]
; 图层状态简易切换[lxx_laman]

;;laylst-图层状态表(全局); sslaylst-图层状态表长度; layln-图层状态命名; layladd-当前图层状态; laytbl-图层符号表数据
(defun C:lxx_lass ( )
	(lxx_lasss T nil)
)
;(setq mode T n nil)
(defun lxx_lasss ( mode n / sslaylst n layln m k layladd laytbl stop cf )
	(princ "\n图层状态-保存工具-------用lxx_lasr恢复---------lxx.2001.4")
	(setq sslaylst (if laylst (length laylst)))
	(if laylst
		(progn
			(princ "\n已有命名:")
			(foreach n laylst (princ (strcat "  \"" (car n) "\"") ))
		)
	)
	(while (not stop)
		(if mode
			(setq layln (getstring (strcat "\n输入*显示laylst列表/命名<*>:")))
			(setq layln (rtos n 2 0))
		)
		(if (not (or (= layln "") (assoc layln laylst)))
			(setq stop T)
			(progn
				(princ "重复!!!记录覆盖更新中<<<<<<         ")
				(setq stop T cf T)
				(if laylst
					(foreach n laylst (princ (strcat "  \"" (car n) "\"") ))
				)
			)
		);;不准直接按空格
	)
	(if (= "*" layln)
		(foreach n laylst (foreach m n (print m)))
		(progn
			(setq k t layladd '())
			(while (setq laytbl (tblnext "layer" k));;从第一个查询
				(setq k nil layladd (cons laytbl layladd));;图层数据连接
			)
			;(textpage)
			;(princ "\n当前保存的层状态----2:图层名; 70(1) 冻结(2) 视口冻结(4) 锁定; 62(-)关闭; 6:线形名")
			(princ (strcat "\n--------------------当前命名:" layln "--------------------"))
			(setq layladd (cons layln layladd));;图层状态名+图层数据
			(if cf
				(setq laylst (subst layladd (assoc layln laylst) laylst));;图层列表连接
				(setq laylst (cons layladd laylst));;图层列表连接
			)
			;(foreach n layladd (print n));;显示已经保存的
		)
	);end if
	(if (> (length laylst) 20);;;;最多20个存储
		(setq
			laylst (reverse laylst)
			laylst (cdr laylst)
			laylst (reverse laylst)
		)
	)
	(if (= "*" layln)
		(princ)
		(if cf
			(princ (strcat "\n图层状态" layln "已更新!!!" ))
			(princ (strcat "\n图层状态已经保存为:" layln))
		)
	)
	(setq
		laylst
			(vl-sort
				laylst
				'(lambda(e1 e2)
					(if (equal (car e1) (car e2) 1e-4)
						(> (car e1) (car e2))
						(< (car e1) (car e2))
					)
				)
			)
	)
	(princ)
)


;;恢复图层状态
(defun C:lxx_lasr() (lxx_lasrr))

(defun lxx_lasrr ( / i roop ix n ik layladd )
	(defun *error*(msg)
		(princ)
	)
	(if (setq temp (lxx_xsdhk_G (mapcar 'car laylst)))
		(setq layln (cdr temp))
	)
	(if (= "*" layln)
		(progn
			(foreach n laylst (foreach m n (print m)))
			(princ)
		)
		(progn
			(foreach x laylst
				(if (member layln x)
					(setq layladd (member layln x))
				)
			)
			(if layladd
				(foreach nn (cdr layladd)
					(apply 'lxx_CreateLayer (mapcar 'cdr (cdr nn)))
				)
			)
			(foreach n layladd (print n))
			(princ)
		)
	)
	(entmake)
)


;;清除图层状态
(defun lxx_ladelete () (setq laylst nil) (princ "\n图层状态已清空") (princ))

(defun C:lxx_del ( ) (lxx_ladelete))
;;把图层状态导出到文件
(defun lxx_dczt( / fn )
	(setq fn (if mai_mini_path (mai_fix_dir1 (strcat mai_mini_path "用户设置\\图层状态.txt")) "C:\\图层状态.txt"))  ;;设定文件路径
	(lxx_lst_2file (lxx_str_of_lst_deal laylst) fn "W")
	(if mai_mini_path
		(mai_shell_ascii_edit fn nil)
		(startapp (strcat "explorer /select, C:\\图层状态.txt, /e"))
	)
)
;;从文件中加载图层状态
(defun lxx_jzzt( / str DD fn_desc fn )
	(setq fn (if mai_mini_path (mai_fix_dir1 (strcat mai_mini_path "用户设置\\图层状态.txt")) "C:\\图层状态.txt"))  ;;设定文件路径
	(if (findfile fn)
		(progn
			(setq
				fn_desc (open fn "R") ;; 如果文件不在 AutoCAD 启动目录下，需要文件全名
				laylst (read (read-line fn_desc))
			)
			(close fn_desc)
			(princ "\n导入图层状态成功")
		)
		(princ (strcat "\n" fn "文件不存在,请先导出再试"))
	)
	(princ)
)
;;;;lst表，fn文件路径，mode读写模式，"W"写覆盖，"A"添加，"R"只读
(defun lxx_lst_2file (lst fn mode / str fn_desc)
	(setq
		str (vl-princ-to-string lst)
		fn_desc (open fn mode)
	) ;; 如果文件不在 AutoCAD 启动目录下，需要文件全名
	(write-line str fn_desc)
	(close fn_desc)
)
;;cdr字符不变
(defun lxx_cdr_str_unchange ( lst / lst_new str )
	(if (= (type (setq str (cdr lst))) 'STR)
		(setq str (strcat "\"" str "\""))
	)
	(setq lst_new (cons (car lst) str))
)

;;写入列表
(defun lxx_str_of_lst_deal ( lst / n2 n2_new_str n1_new lst_new list_temp_new list_temp_new_new list_temp_new_str n1 n2_new n3 i res)
	(foreach n1 lst
		(foreach n2 n1
			(if (listp n2)
				(foreach n3 n2
					(setq n2_new (append n2_new (list (lxx_cdr_str_unchange n3))))
				)
				(if (= (type n2) 'STR)
					(setq n2_new_str (strcat "\"" n2 "\""))
					(setq n2_new n2)
				)
			)
			(if n2_new_str
				(setq
					n1_new (list n2_new_str)
					n2_new_str nil
					n2_new nil
				)
				(setq
					n1_new (append n1_new (list n2_new))
					n2_new_str nil
					n2_new nil
				)
			)
		)
		(setq
			lst_new (append lst_new (list n1_new))
			n1_new nil
		)
	)
	(setq res lst_new)
)

(defun lxx_CreateLayer ( name state color ltype / data )
	(setq data (list
					'(0 . "LAYER")
					'(100 . "AcDbSymbolTableRecord")
					'(100 . "AcDbLayerTableRecord")
					(cons 70 state)
					(cons 2 name)
					(cons 6 (if (tblsearch "LTYPE" ltype) ltype "Continuous"))
					(cons 62 color)
					(cons 290 0)
					(cons 370 1)
				)
	)
	(if (tblsearch "LAYER" name)
		(entmod (cons (cons -1 (tblobjname "LAYER" name)) data))
		(entmakex data)
	)
)

;;快速建立/激活指定图层状态名
(defun lxx_active_ZT ( n / layln layladd x nn )
	(setq layln (rtos n 2 0))
	(foreach x laylst
		(if (member layln x)
			(setq layladd (member layln x))
		)
	)
	(if layladd
		(foreach nn (cdr layladd)
			(apply 'lxx_CreateLayer (mapcar 'cdr (cdr nn)))
		)
	)
)
;;;批量定义快捷键================================分割线===================================
(defun lxx_GX_SUB( / n nn pre)
	(apply
		'(lambda ( / n nn times pre pre1 pre2 )
			(setq
				n 0
				pre1 "qq"    ;;;pre前缀为定义快捷命令的前缀,如新生成的命令qq1,qq2等都是快捷命令
				pre2 "ww"    ;;;pre前缀为定义快捷命令的前缀,如新生成的命令qq1,qq2等都是快捷命令
				times 20
			);;256
			(repeat (1+ times)
				(setq n (1+ n) nn (itoa n))
				(eval (read (strcat "(defun c:" pre1 nn "(/ n)(lxx_active_ZT " nn "))" )))
				(eval (read (strcat "(defun c:" pre2 nn "(/ n)(lxx_lasss nil " nn "))")))
			)
		)
		nil
	)
)

;;;******************************************
;;;添加列表框内列表
;;;******************************************
(defun lxx_adlst ( key lst);;;仅对popup_list或list_box有效
	(start_list key 3);;;处理列表开始
	(mapcar 'add_list  lst)
	(end_list);;;添加列表结束
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun lxx_xsdhk_G (lst / x replace lsdcl fn dclid num return# )
	(setq fn (open (setq lsdcl (vl-filename-mktemp "tmp" "" ".dcl")) "w"))
	(foreach x '(
					"yyy : dialog{label=\"StateManager\";"
					":list_box{key=\"9\";height=18;width=12;}"
					":button{key=\"B_save\";label=\"保存图层状态\";width=1;height=2;is_default=true;}"
					":button{key=\"QK\";label=\"清除图层状态\";width=1;height=2;}"
					":button{key=\"dr\";label=\"导入图层状态\";width=1;height=2;}"
					":button{key=\"dc\";label=\"导出图层状态\";width=1;height=2;}"
					":button{key=\"GX\";label=\"快捷键  激活\";width=1;height=2;}"
					":button{key=\"cancel\";label=\"Cancel\";is_cancel=true;width=1;height=2;}}"
				)
		(write-line x fn)
	)
	(close fn)
	(setq dclid (load_dialog lsdcl))
	(vl-file-delete lsdcl)
	(new_dialog "yyy" dclid "" screenpt)
	(lxx_adlst "9"  lst)
	(action_tile "9" "(setq num (atoi $value))(done_dialog)")
	(action_tile "B_save" "(done_dialog 1)")
	(action_tile "QK" "(done_dialog 2)")
	(action_tile "dc" "(done_dialog 3)")
	(action_tile "dr" "(done_dialog 4)")
	(action_tile "GX" "(done_dialog 5)")
	(setq return# (start_dialog))
	(unload_dialog dclid)
	(cond
	 ;;手动输入名称,后续省略
		(	(= return# 1) (lxx_lasss T nil) (lxx_lasrr))
		(	(= return# 2) (ladelete) (lxx_lasrr))
		(	(= return# 3) (lxx_dczt) (lxx_lasrr))
		(	(= return# 4) (lxx_jzzt) (lxx_lasrr))
		(	(= return# 5)
			(alert "\n快速保存WW1~WW20,\n快速恢复QQ1~QQ20\n保存的都是以数字命名的1~20")
			(lxx_GX_SUB);更新快捷键
			(lxx_lasrr)
		)
	)
	(if num (cons num (nth num lst)))
)


(defun c:lxx_laman( / ladict1 ladict n statenemelst num m )
	(setq
		ladict1 (vla-GetExtensionDictionary (vla-get-layers (vla-get-ActiveDocument (vlax-get-acad-object))))
		m (vla-get-count ladict1)
	)
	(repeat m
		(setq
			m (1- m)
			ladict (vla-item ladict1 m)
			n (vla-get-count ladict)
		)
		(repeat n
			(setq
				n (1- n)
				statenemelst (cons (vla-get-name (vla-item ladict n)) statenemelst)
			)
		)
	)
	(and
		;(setq statenemelst (vl-remove-if '(lambda(x)(= "*" (substr x 1 1))) statenemelst))
		(setq num (car (lxx_xsdhk statenemelst)))
		(command "_.layer" "a" "r" (nth num statenemelst) "" "")
	)
	(princ)
)

(defun lxx_xsdhk (lst / x replace lsdcl fn dclid num  )
	(setq fn (open (setq lsdcl (vl-filename-mktemp "tmp" "" ".dcl")) "w"))
	(foreach x
				'(
					"yyy : dialog{label=\"StateManager\";"
					":list_box{key=\"9\";height=18;width=12;}"
					":button{key=\"cancel\";label=\"Cancel\";is_cancel=true;width=1;height=2;}}"
				)
		(write-line x fn)
	)
	(close fn)
	(setq dclid (load_dialog lsdcl))
	(vl-file-delete lsdcl)
	(new_dialog "yyy" dclid "" screenpt)
	(lxx_adlst "9" lst)
	(action_tile "9" "(setq num (atoi $value))(done_dialog)")
	(start_dialog)
	(unload_dialog dclid)
	(if num
		(cons num (nth num lst))
	)
)
(princ)
