Skip to content

Commit 3506a1b

Browse files
committed
Support messageBoxRedirect in non-ide engines
1 parent a4b681a commit 3506a1b

21 files changed

+270
-247
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Name: msgChanged
2+
3+
Type: message
4+
5+
Syntax: msgChanged
6+
7+
Summary:
8+
Sent to the <messageBoxRedirect> object whenever the <message box> is
9+
changed.
10+
11+
Introduced: 9.0
12+
13+
OS: mac, windows, linux, ios, android, html5
14+
15+
Platforms: desktop, mobile
16+
17+
Example:
18+
on msgChanged
19+
set the text of field "Message" to msg
20+
end msgChanged
21+
22+
Description:
23+
Use the msgChanged <message> to display or log the content of the
24+
<message box>.
25+
26+
References: put (command), container (glossary), command (glossary),
27+
message (glossary), message box (glossary), property (glossary),
28+
messageBoxLastObject (property), messageBoxRedirect (property)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Name: messageBoxLastObject
2+
3+
Type: property
4+
5+
Syntax: get the messageBoxLastObject
6+
7+
Summary:
8+
Get the long id of the last object to update the message box.
9+
10+
Introduced: 9.0
11+
12+
OS: mac, windows, linux, ios, android, html5
13+
14+
Platforms: desktop, mobile
15+
16+
Example:
17+
local tObject
18+
put the messageBoxLastObject into tObject
19+
if tObject is not empty then
20+
edit the script of tObject
21+
end if
22+
23+
Description:
24+
Use the messageBoxLastObject <property> to find the last object that
25+
modified the message box.
26+
27+
References: put (command), container (glossary), command (glossary),
28+
message (glossary), message box (glossary), property (glossary),
29+
msgChanged (message), messageBoxRedirect (property)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Name: messageBoxRedirect
2+
3+
Type: property
4+
5+
Syntax: set the messageBoxRedirect to <object>
6+
7+
Summary:
8+
Set the object that should receive the <msgChanged> <message> when the
9+
the <put> <command> is used without specifying a <container>.
10+
11+
Introduced: 9.0
12+
13+
OS: mac, windows, linux, ios, android, html5
14+
15+
Platforms: desktop, mobile
16+
17+
Example:
18+
set the messageBoxRedirect to the long id of stack "Message Box"
19+
20+
Description:
21+
Use the messageBoxRedirect <property> to provide an object that handles
22+
the <msgChanged> <message>.
23+
24+
References: put (command), container (glossary), command (glossary),
25+
message (glossary), message box (glossary), property (glossary),
26+
msgChanged (message), messageBoxLastObject (property)

docs/notes/bugfix-18245.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Message box properties aded to all engines
2+
3+
Previously global properties `revMessageBoxRedirect` and
4+
`revMessageBoxLastObject` were only availbe in the IDE engine. These
5+
properties have now been renamed to `messageBoxRedirect` and
6+
`messageBoxLastObject` and they are now available in all engines.
7+
8+
Set the `messageBoxRedirect` to the long id of the object that should
9+
receive `msgChanged` messages whenever the `msg` global is modified.

engine/src/cmds.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,7 @@ void MCPut::exec_ctxt(MCExecContext& ctxt)
10611061
MCEngineExecPutOutput(ctxt, t_string);
10621062
}
10631063
else if (prep == PT_INTO || prep == PT_AFTER || prep == PT_BEFORE)
1064-
MCIdeExecPutIntoMessage(ctxt, t_string, prep);
1064+
MCDebuggingExecPutIntoMessage(ctxt, t_string, prep);
10651065
else if (prep == PT_HEADER || prep == PT_NEW_HEADER)
10661066
MCServerExecPutHeader(ctxt, t_string, prep == PT_NEW_HEADER);
10671067
else if (prep == PT_CONTENT)
@@ -1138,7 +1138,7 @@ void MCPut::compile(MCSyntaxFactoryRef ctxt)
11381138
case PT_AFTER:
11391139
case PT_BEFORE:
11401140
MCSyntaxFactoryEvalConstantInt(ctxt, prep);
1141-
MCSyntaxFactoryExecMethod(ctxt, kMCIdeExecPutIntoMessageMethodInfo);
1141+
MCSyntaxFactoryExecMethod(ctxt, kMCDebuggingExecPutIntoMessageMethodInfo);
11421142
break;
11431143
case PT_HEADER:
11441144
case PT_NEW_HEADER:

engine/src/debug.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void MCB_setvalue(MCExecContext &ctxt, MCExecValue p_value, MCNameRef name)
129129

