* Copyright (C) 1991-2001 SciTech Software, Inc.
* All rights reserved.
*
-* ======================================================================
-* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
-* | |
-* |This copyrighted computer code is a proprietary trade secret of |
-* |SciTech Software, Inc., located at 505 Wall Street, Chico, CA 95928 |
-* |USA (www.scitechsoft.com). ANY UNAUTHORIZED POSSESSION, USE, |
-* |VIEWING, COPYING, MODIFICATION OR DISSEMINATION OF THIS CODE IS |
-* |STRICTLY PROHIBITED BY LAW. Unless you have current, express |
-* |written authorization from SciTech to possess or use this code, you |
-* |may be subject to civil and/or criminal penalties. |
-* | |
-* |If you received this code in error or you would like to report |
-* |improper use, please immediately contact SciTech Software, Inc. at |
-* |530-894-8400. |
-* | |
-* |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW|
-* ======================================================================
+* ========================================================================
+*
+* The contents of this file are subject to the wxWindows License
+* Version 3.0 (the "License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.wxwindows.org/licence3.txt
+*
+* Software distributed under the License is distributed on an
+* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* ========================================================================
*
* Language: ANSI C++
* Environment: Any
// For compilers that support precompilation
#include "wx/wxprec.h"
+#include "wx/html/forcelnk.h"
// Include private headers
#include "wx/applet/applet.h"
+#include "wx/applet/window.h"
+#include "wx/applet/loadpage.h"
+
+// Preprocessor Stuff
+#include "wx/applet/prepinclude.h"
+#include "wx/applet/prepecho.h"
+#include "wx/applet/prepifelse.h"
+
+/*---------------------------- Global variables ---------------------------*/
+
+wxHashTable wxHtmlAppletWindow::m_Cookies;
+
/*------------------------- Implementation --------------------------------*/
// Empty event handler. We include this event handler simply so that
// sub-classes of wxApplet can reference wxApplet in the event tables
// that they create as necessary.
BEGIN_EVENT_TABLE(wxHtmlAppletWindow, wxHtmlWindow)
+ EVT_LOAD_PAGE(wxHtmlAppletWindow::OnLoadPage)
+ EVT_PAGE_LOADED(wxHtmlAppletWindow::OnPageLoaded)
END_EVENT_TABLE()
// Implement the class functions for wxHtmlAppletWindow
wxHtmlAppletWindow::wxHtmlAppletWindow(
wxWindow *parent,
wxWindowID id,
+ wxToolBarBase *navBar,
+ int navBackId,
+ int navForwardId,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
: wxHtmlWindow(parent,id,pos,size,style,name)
{
- // Ensure all cookie data is destroyed when window is killed
- m_Cookies.DeleteContents(true);
+ // Init our locks
+ UnLock();
+
+ // setup client navbars
+ if (navBar) {
+ m_NavBar = navBar;
+ m_NavBackId = navBackId;
+ m_NavForwardId = navForwardId;
+ }
+ else {
+ m_NavBar = NULL;
+ }
+
+ // Add HTML preprocessors
+ // deleting preprocessors is done by the code within the window
+
+ incPreprocessor = new wxIncludePrep(); // #include preprocessor
+ wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
+ wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
+
+ this->AddProcessor(incPreprocessor);
+ this->AddProcessor(echoPreprocessor);
+ this->AddProcessor(ifPreprocessor);
}
/****************************************************************************
HTML page.
****************************************************************************/
wxApplet *wxHtmlAppletWindow::CreateApplet(
- const wxString& className,
+ const wxString& classId,
+ const wxString& iName,
+ const wxHtmlTag& params,
const wxSize& size)
{
- // We presently only allow one applet per page of the same class!
- if (m_AppletList.Find(className))
- return NULL;
-
// Dynamically create the class instance at runtime
- wxClassInfo *info = wxClassInfo::FindClass(className.c_str());
+ wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
if (!info)
return NULL;
wxObject *obj = info->CreateObject();
wxApplet *applet = wxDynamicCast(obj,wxApplet);
if (!applet)
return NULL;
- if (!applet->Create(this,size)) {
+ if (!applet->Create(this,params,size)) {
delete applet;
return NULL;
}
- m_AppletList.Append(className,applet);
+ m_AppletList.Append(iName,applet);
return applet;
}
if (!node)
return NULL;
return node->GetData();
-}
+}
/****************************************************************************
PARAMETERS:
}
}
return false;
-}
+}
/****************************************************************************
PARAMETERS:
Remove an applet from the manager. Called during applet destruction
****************************************************************************/
bool wxHtmlAppletWindow::LoadPage(
- const wxString& hRef)
+ const wxString& link)
{
+ wxString href(link);
+
+ // TODO: This needs to be made platform inde if possible.
+ if (link.GetChar(0) == '?'){
+ wxString cmd = link.BeforeFirst('=');
+ wxString cmdValue = link.AfterFirst('=');
+
+ if(!(cmd.CmpNoCase("?EXTERNAL"))){
+#ifdef __WINDOWS__
+ ShellExecute(this ? (HWND)this->GetHWND() : NULL,NULL,cmdValue.c_str(),NULL,"",SW_SHOWNORMAL);
+#else
+ #error Platform not implemented yet!
+#endif
+ return true;
+ }
+ if (!(cmd.CmpNoCase("?EXECUTE"))){
+ wxMessageBox(cmdValue);
+ return true;
+ }
+ if (!(cmd.CmpNoCase("?VIRTUAL"))){
+ VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
+ if (&temp) {
+ href = temp.GetHref();
+ }
+ else {
+#ifdef CHECKED
+ wxMessageBox("VIRTUAL LINK ERROR: " + cmdValue + " does not exist.");
+#endif
+ return true;
+ }
+ }
+ }
+
+ // Make a copy of the current path the translate for <!-- include files from what will be the new path
+ // we cannot just grab this value from the base class since it is not correct until after LoadPage is
+ // called. And we need the incPreprocessor to know the right path before LoadPage.
+ wxFileSystem fs;
+ fs.ChangePathTo(m_FS->GetPath(), true);
+ fs.ChangePathTo(link);
+ incPreprocessor->ChangeDirectory(fs.GetPath());
+
+ // Inform all the applets that the new page is being loaded
for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
- (node->GetData())->OnLinkClicked(hRef);
- return wxHtmlWindow::LoadPage(hRef);
+ (node->GetData())->OnLinkClicked(wxHtmlLinkInfo(href));
+ bool stat = wxHtmlWindow::LoadPage(href);
+
+
+
+ // Enable/Dis the navbar tools
+ if (m_NavBar) {
+ m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
+ m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
+ }
+ return stat;
}
/****************************************************************************
void wxHtmlAppletWindow::OnLinkClicked(
const wxHtmlLinkInfo& link)
{
- for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
- (node->GetData())->OnLinkClicked(link);
- wxHtmlWindow::LoadPage(link.GetHref());
+ LoadPage(link.GetHref());
}
/****************************************************************************
****************************************************************************/
bool wxHtmlAppletWindow::HistoryForward()
{
- if (!HistoryCanForward())
+ if (!HistoryCanForward())
return false;
+
for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
(node->GetData())->OnHistoryForward();
+
return wxHtmlWindow::HistoryForward();
}
****************************************************************************/
bool wxHtmlAppletWindow::HistoryBack()
{
- if (!HistoryCanBack())
+ if (!HistoryCanBack())
return false;
+
for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext())
(node->GetData())->OnHistoryBack();
+
return wxHtmlWindow::HistoryBack();
}
****************************************************************************/
void wxHtmlAppletWindow::SendMessage(
wxEvent& msg)
-{
+{
// Preset the skip flag
msg.Skip();
-
+
// Process all applets in turn and send them the message
for (wxAppletList::Node *node = m_AppletList.GetFirst(); node; node = node->GetNext()) {
(node->GetData())->OnMessage(msg);
- if (!msg.GetSkipped())
+ if (!msg.GetSkipped()){
+ wxMessageBox("BREAK");
break;
+ }
}
}
/****************************************************************************
PARAMETERS:
-msg - wxEvent message to be sent to all wxApplets
+name - Uniq wxString used as hash key
+cookie - wxObject data returned when name is found.
RETURNS:
True if new cookie was added, false if cookie with same name already exists.
// Fail if the named cookie already exists!
if (m_Cookies.Get(name))
return false;
- m_Cookies.Put(name,cookie);
+ m_Cookies.Put(name,cookie);
return true;
}
/****************************************************************************
PARAMETERS:
-msg - wxEvent message to be sent to all wxApplets
+name - wxString uniq haskey used to remove item from hash
RETURNS:
True if found and deleted, false if not found in table.
return m_Cookies.Get(name);
}
+/****************************************************************************
+PARAMETERS:
+event - Event to handle
+
+REMARKS:
+This function handles delayed LoadPage events posted from applets that
+need to change the page for the current window to a new window.
+****************************************************************************/
+void wxHtmlAppletWindow::OnLoadPage(
+ wxLoadPageEvent &event)
+{
+ // Test the mutex lock. We have to do this here because wxHTML constantly
+ // calls wxYield which processes the message queue. This in turns means
+ // that we may end up processing a new 'loadPage' event while the new
+ // page is still loading! We need to avoid this so we use a simple
+ // lock to avoid loading a page while presently loading another page.
+ if (TryLock()) {
+ if (event.GetHtmlWindow() == this){
+ if (LoadPage(event.GetHRef())){
+ // wxPageLoadedEvent evt;
+ // NOTE: This is reserved for later use as we might need to send
+ // page loaded events to applets.
+ }
+ }
+ UnLock();
+ }
+}
+
+/****************************************************************************
+PARAMETERS:
+event - Event to handle
+
+REMARKS:
+This function handles delayed LoadPage events posted from applets that
+need to change the page for the current window to a new window.
+****************************************************************************/
+void wxHtmlAppletWindow::OnPageLoaded(
+ wxPageLoadedEvent &)
+{
+ Enable(true);
+}
+
+/****************************************************************************
+PARAMETERS:
+none
+
+REMARKS:
+This function tries to lock the mutex. If it can't, returns
+immediately with false.
+***************************************************************************/
+bool wxHtmlAppletWindow::TryLock()
+{
+ if (!m_mutexLock) {
+ m_mutexLock = true;
+ return true;
+ }
+ return false;
+}
+
+/****************************************************************************
+PARAMETERS:
+name - name of the last applet that changed the data in this object
+group - name of the group the allplet belongs to.
+href - webpage to go to.
+
+REMARKS:
+VirtualData is used to store information on the virtual links.
+****************************************************************************/
+VirtualData::VirtualData(
+ wxString& name,
+ wxString& group,
+ wxString& href )
+{
+ m_name = name;
+ m_group = group;
+ m_href = href;
+}
+
#include "wx/html/m_templ.h"
/****************************************************************************
of automatically constructing the wxApplet objects of the appropriate
class based on the <embed> tag information.
****************************************************************************/
-TAG_HANDLER_BEGIN(Embed, "EMBED")
+TAG_HANDLER_BEGIN(wxApplet, "WXAPPLET")
TAG_HANDLER_PROC(tag)
{
- wxWindow *wnd;
- wxHtmlAppletWindow *appletWindow;
- wxApplet *applet;
- int width, height;
- int floatPercent = 0;
-
- wnd = m_WParser->GetWindow();
- if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL) {
- tag.ScanParam("WIDTH", "%i", &width);
- tag.ScanParam("HEIGHT", "%i", &height);
- if (tag.HasParam("FLOAT"))
- tag.ScanParam("FLOAT", "%i", &floatPercent);
- if (tag.HasParam("APPLET")) {
- if ((applet = appletWindow->CreateApplet(tag.GetParam("APPLET"), wxSize(width, height))) != NULL) {
- applet->Show(true);
- m_WParser->OpenContainer()->InsertCell(new wxHtmlWidgetCell(applet,floatPercent));
+ wxWindow *wnd;
+ wxHtmlAppletWindow *appletWindow;
+ wxApplet *applet;
+ wxString classId;
+ wxString name;
+ int width, height;
+
+ wnd = m_WParser->GetWindow();
+
+ if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
+ tag.ScanParam("WIDTH", "%i", &width);
+ tag.ScanParam("HEIGHT", "%i", &height);
+ if (tag.HasParam("CLASSID")){
+ classId = tag.GetParam("CLASSID");
+ if ( classId.IsNull() || classId.Len() == 0 ){
+ wxMessageBox("wxApplet tag error: CLASSID is NULL or empty.","Error",wxICON_ERROR);
+ return false;
}
+ if (tag.HasParam("NAME"))
+ name = tag.GetParam("NAME");
+
+ // If the name is NULL or len is zero then we assume that the html guy
+ // didn't include the name param which is optional.
+ if ( name.IsNull() || name.Len() == 0 )
+ name = classId;
+
+ // We got all the params and can now create the applet
+ if ((applet = appletWindow->CreateApplet(classId, name, tag , wxSize(width, height))) != NULL){
+ applet->Show(true);
+ m_WParser->OpenContainer()->InsertCell(new wxHtmlWidgetCell(applet,0));
+ }
+ else
+ wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
+ }
+ else{
+ wxMessageBox("wxApplet tag error: Can not find CLASSID param.","Error",wxICON_ERROR);
+ return false;
}
- else if (tag.HasParam("TEXT")) {
- // TODO: Somehow get the text returned from this class displayed on the page!
- }
+ //Add more param parsing here. If or when spec changes.
+ //For now we'll ignore any other params those HTML guys
+ //might put in our tag.
}
- return false;
+
+ return false;
}
-TAG_HANDLER_END(Embed)
+TAG_HANDLER_END(wxApplet)
+
+TAGS_MODULE_BEGIN(wxApplet)
+ TAGS_MODULE_ADD(wxApplet)
+TAGS_MODULE_END(wxApplet)
-TAGS_MODULE_BEGIN(Embed)
- TAGS_MODULE_ADD(Embed)
-TAGS_MODULE_END(Embed)
+// This is our little forcelink hack.
+FORCE_LINK(loadpage)