]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/src/applet/appletwindow.cpp
applied patch 430835 (missing wxSTD breaking compilation for VC++ 5)
[wxWidgets.git] / contrib / src / applet / appletwindow.cpp
... / ...
CommitLineData
1/****************************************************************************
2*
3* wxWindows HTML Applet Package
4*
5* Copyright (C) 1991-2001 SciTech Software, Inc.
6* All rights reserved.
7*
8* ======================================================================
9* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
10* | |
11* |This copyrighted computer code is a proprietary trade secret of |
12* |SciTech Software, Inc., located at 505 Wall Street, Chico, CA 95928 |
13* |USA (www.scitechsoft.com). ANY UNAUTHORIZED POSSESSION, USE, |
14* |VIEWING, COPYING, MODIFICATION OR DISSEMINATION OF THIS CODE IS |
15* |STRICTLY PROHIBITED BY LAW. Unless you have current, express |
16* |written authorization from SciTech to possess or use this code, you |
17* |may be subject to civil and/or criminal penalties. |
18* | |
19* |If you received this code in error or you would like to report |
20* |improper use, please immediately contact SciTech Software, Inc. at |
21* |530-894-8400. |
22* | |
23* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
24* ======================================================================
25*
26* Language: ANSI C++
27* Environment: Any
28*
29* Description: Main wxHtmlAppletWindow class implementation
30*
31****************************************************************************/
32
33// For compilers that support precompilation
34#include "wx/wxprec.h"
35#include "wx/html/forcelnk.h"
36
37// Include private headers
38#include "wx/applet/applet.h"
39#include "wx/applet/window.h"
40#include "wx/applet/loadpage.h"
41
42// Preprocessor Stuff
43#include "wx/applet/prepinclude.h"
44#include "wx/applet/prepecho.h"
45#include "wx/applet/prepifelse.h"
46
47
48/*---------------------------- Global variables ---------------------------*/
49
50wxHashTable wxHtmlAppletWindow::m_Cookies;
51
52/*------------------------- Implementation --------------------------------*/
53
54// Empty event handler. We include this event handler simply so that
55// sub-classes of wxApplet can reference wxApplet in the event tables
56// that they create as necessary.
57BEGIN_EVENT_TABLE(wxHtmlAppletWindow, wxHtmlWindow)
58 EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage)
59 EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded)
60END_EVENT_TABLE()
61
62// Implement the class functions for wxHtmlAppletWindow
63IMPLEMENT_CLASS(wxHtmlAppletWindow, wxHtmlWindow);
64
65// Define the wxAppletList implementation
66#include "wx/listimpl.cpp"
67WX_DEFINE_LIST(wxAppletList);
68
69/****************************************************************************
70REMARKS:
71Constructor for the applet window class.
72****************************************************************************/
73wxHtmlAppletWindow::wxHtmlAppletWindow(
74 wxWindow *parent,
75 wxWindowID id,
76 wxToolBarBase *navBar,
77 int navBackId,
78 int navForwardId,
79 const wxPoint& pos,
80 const wxSize& size,
81 long style,
82 const wxString& name)
83 : wxHtmlWindow(parent,id,pos,size,style,name)
84{
85 //setup client navbars
86 if (navBar) {
87 m_NavBar = navBar;
88 m_NavBackId = navBackId;
89 m_NavForwardId = navForwardId;
90 }
91 else {
92 m_NavBar = NULL;
93 }
94
95 //Add HTML preprocessors
96 // deleting preprocessors is done by the code within the window
97
98 incPreprocessor = new wxIncludePrep(); // #include preprocessor
99 wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
100 wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
101
102 this->AddProcessor(incPreprocessor);
103 this->AddProcessor(echoPreprocessor);
104 this->AddProcessor(ifPreprocessor);
105
106
107}
108
109/****************************************************************************
110REMARKS:
111Destructor for the applet window class.
112****************************************************************************/
113wxHtmlAppletWindow::~wxHtmlAppletWindow()
114{
115}
116
117/****************************************************************************
118PARAMETERS:
119className - Name of the applet class to create an object for
120size - Initial size of the applet to be created
121
122RETURNS:
123Pointer to the wxApplet created, or NULL if unable to create the applet.
124
125REMARKS:
126This function is used to create new wxApplet objects dynamically based on the
127class name as a string. This allows instances of wxApplet classes to be
128created dynamically based on string values embedded in the custom tags of an
129HTML page.
130****************************************************************************/
131wxApplet *wxHtmlAppletWindow::CreateApplet(
132 const wxString& classId,
133 const wxString& iName,
134 const wxHtmlTag& params,
135 const wxSize& size)
136{
137 // Dynamically create the class instance at runtime
138 wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
139 if (!info)
140 return NULL;
141 wxObject *obj = info->CreateObject();
142 if (!obj)
143 return NULL;
144 wxApplet *applet = wxDynamicCast(obj,wxApplet);
145 if (!applet)
146 return NULL;
147 if (!applet->Create(this,params,size)) {
148 delete applet;
149 return NULL;
150 }
151 m_AppletList.Append(iName,applet);
152 return applet;
153}
154
155/****************************************************************************
156PARAMETERS:
157appletName - Name of the applet class to find
158
159RETURNS:
160Pointer to the wxApplet found, or NULL if not found.
161
162REMARKS:
163Find an instance of an applet based on it's name
164****************************************************************************/
165wxApplet *wxHtmlAppletWindow::FindApplet(
166 const wxString& appletName)
167{
168 wxAppletList::Node *node = m_AppletList.Find(appletName);
169 if (!node)
170 return NULL;
171 return node->GetData();
172}
173
174/****************************************************************************
175PARAMETERS:
176applet - Pointer to the applet object to remove from the list
177
178RETURNS:
179True if the applet was found and removed, false if not. The applet itself
180is *not* destroyed!
181
182REMARKS:
183Remove an applet from the manager. Called during applet destruction
184****************************************************************************/
185bool wxHtmlAppletWindow::RemoveApplet(
186 const wxApplet *applet)
187{
188 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
189 if (node->GetData() == applet) {
190 m_AppletList.DeleteNode(node);
191 return true;
192 }
193 }
194 return false;
195}
196
197/****************************************************************************
198PARAMETERS:
199URL - New URL for the page to load
200
201RETURNS:
202True if page loaded successfully, false if not
203
204REMARKS:
205Remove an applet from the manager. Called during applet destruction
206****************************************************************************/
207bool wxHtmlAppletWindow::LoadPage(
208 const wxString& link)
209{
210 wxString href(link);
211
212 // TODO: This needs to be made platform inde if possible.
213 if (link.GetChar(0) == '?'){
214 wxString cmd = link.BeforeFirst('=');
215 wxString cmdValue = link.AfterFirst('=');
216
217 if(!(cmd.CmpNoCase("?EXTERNAL"))){
218#ifdef __WINDOWS__
219 ShellExecute(this ? (HWND)this->GetHWND() : NULL,NULL,cmdValue.c_str(),NULL,"",SW_SHOWNORMAL);
220#else
221 #error Platform not implemented yet!
222#endif
223 return true;
224 }
225 if (!(cmd.CmpNoCase("?EXECUTE"))){
226 wxMessageBox(cmdValue);
227 return true;
228 }
229 if (!(cmd.CmpNoCase("?VIRTUAL"))){
230 VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
231 if (&temp) {
232 href = temp.GetHref();
233 }
234 else {
235#ifdef CHECKED
236 wxMessageBox("VIRTUAL LINK ERROR: " + cmdValue + " does not exist.");
237#endif
238 return true;
239 }
240 }
241 }
242
243 // Grab the directory from the string for use in the include preprocessor
244 // make sure we get either type of / or \.
245 int ch = link.Find('\\', true);
246 if (ch == -1) ch = link.Find('/', true);
247 if (ch != -1) {
248 wxFileSystem fs;
249 wxString tmp = link.Mid(0, ch+1);
250 fs.ChangePathTo(incPreprocessor->GetDirectory(), true);
251 fs.ChangePathTo(tmp, true);
252 incPreprocessor->ChangeDirectory(fs.GetPath());
253 }
254
255 // Inform all the applets that the new page is being loaded
256 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
257 (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
258 bool stat = wxHtmlWindow::LoadPage(href);
259
260 // Enable/Dis the navbar tools
261 if (m_NavBar) {
262 m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
263 m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
264 }
265 return stat;
266}
267
268/****************************************************************************
269PARAMETERS:
270URL - String URL that we are navigating to
271
272REMARKS:
273Called when the user navigates to a new URL from the current page. We simply
274call the LoadPage function above to load the new page and display it.
275****************************************************************************/
276void wxHtmlAppletWindow::OnLinkClicked(
277 const wxHtmlLinkInfo& link)
278{
279 LoadPage(link.GetHref());
280}
281
282/****************************************************************************
283REMARKS:
284Called when the user navigates forward within the HTML history stack.
285We call all the applets in turn allowing them to handle the navigation
286command prior to being destructed when the current page is destroyed.
287****************************************************************************/
288bool wxHtmlAppletWindow::HistoryForward()
289{
290 if (!HistoryCanForward())
291 return false;
292
293 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
294 (node->GetData())->OnHistoryForward();
295
296 return wxHtmlWindow::HistoryForward();
297}
298
299/****************************************************************************
300REMARKS:
301Called when the user navigates backwards within the HTML history stack.
302We call all the applets in turn allowing them to handle the navigation
303command prior to being destructed when the current page is destroyed.
304****************************************************************************/
305bool wxHtmlAppletWindow::HistoryBack()
306{
307 if (!HistoryCanBack())
308 return false;
309
310 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
311 (node->GetData())->OnHistoryBack();
312
313 return wxHtmlWindow::HistoryBack();
314}
315
316/****************************************************************************
317PARAMETERS:
318msg - wxEvent message to be sent to all wxApplets
319
320REMARKS:
321This function is called by the wxApplet's when they need to send a message
322to all other applets on the current page. This is the primary form of
323communication between applets on the page if they need to inform each
324other of internal information.
325
326Note that the event handling terminates as soon as the first wxApplet
327handles the event. If the event should be handled by all wxApplet's,
328the event handlers for the applets should not reset the wxEvent::Skip()
329value (ie: by default it is true).
330****************************************************************************/
331void wxHtmlAppletWindow::SendMessage(
332 wxEvent& msg)
333{
334 // Preset the skip flag
335 msg.Skip();
336
337 // Process all applets in turn and send them the message
338 for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
339 (node->GetData())->OnMessage(msg);
340 if (!msg.GetSkipped()){
341 wxMessageBox("BREAK");
342 break;
343 }
344 }
345}
346
347/****************************************************************************
348PARAMETERS:
349name - Uniq wxString used as hash key
350cookie - wxObject data returned when name is found.
351
352RETURNS:
353True if new cookie was added, false if cookie with same name already exists.
354
355REMARKS:
356This function is called by the wxApplet's when they need register a cookie
357of data in the applet window's cookie table. Cookies are arbitrary data
358objects that are references by unique name's by the wxApplet. These
359values can be used to store and retrieve data that needs to remain
360persisent across invocations of the wxApplet. Ie: The first time an
361applet is created it would use the cookie to store data to maintain
362it's present state so that if you navigated back to the same page
363is would be able to re-load the prior state as though the applet
364was never actually destructed.
365
366Note: If a cookie with the same name already exists, this function returns
367 false. Hence if you wish to replace a cookie you should first call
368 UnRegisterCookie to ensure the cookie is deleted and then call this
369 function.
370****************************************************************************/
371bool wxHtmlAppletWindow::RegisterCookie(
372 const wxString& name,
373 wxObject *cookie)
374{
375 // Fail if the named cookie already exists!
376 if (m_Cookies.Get(name))
377 return false;
378 m_Cookies.Put(name,cookie);
379 return true;
380}
381
382/****************************************************************************
383PARAMETERS:
384name - wxString uniq haskey used to remove item from hash
385
386RETURNS:
387True if found and deleted, false if not found in table.
388
389REMARKS:
390This function is called by the wxApplet's when they need de-register a
391cookie of data in the applet window's cookie table. The data in the
392cookie itself is also deleted before it is removed from the table.
393****************************************************************************/
394bool wxHtmlAppletWindow::UnRegisterCookie(
395 const wxString& name)
396{
397 wxObject *data = m_Cookies.Delete(name);
398 if (data) {
399 delete data;
400 return true;
401 }
402 return false;
403}
404
405/****************************************************************************
406PARAMETERS:
407msg - wxEvent message to be sent to all wxApplets
408
409RETURNS:
410Pointer to the cookie data if found, NULL if not found.
411
412REMARKS:
413This function is called by the wxApplet's when they need to find a cookie
414of data given it's public name. If the cookie is not found, NULL is
415returned.
416****************************************************************************/
417wxObject *wxHtmlAppletWindow::FindCookie(
418 const wxString& name)
419{
420 return m_Cookies.Get(name);
421}
422
423/****************************************************************************
424PARAMETERS:
425event - Event to handle
426
427REMARKS:
428This function handles delayed LoadPage events posted from applets that
429need to change the page for the current window to a new window.
430****************************************************************************/
431void wxHtmlAppletWindow::OnLoadPage(
432 wxLoadPageEvent &event)
433{
434 if (event.GetHtmlWindow() == this){
435 if (LoadPage(event.GetHRef())){
436 wxPageLoadedEvent evt;
437 }
438 }
439}
440
441/****************************************************************************
442PARAMETERS:
443event - Event to handle
444
445REMARKS:
446This function handles delayed LoadPage events posted from applets that
447need to change the page for the current window to a new window.
448****************************************************************************/
449void wxHtmlAppletWindow::OnPageLoaded(
450 wxPageLoadedEvent &)
451{
452 Enable(true);
453}
454
455/****************************************************************************
456PARAMETERS:
457name - name of the last applet that changed the data in this object
458group - name of the group the allplet belongs to.
459href - webpage to go to.
460
461REMARKS:
462VirtualData is used to store information on the virtual links.
463****************************************************************************/
464VirtualData::VirtualData(
465 wxString& name,
466 wxString& group,
467 wxString& href )
468{
469 m_name = name;
470 m_group = group;
471 m_href = href;
472}
473
474#include "wx/html/m_templ.h"
475
476/****************************************************************************
477REMARKS:
478Implementation for the <embed> HTML tag handler. This handler takes care
479of automatically constructing the wxApplet objects of the appropriate
480class based on the <embed> tag information.
481****************************************************************************/
482TAG_HANDLER_BEGIN(wxApplet, "WXAPPLET")
483
484TAG_HANDLER_PROC(tag)
485{
486 wxWindow *wnd;
487 wxHtmlAppletWindow *appletWindow;
488 wxApplet *applet;
489 wxString classId;
490 wxString name;
491 int width, height;
492
493 wnd = m_WParser->GetWindow();
494
495 if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
496 tag.ScanParam("WIDTH", "%i", &width);
497 tag.ScanParam("HEIGHT", "%i", &height);
498 if (tag.HasParam("CLASSID")){
499 classId = tag.GetParam("CLASSID");
500 if ( classId.IsNull() || classId.Len() == 0 ){
501 wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
502 return false;
503 }
504 if (tag.HasParam("NAME"))
505 name = tag.GetParam("NAME");
506
507 // If the name is NULL or len is zero then we assume that the html guy
508 // didn't include the name param which is optional.
509 if ( name.IsNull() || name.Len() == 0 )
510 name = classId;
511
512 // We got all the params and can now create the applet
513 if ((applet = appletWindow->CreateApplet(classId, name, tag , wxSize(width, height))) != NULL){
514 applet->Show(true);
515 m_WParser->OpenContainer()->InsertCell(new wxHtmlWidgetCell(applet,0));
516 }
517 else
518 wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
519 }
520 else{
521 wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
522 return false;
523 }
524 //Add more param parsing here. If or when spec changes.
525 //For now we'll ignore any other params those HTML guys
526 //might put in our tag.
527 }
528
529 return false;
530}
531
532TAG_HANDLER_END(wxApplet)
533
534TAGS_MODULE_BEGIN(wxApplet)
535 TAGS_MODULE_ADD(wxApplet)
536TAGS_MODULE_END(wxApplet)
537
538// This is our little forcelink hack.
539FORCE_LINK(loadpage)
540