diff --git a/src/backend/sql/gnc-transaction-sql.c b/src/backend/sql/gnc-transaction-sql.c
index eca64cf..51c7d85 100644
--- a/src/backend/sql/gnc-transaction-sql.c
+++ b/src/backend/sql/gnc-transaction-sql.c
@@ -83,6 +83,7 @@ static const GncSqlColumnTableEntry tx_col_table[] =
     { "post_date",     CT_TIMESPEC,       0,                      0,                 "post-date" },
     { "enter_date",    CT_TIMESPEC,       0,                      0,                 "enter-date" },
     { "description",   CT_STRING,         TX_MAX_DESCRIPTION_LEN, 0,                 "description" },
+    { "association",   CT_STRING,         TX_MAX_DESCRIPTION_LEN, 0,                 "association" },
     { NULL }
     /*@ +full_init_block @*/
 };
@@ -1124,6 +1125,10 @@ compile_split_query( GncSqlBackend* be, QofQuery* query )
                     {
                         convert_query_term_to_sql( be, "t.description", term, sql );
                     }
+                    else if ( strcmp( paramPath->next->data, TRANS_ASSOCIATION) == 0 )
+                    {
+                        convert_query_term_to_sql( be, "t.association", term, sql );
+                    }
                     else
                     {
                         unknownPath = TRUE;
diff --git a/src/backend/xml/gnc-transaction-xml-v2.c b/src/backend/xml/gnc-transaction-xml-v2.c
index 9fdbaf5..49d317a 100644
--- a/src/backend/xml/gnc-transaction-xml-v2.c
+++ b/src/backend/xml/gnc-transaction-xml-v2.c
@@ -179,6 +179,13 @@ gnc_transaction_dom_tree_create(Transaction *trn)
                         (xmlChar*)xaccTransGetDescription(trn));
     }
 
+    if (xaccTransGetAssociation(trn))
+    {
+        xmlNewTextChild(ret, NULL, BAD_CAST "trn:association",
+                        (xmlChar*)xaccTransGetAssociation(trn));
+    }
+
+
     {
         xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots",
                              xaccTransGetSlots(trn));
@@ -510,6 +517,15 @@ trn_description_handler(xmlNodePtr node, gpointer trans_pdata)
 }
 
 static gboolean