130130
void MCB_setmsg(MCExecContext &ctxt, MCStringRef p_string)
131131
{
132-
if (MCnoui)
132+
if (!MCmessageboxredirect.IsValid())
133133
{
134134
MCAutoStringRefAsCString t_output;
135135
/* UNCHECKED */ t_output . Lock(p_string);
@@ -139,31 +139,47 @@ void MCB_setmsg(MCExecContext &ctxt, MCStringRef p_string)
139139
MCS_write("\n", sizeof(char), 1, IO_stdout);
140140
return;
141141
}
142-
143-
if (!MCModeHandleMessageBoxChanged(ctxt, p_string))
142+
else
144143
{
145-
// MW-2004-11-17: Now use global 'MCmbstackptr' instead
146-
if (!MCmbstackptr)
147-
MCmbstackptr = MCdispatcher->findstackname(MCN_messagename);
148-
149-
if (MCmbstackptr)
144+
MCObject *t_src_object = nil;
145+
if (ctxt.GetObject() != nil)
146+
t_src_object = ctxt.GetObject();
147+
148+
bool t_in_msg_box = false;
149+
150+
MCObject *t_obj_ptr = t_src_object;
151+
while (t_obj_ptr != nil)
152+
{
153+
if (t_obj_ptr == MCmessageboxredirect)
154+
{
155+
t_in_msg_box = true;
156+
break;
157+
}
158+
t_obj_ptr = t_obj_ptr->getparent();
159+
}
160+
161+
if (!t_in_msg_box)
150162
{
151-
Window_mode newmode = MCmbstackptr->userlevel() == 0 ? WM_MODELESS
152-
: (Window_mode)(MCmbstackptr->userlevel() + WM_TOP_LEVEL_LOCKED);
163+
MCmessageboxlastobject = t_src_object->GetHandle();
153164

154-
// MW-2011-07-05: [[ Bug 9608 ]] The 'ep' that is passed through to us does
155-
// not necessarily have an attached object any more. Given that the 'rel'
156-
// parameter of the open stack call is unused, computing it from that
157-
// context is redundent.
158-
if (MCmbstackptr->getmode() != newmode)
159-
MCmbstackptr->openrect(MCmbstackptr -> getrect(), newmode, NULL, WP_DEFAULT,OP_NONE);
160-
else
161-
MCmbstackptr->raise();
162-
MCCard *cptr = MCmbstackptr->getchild(CT_THIS, kMCEmptyString, CT_CARD);
163-
MCField *fptr = (MCField *)cptr->getchild(CT_FIRST, kMCEmptyString, CT_FIELD, CT_CARD);
164-
if (fptr != NULL)
165-
fptr->settext(0, p_string, False);
165+
MCNameDelete(MCmessageboxlasthandler);
166+
MCmessageboxlasthandler = nil;
167+
MCNameClone(ctxt.GetHandler()->getname(), MCmessageboxlasthandler);
168+
169+
MCmessageboxlastline = ctxt . GetLine();
170+
}
171+
172+
bool t_added = false;
173+
if (MCnexecutioncontexts < MAX_CONTEXTS && ctxt.GetObject() != nil)
174+
{
175+
MCexecutioncontexts[MCnexecutioncontexts++] = &ctxt;
176+
t_added = true;
166177
}
178+
179+
MCmessageboxredirect -> message(MCM_msgchanged);
180+
181+
if (t_added)
182+
MCnexecutioncontexts--;
167183
}
168184
}
169185

engine/src/exec-debugging.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3434
#include "mcerror.h"
3535
#include "param.h"
3636

37+
#include "chunk.h"
38+
#include "scriptpt.h"
39+
#include "osspec.h"
40+
3741
////////////////////////////////////////////////////////////////////////////////
3842

3943
MC_EXEC_DEFINE_EXEC_METHOD(Debugging, Breakpoint, 2)
@@ -60,6 +64,8 @@ MC_EXEC_DEFINE_SET_METHOD(Debugging, WatchedVariables, 1)
6064

6165
MC_EXEC_DEFINE_EXEC_METHOD(Debugging, Assert, 3)
6266

67+
MC_EXEC_DEFINE_EXEC_METHOD(Debugging, PutIntoMessage, 2)
68+
6369
////////////////////////////////////////////////////////////////////////////////
6470

