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