+trn_association_handler(xmlNodePtr node, gpointer trans_pdata)
+{
+    struct trans_pdata *pdata = trans_pdata;
+    Transaction *trn = pdata->trans;
+
+    return set_tran_string(node, trn, xaccTransSetAssociation);
+}
+
+static gboolean
 trn_slots_handler(xmlNodePtr node, gpointer trans_pdata)
 {
     struct trans_pdata *pdata = trans_pdata;
@@ -567,6 +583,7 @@ struct dom_tree_handler trn_dom_handlers[] =
     { "trn:date-posted", trn_date_posted_handler, 1, 0 },
     { "trn:date-entered", trn_date_entered_handler, 1, 0 },
     { "trn:description", trn_description_handler, 0, 0 },
+    { "trn:association", trn_association_handler, 0, 0 },
     { "trn:slots", trn_slots_handler, 0, 0 },
     { "trn:splits", trn_splits_handler, 1, 0 },
     { NULL, NULL, 0, 0 },
diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c
index 567a275..b02d34a 100644
--- a/src/engine/Transaction.c
+++ b/src/engine/Transaction.c
@@ -194,6 +194,7 @@ enum
     PROP_0,
     PROP_NUM,
     PROP_DESCRIPTION,
+    PROP_ASSOCIATION,
     PROP_CURRENCY,
     PROP_POST_DATE,
     PROP_ENTER_DATE
@@ -262,6 +263,7 @@ gnc_transaction_init(Transaction* trans)
     /* Fill in some sane defaults */
     trans->num         = CACHE_INSERT("");
     trans->description = CACHE_INSERT("");
+    trans->association = CACHE_INSERT("");
 
     trans->common_currency = NULL;
     trans->splits = NULL;
@@ -314,6 +316,9 @@ gnc_transaction_get_property(GObject* object,
     case PROP_DESCRIPTION:
         g_value_set_string(value, tx->description);
         break;
+    case PROP_ASSOCIATION:
+        g_value_set_string(value, tx->association);
+        break;
     case PROP_CURRENCY:
         g_value_take_object(value, tx->common_currency);
         break;
@@ -472,7 +477,8 @@ xaccTransDump (const Transaction *trans, const char *tag)
     printf("    Posted:      %s\n", gnc_print_date(trans->date_posted));
     printf("    Num:         %s\n", trans->num ? trans->num : "(null)");
     printf("    Description: %s\n",
-           trans->description ? trans->description : "(null)");
+    printf("    Association: %s\n",
+           trans->association ? trans->association : "(null)");
     printf("    Currency:    %s\n",
            gnc_commodity_get_printname(trans->common_currency));
     printf("    version:     %x\n", qof_instance_get_version(trans));
@@ -542,6 +548,7 @@ xaccDupeTransaction (const Transaction *from)
 
     to->num         = CACHE_INSERT (from->num);
     to->description = CACHE_INSERT (from->description);
+    to->association = CACHE_INSERT (from->association);
 
     to->splits = g_list_copy (from->splits);
     for (node = to->splits; node; node = node->next)
@@ -586,6 +593,7 @@ xaccTransClone (const Transaction *from)
     to->date_posted     = from->date_posted;
     to->num             = CACHE_INSERT (from->num);
     to->description     = CACHE_INSERT (from->description);
+    to->association     = CACHE_INSERT (from->association);
     to->common_currency = from->common_currency;
     qof_instance_copy_version(to, from);
     qof_instance_copy_version_check(to, from);
@@ -726,6 +734,7 @@ xaccFreeTransaction (Transaction *trans)
     /* free up transaction strings */
     CACHE_REMOVE(trans->num);
     CACHE_REMOVE(trans->description);
+    CACHE_REMOVE(trans->association);
 
     /* Just in case someone looks up freed memory ... */
     trans->num         = (char *) 1;
@@ -847,6 +856,14 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb,
         return FALSE;
     }
 
+    if ((same_book && ta->association != tb->association)
+            || (!same_book && g_strcmp0(ta->association, tb->association)))
+    {
+        PINFO ("assocations differ: %s vs %s", ta->association, tb->association);
+        return FALSE;
+    }
+
+
     if (kvp_frame_compare(ta->inst.kvp_data, tb->inst.kvp_data) != 0)
     {
         char *frame_a;
@@ -1603,6 +1620,7 @@ xaccTransRollbackEdit (Transaction *trans)
     orig = trans->orig;
     SWAP(trans->num, orig->num);
     SWAP(trans->description, orig->description);
+    SWAP(trans->association, orig->association);
     trans->date_entered = orig->date_entered;
     trans->date_posted = orig->date_posted;
     SWAP(trans->common_currency, orig->common_currency);
@@ -2007,6 +2025,25 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
 }
 
 static void
+qofTransSetAssociation (Transaction *trans, const char *assoc)
+{
+    if (!qof_begin_edit(&trans->inst)) return;
+    xaccTransSetAssociation(trans, assoc);
+    qof_commit_edit(&trans->inst);
+}
+
+void
+xaccTransSetAssociation (Transaction *trans, const char *assoc)
+{
+    if (!trans || !assoc) return;
+    xaccTransBeginEdit(trans);
+
+    CACHE_REPLACE(trans->association, assoc);
+    qof_instance_set_dirty(QOF_INSTANCE(trans));
+    xaccTransCommitEdit(trans);
+}
+
+static void
 qofTransSetNotes (Transaction *trans, const char *notes)
 {
     if (!qof_begin_edit(&trans->inst)) return;
@@ -2090,6 +2127,12 @@ xaccTransGetDescription (const Transaction *trans)
 }
 
 const char *
+xaccTransGetAssociation (const Transaction *trans)
+{
+    return trans ? trans->association : NULL;
+}
+
+const char *
 xaccTransGetNotes (const Transaction *trans)
 {
     return trans ?
@@ -2665,6 +2708,11 @@ gboolean xaccTransRegister (void)
             (QofSetterFunc)qofTransSetDescription
         },
         {
+            TRANS_ASSOCIATION, QOF_TYPE_STRING,
+            (QofAccessFunc)xaccTransGetAssociation,
+            (QofSetterFunc)qofTransSetAssociation
+        },
+        {
             TRANS_DATE_ENTERED, QOF_TYPE_DATE,
             (QofAccessFunc)xaccTransRetDateEnteredTS,
             (QofSetterFunc)qofTransSetDateEntered
diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h
index 51ba5e0..04c0c76 100644
--- a/src/engine/Transaction.h
+++ b/src/engine/Transaction.h
@@ -310,6 +310,9 @@ void          xaccTransSetNum (Transaction *trans, const char *num);
 /** Sets the transaction Description */
 void          xaccTransSetDescription (Transaction *trans, const char *desc);
 
+/** Sets the transaction Association */
+void          xaccTransSetAssociation (Transaction *trans, const char *desc);
+
 /** Sets the transaction Notes
  *
  The Notes field is only visible in the register in double-line mode */
@@ -323,6 +326,8 @@ void          xaccTransSetNotes (Transaction *trans, const char *notes);
 const char *  xaccTransGetNum (const Transaction *trans);
 /** Gets the transaction Description */
 const char *  xaccTransGetDescription (const Transaction *trans);
+/** Gets the transaction association */
+const char *  xaccTransGetAssociation(const Transaction *trans);
 /** Gets the transaction Notes
  *
  The Notes field is only visible in the register in double-line mode */
@@ -717,6 +722,7 @@ Timespec xaccTransGetVoidTime(const Transaction *tr);
 #define TRANS_KVP		"kvp"
 #define TRANS_NUM		"num"
 #define TRANS_DESCRIPTION	"desc"
+#define TRANS_ASSOCIATION	"assoc"
 #define TRANS_DATE_ENTERED	"date-entered"
 #define TRANS_DATE_POSTED	"date-posted"
 #define TRANS_DATE_DUE		"date-due"
diff --git a/src/engine/TransactionP.h b/src/engine/TransactionP.h
index d7935e8..1d19f55 100644
--- a/src/engine/TransactionP.h
+++ b/src/engine/TransactionP.h
@@ -89,6 +89,11 @@ struct transaction_s
      */
     char * description;
 
+    /* The association field is a user-assigned value.
+     * It is meant to store a filename for linkage to each transaction.
+     */
+    char * association;
+
     /* The common_currency field is the balancing common currency for
      * all the splits in the transaction.  Alternate, better(?) name:
      * "valuation currency": it is the currency in which all of the
diff --git a/src/gnome-utils/gnc-gnome-utils.c b/src/gnome-utils/gnc-gnome-utils.c
index d023e48..5172aad 100644
--- a/src/gnome-utils/gnc-gnome-utils.c
+++ b/src/gnome-utils/gnc-gnome-utils.c
@@ -398,6 +398,69 @@ gnc_gnome_help (const char *file_name, const char *anchor)
 
 #endif
 
+#ifdef MAC_INTEGRATION
+
+/* Don't be alarmed if this function looks strange to you: It's
+ * written in Objective-C, the native language of the OSX Cocoa
+ * toolkit.
+ */
+void
+gnc_launch_assoc (const char *uri)
+{
+    const gchar *message =
+	_("This function is not yet implemented on the Mac platform.");
+    gnc_error_dialog(NULL, "%s", message);
+    [pool release];
+    return;
+}
+#elif defined G_OS_WIN32 /* G_OS_WIN32 */
+void
+gnc_launch_assoc (const char *uri)
+{
+    gchar *found = NULL;
+
+    if (g_file_test (uri, G_FILE_TEST_IS_REGULAR))
+    {
+       found = g_strdup (fullpath);
+       break;
+    }
+
+    if (!found)
+    {
+        const gchar *message =
+            _("GnuCash could not find the associated file.");
+        gnc_error_dialog (NULL, message);
+    }
+    else
+    {
+        gnc_show_htmlhelp (found, anchor);
+    }
+    g_free (found);
+}
+#else
+void
+gnc_launch_assoc (const char *uri)
+{
+    GError *error = NULL;
+    gboolean success;
+
+    DEBUG ("Attempting to open uri %s", uri);
+    success = gtk_show_uri (NULL, uri, gtk_get_current_event_time (), &error);
+    if (success)
+        return;
+
+    g_assert(error != NULL);
+    {
+        const gchar *message =
+            _("GnuCash could not open the associated file.");
+        gnc_error_dialog(NULL, "%s", message);
+    }
+    PERR ("%s", error->message);
+    g_error_free(error);
+}
+
+#endif
+
 /********************************************************************\
  * gnc_gnome_get_pixmap                                             *
  *   returns a GtkWidget given a pixmap filename                    *
diff --git a/src/gnome-utils/gnc-gnome-utils.h b/src/gnome-utils/gnc-gnome-utils.h
index ce4b83f..52a279c 100644
--- a/src/gnome-utils/gnc-gnome-utils.h
+++ b/src/gnome-utils/gnc-gnome-utils.h
@@ -56,6 +56,9 @@ void gnc_gtk_add_rc_file (void);
  */
 void gnc_gnome_help (const char *file_name,
                      const char *anchor);
+/** Launch the default gnome browser and open the provided URI.
+ */
+void gnc_launch_assoc (const char *uri);
 
 /** Set the help callback to 'gnc_book_options_help_cb' to open a help browser
  *  and point it to the Book Options link in the Help file.
diff --git a/src/gnome-utils/gnc-tree-view.c b/src/gnome-utils/gnc-tree-view.c
index ce79914..1849d51 100644
--- a/src/gnome-utils/gnc-tree-view.c
+++ b/src/gnome-utils/gnc-tree-view.c
@@ -848,7 +848,7 @@ gnc_tree_view_get_column_order (GncTreeView *view,
         }
         num_cols++;
     }
-    DEBUG ("got %lu columns: %s", num_cols, col_names);
+    //DEBUG ("got %lu columns: %s", num_cols, col_names);
     col_str_list = g_strsplit (col_names, ";", 0);
 
     /* Clean up */
diff --git a/src/gnome/gnc-plugin-page-register.c b/src/gnome/gnc-plugin-page-register.c
index 33e1b26..f267645 100644
--- a/src/gnome/gnc-plugin-page-register.c
+++ b/src/gnome/gnc-plugin-page-register.c
@@ -170,6 +170,9 @@ static void gnc_plugin_page_register_cmd_scrub_current (GtkAction *action, GncPl
 static void gnc_plugin_page_register_cmd_account_report (GtkAction *action, GncPluginPageRegister *plugin_page);
 static void gnc_plugin_page_register_cmd_transaction_report (GtkAction *action, GncPluginPageRegister *plugin_page);
 
+static void gnc_plugin_page_register_cmd_associate_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
+static void gnc_plugin_page_register_cmd_execassociated_transaction (GtkAction *action, GncPluginPageRegister *plugin_page);
+
 static void gnc_plugin_page_help_changed_cb( GNCSplitReg *gsr, GncPluginPageRegister *register_page );
 static void gnc_plugin_page_register_refresh_cb (GHashTable *changes, gpointer user_data);
 static void gnc_plugin_page_register_close_cb (gpointer user_data);
@@ -185,26 +188,30 @@ static void gnc_plugin_page_register_event_handler (QofInstance *entity,
 /*                          Actions                         */
 /************************************************************/
 
-#define CUT_TRANSACTION_LABEL         N_("Cu_t Transaction")
-#define COPY_TRANSACTION_LABEL        N_("_Copy Transaction")
-#define PASTE_TRANSACTION_LABEL       N_("_Paste Transaction")
-#define DUPLICATE_TRANSACTION_LABEL   N_("Dup_licate Transaction")
-#define DELETE_TRANSACTION_LABEL      N_("_Delete Transaction")
-#define CUT_SPLIT_LABEL               N_("Cu_t Split")
-#define COPY_SPLIT_LABEL              N_("_Copy Split")
-#define PASTE_SPLIT_LABEL             N_("_Paste Split")
-#define DUPLICATE_SPLIT_LABEL         N_("Dup_licate Split")
-#define DELETE_SPLIT_LABEL            N_("_Delete Split")
-#define CUT_TRANSACTION_TIP           N_("Cut the selected transaction into clipboard")
-#define COPY_TRANSACTION_TIP          N_("Copy the selected transaction into clipboard")
-#define PASTE_TRANSACTION_TIP         N_("Paste the transaction from the clipboard")
-#define DUPLICATE_TRANSACTION_TIP     N_("Make a copy of the current transaction")
-#define DELETE_TRANSACTION_TIP        N_("Delete the current transaction")
-#define CUT_SPLIT_TIP                 N_("Cut the selected split into clipboard")
-#define COPY_SPLIT_TIP                N_("Copy the selected split into clipboard")
-#define PASTE_SPLIT_TIP               N_("Paste the split from the clipboard")
-#define DUPLICATE_SPLIT_TIP           N_("Make a copy of the current split")
-#define DELETE_SPLIT_TIP              N_("Delete the current split")
+#define CUT_TRANSACTION_LABEL            N_("Cu_t Transaction")
+#define COPY_TRANSACTION_LABEL           N_("_Copy Transaction")
+#define PASTE_TRANSACTION_LABEL          N_("_Paste Transaction")
+#define DUPLICATE_TRANSACTION_LABEL      N_("Dup_licate Transaction")
+#define DELETE_TRANSACTION_LABEL         N_("_Delete Transaction")
+#define ASSOCIATE_TRANSACTION_LABEL      N_("_Associate Link with Transaction")
+#define EXECASSOCIATED_TRANSACTION_LABEL N_("_Open Associated Link")
+#define CUT_SPLIT_LABEL                  N_("Cu_t Split")
+#define COPY_SPLIT_LABEL                 N_("_Copy Split")
+#define PASTE_SPLIT_LABEL                N_("_Paste Split")
+#define DUPLICATE_SPLIT_LABEL            N_("Dup_licate Split")
+#define DELETE_SPLIT_LABEL               N_("_Delete Split")
+#define CUT_TRANSACTION_TIP              N_("Cut the selected transaction into clipboard")
+#define COPY_TRANSACTION_TIP             N_("Copy the selected transaction into clipboard")
+#define PASTE_TRANSACTION_TIP            N_("Paste the transaction from the clipboard")
+#define DUPLICATE_TRANSACTION_TIP        N_("Make a copy of the current transaction")
+#define DELETE_TRANSACTION_TIP           N_("Delete the current transaction")
+#define ASSOCIATE_TRANSACTION_TIP        N_("Associate a link with the current transaction")
+#define EXECASSOCIATED_TRANSACTION_TIP   N_("Open the associated link with the current transaction")
+#define CUT_SPLIT_TIP                    N_("Cut the selected split into clipboard")
+#define COPY_SPLIT_TIP                   N_("Copy the selected split into clipboard")
+#define PASTE_SPLIT_TIP                  N_("Paste the split from the clipboard")
+#define DUPLICATE_SPLIT_TIP              N_("Make a copy of the current split")
+#define DELETE_SPLIT_TIP                 N_("Delete the current split")
 
 static GtkActionEntry gnc_plugin_page_register_actions [] =
 {
@@ -297,6 +304,16 @@ static GtkActionEntry gnc_plugin_page_register_actions [] =
         "ReverseTransactionAction", NULL, N_("Add _Reversing Transaction"), NULL, NULL,
         G_CALLBACK (gnc_plugin_page_register_cmd_reverse_transaction)
     },
+    {
+        "AssociateTransactionAction", NULL, ASSOCIATE_TRANSACTION_LABEL, NULL,
+        ASSOCIATE_TRANSACTION_TIP,
+        G_CALLBACK (gnc_plugin_page_register_cmd_associate_transaction)
+    },
+    {
+        "ExecAssociatedTransactionAction", NULL, EXECASSOCIATED_TRANSACTION_LABEL, NULL,
+        EXECASSOCIATED_TRANSACTION_TIP,
+        G_CALLBACK (gnc_plugin_page_register_cmd_execassociated_transaction)
+    },
 
     /* View menu */
 
@@ -461,6 +478,8 @@ static action_toolbar_labels toolbar_labels[] =
     { "BlankTransactionAction",     N_("Blank") },
     { "ActionsReconcileAction",     N_("Reconcile") },
     { "ActionsAutoClearAction",     N_("Auto-clear") },
+    { "AssociateTransactionAction",     N_("Set Link") },
+    { "ExecAssociatedTransactionAction",     N_("Open Link") },
     { NULL, NULL },
 };
 
@@ -804,6 +823,7 @@ static const char* readonly_inactive_actions[] =
     "ScheduleTransactionAction",
     "ScrubAllAction",
     "ScrubCurrentAction",
+    "AssociateTransactionAction",
     NULL
 };
 
@@ -827,6 +847,8 @@ static const char* tran_action_labels[] =
     PASTE_TRANSACTION_LABEL,
     DUPLICATE_TRANSACTION_LABEL,
     DELETE_TRANSACTION_LABEL,
+    ASSOCIATE_TRANSACTION_LABEL,
+    EXECASSOCIATED_TRANSACTION_LABEL,
     NULL
 };
 
@@ -838,6 +860,8 @@ static const char* tran_action_tips[] =
     PASTE_TRANSACTION_TIP,
     DUPLICATE_TRANSACTION_TIP,
     DELETE_TRANSACTION_TIP,
+    ASSOCIATE_TRANSACTION_TIP,
+    EXECASSOCIATED_TRANSACTION_TIP,
     NULL
 };
 