6571
void MCDebuggingExecDebugDo(MCExecContext& ctxt, MCStringRef p_script, uinteger_t p_line, uinteger_t p_pos)
@@ -456,3 +462,92 @@ void MCDebuggingExecAssert(MCExecContext& ctxt, int type, bool p_eval_success, b
456462

457463
ctxt . GetObject() -> message(MCM_assert_error, &t_handler);
458464
}
465+
466+
////////////////////////////////////////////////////////////////////////////////
467+
468+
void MCDebuggingExecPutIntoMessage(MCExecContext& ctxt, MCStringRef p_value, int p_where)
469+
{
470+
if (!MCS_put(ctxt, p_where == PT_INTO ? kMCSPutIntoMessage : (p_where == PT_BEFORE ? kMCSPutBeforeMessage : kMCSPutAfterMessage), p_value))
471+
ctxt . LegacyThrow(EE_PUT_CANTSETINTO);
472+
}
473+
474+
static MCObject *getobj(MCExecContext& ctxt, MCStringRef p_string)
475+
{
476+
MCObject *objptr = NULL;
477+
MCChunk *tchunk = new (nothrow) MCChunk(False);
478+
MCerrorlock++;
479+
MCScriptPoint sp(p_string);
480+
if (tchunk->parse(sp, False) == PS_NORMAL)
481+
{
482+
uint4 parid;
483+
tchunk->getobj(ctxt, objptr, parid, True);
484+
}
485+
MCerrorlock--;
486+
delete tchunk;
487+
return objptr;
488+
}
489+
490+
void MCDebuggingSetMessageBoxRedirect(MCExecContext& ctxt, MCStringRef p_target)
491+
{
492+
MCObject *t_object;
493+
t_object = getobj(ctxt, p_target);
494+
495+
if (t_object != NULL)
496+
MCmessageboxredirect = t_object -> GetHandle();
497+
else
498+
MCmessageboxredirect = nil;
499+
}
500+
501+
void MCDebuggingGetMessageBoxLastObject(MCExecContext& ctxt, MCStringRef& r_object)
502+
{
503+
if (MCmessageboxlastobject.IsValid())
504+
{
505+
bool t_success;
506+
507+
MCAutoStringRef t_obj, t_long_id;
508+
MCAutoValueRef t_id_value;
509+
t_success = MCStringCreateMutable(0, &t_obj);
510+
511+
if (t_success)
512+
t_success = MCmessageboxlastobject->names(P_LONG_ID, &t_id_value);
513+
if (t_success && ctxt . ConvertToString(*t_id_value, &t_long_id))
514+
t_success = MCStringAppendFormat(*t_obj, "%@,%@,%u", *t_long_id, MCNameGetString(MCmessageboxlasthandler), MCmessageboxlastline);
515+
516+
if (t_success && MCmessageboxlastobject->getparentscript() != nil)
517+
{
518+
t_success = MCmessageboxlastobject->getparentscript()->GetObject()->names(P_LONG_ID, &t_id_value);
519+
if (t_success && ctxt . ConvertToString(*t_id_value, &t_long_id))
520+
t_success = MCStringAppendFormat(*t_obj, ",%@", *t_long_id);
521+
}
522+
if (t_success && MCStringCopy(*t_obj, r_object))
523+
return;
524+
}
525+
else
526+
{
527+
r_object = MCValueRetain(kMCEmptyString);
528+
return;
529+
}
530+
531+
ctxt . Throw();
532+
}
533+
534+
void MCDebuggingGetMessageBoxRedirect(MCExecContext& ctxt, MCStringRef& r_id)
535+
{
536+
if (MCmessageboxredirect.IsValid())
537+
{
538+
MCAutoValueRef t_long_id;
539+
if (MCmessageboxredirect -> names(P_LONG_ID, &t_long_id) &&
540+
ctxt . ConvertToString(*t_long_id, r_id))
541+
return;
542+
}
543+
else
544+
{
545+
r_id = MCValueRetain(kMCEmptyString);
546+
return;
547+
}
548+
549+
ctxt . Throw();
550+
}
551+
552+
553+

engine/src/exec-ide.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3131

3232
////////////////////////////////////////////////////////////////////////////////
3333

