;;; newst-treeview.el --- Treeview frontend for newsticker.
-;; Copyright (C) 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2011 Free Software Foundation, Inc.
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Filename: newst-treeview.el
;; URL: http://www.nongnu.org/newsticker
;; Created: 2007
;; Keywords: News, RSS, Atom
-;; Time-stamp: "31. Oktober 2008, 20:44:46 (ulf)"
+;; Package: newsticker
;; ======================================================================
;;; History:
;;
-
;; ======================================================================
;;; Code:
-(require 'newsticker-reader "newst-reader")
+(require 'newst-reader)
(require 'widget)
(require 'tree-widget)
(require 'wid-edit)
(defface newsticker-treeview-face
'((((class color) (background dark))
- (:family "helvetica" :foreground "misty rose" :bold nil))
+ (:family "sans" :foreground "white" :bold nil))
(((class color) (background light))
- (:family "helvetica" :foreground "black" :bold nil)))
+ (:family "sans" :foreground "black" :bold nil)))
"Face for newsticker tree."
:group 'newsticker-treeview)
30
"Width of tree window in treeview layout.
See also `newsticker-treeview-listwindow-height'."
- :type 'int
+ :type 'integer
:group 'newsticker-treeview)
(defcustom newsticker-treeview-listwindow-height
10
"Height of list window in treeview layout.
See also `newsticker-treeview-treewindow-width'."
- :type 'int
+ :type 'integer
:group 'newsticker-treeview)
(defcustom newsticker-treeview-automatically-mark-displayed-items-as-old
"Name of the newsticker groups settings file."
:type 'string
:group 'newsticker-treeview)
+(make-obsolete 'newsticker-groups-filename 'newsticker-dir "23.1")
;; ======================================================================
;;; internal variables
;; ======================================================================
(defvar newsticker--treeview-windows nil)
(defvar newsticker--treeview-buffers nil)
-(defvar newsticker--treeview-current-feed nil)
+(defvar newsticker--treeview-current-feed nil
+ "Feed name of currently shown item.")
(defvar newsticker--treeview-current-vfeed nil)
(defvar newsticker--treeview-list-show-feed nil)
(defvar newsticker--saved-window-config nil)
(string= (widget-get node1 :tag) (widget-get node2 :tag)))))
(defun newsticker--treeview-do-get-node-of-feed (feed-name startnode)
- "Recursivly search node for feed FEED-NAME starting from STARTNODE."
+ "Recursively search node for feed FEED-NAME starting from STARTNODE."
;;(message "%s/%s" feed-name (widget-get startnode :nt-feed))
(if (string= feed-name (or (widget-get startnode :nt-feed)
(widget-get startnode :nt-vfeed)))
newsticker--treeview-vfeed-tree)))
(defun newsticker--treeview-do-get-node (id startnode)
- "Recursivly search node with ID starting from STARTNODE."
+ "Recursively search node with ID starting from STARTNODE."
(if (newsticker--treeview-ids-eq id (widget-get startnode :nt-id))
(throw 'found startnode)
(let ((children (widget-get startnode :children)))
"Add news ITEM for FEED to newsticker treeview list window.
If string SHOW-FEED is non-nil it is shown in the item string."
(setq newsticker--treeview-list-show-feed show-feed)
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(let* ((inhibit-read-only t)
pos1 pos2)
(goto-char (point-max))
(defun newsticker--treeview-list-clear ()
"Clear the newsticker treeview list window."
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(let ((inhibit-read-only t))
(erase-buffer)
(kill-all-local-variables)
(defun newsticker--treeview-list-update-faces ()
"Update faces in the treeview list buffer."
(let (pos-sel)
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
- (let ((inhibit-read-only t))
- (goto-char (point-min))
- (while (not (eobp))
- (let* ((pos (save-excursion (end-of-line) (point)))
- (item (get-text-property (point) :nt-item))
- (age (newsticker--age item))
- (selected (get-text-property (point) :nt-selected))
- (face (cond ((eq age 'new)
- 'newsticker-treeview-new-face)
- ((eq age 'old)
- 'newsticker-treeview-old-face)
- ((eq age 'immortal)
- 'newsticker-treeview-immortal-face)
- ((eq age 'obsolete)
- 'newsticker-treeview-obsolete-face)
- (t
- 'bold))))
- (put-text-property (point) pos 'face face)
- (if selected
- (move-overlay newsticker--selection-overlay (point)
- (1+ pos) ;include newline
- (current-buffer)))
- (if selected (setq pos-sel (point)))
- (forward-line 1)
- (beginning-of-line))))) ;; FIXME!?
+ (with-current-buffer (newsticker--treeview-list-buffer)
+ (save-excursion
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (let* ((pos (point-at-eol))
+ (item (get-text-property (point) :nt-item))
+ (age (newsticker--age item))
+ (selected (get-text-property (point) :nt-selected))
+ (face (cond ((eq age 'new)
+ 'newsticker-treeview-new-face)
+ ((eq age 'old)
+ 'newsticker-treeview-old-face)
+ ((eq age 'immortal)
+ 'newsticker-treeview-immortal-face)
+ ((eq age 'obsolete)
+ 'newsticker-treeview-obsolete-face)
+ (t
+ 'bold))))
+ (put-text-property (point) pos 'face face)
+ (if selected
+ (move-overlay newsticker--selection-overlay (point)
+ (1+ pos) ;include newline
+ (current-buffer)))
+ (if selected (setq pos-sel (point)))
+ (forward-line 1)
+ (beginning-of-line)))))) ;; FIXME!?
(when pos-sel
(if (window-live-p (newsticker--treeview-list-window))
(set-window-point (newsticker--treeview-list-window) pos-sel)))))
(defun newsticker--treeview-list-clear-highlight ()
"Clear the highlight in the treeview list buffer."
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(let ((inhibit-read-only t))
(put-text-property (point-min) (point-max) :nt-selected nil))
(newsticker--treeview-list-update-faces)))
"Update the highlight in the treeview list buffer."
(newsticker--treeview-list-clear-highlight)
(let (pos num-lines)
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(let ((inhibit-read-only t))
- (put-text-property (save-excursion (beginning-of-line) (point))
- (save-excursion (end-of-line) (point))
- :nt-selected t))
+ (put-text-property (point-at-bol) (point-at-eol) :nt-selected t))
(newsticker--treeview-list-update-faces))))
(defun newsticker--treeview-list-highlight-start ()
"Return position of selection in treeview list buffer."
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
- (goto-char (point-min))
- (next-single-property-change (point) :nt-selected)))
+ (with-current-buffer (newsticker--treeview-list-buffer)
+ (save-excursion
+ (goto-char (point-min))
+ (next-single-property-change (point) :nt-selected))))
(defun newsticker--treeview-list-update (clear-buffer)
"Update the faces and highlight in the treeview list buffer.
'face face
'keymap newsticker-treeview-list-sort-button-map)))
+(defun newsticker--treeview-list-select (item)
+ "Select ITEM in treeview's list buffer."
+ (newsticker--treeview-list-clear-highlight)
+ (let (pos num-lines)
+ (save-current-buffer
+ (set-buffer (newsticker--treeview-list-buffer))
+ (goto-char (point-min))
+ (catch 'found
+ (while t
+ (let ((it (get-text-property (point) :nt-item)))
+ (when (eq it item)
+ (newsticker--treeview-list-update-highlight)
+ (newsticker--treeview-list-update-faces)
+ (newsticker--treeview-item-show
+ item (get-text-property (point) :nt-feed))
+ (throw 'found t)))
+ (forward-line 1)
+ (when (eobp)
+ (goto-char (point-min))
+ (throw 'found nil)))))))
+
;; ======================================================================
;;; item window
;; ======================================================================
(defun newsticker--treeview-item-show-text (title description)
"Show text in treeview item buffer consisting of TITLE and DESCRIPTION."
- (save-excursion
- (set-buffer (newsticker--treeview-item-buffer))
+ (with-current-buffer (newsticker--treeview-item-buffer)
(when (fboundp 'w3m-process-stop)
(w3m-process-stop (current-buffer)))
(let ((inhibit-read-only t))
(insert "\n\n" description)
(when newsticker-justification
(fill-region (point-min) (point-max) newsticker-justification))
- (newsticker-treeview-mode)
+ (newsticker-treeview-item-mode)
(goto-char (point-min)))))
-(defun newsticker--treeview-item-show (item feed)
- "Show news ITEM coming from FEED in treeview item buffer."
- (save-excursion
- (set-buffer (newsticker--treeview-item-buffer))
+(defun newsticker--treeview-item-show (item feed-name-symbol)
+ "Show news ITEM coming from FEED-NAME-SYMBOL in treeview item buffer."
+ (setq newsticker--treeview-current-feed (symbol-name feed-name-symbol))
+ (with-current-buffer (newsticker--treeview-item-buffer)
(when (fboundp 'w3m-process-stop)
(w3m-process-stop (current-buffer)))
(let ((inhibit-read-only t)
(kill-all-local-variables)
(remove-overlays)
- (when (and item feed)
+ (when (and item feed-name-symbol)
(let ((wwidth (1- (window-width (newsticker--treeview-item-window)))))
(if newsticker-use-full-width
(set (make-local-variable 'fill-column) wwidth))
(not is-rendered-HTML))
(fill-region marker1 marker2 newsticker-justification))
- (newsticker-treeview-mode)
+ (newsticker-treeview-item-mode)
(goto-char (point-min))
;; insert logo at top
(let* ((newsticker-enable-logo-manipulations nil)
- (img (newsticker--image-read feed nil)))
+ (img (newsticker--image-read feed-name-symbol nil)))
(if (and (display-images-p) img)
(newsticker--insert-image img (car item))
- (insert (newsticker--real-feed-name feed))))
+ (insert (newsticker--real-feed-name feed-name-symbol))))
(add-text-properties (point-min) (point)
(list 'face 'newsticker-feed-face
'mouse-face 'highlight
(set-buffer (newsticker--treeview-item-buffer))
(let ((inhibit-read-only t))
(erase-buffer))
- (newsticker-treeview-mode)))
+ (newsticker-treeview-item-mode)))
;; ======================================================================
;;; Tree window
well. Argument IGNORE is ignored. Note that this function, if
called recursively, makes w invalid. You should keep w's nt-id in
that case."
- ;;(message "newsticker--treeview-tree-update-tag %s, %s" (widget-get w :tag)
- ;; (widget-type w))
(let* ((parent (widget-get w :parent))
(feed (or (widget-get w :nt-feed) (widget-get parent :nt-feed)))
(vfeed (or (widget-get w :nt-vfeed) (widget-get parent :nt-vfeed)))
(let ((p (point))
(notify (widget-get w :notify)))
;; FIXME: This moves point!!!!
- (save-excursion
- (set-buffer (newsticker--treeview-tree-buffer))
+ (with-current-buffer (newsticker--treeview-tree-buffer)
(widget-value-set w (widget-value w)))
(goto-char p))))))
(newsticker--treeview-get-current-node)
:parent) :from)))
(when (or (integerp pos) (and (markerp pos) (marker-position pos)))
- (save-excursion
- (set-buffer (newsticker--treeview-tree-buffer))
+ (with-current-buffer (newsticker--treeview-tree-buffer)
(goto-char pos)
(move-overlay newsticker--tree-selection-overlay
- (save-excursion (beginning-of-line) (point))
- (save-excursion (end-of-line) (1+ (point)))
+ (point-at-bol) (1+ (point-at-eol))
(current-buffer)))
(if (window-live-p (newsticker--treeview-tree-window))
(set-window-point (newsticker--treeview-tree-window) pos)))))
;; ======================================================================
;;; Toolbar
;; ======================================================================
-;;(makunbound 'newsticker-treeview-tool-bar-map)
(defvar newsticker-treeview-tool-bar-map
(if (featurep 'xemacs)
nil
(if (boundp 'tool-bar-map)
(let ((tool-bar-map (make-sparse-keymap)))
+ (tool-bar-add-item "newsticker/prev-feed"
+ 'newsticker-treeview-prev-feed
+ 'newsticker-treeview-prev-feed
+ :help "Go to previous feed"
+ ;;:enable '(newsticker-previous-feed-available-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/prev-item"
+ 'newsticker-treeview-prev-item
+ 'newsticker-treeview-prev-item
+ :help "Go to previous item"
+ ;;:enable '(newsticker-previous-item-available-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/next-item"
+ 'newsticker-treeview-next-item
+ 'newsticker-treeview-next-item
+ :visible t
+ :help "Go to next item"
+ ;;:enable '(newsticker-next-item-available-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/next-feed"
+ 'newsticker-treeview-next-feed
+ 'newsticker-treeview-next-feed
+ :help "Go to next feed"
+ ;;:enable '(newsticker-next-feed-available-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/mark-immortal"
+ 'newsticker-treeview-toggle-item-immortal
+ 'newsticker-treeview-toggle-item-immortal
+ :help "Toggle current item as immortal"
+ ;;:enable '(newsticker-item-not-immortal-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/mark-read"
+ 'newsticker-treeview-mark-item-old
+ 'newsticker-treeview-mark-item-old
+ :help "Mark current item as read"
+ ;;:enable '(newsticker-item-not-old-p) FIXME
+ )
+ (tool-bar-add-item "newsticker/get-all"
+ 'newsticker-get-all-news
+ 'newsticker-get-all-news
+ :help "Get news for all feeds")
+ (tool-bar-add-item "newsticker/update"
+ 'newsticker-treeview-update
+ 'newsticker-treeview-update
+ :help "Update newsticker buffer")
+ (tool-bar-add-item "newsticker/browse-url"
+ 'newsticker-browse-url
+ 'newsticker-browse-url
+ :help "Browse URL for item at point")
+ ;; standard icons / actions
(define-key tool-bar-map [newsticker-sep-1]
(list 'menu-item "--double-line"))
- (define-key tool-bar-map [newsticker-browse-url]
- (list 'menu-item "newsticker-browse-url"
- 'newsticker-browse-url
- :visible t
- :help "Browse URL for item at point"
- :image newsticker--browse-image))
- (define-key tool-bar-map [newsticker-buffer-force-update]
- (list 'menu-item "newsticker-treeview-update"
- 'newsticker-treeview-update
- :visible t
- :help "Update newsticker buffer"
- :image newsticker--update-image
- :enable t))
- (define-key tool-bar-map [newsticker-get-all-news]
- (list 'menu-item "newsticker-get-all-news" 'newsticker-get-all-news
- :visible t
- :help "Get news for all feeds"
- :image newsticker--get-all-image))
- (define-key tool-bar-map [newsticker-mark-item-at-point-as-read]
- (list 'menu-item "newsticker-treeview-mark-item-old"
- 'newsticker-treeview-mark-item-old
- :visible t
- :image newsticker--mark-read-image
- :help "Mark current item as read"
- ;;:enable '(newsticker-item-not-old-p) FIXME
- ))
- (define-key tool-bar-map [newsticker-mark-item-at-point-as-immortal]
- (list 'menu-item "newsticker-treeview-toggle-item-immortal"
- 'newsticker-treeview-toggle-item-immortal
- :visible t
- :image newsticker--mark-immortal-image
- :help "Toggle current item as immortal"
- :enable t
- ;;'(newsticker-item-not-immortal-p) FIXME
- ))
- (define-key tool-bar-map [newsticker-next-feed]
- (list 'menu-item "newsticker-treeview-next-feed"
- 'newsticker-treeview-next-feed
- :visible t
- :help "Go to next feed"
- :image newsticker--next-feed-image
- :enable t
- ;;'(newsticker-next-feed-available-p) FIXME
- ))
- (define-key tool-bar-map [newsticker-treeview-next-item]
- (list 'menu-item "newsticker-treeview-next-item"
- 'newsticker-treeview-next-item
- :visible t
- :help "Go to next item"
- :image newsticker--next-item-image
- :enable t
- ;;'(newsticker-next-item-available-p) FIXME
- ))
- (define-key tool-bar-map [newsticker-treeview-prev-item]
- (list 'menu-item "newsticker-treeview-prev-item"
- 'newsticker-treeview-prev-item
- :visible t
- :help "Go to previous item"
- :image newsticker--previous-item-image
- :enable t
- ;;'(newsticker-previous-item-available-p) FIXME
- ))
- (define-key tool-bar-map [newsticker-treeview-prev-feed]
- (list 'menu-item "newsticker-treeview-prev-feed"
- 'newsticker-treeview-prev-feed
- :visible t
- :help "Go to previous feed"
- :image newsticker--previous-feed-image
- :enable t
- ;;'(newsticker-previous-feed-available-p) FIXME
- ))
- ;; standard icons / actions
(tool-bar-add-item "close"
'newsticker-treeview-quit
'newsticker-treeview-quit
(defun newsticker-treeview-browse-url ()
"Call `browse-url' for the link of the item at point."
(interactive)
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(let ((url (get-text-property (point) :nt-link)))
(when url
(browse-url url)
(get-buffer-create "*Newsticker Item*") t)
(unless newsticker--selection-overlay
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(setq newsticker--selection-overlay (make-overlay (point-min)
(point-max)))
(overlay-put newsticker--selection-overlay 'face
'newsticker-treeview-selection-face)))
(unless newsticker--tree-selection-overlay
- (save-excursion
- (set-buffer (newsticker--treeview-tree-buffer))
+ (with-current-buffer (newsticker--treeview-tree-buffer)
(setq newsticker--tree-selection-overlay (make-overlay (point-min)
(point-max)))
(overlay-put newsticker--tree-selection-overlay 'face
"Update all treeview buffers and windows.
Note: does not update the layout."
(interactive)
- (newsticker--cache-update)
- (newsticker--group-manage-orphan-feeds)
- (newsticker--treeview-list-update t)
- (newsticker--treeview-item-update)
- (newsticker--treeview-tree-update-tags)
- (cond (newsticker--treeview-current-feed
- (newsticker--treeview-list-items newsticker--treeview-current-feed))
- (newsticker--treeview-current-vfeed
- (newsticker--treeview-list-items-with-age
- (intern newsticker--treeview-current-vfeed))))
- (newsticker--treeview-tree-update-highlight)
- (newsticker--treeview-list-update-highlight))
+ (let ((cur-item (newsticker--treeview-get-selected-item)))
+ (if (newsticker--group-manage-orphan-feeds)
+ (newsticker--treeview-tree-update))
+ (newsticker--treeview-list-update t)
+ (newsticker--treeview-item-update)
+ (newsticker--treeview-tree-update-tags)
+ (cond (newsticker--treeview-current-feed
+ (newsticker--treeview-list-items newsticker--treeview-current-feed))
+ (newsticker--treeview-current-vfeed
+ (newsticker--treeview-list-items-with-age
+ (intern newsticker--treeview-current-vfeed))))
+ (newsticker--treeview-tree-update-highlight)
+ (newsticker--treeview-list-update-highlight)
+ (let ((cur-feed (or newsticker--treeview-current-feed
+ newsticker--treeview-current-vfeed)))
+ (if (and cur-feed cur-item)
+ (newsticker--treeview-list-select cur-item)))))
(defun newsticker-treeview-quit ()
"Quit newsticker treeview."
(interactive)
- (newsticker-treeview-save)
(setq newsticker--sentinel-callback nil)
(bury-buffer "*Newsticker Tree*")
(bury-buffer "*Newsticker List*")
(when newsticker--frame
(if (frame-live-p newsticker--frame)
(delete-frame newsticker--frame))
- (setq newsticker--frame nil)))
+ (setq newsticker--frame nil))
+ (newsticker-treeview-save))
(defun newsticker-treeview-save ()
"Save newsticker data including treeview settings."
(interactive)
- (newsticker--cache-save)
- (save-excursion
- (let ((coding-system-for-write 'utf-8)
- (buf (find-file-noselect newsticker-groups-filename)))
- (when buf
- (set-buffer buf)
+ (let ((coding-system-for-write 'utf-8)
+ (buf (find-file-noselect (concat newsticker-dir "/groups"))))
+ (when buf
+ (with-current-buffer buf
(setq buffer-undo-list t)
(erase-buffer)
(insert ";; -*- coding: utf-8 -*-\n")
(insert (prin1-to-string newsticker-groups))
- (save-buffer)))))
+ (save-buffer)
+ (kill-buffer)))))
(defun newsticker--treeview-load ()
"Load treeview settings."
(let* ((coding-system-for-read 'utf-8)
- (buf (and (file-exists-p newsticker-groups-filename)
- (find-file-noselect newsticker-groups-filename))))
+ (filename
+ (or (and (file-exists-p newsticker-groups-filename)
+ (y-or-n-p
+ (format "Old newsticker groups (%s) file exists. Read it? "
+ newsticker-groups-filename))
+ newsticker-groups-filename)
+ (concat newsticker-dir "/groups")))
+ (buf (and (file-exists-p filename)
+ (find-file-noselect filename))))
+ (and (file-exists-p newsticker-groups-filename)
+ (y-or-n-p (format "Delete old newsticker groups file? "))
+ (delete-file newsticker-groups-filename))
(when buf
(set-buffer buf)
(goto-char (point-min))
(setq newsticker-groups (read buf))
(error
(message "Error while reading newsticker groups file!")
- (setq newsticker-groups nil))))))
+ (setq newsticker-groups nil)))
+ (kill-buffer buf))))
(defun newsticker-treeview-scroll-item ()
(interactive)
(newsticker--treeview-restore-layout)
(newsticker--treeview-list-update-highlight)
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(beginning-of-line)
(let ((item (get-text-property (point) :nt-item))
(feed (get-text-property (point) :nt-feed)))
(forward-line -1))
(newsticker-treeview-show-item))
-(defun newsticker-treeview-next-new-or-immortal-item ()
- "Move to next new or immortal item."
+(defun newsticker-treeview-next-new-or-immortal-item (&optional
+ current-item-counts
+ dont-wrap-trees)
+ "Move to next new or immortal item.
+Will move to next feed until an item is found. Will not move if
+optional argument CURRENT-ITEM-COUNTS is t and current item is
+new or immortal. Will not move from virtual to ordinary feed
+tree or vice versa if optional argument DONT-WRAP-TREES is non-nil."
(interactive)
(newsticker--treeview-restore-layout)
(newsticker--treeview-list-clear-highlight)
- (catch 'found
- (let ((index (newsticker-treeview-next-item)))
- (while t
- (save-current-buffer
- (set-buffer (newsticker--treeview-list-buffer))
- (forward-line 1)
- (when (eobp)
- (forward-line -1)
- (throw 'found nil)))
- (when (memq (newsticker--age
- (newsticker--treeview-get-selected-item)) '(new immortal))
- (newsticker-treeview-show-item)
- (throw 'found t))))))
+ (unless (catch 'found
+ (let ((move (not current-item-counts)))
+ (while t
+ (save-current-buffer
+ (set-buffer (newsticker--treeview-list-buffer))
+ (when move (forward-line 1)
+ (when (eobp)
+ (forward-line -1)
+ (throw 'found nil))))
+ (when (memq (newsticker--age
+ (newsticker--treeview-get-selected-item))
+ '(new immortal))
+ (newsticker-treeview-show-item)
+ (throw 'found t))
+ (setq move t))))
+ (let ((wrap-trees (not dont-wrap-trees)))
+ (when (or (newsticker-treeview-next-feed t)
+ (and wrap-trees (newsticker--treeview-first-feed)))
+ (newsticker-treeview-next-new-or-immortal-item t t)))))
(defun newsticker-treeview-prev-new-or-immortal-item ()
- "Move to previous new or immortal item."
+ "Move to previous new or immortal item.
+Will move to previous feed until an item is found."
(interactive)
(newsticker--treeview-restore-layout)
(newsticker--treeview-list-clear-highlight)
- (catch 'found
- (let ((index (newsticker-treeview-next-item)))
- (while t
- (save-current-buffer
- (set-buffer (newsticker--treeview-list-buffer))
- (forward-line -1)
- (when (bobp)
- (throw 'found nil)))
- (when (memq (newsticker--age
- (newsticker--treeview-get-selected-item)) '(new immortal))
- (newsticker-treeview-show-item)
- (throw 'found t))))))
+ (unless (catch 'found
+ (while t
+ (save-current-buffer
+ (set-buffer (newsticker--treeview-list-buffer))
+ (when (bobp)
+ (throw 'found nil))
+ (forward-line -1))
+ (when (memq (newsticker--age
+ (newsticker--treeview-get-selected-item))
+ '(new immortal))
+ (newsticker-treeview-show-item)
+ (throw 'found t))
+ (when (bobp)
+ (throw 'found nil))))
+ (when (newsticker-treeview-prev-feed t)
+ (set-buffer (newsticker--treeview-list-buffer))
+ (goto-char (point-max))
+ (newsticker-treeview-prev-new-or-immortal-item))))
(defun newsticker--treeview-get-selected-item ()
"Return item that is currently selected in list buffer."
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(beginning-of-line)
(get-text-property (point) :nt-item)))
(setcar (nthcdr 4 item) new-age)
;; clean up ticker FIXME
)
- (newsticker--cache-update))
+ (newsticker--cache-save-feed
+ (newsticker--cache-get-feed (intern newsticker--treeview-current-feed)))
+ (newsticker--treeview-tree-do-update-tags newsticker--treeview-vfeed-tree))
(defun newsticker-treeview-mark-list-items-old ()
"Mark all listed items as old."
(interactive)
(let ((current-feed (or newsticker--treeview-current-feed
newsticker--treeview-current-vfeed)))
- (save-excursion
- (set-buffer (newsticker--treeview-list-buffer))
+ (with-current-buffer (newsticker--treeview-list-buffer)
(goto-char (point-min))
(while (not (eobp))
(let ((item (get-text-property (point) :nt-item)))
(defun newsticker--treeview-set-current-node (node)
"Make NODE the current node."
- (save-excursion
- (set-buffer (newsticker--treeview-tree-buffer))
+ (with-current-buffer (newsticker--treeview-tree-buffer)
(setq newsticker--treeview-current-node-id
(widget-get node :nt-id))
(setq newsticker--treeview-current-feed (widget-get node :nt-feed))
(node
(widget-apply-action node)))))
-(defun newsticker-treeview-next-feed ()
- "Move to next feed."
+(defun newsticker--treeview-first-feed ()
+ "Jump to the depth-first feed in the `newsticker-groups' tree."
+ (newsticker-treeview-jump
+ (car (reverse (newsticker--group-get-feeds newsticker-groups t)))))
+
+(defun newsticker-treeview-next-feed (&optional stay-in-tree)
+ "Move to next feed.
+Optional argument STAY-IN-TREE prevents moving from real feed
+tree to virtual feed tree or vice versa.
+Return t if a new feed was activated, nil otherwise."
(interactive)
(newsticker--treeview-restore-layout)
- (let ((cur (newsticker--treeview-get-current-node)))
- ;;(message "newsticker-treeview-next-feed from %s"
- ;; (widget-get cur :tag))
- (if cur
- (let ((new (or (newsticker--treeview-get-next-sibling cur)
- (newsticker--treeview-get-next-uncle cur)
- (newsticker--treeview-get-other-tree))))
- (newsticker--treeview-activate-node new))
- (newsticker--treeview-activate-node
- (car (widget-get newsticker--treeview-feed-tree :children)))))
- (newsticker--treeview-tree-update-highlight))
+ (let ((cur (newsticker--treeview-get-current-node))
+ (new nil))
+ (setq new
+ (if cur
+ (or (newsticker--treeview-get-next-sibling cur)
+ (newsticker--treeview-get-next-uncle cur)
+ (and (not stay-in-tree)
+ (newsticker--treeview-get-other-tree)))
+ (car (widget-get newsticker--treeview-feed-tree :children))))
+ (if new
+ (progn
+ (newsticker--treeview-activate-node new)
+ (newsticker--treeview-tree-update-highlight)
+ (not (eq new cur)))
+ nil)))
-(defun newsticker-treeview-prev-feed ()
- "Move to previous feed."
+(defun newsticker-treeview-prev-feed (&optional stay-in-tree)
+ "Move to previous feed.
+Optional argument STAY-IN-TREE prevents moving from real feed
+tree to virtual feed tree or vice versa.
+Return t if a new feed was activated, nil otherwise."
(interactive)
(newsticker--treeview-restore-layout)
- (let ((cur (newsticker--treeview-get-current-node)))
- (message "newsticker-treeview-prev-feed from %s"
- (widget-get cur :tag))
+ (let ((cur (newsticker--treeview-get-current-node))
+ (new nil))
(if cur
- (let ((new (or (newsticker--treeview-get-prev-sibling cur)
- (newsticker--treeview-get-prev-uncle cur)
- (newsticker--treeview-get-other-tree))))
- (newsticker--treeview-activate-node new t))
- (newsticker--treeview-activate-node
- (car (widget-get newsticker--treeview-feed-tree :children)) t)))
- (newsticker--treeview-tree-update-highlight))
+ (progn
+ (setq new
+ (if cur
+ (or (newsticker--treeview-get-prev-sibling cur)
+ (newsticker--treeview-get-prev-uncle cur)
+ (and (not stay-in-tree)
+ (newsticker--treeview-get-other-tree)))
+ (car (widget-get newsticker--treeview-feed-tree :children))))
+ (if new
+ (progn
+ (newsticker--treeview-activate-node new t)
+ (newsticker--treeview-tree-update-highlight)
+ (not (eq new cur)))
+ nil))
+ nil)))
(defun newsticker-treeview-next-page ()
"Scroll item buffer."
(newsticker--treeview-unfold-node group-name))
(setq node (newsticker--treeview-get-node-of-feed feed-name)))
(when node
- (save-excursion
- (set-buffer (newsticker--treeview-tree-buffer))
+ (with-current-buffer (newsticker--treeview-tree-buffer)
(widget-put node :nt-selected t)
(widget-apply-action node)
(newsticker--treeview-set-current-node node)))))
(list (let ((completion-ignore-case t))
(completing-read
"Jump to feed: "
- (mapcar 'car (append newsticker-url-list
- newsticker-url-list-defaults))
- nil t))))
+ (append '("new" "obsolete" "immortal" "all")
+ (mapcar 'car (append newsticker-url-list
+ newsticker-url-list-defaults)))
+ nil t))))
(newsticker--treeview-unfold-node feed-name))
;; ======================================================================
(let ((subfeeds (newsticker--group-get-feeds n t)))
(when subfeeds
(setq result (append subfeeds result)))))))
- group)
+ (cdr group))
result))
(defun newsticker-group-add-group (name parent)
(defun newsticker--group-manage-orphan-feeds ()
"Put unmanaged feeds into `newsticker-groups'.
-Remove obsolete feeds as well."
+Remove obsolete feeds as well.
+Return t if groups have changed, nil otherwise."
(unless newsticker-groups
(setq newsticker-groups '("Feeds")))
(let ((new-feed nil)
(append newsticker-url-list-defaults newsticker-url-list))
(setq newsticker-groups
(newsticker--group-remove-obsolete-feeds newsticker-groups))
- (if (or new-feed
- (not (= grouped-feeds
- (newsticker--count-grouped-feeds newsticker-groups))))
- (newsticker--treeview-tree-update))))
+ (or new-feed
+ (not (= grouped-feeds
+ (newsticker--count-grouped-feeds newsticker-groups))))))
;; ======================================================================
;;; Modes
(define-key menu [newsticker-treeview-mark-list-items-old]
(list 'menu-item "Mark all items old"
'newsticker-treeview-mark-list-items-old))
+ (define-key menu [newsticker-treeview-mark-item-old]
+ (list 'menu-item "Mark current item old"
+ 'newsticker-treeview-mark-item-old))
+ (define-key menu [newsticker-treeview-toggle-item-immortal]
+ (list 'menu-item "Mark current item immortal (toggle)"
+ 'newsticker-treeview-toggle-item-immortal))
+ (define-key menu [newsticker-treeview-get-news]
+ (list 'menu-item "Get news for current feed"
+ 'newsticker-treeview-get-news))
menu)
- "Map for newsticker tree menu.")
+ "Map for newsticker list menu.")
+
+(defvar newsticker-treeview-item-menu
+ (let ((menu (make-sparse-keymap "Newsticker Item")))
+ (define-key menu [newsticker-treeview-mark-item-old]
+ (list 'menu-item "Mark current item old"
+ 'newsticker-treeview-mark-item-old))
+ (define-key menu [newsticker-treeview-toggle-item-immortal]
+ (list 'menu-item "Mark current item immortal (toggle)"
+ 'newsticker-treeview-toggle-item-immortal))
+ (define-key menu [newsticker-treeview-get-news]
+ (list 'menu-item "Get news for current feed"
+ 'newsticker-treeview-get-news))
+ menu)
+ "Map for newsticker item menu.")
(defvar newsticker-treeview-mode-map
(let ((map (make-sparse-keymap 'newsticker-treeview-mode-map)))
(define-key newsticker-treeview-list-mode-map [down-mouse-3]
newsticker-treeview-list-menu))
+(define-derived-mode newsticker-treeview-item-mode newsticker-treeview-mode
+ "Item"
+ (define-key newsticker-treeview-item-mode-map [down-mouse-3]
+ newsticker-treeview-item-menu))
+
(defun newsticker-treeview-tree-click (event)
"Handle click EVENT on a tag in the newsticker tree."
(interactive "e")
"Actually handle click event.
POS gives the position where EVENT occurred."
(interactive)
- (unless pos (setq pos (point)))
- (let ((pos (or pos (point)))
- (nt-id (get-text-property pos :nt-id))
- (item (get-text-property pos :nt-item)))
+ (let* ((pos (or pos (point)))
+ (nt-id (get-text-property pos :nt-id))
+ (item (get-text-property pos :nt-item)))
(cond (item
;; click in list buffer
(newsticker-treeview-show-item))
(setq newsticker--treeview-windows nil)
(setq newsticker--treeview-buffers nil)
(delete-other-windows)
- (split-window-horizontally newsticker-treeview-treewindow-width)
+ (split-window-right newsticker-treeview-treewindow-width)
(add-to-list 'newsticker--treeview-windows (selected-window) t)
(other-window 1)
- (split-window-vertically newsticker-treeview-listwindow-height)
+ (split-window-below newsticker-treeview-listwindow-height)
(add-to-list 'newsticker--treeview-windows (selected-window) t)
(other-window 1)
(add-to-list 'newsticker--treeview-windows (selected-window) t)
(newsticker--treeview-frame-init)
(newsticker--treeview-window-init)
(newsticker--treeview-buffer-init)
- (newsticker--group-manage-orphan-feeds)
+ (if (newsticker--group-manage-orphan-feeds)
+ (newsticker--treeview-tree-update))
(newsticker--treeview-set-current-node newsticker--treeview-feed-tree)
(newsticker-start t) ;; will start only if not running
(newsticker-treeview-update)
(when newsticker--treeview-current-feed
(newsticker-get-news newsticker--treeview-current-feed)))
-(provide 'newsticker-treeview)
+(provide 'newst-treeview)
-;; arch-tag: 5dbaff48-1f3e-4fc6-8ebd-e966fc90d2d4
;;; newst-treeview.el ends here