]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/applet/appletwindow.cpp
1 /****************************************************************************
3 * wxWindows HTML Applet Package
5 * Copyright (C) 1991-2001 SciTech Software, Inc.
8 * ======================================================================
9 * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
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. |
19 * |If you received this code in error or you would like to report |
20 * |improper use, please immediately contact SciTech Software, Inc. at |
23 * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
24 * ======================================================================
29 * Description: Main wxHtmlAppletWindow class implementation
31 ****************************************************************************/
33 // For compilers that support precompilation
34 #include "wx/wxprec.h"
36 #include "wx/process.h"
37 #include "wx/spawnbrowser.h"
38 #include "wx/html/forcelnk.h"
41 #include <process.h> // spawnl()
43 // Include private headers
44 #include "wx/applet/applet.h"
45 #include "wx/applet/window.h"
46 #include "wx/applet/loadpage.h"
47 #include "wx/applet/plugin.h"
50 #include "wx/applet/prepinclude.h"
51 #include "wx/applet/prepecho.h"
52 #include "wx/applet/prepifelse.h"
54 /*---------------------------- Global variables ---------------------------*/
56 wxHashTable
wxHtmlAppletWindow::m_Cookies
;
58 /*------------------------- Implementation --------------------------------*/
60 // Empty event handler. We include this event handler simply so that
61 // sub-classes of wxApplet can reference wxApplet in the event tables
62 // that they create as necessary.
63 BEGIN_EVENT_TABLE(wxHtmlAppletWindow
, wxHtmlWindow
)
64 EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage
)
65 EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded
)
68 // Implement the class functions for wxHtmlAppletWindow
69 IMPLEMENT_CLASS(wxHtmlAppletWindow
, wxHtmlWindow
);
71 // Define the wxAppletList implementation
72 #include "wx/listimpl.cpp"
73 WX_DEFINE_LIST(wxAppletList
);
75 /****************************************************************************
77 Constructor for the applet window class.
78 ****************************************************************************/
79 wxHtmlAppletWindow::wxHtmlAppletWindow(
82 wxToolBarBase
*navBar
,
89 const wxString
& docroot
)
90 : wxHtmlWindow(parent
,id
,pos
,size
,style
,name
)
95 // setup client navbars
98 m_NavBackId
= navBackId
;
99 m_NavForwardId
= navForwardId
;
108 // Set the key_type for applets
109 m_AppletList
= wxAppletList(wxKEY_STRING
);
111 // Add HTML preprocessors
112 // deleting preprocessors is done by the code within the window
114 incPreprocessor
= new wxIncludePrep(); // #include preprocessor
115 incPreprocessor
->ChangeDirectory(m_DocRoot
);
117 wxEchoPrep
* echoPreprocessor
= new wxEchoPrep(); // #echo preprocessor
118 wxIfElsePrep
* ifPreprocessor
= new wxIfElsePrep();
120 this->AddProcessor(incPreprocessor
);
121 this->AddProcessor(echoPreprocessor
);
122 this->AddProcessor(ifPreprocessor
);
125 /****************************************************************************
127 Destructor for the applet window class.
128 ****************************************************************************/
129 wxHtmlAppletWindow::~wxHtmlAppletWindow()
133 /****************************************************************************
135 className - Name of the applet class to create an object for
136 size - Initial size of the applet to be created
139 Pointer to the wxApplet created, or NULL if unable to create the applet.
142 This function is used to create new wxApplet objects dynamically based on the
143 class name as a string. This allows instances of wxApplet classes to be
144 created dynamically based on string values embedded in the custom tags of an
146 ****************************************************************************/
147 wxApplet
*wxHtmlAppletWindow::CreateApplet(
148 const wxString
& classId
,
149 const wxString
& iName
,
150 const wxHtmlTag
& params
,
153 // Dynamically create the class instance at runtime
154 wxClassInfo
*info
= wxClassInfo::FindClass(classId
.c_str());
157 wxObject
*obj
= info
->CreateObject();
160 wxApplet
*applet
= wxDynamicCast(obj
,wxApplet
);
163 if (!applet
->Create(this,params
,size
)) {
168 // do some fixups on the size if its screwed up
169 wxSize nsize
= applet
->GetBestSize();
170 if (nsize
.x
< size
.x
) nsize
.x
= size
.x
;
171 if (nsize
.y
< size
.y
) nsize
.y
= size
.y
;
172 applet
->SetSize(nsize
);
175 m_AppletList
.Append(iName
,(wxObject
*)applet
);
179 /****************************************************************************
181 classId - Name of the Plugin class to create an object for
184 Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
187 This function is used to create new wxPlugIn objects dynamically based on the
188 class name as a string. This allows instances of wxPlugIn classes to be
189 created dynamically based on string values embedded in the custom tags of an
191 ****************************************************************************/
192 bool wxHtmlAppletWindow::CreatePlugIn(
193 const wxString
& classId
)
195 // Dynamically create the class instance at runtime
196 wxClassInfo
*info
= wxClassInfo::FindClass(classId
.c_str());
199 wxObject
*obj
= info
->CreateObject();
202 wxPlugIn
*plugIn
= wxDynamicCast(obj
,wxPlugIn
);
205 if (!plugIn
->Create(this)) {
212 /****************************************************************************
214 appletName - Name of the applet class to find
217 Pointer to the wxApplet found, or NULL if not found.
220 Find an instance of an applet based on it's name
221 ****************************************************************************/
222 wxApplet
*wxHtmlAppletWindow::FindApplet(
223 const wxString
& appletName
)
225 wxAppletList::Node
*node
= m_AppletList
.Find(appletName
);
228 return node
->GetData();
231 /****************************************************************************
233 applet - Pointer to the applet object to remove from the list
236 True if the applet was found and removed, false if not. The applet itself
240 Remove an applet from the manager. Called during applet destruction
241 ****************************************************************************/
242 bool wxHtmlAppletWindow::RemoveApplet(
243 const wxApplet
*applet
)
245 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext()) {
246 if (node
->GetData() == applet
) {
247 m_AppletList
.DeleteNode(node
);
254 /****************************************************************************
256 URL - New URL for the page to load
259 True if page loaded successfully, false if not
262 Remove an applet from the manager. Called during applet destruction
263 ****************************************************************************/
265 bool wxHtmlAppletWindow::LoadPage(
266 const wxString
& link
)
270 // TODO: technically we allow no relative paths
272 // Check to see if it is a real url, if not it is a file
273 if (link
.Mid(0, 5).CmpNoCase("http:") != 0) {
275 // Check for abs path. If it is not then tack on the path
276 // supplied at creation.
277 // TODO: Abs paths are only used in testing (remove this)
278 if (link
.GetChar(1) != ':')
279 href
= m_DocRoot
+ href
;
282 if (link
.GetChar(0) == '?'){
283 wxString cmd
= link
.BeforeFirst('=');
284 wxString cmdValue
= link
.AfterFirst('=');
286 // Launches the default Internet browser for the system.
287 if(!(cmd
.CmpNoCase("?EXTERNAL"))){
288 return wxSpawnBrowser(this, cmdValue
.c_str());
291 // Launches an external program on the system.
292 if (!(cmd
.CmpNoCase("?EXECUTE"))){
293 int code
= spawnl( P_NOWAIT
, cmdValue
, NULL
);
297 // Looks for a href in a variable stored as a cookie. The href can be
298 // changed on the fly.
299 if (!(cmd
.CmpNoCase("?VIRTUAL"))){
300 VirtualData
& temp
= *((VirtualData
*)FindCookie(cmdValue
));
302 href
= temp
.GetHref();
306 wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue
.c_str());
312 // This launches a qlet - It is like an applet but is more generic in that it
313 // can be of any wxWin type so it then has the freedom to do more stuff.
314 if (!(cmd
.CmpNoCase("?WXAPPLET"))){
315 if (!cmdValue
.IsNull()){
316 if (!CreatePlugIn(cmdValue
)){
318 wxLogError(_T("Launch Applet ERROR: '%s' does not exist."), cmdValue
.c_str());
326 // Inform all the applets that the new page is being loaded
327 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
328 (node
->GetData())->OnLinkClicked(wxHtmlLinkInfo(href
));
330 bool stat
= wxHtmlWindow::LoadPage(href
);
333 // Enable/Dis the navbar tools
335 m_NavBar
->EnableTool(m_NavForwardId
,HistoryCanForward());
336 m_NavBar
->EnableTool(m_NavBackId
,HistoryCanBack());
341 /****************************************************************************
343 URL - String URL that we are navigating to
346 Called when the user navigates to a new URL from the current page. We simply
347 call the LoadPage function above to load the new page and display it.
348 ****************************************************************************/
349 void wxHtmlAppletWindow::OnLinkClicked(
350 const wxHtmlLinkInfo
& link
)
352 LoadPage(link
.GetHref());
355 /****************************************************************************
357 Called when the user navigates forward within the HTML history stack.
358 We call all the applets in turn allowing them to handle the navigation
359 command prior to being destructed when the current page is destroyed.
360 ****************************************************************************/
361 bool wxHtmlAppletWindow::HistoryForward()
363 if (!HistoryCanForward())
366 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
367 (node
->GetData())->OnHistoryForward();
369 return wxHtmlWindow::HistoryForward();
372 /****************************************************************************
374 Called when the user navigates backwards within the HTML history stack.
375 We call all the applets in turn allowing them to handle the navigation
376 command prior to being destructed when the current page is destroyed.
377 ****************************************************************************/
378 bool wxHtmlAppletWindow::HistoryBack()
380 if (!HistoryCanBack())
383 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
384 (node
->GetData())->OnHistoryBack();
386 return wxHtmlWindow::HistoryBack();
389 /****************************************************************************
391 msg - wxEvent message to be sent to all wxApplets
394 This function is called by the wxApplet's when they need to send a message
395 to all other applets on the current page. This is the primary form of
396 communication between applets on the page if they need to inform each
397 other of internal information.
399 Note that the event handling terminates as soon as the first wxApplet
400 handles the event. If the event should be handled by all wxApplet's,
401 the event handlers for the applets should not reset the wxEvent::Skip()
402 value (ie: by default it is true).
403 ****************************************************************************/
404 void wxHtmlAppletWindow::SendMessage(
407 // Preset the skip flag
410 // Process all applets in turn and send them the message
411 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext()) {
412 (node
->GetData())->OnMessage(msg
);
413 if (!msg
.GetSkipped()){
414 wxMessageBox("BREAK");
420 /****************************************************************************
422 name - Uniq wxString used as hash key
423 cookie - wxObject data returned when name is found.
426 True if new cookie was added, false if cookie with same name already exists.
429 This function is called by the wxApplet's when they need register a cookie
430 of data in the applet window's cookie table. Cookies are arbitrary data
431 objects that are references by unique name's by the wxApplet. These
432 values can be used to store and retrieve data that needs to remain
433 persisent across invocations of the wxApplet. Ie: The first time an
434 applet is created it would use the cookie to store data to maintain
435 it's present state so that if you navigated back to the same page
436 is would be able to re-load the prior state as though the applet
437 was never actually destructed.
439 Note: If a cookie with the same name already exists, this function returns
440 false. Hence if you wish to replace a cookie you should first call
441 UnRegisterCookie to ensure the cookie is deleted and then call this
443 ****************************************************************************/
444 bool wxHtmlAppletWindow::RegisterCookie(
445 const wxString
& name
,
448 // Fail if the named cookie already exists!
449 if (m_Cookies
.Get(name
))
451 m_Cookies
.Put(name
,cookie
);
455 /****************************************************************************
457 name - wxString uniq haskey used to remove item from hash
460 True if found and deleted, false if not found in table.
463 This function is called by the wxApplet's when they need de-register a
464 cookie of data in the applet window's cookie table. The data in the
465 cookie itself is also deleted before it is removed from the table.
466 ****************************************************************************/
467 bool wxHtmlAppletWindow::UnRegisterCookie(
468 const wxString
& name
)
470 wxObject
*data
= m_Cookies
.Delete(name
);
478 /****************************************************************************
480 msg - wxEvent message to be sent to all wxApplets
483 Pointer to the cookie data if found, NULL if not found.
486 This function is called by the wxApplet's when they need to find a cookie
487 of data given it's public name. If the cookie is not found, NULL is
489 ****************************************************************************/
490 wxObject
*wxHtmlAppletWindow::FindCookie(
491 const wxString
& name
)
493 return m_Cookies
.Get(name
);
496 /****************************************************************************
498 event - Event to handle
501 This function handles delayed LoadPage events posted from applets that
502 need to change the page for the current window to a new window.
503 ****************************************************************************/
504 void wxHtmlAppletWindow::OnLoadPage(
505 wxLoadPageEvent
&event
)
507 // Test the mutex lock.
510 if (event
.GetHtmlWindow() == this){
511 if (LoadPage(event
.GetHRef())){
512 // wxPageLoadedEvent evt;
513 // NOTE: This is reserved for later use as we might need to send
514 // page loaded events to applets.
521 /****************************************************************************
523 event - Event to handle
526 This function handles delayed LoadPage events posted from applets that
527 need to change the page for the current window to a new window.
528 ****************************************************************************/
529 void wxHtmlAppletWindow::OnPageLoaded(
535 /****************************************************************************
540 This function tries to lock the mutex. If it can't, returns
541 immediately with false.
542 ***************************************************************************/
543 bool wxHtmlAppletWindow::TryLock()
552 /****************************************************************************
554 name - name of the last applet that changed the data in this object
555 group - name of the group the allplet belongs to.
556 href - webpage to go to.
559 VirtualData is used to store information on the virtual links.
560 ****************************************************************************/
561 VirtualData::VirtualData(
571 /****************************************************************************
574 ****************************************************************************/
575 void AppletProcess::OnTerminate(
579 // we're not needed any more
583 #include "wx/html/m_templ.h"
585 /****************************************************************************
587 Implementation for the <embed> HTML tag handler. This handler takes care
588 of automatically constructing the wxApplet objects of the appropriate
589 class based on the <embed> tag information.
590 ****************************************************************************/
591 TAG_HANDLER_BEGIN(wxApplet
, "WXAPPLET")
593 TAG_HANDLER_PROC(tag
)
596 wxHtmlAppletWindow
*appletWindow
;
602 wnd
= m_WParser
->GetWindow();
604 if ((appletWindow
= wxDynamicCast(wnd
,wxHtmlAppletWindow
)) != NULL
){
605 wxSize size
= wxDefaultSize
;
607 if (tag
.HasParam("WIDTH")) {
608 tag
.GetParamAsInt("WIDTH", &width
);
609 size
.SetWidth(width
);
612 if (tag
.HasParam("HEIGHT")) {
613 tag
.GetParamAsInt("HEIGHT", &height
);
614 size
.SetHeight(height
);
617 al
= wxHTML_ALIGN_BOTTOM
;
618 if (tag
.HasParam(wxT("ALIGN"))) {
619 wxString alstr
= tag
.GetParam(wxT("ALIGN"));
620 alstr
.MakeUpper(); // for the case alignment was in ".."
621 if (alstr
== wxT("TEXTTOP") || alstr
== wxT("TOP"))
622 al
= wxHTML_ALIGN_TOP
;
623 else if ((alstr
== wxT("CENTER")) || (alstr
== wxT("ABSCENTER")))
624 al
= wxHTML_ALIGN_CENTER
;
627 if (tag
.HasParam("CLASSID")){
628 classId
= tag
.GetParam("CLASSID");
629 if ( classId
.IsNull() || classId
.Len() == 0 ){
630 wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR
);
633 if (tag
.HasParam("NAME"))
634 name
= tag
.GetParam("NAME");
636 // If the name is NULL or len is zero then we assume that the html guy
637 // didn't include the name param which is optional.
638 if ( name
.IsNull() || name
.Len() == 0 )
641 // We got all the params and can now create the applet
642 if ((applet
= appletWindow
->CreateApplet(classId
, name
, tag
, size
)) != NULL
){
644 m_WParser
->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet
,al
));
647 wxMessageBox("wxApplet error: Could not create:" + classId
+ "," + name
);
650 wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR
);
653 //Add more param parsing here. If or when spec changes.
654 //For now we'll ignore any other params those HTML guys
655 //might put in our tag.
661 TAG_HANDLER_END(wxApplet
)
663 TAGS_MODULE_BEGIN(wxApplet
)
664 TAGS_MODULE_ADD(wxApplet
)
665 TAGS_MODULE_END(wxApplet
)
667 /*********************************************************************************
669 *********************************************************************************/
670 wxHtmlAppletCell::wxHtmlAppletCell(wxWindow
*wnd
, int align
) : wxHtmlCell()
674 m_Wnd
->GetSize(&sx
, &sy
);
675 m_Width
= sx
, m_Height
= sy
;
678 case wxHTML_ALIGN_TOP
:
679 m_Descent
= m_Height
;
681 case wxHTML_ALIGN_CENTER
:
682 m_Descent
= m_Height
/ 2;
684 case wxHTML_ALIGN_BOTTOM
:
690 SetCanLiveOnPagebreak(FALSE
);
694 void wxHtmlAppletCell::Draw(wxDC
& WXUNUSED(dc
), int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(view_y1
), int WXUNUSED(view_y2
))
696 int absx
= 0, absy
= 0, stx
, sty
;
697 wxHtmlCell
*c
= this;
701 absx
+= c
->GetPosX();
702 absy
+= c
->GetPosY();
706 ((wxScrolledWindow
*)(m_Wnd
->GetParent()))->GetViewStart(&stx
, &sty
);
707 m_Wnd
->Move(absx
- wxHTML_SCROLL_STEP
* stx
, absy
- wxHTML_SCROLL_STEP
* sty
);
712 void wxHtmlAppletCell::DrawInvisible(wxDC
& WXUNUSED(dc
), int WXUNUSED(x
), int WXUNUSED(y
))
714 int absx
= 0, absy
= 0, stx
, sty
;
715 wxHtmlCell
*c
= this;
719 absx
+= c
->GetPosX();
720 absy
+= c
->GetPosY();
724 ((wxScrolledWindow
*)(m_Wnd
->GetParent()))->GetViewStart(&stx
, &sty
);
725 m_Wnd
->Move(absx
- wxHTML_SCROLL_STEP
* stx
, absy
- wxHTML_SCROLL_STEP
* sty
);
730 void wxHtmlAppletCell::Layout(int w
)
733 m_Wnd
->GetSize(&sx
, &sy
);
734 m_Width
= sx
, m_Height
= sy
;
736 wxHtmlCell::Layout(w
);
742 // This is our little forcelink hack.