34-
MC_EXEC_DEFINE_EXEC_METHOD(Ide, PutIntoMessage, 2)
3534
MC_EXEC_DEFINE_EXEC_METHOD(Ide, EditScriptOfObject, 2)
3635
MC_EXEC_DEFINE_EXEC_METHOD(Ide, HideMessageBox, 0)
3736
MC_EXEC_DEFINE_EXEC_METHOD(Ide, ShowMessageBox, 0)
@@ -51,12 +50,6 @@ void MCIdeExecEditScriptOfObject(MCExecContext &ctxt, MCObject *p_object, MCStri
5150

5251
////////////////////////////////////////////////////////////////////////////////
5352

54-
void MCIdeExecPutIntoMessage(MCExecContext& ctxt, MCStringRef p_value, int p_where)
55-
{
56-
if (!MCS_put(ctxt, p_where == PT_INTO ? kMCSPutIntoMessage : (p_where == PT_BEFORE ? kMCSPutBeforeMessage : kMCSPutAfterMessage), p_value))
57-
ctxt . LegacyThrow(EE_PUT_CANTSETINTO);
58-
}
59-
6053
void MCIdeExecHideMessageBox(MCExecContext& ctxt)
6154
{
6255
MCStack *mb = ctxt . GetObject()->getstack()->findstackname(MCN_messagename);

engine/src/exec.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4867,12 +4867,10 @@ void MCLegacySetMultiSpace(MCExecContext& ctxt, uinteger_t p_value);
48674867

48684868
///////////
48694869

4870-
extern MCExecMethodInfo *kMCIdeExecPutIntoMessageMethodInfo;
48714870
extern MCExecMethodInfo *kMCIdeExecEditScriptOfObjectMethodInfo;
48724871
extern MCExecMethodInfo *kMCIdeExecHideMessageBoxMethodInfo;
48734872
extern MCExecMethodInfo *kMCIdeExecShowMessageBoxMethodInfo;
48744873

4875-
void MCIdeExecPutIntoMessage(MCExecContext& ctxt, MCStringRef value, int where);
48764874

48774875
void MCIdeExecEditScriptOfObject(MCExecContext& ctxt, MCObject *p_object, MCStringRef p_at);
48784876
void MCIdeExecHideMessageBox(MCExecContext& ctxt);
@@ -5123,6 +5121,7 @@ extern MCExecMethodInfo *kMCDebuggingSetDebugContextMethodInfo;
51235121
extern MCExecMethodInfo *kMCDebuggingGetExecutionContextsMethodInfo;
51245122
extern MCExecMethodInfo *kMCDebuggingGetWatchedVariablesMethodInfo;
51255123
extern MCExecMethodInfo *kMCDebuggingSetWatchedVariablesMethodInfo;
5124+
extern MCExecMethodInfo *kMCDebuggingExecPutIntoMessageMethodInfo;
51265125

51275126
void MCDebuggingExecBreakpoint(MCExecContext& ctxt, uinteger_t p_line, uinteger_t p_pos);
51285127
void MCDebuggingExecDebugDo(MCExecContext& ctxt, MCStringRef p_script, uinteger_t p_line, uinteger_t p_pos);
@@ -5148,6 +5147,11 @@ void MCDebuggingSetDebugContext(MCExecContext& ctxt, MCStringRef p_value);
51485147
void MCDebuggingGetExecutionContexts(MCExecContext& ctxt, MCStringRef& r_value);
51495148
void MCDebuggingGetWatchedVariables(MCExecContext& ctxt, MCStringRef& r_value);
51505149
void MCDebuggingSetWatchedVariables(MCExecContext& ctxt, MCStringRef p_value);
5150+
void MCDebuggingExecPutIntoMessage(MCExecContext& ctxt, MCStringRef value, int where);
5151+
void MCDebuggingGetMessageBoxLastObject(MCExecContext& ctxt, MCStringRef& r_object);
5152+
void MCDebuggingGetMessageBoxRedirect(MCExecContext& ctxt, MCStringRef& r_id);
5153+
void MCDebuggingSetMessageBoxRedirect(MCExecContext& ctxt, MCStringRef p_target);
5154+
51515155

51525156
///////////
51535157

engine/src/globals.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,12 @@ MCArrayRef MCcommandarguments;
505505

506506
MCHook *MChooks = nil;
507507

508+
MCObjectHandle MCmessageboxredirect = nil;
509+
MCObjectHandle MCmessageboxlastobject = nil;
510+
MCNameRef MCmessageboxlasthandler = nil;
511+
uint32_t MCmessageboxlastline = 0;
512+
513+
508514
////////////////////////////////////////////////////////////////////////////////
509515

510516
extern MCUIDC *MCCreateScreenDC(void);
@@ -873,6 +879,12 @@ void X_clear_globals(void)
873879
#endif
874880

875881
MCDateTimeInitialize();
882+
883+
MCmessageboxredirect = nil;
884+
MCmessageboxlastobject = nil;
885+
MCmessageboxlasthandler = nil;
886+
MCmessageboxlastline = 0;
887+
876888
}
877889

878890
/* ---------------------------------------------------------------- */

0 commit comments

Comments
 (0)