Function: toolbarx-process-dropdown-group
toolbarx-process-dropdown-group is a byte-compiled function defined in
toolbar-x.el.
Signature
(toolbarx-process-dropdown-group DROPDOWN MEANING-ALIST PROPS SWITCHES)
Documentation
Process buttons that appear according to dropdown menu.
Process a dropdown group DROPDOWN with meaning alist
MEANING-ALIST, external property list PROP and GLOBAL-FLAG
specifying scope. For a complete description, see documentation
of toolbarx-install-toolbar. The processed buttons are stored
in the end of SWITCHES, which is returned.
Source Code
;; Defined in ~/.emacs.d/elpa/auctex-14.1.2/toolbar-x.el
(defun toolbarx-process-dropdown-group (dropdown meaning-alist props switches)
"Process buttons that appear according to dropdown menu.
Process a dropdown group DROPDOWN with meaning alist
MEANING-ALIST, external property list PROP and GLOBAL-FLAG
specifying scope. For a complete description, see documentation
of `toolbarx-install-toolbar'. The processed buttons are stored
in the end of SWITCHES, which is returned."
(let* ((dropdown-group (if (eq (car dropdown) :dropdown-group)
(cdr dropdown)
dropdown))
(dropdown-list-splited
(toolbarx-separate-options dropdown-group
(append
(nth 1 toolbarx-button-props)
(nth 1 toolbarx-dropdown-props))))
(dropdown-list (car dropdown-list-splited))
(dropdown-props (cdr dropdown-list-splited))
(merged-props
(toolbarx-merge-props dropdown-props props
(append (nth 2 toolbarx-button-props)
(nth 2 toolbarx-dropdown-props))
(append (nth 3 toolbarx-button-props)
(nth 3 toolbarx-dropdown-props))))
(merged-props-button-only
(let* ((props-button-only)
(prop))
(dolist (p (nth 1 toolbarx-button-props) props-button-only)
(setq prop (memq p merged-props))
(when prop
(setq props-button-only
(append (list p (cadr prop))
props-button-only))))))
(merged-props-dropdown-only
(let* ((props-dropdown-only)
(prop))
(dolist (p (nth 1 toolbarx-dropdown-props) props-dropdown-only)
(setq prop (memq p merged-props))
(when prop
(setq props-dropdown-only
(append (list p (cadr prop))
props-dropdown-only))))))
;; get value for each property and check type ONLY for props that do
;; not concern the dropdown button, like `:type', `:save', etc. The
;; props that concern the button are going to be handled in refresh
;; time.
(filtered-dropdown-group-props-only
(let* ((filtered-props-temp)
(prop-good-val)
(prop))
(save-match-data
(dolist (p (nth 0 toolbarx-dropdown-props) filtered-props-temp)
(unless (string-match "^:dropdown-.*$"
(symbol-name (car p)))
;; property -> (car p)
;; test type function -> (cadr p)
(setq prop (memq (car p) merged-props-dropdown-only))
;; if so, check if value is of correct type
(when prop
(setq prop-good-val (funcall (cadr p) (cadr prop)))
(if (car prop-good-val)
(setq filtered-props-temp
(append filtered-props-temp
(list (car p) (cdr prop-good-val))))
(display-warning
'toolbarx
(format (concat "Wrong type for value in "
"property `%s' in dropdown group")
(car p))))))))))
;; properties for the dropdown button from dropdown merged properties
(dropdown-button-props
(let* ((props))
(save-match-data
(dolist (pr (nth 1 toolbarx-dropdown-props))
(when (and (memq pr merged-props-dropdown-only)
(string-match "^:dropdown-\\(.*\\)$"
(symbol-name pr)))
(let* ((new-pr (intern (concat ":"
(substring (symbol-name pr)
(match-beginning 1)
(match-end 1)))))
(val (cadr (memq pr merged-props-dropdown-only))))
(setq props (append (list new-pr val) props))))))
(unless (memq :image props)
(setq props (append (list :image "dropdown") props)))
props))
(dropdown-button-without-command
(cons 'dropdown dropdown-button-props))
;; `:type' defaults to `radio'
(type (if (memq :type filtered-dropdown-group-props-only)
(cadr (memq :type filtered-dropdown-group-props-only))
'radio))
;; `:default' defaults to 1 or nil depending on `type'
;; if type is toggle and default is not a list, but a
;; integer, set as the list with integer
(default
(let* ((memq-default (memq :default
filtered-dropdown-group-props-only))
(def-temp (cadr memq-default))
(default-temp (if memq-default
def-temp
(if (eq type 'radio) 1 (list 1)))))
default-temp))
;; `:save' defaults to nil and require `:variable'
(save (let* ((save-temp
(when (memq :save filtered-dropdown-group-props-only)
(cadr (memq :save
filtered-dropdown-group-props-only)))))
(if (and save-temp
(not (memq :variable
filtered-dropdown-group-props-only)))
(progn
(display-warning
'toolbarx
(concat "`:save' property with non-nil value should "
"be used only with the `:variable' property; "
"using value nil for `:save'."))
nil)
save-temp)))
;; `:title' defaults to nil
(title (when (memq :title filtered-dropdown-group-props-only)
(cadr (memq :title filtered-dropdown-group-props-only))))
;; the menu variable is buildt from the `:variable' option or
;; make a symbol not used
(variable (if (memq :variable filtered-dropdown-group-props-only)
(cadr (memq :variable
filtered-dropdown-group-props-only))
(let* ((count 0)
(symb (intern (format
"toolbarx-internal-menu-var-%d"
count))))
(while (boundp symb)
(setq count (1+ count))
(setq symb
(intern (format "toolbarx-internal-menu-var-%d"
count))))
symb)))
;; auxiliary variables
(list-strings)
(list-buttons))
;; setting `variable'
(if save
(custom-declare-variable
variable default
"Used as variable of dropdown menu defined with `toolbarx'.")
(when (not (boundp variable))
(set variable default)))
;; now check `variable' content
(set variable
(let ((val (symbol-value variable)))
(if (eq type 'toggle)
(if (listp val)
val
(if (integerp val)
(list val)
(list 1)))
;; then, type is radio
(if (integerp val)
val
(if (and val
(listp val)
(integerp (car val)))
(car val)
1)))))
;; === buiding `list-strings' and `list-buttons' ===
;; if only symbols, build `list-strings' and `list-buttons' from symbols
(if (let ((only-symbols-flag t))
(dolist (i dropdown-list only-symbols-flag)
(setq only-symbols-flag (and only-symbols-flag (symbolp i)))))
(let ((count 0))
(dolist (i dropdown-list)
;; list-strings and list-buttons are built reversed
(setq list-strings (cons (toolbarx-make-string-from-symbol i)
list-strings))
(setq count (1+ count))
(setq list-buttons (cons (list i
:insert
(if (eq type 'radio)
(list 'eq count variable)
(list 'memq count variable)))
list-buttons))))
;; if not, the it must start with string
(unless (stringp (car dropdown-list))
(error "%s %s %s"
"If not all items on dropdown are symbols, then a string"
"must come before each set of buttons; no string found"
"in first position"))
(let ((count 0)
(elem)
(temp-list-buttons))
(while dropdown-list
(setq elem (car dropdown-list))
(setq dropdown-list (cdr dropdown-list))
(if (stringp elem)
;; if string, output `temp-list-buttons' and prepair it again
(progn
;; list-strings and list-buttons are buildt reversed
(setq list-strings (cons elem list-strings))
(when temp-list-buttons
(setq list-buttons (cons (append (nreverse temp-list-buttons)
(list :insert
(if (eq type 'radio)
(list 'eq count
variable)
(list 'memq count
variable))))
list-buttons)))
(setq temp-list-buttons nil)
(setq count (1+ count)))
;; else, if not string, just insert it to `temp-list-buttons'
;; which is also buildt reversed
(setq temp-list-buttons (cons elem temp-list-buttons))))
;; output last temp list, left behind
(when temp-list-buttons
(setq list-buttons (cons (append (nreverse
temp-list-buttons)
(list
:insert (if (eq type 'radio)
(list 'eq count
variable)
(list 'memq count
variable))))
list-buttons)))))
;; lists were made reversed (elements inserted at the beginning)
(setq list-strings (nreverse list-strings))
(setq list-buttons (nreverse list-buttons))
;; now, pass `list-buttons' as a group to `toolbarx-process-group'
(let ((current-switches switches))
(setq current-switches
(toolbarx-process-group list-buttons meaning-alist
merged-props ; pass non-processed props
current-switches))
(setq current-switches
;; outputing dropdown button
(toolbarx-process-group (append dropdown-button-without-command
(list :command
(toolbarx-mount-popup-menu
list-strings variable type
title save)))
meaning-alist merged-props-button-only
switches))
current-switches)))