Index: src/import-export/qif-import/qif-dialog-utils.scm
===================================================================
--- src/import-export/qif-import/qif-dialog-utils.scm	(revision 16932)
+++ src/import-export/qif-import/qif-dialog-utils.scm	(working copy)
@@ -59,6 +59,14 @@
 (define (default-unspec-acct)
   (_ "Unspecified"))
 
+;; The following investment actions implicitly specify
+;; the two accounts involved in the transaction.
+(define qif-import:actions-implicit
+  (list 'buy 'cglong 'cgmid 'cgshort 'div 'intinc 'margint 'reinvdiv
+        'reinvint 'reinvlg 'reinvmd 'reinvsg 'reinvsh 'reminder
+        'rtrncap 'sell 'shrsin 'shrsout 'stksplit))
+
+
 (define (qif-import:gnc-account-exists map-entry acct-list)
   (let ((retval #f))
     (for-each 
@@ -154,9 +162,11 @@
                                                    GNC-LIABILITY-TYPE)))
                     
                     ((divx cgshortx cgmidx cglongx intincx margintx rtrncapx)
-                     (set! qif-account 
-                           (qif-split:category 
-                            (car (qif-xtn:splits xtn))))
+                     (set! qif-account
+                           (and (qif-split:category-is-account?
+                                  (car (qif-xtn:splits xtn)))
+                                (qif-split:category 
+                                  (car (qif-xtn:splits xtn)))))
                      (set! qif-account-types (list GNC-BANK-TYPE
                                                    GNC-CCARD-TYPE
                                                    GNC-CASH-TYPE
@@ -207,9 +217,11 @@
                                                    GNC-ASSET-TYPE
                                                    GNC-LIABILITY-TYPE)))
                     ((buyx sellx xin xout)
-                     (set! qif-account 
-                           (qif-split:category 
-                            (car (qif-xtn:splits xtn))))
+                     (set! qif-account
+                           (and (qif-split:category-is-account?
+                                  (car (qif-xtn:splits xtn)))
+                                (qif-split:category 
+                                  (car (qif-xtn:splits xtn)))))
                      (set! qif-account-types (list GNC-BANK-TYPE
                                                    GNC-CCARD-TYPE
                                                    GNC-CASH-TYPE
@@ -403,28 +415,62 @@
      (lambda (qif-file)
        (for-each 
         (lambda (xtn)
-          ;; iterate over the splits
-          (for-each 
-           (lambda (split)
-             (let ((xtn-is-acct (qif-split:category-is-account? split))
-                   (xtn-cat #f)
-                   (entry #f))
-               (if (not xtn-is-acct)
-                   (begin 
-                     (set! xtn-cat (qif-split:category split)) 
-                     (set! entry (hash-ref cat-hash xtn-cat))
-                     (if (not entry)
-                         (set! entry 
-                               (qif-import:guess-acct
-                                xtn-cat
-                                (if (gnc-numeric-positive-p
-                                     (qif-split:amount split))
-                                    (list GNC-INCOME-TYPE GNC-EXPENSE-TYPE)
-                                    (list GNC-EXPENSE-TYPE GNC-INCOME-TYPE))
-                                gnc-acct-info)))
-                     (qif-map-entry:set-display?! entry #t)
-                     (hash-set! cat-hash xtn-cat entry)))))
-           (qif-xtn:splits xtn)))
+          (let ((action (qif-xtn:action xtn)))
+            ;; Many types of investment transactions implicitly use the
+            ;; brokerage account or a known offshoot. There is no need
+            ;; to consider a category mapping for these.
+            (if (not (and action
+                          (memv action qif-import:actions-implicit)))
+                ;; iterate over the splits
+                (for-each 
+                 (lambda (split)
+                   (let ((xtn-is-acct (qif-split:category-is-account? split))
+                         (xtn-cat #f)
+                         (entry #f))
+                     (if (not xtn-is-acct)
+                         (begin 
+                           (set! xtn-cat (qif-split:category split)) 
+                           (set! entry (hash-ref cat-hash xtn-cat))
+                           ;; NOTE: It would be more robust and efficient if the
+                           ;; three "make display" routines below were combined:
+                           ;;   make-account-display
+                           ;;   make-category-display
+                           ;;   make-memo-display
+                           ;;
+                           ;; This would also require adjusting several callback
+                           ;; functions that reference these procedures from C.
+                           ;;
+                           ;; Until then, the maintainer of this code must make
+                           ;; sure that the logic used in the "if" below matches
+                           ;; the criteria for making memo/payee mappings (seen
+                           ;; in make-memo-display).
+
+                           ;; Add an entry if there isn't one already and either
+                           ;;  (a) the category is non-blank, or
+                           ;;  (b) no memo/payee mapping can be applied
+                           (if (and (not entry)
+                                    (or (not (and (string? xtn-cat)
+                                                  (string=? xtn-cat "")))
+                                        (and (or (not (qif-split:memo split))
+                                                 (equal? (qif-split:memo split) ""))
+                                             (or (> (length (qif-xtn:splits xtn)) 1)
+                                                 (not (qif-xtn:payee xtn))
+                                                 (equal? (qif-xtn:payee xtn) "")))))
+                               (set! entry 
+                                     (qif-import:guess-acct
+                                      xtn-cat
+                                      (if (gnc-numeric-positive-p
+                                           (qif-split:amount split))
+                                          (list GNC-INCOME-TYPE
+                                                GNC-EXPENSE-TYPE)
+                                          (list GNC-EXPENSE-TYPE
+                                                GNC-INCOME-TYPE))
+                                      gnc-acct-info)))
+                           (if entry
+                               (begin
+                                 (qif-map-entry:set-display?! entry #t)
+                                 (hash-set! cat-hash xtn-cat entry)))))))
+                 (qif-xtn:splits xtn)))))
         (qif-file:xtns qif-file)))
      qif-files)
     
@@ -466,47 +512,53 @@
        (for-each 
         (lambda (xtn)
           (let ((payee (qif-xtn:payee xtn))
+                (action (qif-xtn:action xtn))
                 (splits (qif-xtn:splits xtn)))
-            (for-each 
-             (lambda (split)
-               (let ((cat (qif-split:category split))
-                     (memo (qif-split:memo split))
-                     (key-string #f))
-                 ;; for each split: if there's a category, do nothing.
-                 ;; if there's a payee, use that as the
-                 ;; key otherwise, use the split memo.
-                 (cond ((and cat 
-                             (or (not (string? cat))
-                                 (not (string=? cat ""))))
-                        (set! key-string #f))
-                       ((and payee (= (length splits) 1))
-                        (set! key-string payee))
-                       (memo
-                        (set! key-string memo)))
-                 
-                 (if key-string 
-                     (let ((entry (hash-ref memo-hash key-string)))
-                       (if (not entry)
-                           (begin 
-                             (set! entry (make-qif-map-entry))
-                             (qif-map-entry:set-qif-name! entry key-string)
-                             (qif-map-entry:set-gnc-name!
-                              entry (default-unspec-acct))
-                             (qif-map-entry:set-allowed-types!
-                              entry 
-                              (if (gnc-numeric-positive-p
-                                   (qif-split:amount split))
-                                  (list GNC-INCOME-TYPE GNC-EXPENSE-TYPE
-                                        GNC-BANK-TYPE GNC-CCARD-TYPE 
-                                        GNC-LIABILITY-TYPE GNC-ASSET-TYPE
-                                        GNC-STOCK-TYPE GNC-MUTUAL-TYPE)
-                                  (list GNC-EXPENSE-TYPE GNC-INCOME-TYPE
-                                        GNC-BANK-TYPE GNC-CCARD-TYPE 
-                                        GNC-LIABILITY-TYPE GNC-ASSET-TYPE
-                                        GNC-STOCK-TYPE GNC-MUTUAL-TYPE)))))
-                       (qif-map-entry:set-display?! entry #t)
-                       (hash-set! memo-hash key-string entry)))))
-             splits)))
+            ;; Many types of investment transactions implicitly use the
+            ;; brokerage account or a known offshoot. There is no need
+            ;; to consider a memo/payee mapping for these.
+            (if (not (and action
+                          (memv action qif-import:actions-implicit)))
+                (for-each
+                  (lambda (split)
+                    (let ((cat (qif-split:category split))
+                          (memo (qif-split:memo split))
+                          (key-string #f))
+                      ;; for each split: if there's a category, do nothing.
+                      ;; if there's a payee, use that as the
+                      ;; key otherwise, use the split memo.
+                      (cond ((and cat
+                                  (or (not (string? cat))
+                                      (not (string=? cat ""))))
+                             (set! key-string #f))
+                            ((and payee (= (length splits) 1))
+                             (set! key-string payee))
+                            (memo
+                             (set! key-string memo)))
+                      
+                      (if key-string
+                          (let ((entry (hash-ref memo-hash key-string)))
+                            (if (not entry)
+                                (begin
+                                  (set! entry (make-qif-map-entry))
+                                  (qif-map-entry:set-qif-name! entry key-string)
+                                  (qif-map-entry:set-gnc-name!
+                                   entry (default-unspec-acct))
+                                  (qif-map-entry:set-allowed-types!
+                                   entry
+                                   (if (gnc-numeric-positive-p
+                                        (qif-split:amount split))
+                                       (list GNC-INCOME-TYPE GNC-EXPENSE-TYPE
+                                             GNC-BANK-TYPE GNC-CCARD-TYPE
+                                             GNC-LIABILITY-TYPE GNC-ASSET-TYPE
+                                             GNC-STOCK-TYPE GNC-MUTUAL-TYPE)
+                                       (list GNC-EXPENSE-TYPE GNC-INCOME-TYPE
+                                             GNC-BANK-TYPE GNC-CCARD-TYPE
+                                             GNC-LIABILITY-TYPE GNC-ASSET-TYPE
+                                             GNC-STOCK-TYPE GNC-MUTUAL-TYPE)))))
+                            (qif-map-entry:set-display?! entry #t)
+                            (hash-set! memo-hash key-string entry)))))
+                  splits))))
         (qif-file:xtns file)))
      qif-files)
     