@@ -3393,6 +3417,38 @@ gnc_plugin_page_register_cmd_delete_transaction (GtkAction *action,
 }
 
 static void
+gnc_plugin_page_register_cmd_associate_transaction (GtkAction *action,
+        GncPluginPageRegister *plugin_page)
+{
+    GncPluginPageRegisterPrivate *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
+    gsr_default_associate_handler(priv->gsr, NULL);
+    LEAVE(" ");
+
+}
+
+static void
+gnc_plugin_page_register_cmd_execassociated_transaction (GtkAction *action,
+        GncPluginPageRegister *plugin_page)
+{
+    GncPluginPageRegisterPrivate *priv;
+
+    ENTER("(action %p, plugin_page %p)", action, plugin_page);
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
+
+    priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(plugin_page);
+    gsr_default_execassociated_handler(priv->gsr, NULL);
+    LEAVE(" ");
+
+}
+
+static void
 gnc_plugin_page_register_cmd_blank_transaction (GtkAction *action,
         GncPluginPageRegister *plugin_page)
 {
diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c
index 0c66364..04fe6ce 100644
--- a/src/gnome/gnc-split-reg.c
+++ b/src/gnome/gnc-split-reg.c
@@ -45,6 +45,7 @@
 #include "gnc-euro.h"
 #include "gnc-prefs.h"
 #include "gnc-gui-query.h"
+#include "gnc-gnome-utils.h"
 #include "gnc-ledger-display.h"
 #include "gnc-pricedb.h"
 #include "gnc-ui-util.h"
@@ -106,6 +107,8 @@ void gsr_default_paste_txn_handler( GNCSplitReg *w, gpointer ud );
 void gsr_default_void_txn_handler ( GNCSplitReg *w, gpointer ud );
 void gsr_default_unvoid_txn_handler  ( GNCSplitReg *w, gpointer ud );
 void gsr_default_reverse_txn_handler ( GNCSplitReg *w, gpointer ud );
+void gsr_default_associate_handler   ( GNCSplitReg *w, gpointer ud );
+void gsr_default_execassociated_handler   ( GNCSplitReg *w, gpointer ud );
 
 static void gsr_emit_simple_signal( GNCSplitReg *gsr, const char *sigName );
 static void gsr_emit_help_changed( GnucashRegister *reg, gpointer user_data );
@@ -1006,6 +1009,97 @@ gnc_split_reg_reinitialize_trans_cb(GtkWidget *widget, gpointer data)
     gsr_emit_simple_signal( gsr, "reinit_ent" );
 }
 
