]>
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 * ========================================================================
10 * The contents of this file are subject to the wxWindows License
11 * Version 3.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.wxwindows.org/licence3.txt
15 * Software distributed under the License is distributed on an
16 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17 * implied. See the License for the specific language governing
18 * rights and limitations under the License.
20 * ========================================================================
25 * Description: Main wxHtmlAppletWindow class implementation
27 ****************************************************************************/
29 // For compilers that support precompilation
30 #include "wx/wxprec.h"
32 #include "wx/process.h"
33 #include "wx/spawnbrowser.h"
34 #include "wx/html/forcelnk.h"
38 #include <process.h> // spawnl()
41 // Include private headers
42 #include "wx/applet/applet.h"
43 #include "wx/applet/window.h"
44 #include "wx/applet/loadpage.h"
45 #include "wx/applet/plugin.h"
48 #include "wx/applet/prepinclude.h"
49 #include "wx/applet/prepecho.h"
50 #include "wx/applet/prepifelse.h"
52 /*---------------------------- Global variables ---------------------------*/
54 wxHashTable
wxHtmlAppletWindow::m_Cookies
;
56 /*------------------------- Implementation --------------------------------*/
58 // Empty event handler. We include this event handler simply so that
59 // sub-classes of wxApplet can reference wxApplet in the event tables
60 // that they create as necessary.
61 BEGIN_EVENT_TABLE(wxHtmlAppletWindow
, wxHtmlWindow
)
62 EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage
)
63 EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded
)
66 // Implement the class functions for wxHtmlAppletWindow
67 IMPLEMENT_CLASS(wxHtmlAppletWindow
, wxHtmlWindow
);
69 // Define the wxAppletList implementation
70 #include "wx/listimpl.cpp"
71 WX_DEFINE_LIST(wxAppletList
);
73 /****************************************************************************
75 Constructor for the applet window class.
76 ****************************************************************************/
77 wxHtmlAppletWindow::wxHtmlAppletWindow(
80 wxToolBarBase
*navBar
,
87 const wxPalette
& globalPalette
)
88 : wxHtmlWindow(parent
,id
,pos
,size
,style
,name
), m_globalPalette(globalPalette
)
93 // setup client navbars
95 m_NavBarEnabled
= true;
97 m_NavBackId
= navBackId
;
98 m_NavForwardId
= navForwardId
;
101 m_NavBarEnabled
= false;
105 m_NavBackId
= navBackId
;
106 m_NavForwardId
= navForwardId
;
109 // Set the key_type for applets
110 m_AppletList
= wxAppletList(wxKEY_STRING
);
112 // Add HTML preprocessors
113 // deleting preprocessors is done by the code within the window
115 incPreprocessor
= new wxIncludePrep(); // #include preprocessor
116 incPreprocessor
->ChangeDirectory(m_FS
); // give it access to our filesys object
118 wxEchoPrep
* echoPreprocessor
= new wxEchoPrep(); // #echo preprocessor
119 wxIfElsePrep
* ifPreprocessor
= new wxIfElsePrep();
121 this->AddProcessor(incPreprocessor
);
122 this->AddProcessor(echoPreprocessor
);
123 this->AddProcessor(ifPreprocessor
);
126 /****************************************************************************
128 Destructor for the applet window class.
129 ****************************************************************************/
130 wxHtmlAppletWindow::~wxHtmlAppletWindow()
136 /****************************************************************************
138 dc - wxDC object to draw on
141 This function handles drawing the HTML applet window. Because the standard
142 wxWindows classes don't properly handle palette management, we add code
143 in here to properly select the global palette that we use for all drawing
144 into the DC before we allow the regular wxWindows code to finish the
146 ****************************************************************************/
147 void wxHtmlAppletWindow::OnDraw(
150 // TODO: Only do this for <= 8bpp modes!
151 dc
.SetPalette(m_globalPalette
);
152 wxHtmlWindow::OnDraw(dc
);
155 /****************************************************************************
157 className - Name of the applet class to create an object for
158 size - Initial size of the applet to be created
161 Pointer to the wxApplet created, or NULL if unable to create the applet.
164 This function is used to create new wxApplet objects dynamically based on the
165 class name as a string. This allows instances of wxApplet classes to be
166 created dynamically based on string values embedded in the custom tags of an
168 ****************************************************************************/
169 wxApplet
*wxHtmlAppletWindow::CreateApplet(
170 const wxString
& classId
,
171 const wxString
& iName
,
172 const wxHtmlTag
& params
,
175 // Dynamically create the class instance at runtime
176 wxClassInfo
*info
= wxClassInfo::FindClass(classId
.c_str());
179 wxObject
*obj
= info
->CreateObject();
182 wxApplet
*applet
= wxDynamicCast(obj
,wxApplet
);
185 if (!applet
->Create(this,params
,size
)) {
190 // do some fixups on the size if its screwed up
191 wxSize nsize
= applet
->GetBestSize();
192 if (nsize
.x
< size
.x
) nsize
.x
= size
.x
;
193 if (nsize
.y
< size
.y
) nsize
.y
= size
.y
;
194 applet
->SetSize(nsize
);
197 m_AppletList
.Append(iName
,(wxObject
*)applet
);
201 /****************************************************************************
203 classId - Name of the Plugin class to create an object for
206 Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
209 This function is used to create new wxPlugIn objects dynamically based on the
210 class name as a string. This allows instances of wxPlugIn classes to be
211 created dynamically based on string values embedded in the custom tags of an
213 ****************************************************************************/
214 bool wxHtmlAppletWindow::CreatePlugIn(
215 const wxString
& classId
)
217 // Dynamically create the class instance at runtime
218 wxClassInfo
*info
= wxClassInfo::FindClass(classId
.c_str());
221 wxObject
*obj
= info
->CreateObject();
224 wxPlugIn
*plugIn
= wxDynamicCast(obj
,wxPlugIn
);
227 if (!plugIn
->Create(this)) {
234 /****************************************************************************
236 appletName - Name of the applet class to find
239 Pointer to the wxApplet found, or NULL if not found.
242 Find an instance of an applet based on it's name
243 ****************************************************************************/
244 wxApplet
*wxHtmlAppletWindow::FindApplet(
245 const wxString
& appletName
)
247 wxAppletList::Node
*node
= m_AppletList
.Find(appletName
);
250 return node
->GetData();
253 /****************************************************************************
255 applet - Pointer to the applet object to remove from the list
258 True if the applet was found and removed, false if not. The applet itself
262 Remove an applet from the manager. Called during applet destruction
263 ****************************************************************************/
264 bool wxHtmlAppletWindow::RemoveApplet(
265 const wxApplet
*applet
)
267 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext()) {
268 if (node
->GetData() == applet
) {
269 m_AppletList
.DeleteNode(node
);
276 /****************************************************************************
278 URL - New URL for the page to load
281 True if page loaded successfully, false if not
284 Remove an applet from the manager. Called during applet destruction
285 ****************************************************************************/
286 bool wxHtmlAppletWindow::LoadPage(
287 const wxString
& link
)
291 if (link
.GetChar(0) == '?'){
292 wxString cmd
= link
.BeforeFirst('=');
293 wxString cmdValue
= link
.AfterFirst('=');
295 // Launches the default Internet browser for the system.
296 if(!(cmd
.CmpNoCase("?EXTERNAL"))){
297 return wxSpawnBrowser(this, cmdValue
.c_str());
300 // Launches an external program on the system.
301 if (!(cmd
.CmpNoCase("?EXECUTE"))){
302 int code
= spawnl( P_NOWAIT
, cmdValue
, NULL
);
306 // Looks for a href in a variable stored as a cookie. The href can be
307 // changed on the fly.
308 if (!(cmd
.CmpNoCase("?VIRTUAL"))){
309 VirtualData
& temp
= *((VirtualData
*)FindCookie(cmdValue
));
311 href
= temp
.GetHref();
315 wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue
.c_str());
321 // This launches a qlet - It is like an applet but is more generic in that it
322 // can be of any wxWin type so it then has the freedom to do more stuff.
323 if (!(cmd
.CmpNoCase("?WXAPPLET"))){
324 if (!cmdValue
.IsNull()){
325 if (!CreatePlugIn(cmdValue
)){
327 wxLogError(_T("Launch Applet ERROR: '%s' does not exist."), cmdValue
.c_str());
335 // Inform all the applets that the new page is being loaded
336 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
337 (node
->GetData())->OnLinkClicked(wxHtmlLinkInfo(href
));
340 bool stat
= wxHtmlWindow::LoadPage(href
);
343 // Enable/Dis the navbar tools
344 if (m_NavBarEnabled
) {
345 m_NavBar
->EnableTool(m_NavForwardId
,HistoryCanForward());
346 m_NavBar
->EnableTool(m_NavBackId
,HistoryCanBack());
351 /****************************************************************************
353 URL - String URL that we are navigating to
356 Called when the user navigates to a new URL from the current page. We simply
357 call the LoadPage function above to load the new page and display it.
358 ****************************************************************************/
359 void wxHtmlAppletWindow::OnLinkClicked(
360 const wxHtmlLinkInfo
& link
)
362 LoadPage(link
.GetHref());
365 /****************************************************************************
367 Called when the user navigates forward within the HTML history stack.
368 We call all the applets in turn allowing them to handle the navigation
369 command prior to being destructed when the current page is destroyed.
370 ****************************************************************************/
371 bool wxHtmlAppletWindow::HistoryForward()
373 if (!HistoryCanForward())
376 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
377 (node
->GetData())->OnHistoryForward();
379 return wxHtmlWindow::HistoryForward();
382 /****************************************************************************
384 Called when the user navigates backwards within the HTML history stack.
385 We call all the applets in turn allowing them to handle the navigation
386 command prior to being destructed when the current page is destroyed.
387 ****************************************************************************/
388 bool wxHtmlAppletWindow::HistoryBack()
390 if (!HistoryCanBack())
393 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext())
394 (node
->GetData())->OnHistoryBack();
396 return wxHtmlWindow::HistoryBack();
399 /****************************************************************************
401 This function is used to disable the navigation bars. If you want to
402 toggle to the navbars off you must call this function.
403 ****************************************************************************/
404 void wxHtmlAppletWindow::DisableNavBar()
406 m_NavBarEnabled
= false;
409 /****************************************************************************
411 This function is used to enable the nav bars. If you toggle the nav bars on
412 you must call this function.
413 ****************************************************************************/
414 void wxHtmlAppletWindow::EnableNavBar()
416 m_NavBarEnabled
= true;
419 /****************************************************************************
421 This function is used to set the nav bar to a new nav bar if you deleted the
422 one that you were useing. Usally this happens when you toggle a nav bar
424 ****************************************************************************/
425 void wxHtmlAppletWindow::SetNavBar(wxToolBarBase
*navBar
)
430 /****************************************************************************
432 msg - wxEvent message to be sent to all wxApplets
435 This function is called by the wxApplet's when they need to send a message
436 to all other applets on the current page. This is the primary form of
437 communication between applets on the page if they need to inform each
438 other of internal information.
440 Note that the event handling terminates as soon as the first wxApplet
441 handles the event. If the event should be handled by all wxApplet's,
442 the event handlers for the applets should not reset the wxEvent::Skip()
443 value (ie: by default it is true).
444 ****************************************************************************/
445 void wxHtmlAppletWindow::SendMessage(
448 // Preset the skip flag
451 // Process all applets in turn and send them the message
452 for (wxAppletList::Node
*node
= m_AppletList
.GetFirst(); node
; node
= node
->GetNext()) {
453 (node
->GetData())->OnMessage(msg
);
454 if (!msg
.GetSkipped()){
455 wxMessageBox("BREAK");
461 /****************************************************************************
463 name - Uniq wxString used as hash key
464 cookie - wxObject data returned when name is found.
467 True if new cookie was added, false if cookie with same name already exists.
470 This function is called by the wxApplet's when they need register a cookie
471 of data in the applet window's cookie table. Cookies are arbitrary data
472 objects that are references by unique name's by the wxApplet. These
473 values can be used to store and retrieve data that needs to remain
474 persisent across invocations of the wxApplet. Ie: The first time an
475 applet is created it would use the cookie to store data to maintain
476 it's present state so that if you navigated back to the same page
477 is would be able to re-load the prior state as though the applet
478 was never actually destructed.
480 Note: If a cookie with the same name already exists, this function returns
481 false. Hence if you wish to replace a cookie you should first call
482 UnRegisterCookie to ensure the cookie is deleted and then call this
484 ****************************************************************************/
485 bool wxHtmlAppletWindow::RegisterCookie(
486 const wxString
& name
,
489 // Fail if the named cookie already exists!
490 if (m_Cookies
.Get(name
))
492 m_Cookies
.Put(name
,cookie
);
496 /****************************************************************************
498 name - wxString uniq haskey used to remove item from hash
501 True if found and deleted, false if not found in table.
504 This function is called by the wxApplet's when they need de-register a
505 cookie of data in the applet window's cookie table. The data in the
506 cookie itself is also deleted before it is removed from the table.
507 ****************************************************************************/
508 bool wxHtmlAppletWindow::UnRegisterCookie(
509 const wxString
& name
)
511 wxObject
*data
= m_Cookies
.Delete(name
);
519 /****************************************************************************
521 msg - wxEvent message to be sent to all wxApplets
524 Pointer to the cookie data if found, NULL if not found.
527 This function is called by the wxApplet's when they need to find a cookie
528 of data given it's public name. If the cookie is not found, NULL is
530 ****************************************************************************/
531 wxObject
*wxHtmlAppletWindow::FindCookie(
532 const wxString
& name
)
534 return m_Cookies
.Get(name
);
537 /****************************************************************************
539 event - Event to handle
542 This function handles delayed LoadPage events posted from applets that
543 need to change the page for the current window to a new window.
544 ****************************************************************************/
545 void wxHtmlAppletWindow::OnLoadPage(
546 wxLoadPageEvent
&event
)
548 // Test the mutex lock.
551 if (event
.GetHtmlWindow() == this){
552 if (LoadPage(event
.GetHRef())){
553 // wxPageLoadedEvent evt;
554 // NOTE: This is reserved for later use as we might need to send
555 // page loaded events to applets.
562 /****************************************************************************
564 event - Event to handle
567 This function handles delayed LoadPage events posted from applets that
568 need to change the page for the current window to a new window.
569 ****************************************************************************/
570 void wxHtmlAppletWindow::OnPageLoaded(
576 /****************************************************************************
581 This function tries to lock the mutex. If it can't, returns
582 immediately with false.
583 ***************************************************************************/
584 bool wxHtmlAppletWindow::TryLock()
593 /****************************************************************************
595 name - name of the last applet that changed the data in this object
596 group - name of the group the allplet belongs to.
597 href - webpage to go to.
600 VirtualData is used to store information on the virtual links.
601 ****************************************************************************/
602 VirtualData::VirtualData(
612 /****************************************************************************
615 VirtualData is used to store information on the virtual links.
616 ****************************************************************************/
617 VirtualData::VirtualData()
624 /****************************************************************************
627 ****************************************************************************/
628 void AppletProcess::OnTerminate(
632 // we're not needed any more
636 #include "wx/html/m_templ.h"
638 /****************************************************************************
640 Implementation for the <embed> HTML tag handler. This handler takes care
641 of automatically constructing the wxApplet objects of the appropriate
642 class based on the <embed> tag information.
643 ****************************************************************************/
644 TAG_HANDLER_BEGIN(wxApplet
, "WXAPPLET")
646 TAG_HANDLER_PROC(tag
)
649 wxHtmlAppletWindow
*appletWindow
;
655 wnd
= m_WParser
->GetWindow();
657 if ((appletWindow
= wxDynamicCast(wnd
,wxHtmlAppletWindow
)) != NULL
){
658 wxSize size
= wxDefaultSize
;
660 if (tag
.HasParam("WIDTH")) {
661 tag
.GetParamAsInt("WIDTH", &width
);
662 size
.SetWidth(width
);
665 if (tag
.HasParam("HEIGHT")) {
666 tag
.GetParamAsInt("HEIGHT", &height
);
667 size
.SetHeight(height
);
670 al
= wxHTML_ALIGN_BOTTOM
;
671 if (tag
.HasParam(wxT("ALIGN"))) {
672 wxString alstr
= tag
.GetParam(wxT("ALIGN"));
673 alstr
.MakeUpper(); // for the case alignment was in ".."
674 if (alstr
== wxT("TEXTTOP") || alstr
== wxT("TOP"))
675 al
= wxHTML_ALIGN_TOP
;
676 else if ((alstr
== wxT("CENTER")) || (alstr
== wxT("ABSCENTER")))
677 al
= wxHTML_ALIGN_CENTER
;
680 if (tag
.HasParam("CLASSID")){
681 classId
= tag
.GetParam("CLASSID");
682 if ( classId
.IsNull() || classId
.Len() == 0 ){
683 wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR
);
686 if (tag
.HasParam("NAME"))
687 name
= tag
.GetParam("NAME");
689 // If the name is NULL or len is zero then we assume that the html guy
690 // didn't include the name param which is optional.
691 if ( name
.IsNull() || name
.Len() == 0 )
694 // We got all the params and can now create the applet
695 if ((applet
= appletWindow
->CreateApplet(classId
, name
, tag
, size
)) != NULL
){
697 m_WParser
->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet
,al
));
700 wxMessageBox("wxApplet error: Could not create:" + classId
+ "," + name
);
703 wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR
);
706 //Add more param parsing here. If or when spec changes.
707 //For now we'll ignore any other params those HTML guys
708 //might put in our tag.
714 TAG_HANDLER_END(wxApplet
)
716 TAGS_MODULE_BEGIN(wxApplet
)
717 TAGS_MODULE_ADD(wxApplet
)
718 TAGS_MODULE_END(wxApplet
)
720 /*********************************************************************************
722 *********************************************************************************/
723 wxHtmlAppletCell::wxHtmlAppletCell(wxWindow
*wnd
, int align
) : wxHtmlCell()
727 m_Wnd
->GetSize(&sx
, &sy
);
728 m_Width
= sx
, m_Height
= sy
;
731 case wxHTML_ALIGN_TOP
:
732 m_Descent
= m_Height
;
734 case wxHTML_ALIGN_CENTER
:
735 m_Descent
= m_Height
/ 2;
737 case wxHTML_ALIGN_BOTTOM
:
743 SetCanLiveOnPagebreak(FALSE
);
747 void wxHtmlAppletCell::Draw(wxDC
& WXUNUSED(dc
), int WXUNUSED(x
), int WXUNUSED(y
), int WXUNUSED(view_y1
), int WXUNUSED(view_y2
))
749 int absx
= 0, absy
= 0, stx
, sty
;
750 wxHtmlCell
*c
= this;
754 absx
+= c
->GetPosX();
755 absy
+= c
->GetPosY();
759 ((wxScrolledWindow
*)(m_Wnd
->GetParent()))->GetViewStart(&stx
, &sty
);
760 m_Wnd
->Move(absx
- wxHTML_SCROLL_STEP
* stx
, absy
- wxHTML_SCROLL_STEP
* sty
);
765 void wxHtmlAppletCell::DrawInvisible(wxDC
& WXUNUSED(dc
), int WXUNUSED(x
), int WXUNUSED(y
))
767 int absx
= 0, absy
= 0, stx
, sty
;
768 wxHtmlCell
*c
= this;
772 absx
+= c
->GetPosX();
773 absy
+= c
->GetPosY();
777 ((wxScrolledWindow
*)(m_Wnd
->GetParent()))->GetViewStart(&stx
, &sty
);
778 m_Wnd
->Move(absx
- wxHTML_SCROLL_STEP
* stx
, absy
- wxHTML_SCROLL_STEP
* sty
);
783 void wxHtmlAppletCell::Layout(int w
)
786 m_Wnd
->GetSize(&sx
, &sy
);
787 m_Width
= sx
, m_Height
= sy
;
789 wxHtmlCell::Layout(w
);
795 // This is our little forcelink hack.