André, attached is my attempt to refactor the code below using 
RefInset::localDispatch and so get rid of dynamic_cast.

LFUN_REF_APPLY now passes control to localDispatch if an existing reference 
inset is 'open'. If no such inset exists, then it inserts a new inset at 
the current cursor position.

I found that I needed to create a function, string2RefInset, to turn a 
string into a RefInset because both paths require it. It seems sensible to 
me to add this function to ref_inset.[Ch]. Are you happy with this or 
should I put it somewhere else?

Angus

For reference, here's the current code:

        case LFUN_REF_APPLY: {
                // Turn 'argument' into a temporary RefInset.
                // argument comes with a head "LatexCommand " and a
                // tail "\nend_inset\n\n". Strip them off.
                string trimmed;
                string body = split(argument, trimmed, ' ');
                split(body, trimmed, '\n');

                MathArray ar;
                mathed_parse_cell(ar, trimmed);
                if (ar.size() != 1) {
                        result = UNDISPATCHED;
                        break;
                }

                RefInset * tmp = ar[0].nucleus()->asRefInset();
                if (!tmp) {
                        result = UNDISPATCHED;
                        break;
                }

                // Apply this 'tmp' to the document.
                InsetBase * base =
                        bv->owner()->getDialogs().getOpenInset("ref");
                if (base) {
                        RefInset * inset = dynamic_cast<RefInset *>(base);
                        if (!inset) {
                                result = UNDISPATCHED;
                                break;
                        }

                        *inset = *tmp;
                } else {
                        mathcursor->insert(ar);
                }
                updateLocal(bv, true);
        }
        break;
Index: src/mathed/formulabase.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/formulabase.C,v
retrieving revision 1.241
diff -u -p -r1.241 formulabase.C
--- src/mathed/formulabase.C	26 Feb 2003 09:06:18 -0000	1.241
+++ src/mathed/formulabase.C	26 Feb 2003 10:53:33 -0000
@@ -805,40 +805,22 @@ dispatch_result InsetFormulaBase::localD
 	break;
 
 	case LFUN_REF_APPLY: {
-		// argument comes with a head "LatexCommand " and a
-		// tail "\nend_inset\n\n". Strip them off.
-		string trimmed;
-		string body = split(argument, trimmed, ' ');
-		split(body, trimmed, '\n');
-		lyxerr << "passing '" << trimmed << "' to the math parser\n";
-
-		MathArray ar;
-		mathed_parse_cell(ar, trimmed);
-		if (ar.size() != 1) {
-			result = UNDISPATCHED;
-			break;
-		}
-
-		RefInset * tmp = ar[0].nucleus()->asRefInset();
-		if (!tmp) {
-			result = UNDISPATCHED;
-			break;
-		}
-
 		InsetBase * base =
 			bv->owner()->getDialogs().getOpenInset("ref");
+
 		if (base) {
-			RefInset * inset = dynamic_cast<RefInset *>(base);
-			if (!inset) {
+			result = base->localDispatch(cmd);
+		} else {
+			// Turn 'argument' into a temporary RefInset.
+			MathArray ar;
+			if (string2RefInset(argument, ar)) {
+				mathcursor->insert(ar);
+			} else {
 				result = UNDISPATCHED;
-				break;
 			}
-
-			*inset = *tmp;
-		} else {
-			mathcursor->insert(ar);
 		}
-		updateLocal(bv, true);
+		if (result == DISPATCHED)
+			updateLocal(bv, true);
 	}
 	break;
 
Index: src/mathed/ref_inset.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ref_inset.C,v
retrieving revision 1.16
diff -u -p -r1.16 ref_inset.C
--- src/mathed/ref_inset.C	25 Feb 2003 15:38:45 -0000	1.16
+++ src/mathed/ref_inset.C	26 Feb 2003 10:53:33 -0000
@@ -14,6 +14,8 @@
 #include "debug.h"
 #include "math_mathmlstream.h"
 #include "Lsstream.h"
+#include "math_parser.h"
+#include "support/lstrings.h"
 
 
 RefInset::RefInset()
@@ -41,7 +43,6 @@ void RefInset::infoize(std::ostream & os
 dispatch_result
 RefInset::dispatch(FuncRequest const & cmd, idx_type & idx, pos_type & pos)
 {
-	lyxerr << "RefInset::dispatch " << cmd.argument << std::endl;
 	switch (cmd.action) {
 		case LFUN_MOUSE_RELEASE:
 			if (cmd.button() == mouse_button::button3) {
@@ -126,6 +127,33 @@ int RefInset::docbook(std::ostream & os,
 	}
 
 	return 0;
+}
+
+
+dispatch_result RefInset::localDispatch(FuncRequest const & cmd)
+{
+	MathArray ar;
+	if (!string2RefInset(cmd.argument, ar))
+		return UNDISPATCHED;
+
+	*this = *ar[0].nucleus()->asRefInset();
+	return DISPATCHED;
+}
+
+
+bool string2RefInset(string const & str, MathArray & ar)
+{
+	// str comes with a head "LatexCommand " and a
+	// tail "\nend_inset\n\n". Strip them off.
+	string trimmed;
+	string body = split(str, trimmed, ' ');
+	split(body, trimmed, '\n');
+
+	mathed_parse_cell(ar, trimmed);
+	if (ar.size() != 1)
+		return false;
+
+	return ar[0].nucleus()->asRefInset();
 }
 
 
Index: src/mathed/ref_inset.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/mathed/ref_inset.h,v
retrieving revision 1.9
diff -u -p -r1.9 ref_inset.h
--- src/mathed/ref_inset.h	25 Feb 2003 18:21:48 -0000	1.9
+++ src/mathed/ref_inset.h	26 Feb 2003 10:53:33 -0000
@@ -33,6 +33,8 @@ public:
 	/// docbook output
 	int docbook(std::ostream & os, bool) const;
 
+	/// small wrapper for the time being
+	dispatch_result localDispatch(FuncRequest const & cmd);
 
 	struct ref_type_info {
 		///
@@ -48,5 +50,11 @@ public:
 	///
 	static string const & getName(int type);
 };
+
+/** Fills ar with the contents of str.
+ *  str is created by the reference dialog and returned to the LyX core.
+ *  The function returns true if it succeeds in creating a RefInset.
+ */
+bool string2RefInset(string const & str, MathArray & ar);
 
 #endif

Reply via email to