+/**
+ * Associates a link with the current transaction.
+ **/
+void
+gsr_default_associate_handler( GNCSplitReg *gsr, gpointer data )
+{
+    CursorClass cursor_class;
+    SplitRegister *reg;
+    Transaction *trans;
+    Split *split;
+    GtkWidget *dialog;
+
+    reg = gnc_ledger_display_get_split_register( gsr->ledger );
+
+    /* get the current split based on cursor position */
+    split = gnc_split_register_get_current_split(reg);
+    if (split == NULL)
+    {
+        gnc_split_register_cancel_cursor_split_changes (reg);
+        return;
+    }
+
+    trans = xaccSplitGetParent(split);
+    cursor_class = gnc_split_register_get_current_cursor_class (reg);
+
+    if (cursor_class == CURSOR_CLASS_NONE)
+        return;
+
+    if (is_trans_readonly_and_warn(trans))
+        return;
+
+	dialog = gtk_file_chooser_dialog_new ("Open File",
+                                     GTK_WINDOW(gsr->window),
+                                     GTK_FILE_CHOOSER_ACTION_OPEN,
+                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                     NULL);
+
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ 	{
+	    char *filename;
+            char *uri;
+
+	    filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+            uri = g_strdup_printf( "file://%s", filename);
+	    xaccTransSetAssociation(trans, uri);
+	    g_free(filename);
+         }
+
+	gtk_widget_destroy (dialog);
+
+}
+
+/**
+ * Executes the associated link with the current transaction.
+ **/
+void
+gsr_default_execassociated_handler( GNCSplitReg *gsr, gpointer data )
+{
+    CursorClass cursor_class;
+    SplitRegister *reg;
+    Transaction *trans;
+    Split *split;
+    GtkWidget *dialog;
+    const char *uri;
+
+    reg = gnc_ledger_display_get_split_register( gsr->ledger );
+
+    /* get the current split based on cursor position */
+    split = gnc_split_register_get_current_split(reg);
+    if (split == NULL)
+    {
+        gnc_split_register_cancel_cursor_split_changes (reg);
+        return;
+    }
+
+    trans = xaccSplitGetParent(split);
+    cursor_class = gnc_split_register_get_current_cursor_class (reg);
+
+    if (cursor_class == CURSOR_CLASS_NONE)
+        return;
+
+#ifdef DUMP_FUNCTIONS
+   xaccTransDump (trans, "ExecAssociated")
+#endif
+
+    uri = xaccTransGetAssociation(trans);
+    gnc_launch_assoc(uri);
+    return;
+}
+
 void
 gsr_default_delete_handler( GNCSplitReg *gsr, gpointer data )
 {
diff --git a/src/gnome/gnc-split-reg.h b/src/gnome/gnc-split-reg.h
index e9e8bce..ab4646e 100644
--- a/src/gnome/gnc-split-reg.h
+++ b/src/gnome/gnc-split-reg.h
@@ -242,6 +242,8 @@ void gnc_split_reg_balancing_entry (GNCSplitReg *gsr, Account *account,
                                     time64 statement_date, gnc_numeric balancing_amount);
 
 void gsr_default_delete_handler( GNCSplitReg *gsr, gpointer data );
+void gsr_default_associate_handler( GNCSplitReg *gsr, gpointer data );
+void gsr_default_execassociated_handler( GNCSplitReg *gsr, gpointer data );
 void gnc_split_reg_enter( GNCSplitReg *gsr, gboolean next_transaction );
 void gsr_default_delete_handler( GNCSplitReg *gsr, gpointer data );
 void gsr_default_reinit_handler( GNCSplitReg *gsr, gpointer data );
diff --git a/src/gnome/ui/gnc-plugin-page-register-ui.xml b/src/gnome/ui/gnc-plugin-page-register-ui.xml
index ddcc51c..82e8e61 100644
--- a/src/gnome/ui/gnc-plugin-page-register-ui.xml
+++ b/src/gnome/ui/gnc-plugin-page-register-ui.xml
@@ -20,6 +20,9 @@
       <menuitem name="VoidTransaction"    	action="VoidTransactionAction"/>
       <menuitem name="UnvoidTransaction"  	action="UnvoidTransactionAction"/>
       <menuitem name="ReverseTransaction" 	action="ReverseTransactionAction"/>
+      <separator name="TransactionSep3"/>
+      <menuitem name="AssociateTransaction"    	action="AssociateTransactionAction"/>
+      <menuitem name="ExecAssociateTransaction" action="ExecAssociatedTransactionAction"/>
     </menu>
 
     <menu name="View" action="ViewAction">
