]> git.saurik.com Git - wxWidgets.git/blobdiff - contrib/src/applet/appletwindow.cpp
set the background brush to the window's background colour
[wxWidgets.git] / contrib / src / applet / appletwindow.cpp
index 82c5f851badcc9b2bb7f158840a3acaba7617985..cd9cc4e7dc0ab89b188d197f1ac5b2bee6101d00 100644 (file)
 
 // For compilers that support precompilation
 #include "wx/wxprec.h"
+#include "wx/utils.h"
+#include "wx/process.h"
+#include "wx/spawnbrowser.h"
 #include "wx/html/forcelnk.h"
 
+// crt
+#ifdef __WXMSW__
+#include <process.h>        // spawnl()
+#endif
+
 // Include private headers
 #include "wx/applet/applet.h"
 #include "wx/applet/window.h"
 #include "wx/applet/loadpage.h"
+#include "wx/applet/plugin.h"
 
 // Preprocessor Stuff
 #include "wx/applet/prepinclude.h"
 #include "wx/applet/prepecho.h"
 #include "wx/applet/prepifelse.h"
 
-
 /*---------------------------- Global variables ---------------------------*/
 
 wxHashTable wxHtmlAppletWindow::m_Cookies;             
@@ -75,26 +83,38 @@ wxHtmlAppletWindow::wxHtmlAppletWindow(
     const wxPoint& pos,
     const wxSize& size,
     long style,
-    const wxString& name)
-    : wxHtmlWindow(parent,id,pos,size,style,name)
+    const wxString& name,
+    const wxPalette& globalPalette)
+    : wxHtmlWindow(parent,id,pos,size,style,name), m_globalPalette(globalPalette)
 {
     // Init our locks
     UnLock();
 
     // setup client navbars
     if (navBar) {
+        m_NavBarEnabled = true;
         m_NavBar = navBar;
         m_NavBackId = navBackId;
         m_NavForwardId = navForwardId;
         }
     else {
+        m_NavBarEnabled = false;
         m_NavBar = NULL;
         }
 
+    m_NavBackId = navBackId;
+    m_NavForwardId = navForwardId;
+
+
+    // Set the key_type for applets
+    m_AppletList = wxAppletList(wxKEY_STRING);
+
     // Add HTML preprocessors
     // deleting preprocessors is done by the code within the window
 
     incPreprocessor = new wxIncludePrep(); // #include preprocessor
+    incPreprocessor->ChangeDirectory(m_FS); // give it access to our filesys object
+
     wxEchoPrep * echoPreprocessor = new wxEchoPrep(); // #echo preprocessor
     wxIfElsePrep * ifPreprocessor = new wxIfElsePrep();
 
@@ -111,6 +131,27 @@ wxHtmlAppletWindow::~wxHtmlAppletWindow()
 {
 }
 
+#include "scitech.h"
+
+/****************************************************************************
+PARAMETERS:
+dc  - wxDC object to draw on
+
+REMARKS:
+This function handles drawing the HTML applet window. Because the standard
+wxWindows classes don't properly handle palette management, we add code
+in here to properly select the global palette that we use for all drawing
+into the DC before we allow the regular wxWindows code to finish the
+drawing process.
+****************************************************************************/
+void wxHtmlAppletWindow::OnDraw(
+    wxDC& dc)
+{
+    // TODO: Only do this for <= 8bpp modes!
+    dc.SetPalette(m_globalPalette);
+    wxHtmlWindow::OnDraw(dc);
+}
+
 /****************************************************************************
 PARAMETERS:
 className       - Name of the applet class to create an object for
@@ -145,10 +186,51 @@ wxApplet *wxHtmlAppletWindow::CreateApplet(
         delete applet;
         return NULL;
         }
-    m_AppletList.Append(iName,applet);
+    else {
+        // do some fixups on the size if its screwed up
+        wxSize nsize = applet->GetBestSize();
+        if (nsize.x < size.x) nsize.x = size.x;
+        if (nsize.y < size.y) nsize.y = size.y;
+        applet->SetSize(nsize);
+        }
+
+    m_AppletList.Append(iName,(wxObject*)applet);
     return applet;
 }
 
+/****************************************************************************
+PARAMETERS:
+classId       - Name of the Plugin class to create an object for
+
+RETURNS:
+Pointer to the wxplugIn created, or NULL if unable to create the PlugIn.
+
+REMARKS:
+This function is used to create new wxPlugIn objects dynamically based on the
+class name as a string. This allows instances of wxPlugIn classes to be
+created dynamically based on string values embedded in the custom tags of an
+HTML page.
+****************************************************************************/
+bool wxHtmlAppletWindow::CreatePlugIn(
+    const wxString& classId )
+{
+    // Dynamically create the class instance at runtime
+    wxClassInfo *info = wxClassInfo::FindClass(classId.c_str());
+    if (!info)
+        return false;
+    wxObject *obj = info->CreateObject();
+    if (!obj)
+        return false;
+    wxPlugIn *plugIn = wxDynamicCast(obj,wxPlugIn);
+    if (!plugIn)
+        return false;
+    if (!plugIn->Create(this)) {
+        delete plugIn;
+        return false;
+        }
+    return true;
+}
+
 /****************************************************************************
 PARAMETERS:
 appletName      - Name of the applet class to find
@@ -204,25 +286,25 @@ Remove an applet from the manager. Called during applet destruction
 bool wxHtmlAppletWindow::LoadPage(
     const wxString& link)
 {
-    wxString    href(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('=');
 
+        // Launches the default Internet browser for the system.
         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;
+            return wxSpawnBrowser(this, cmdValue.c_str());
             }
+
+        // Launches an external program on the system.
         if (!(cmd.CmpNoCase("?EXECUTE"))){
-            wxMessageBox(cmdValue);
-            return true;
+            int code = spawnl( P_NOWAIT, cmdValue , NULL );
+            return (!code);
             }
+
+        // Looks for a href in a variable stored as a cookie. The href can be
+        // changed on the fly.
         if (!(cmd.CmpNoCase("?VIRTUAL"))){
             VirtualData& temp = *((VirtualData*)FindCookie(cmdValue));
             if (&temp) {
@@ -230,30 +312,36 @@ bool wxHtmlAppletWindow::LoadPage(
                 }
             else {
 #ifdef CHECKED
-                wxMessageBox("VIRTUAL LINK ERROR: " + cmdValue + " does not exist.");
+                wxLogError(_T("VIRTUAL LINK ERROR: '%s' does not exist."), cmdValue.c_str());
 #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());
+        // This launches a qlet - It is like an applet but is more generic in that it
+        // can be of any wxWin type so it then has the freedom to do more stuff.
+        if (!(cmd.CmpNoCase("?WXAPPLET"))){
+            if (!cmdValue.IsNull()){
+                if (!CreatePlugIn(cmdValue)){
+#ifdef CHECKED
+                    wxLogError(_T("Launch Applet ERROR: '%s' does not exist."), cmdValue.c_str());
+#endif
+                    }
+                }
+             return true;
+            }
+        }
 
     // 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(wxHtmlLinkInfo(href));
-    bool stat = wxHtmlWindow::LoadPage(href);
-
+    Show(false);
 
+    bool stat = wxHtmlWindow::LoadPage(href);
+    Show(true);
 
     // Enable/Dis the navbar tools
-    if (m_NavBar) {
+    if (m_NavBarEnabled) {
         m_NavBar->EnableTool(m_NavForwardId,HistoryCanForward());
         m_NavBar->EnableTool(m_NavBackId,HistoryCanBack());
         }
@@ -308,6 +396,37 @@ bool wxHtmlAppletWindow::HistoryBack()
     return wxHtmlWindow::HistoryBack();
 }
 
+/****************************************************************************
+REMARKS:
+This function is used to disable the navigation bars. If you want to
+toggle to the navbars off you must call this function.
+****************************************************************************/
+void wxHtmlAppletWindow::DisableNavBar()
+{
+    m_NavBarEnabled = false;
+}
+
+/****************************************************************************
+REMARKS:
+This function is used to enable the nav bars. If you toggle the nav bars on
+you must call this function.
+****************************************************************************/
+void wxHtmlAppletWindow::EnableNavBar()
+{
+    m_NavBarEnabled = true;
+}
+
+/****************************************************************************
+REMARKS:
+This function is used to set the nav bar to a new nav bar if you deleted the
+one that you were useing. Usally this happens when you toggle a nav bar
+on or off.
+****************************************************************************/
+void wxHtmlAppletWindow::SetNavBar(wxToolBarBase *navBar)
+{
+    m_NavBar = navBar;
+}
+
 /****************************************************************************
 PARAMETERS:
 msg - wxEvent message to be sent to all wxApplets
@@ -426,12 +545,9 @@ 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()) {
+    // Test the mutex lock.
+    if (!(IsLocked())){
+        Lock();
         if (event.GetHtmlWindow() == this){
             if (LoadPage(event.GetHRef())){
                 // wxPageLoadedEvent evt;
@@ -493,6 +609,30 @@ VirtualData::VirtualData(
     m_href = href;
 }
 
+/****************************************************************************
+PARAMETERS:
+REMARKS:
+VirtualData is used to store information on the virtual links.
+****************************************************************************/
+VirtualData::VirtualData()
+{
+    m_name.Empty();
+    m_group.Empty();
+    m_href.Empty();
+}
+
+/****************************************************************************
+PARAMETERS:
+REMARKS:
+****************************************************************************/
+void AppletProcess::OnTerminate(
+    int,
+    int )
+{
+    // we're not needed any more
+    delete this;
+}
+
 #include "wx/html/m_templ.h"
 
 /****************************************************************************
@@ -515,8 +655,28 @@ TAG_HANDLER_PROC(tag)
        wnd = m_WParser->GetWindow();
 
        if ((appletWindow = wxDynamicCast(wnd,wxHtmlAppletWindow)) != NULL){
-               tag.ScanParam("WIDTH", "%i", &width);
-               tag.ScanParam("HEIGHT", "%i", &height); 
+        wxSize size = wxDefaultSize;
+               int al;
+        if (tag.HasParam("WIDTH")) {
+            tag.GetParamAsInt("WIDTH", &width);
+            size.SetWidth(width);
+            }
+               
+        if (tag.HasParam("HEIGHT")) {
+            tag.GetParamAsInt("HEIGHT", &height);
+            size.SetHeight(height);
+            }
+
+        al = wxHTML_ALIGN_BOTTOM;
+        if (tag.HasParam(wxT("ALIGN"))) {
+            wxString alstr = tag.GetParam(wxT("ALIGN"));
+            alstr.MakeUpper();  // for the case alignment was in ".."
+            if (alstr == wxT("TEXTTOP") || alstr == wxT("TOP"))
+                al = wxHTML_ALIGN_TOP;
+            else if ((alstr == wxT("CENTER")) || (alstr == wxT("ABSCENTER")))
+                al = wxHTML_ALIGN_CENTER;
+            }
+
         if (tag.HasParam("CLASSID")){
             classId = tag.GetParam("CLASSID");
             if ( classId.IsNull() || classId.Len() == 0 ){
@@ -532,9 +692,9 @@ TAG_HANDLER_PROC(tag)
                 name = classId;
 
             // We got all the params and can now create the applet
-                       if ((applet = appletWindow->CreateApplet(classId, name, tag , wxSize(width, height))) != NULL){
+                       if ((applet = appletWindow->CreateApplet(classId, name, tag , size)) != NULL){
                                applet->Show(true);
-                               m_WParser->OpenContainer()->InsertCell(new wxHtmlWidgetCell(applet,0));
+                               m_WParser->OpenContainer()->InsertCell(new wxHtmlAppletCell(applet,al));
                                }
             else
                 wxMessageBox("wxApplet error: Could not create:" + classId + "," + name);
@@ -557,6 +717,81 @@ TAGS_MODULE_BEGIN(wxApplet)
     TAGS_MODULE_ADD(wxApplet)
 TAGS_MODULE_END(wxApplet)
 
+/*********************************************************************************
+wxHtmlAppletCell
+*********************************************************************************/
+wxHtmlAppletCell::wxHtmlAppletCell(wxWindow *wnd, int align) : wxHtmlCell()
+{
+    int sx, sy;
+    m_Wnd = wnd;
+    m_Wnd->GetSize(&sx, &sy);
+    m_Width = sx, m_Height = sy;
+
+    switch (align) {
+        case wxHTML_ALIGN_TOP :
+            m_Descent = m_Height;
+            break;
+        case wxHTML_ALIGN_CENTER :
+            m_Descent = m_Height / 2;
+            break;
+        case wxHTML_ALIGN_BOTTOM :
+        default :
+            m_Descent = 0;
+            break;
+        }
+
+    SetCanLiveOnPagebreak(FALSE);
+}
+
+
+void wxHtmlAppletCell::Draw(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y), int WXUNUSED(view_y1), int WXUNUSED(view_y2))
+{
+    int absx = 0, absy = 0, stx, sty;
+    wxHtmlCell *c = this;
+
+    while (c)
+    {
+        absx += c->GetPosX();
+        absy += c->GetPosY();
+        c = c->GetParent();
+    }
+
+    ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
+    m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy  - wxHTML_SCROLL_STEP * sty);
+}
+
+
+
+void wxHtmlAppletCell::DrawInvisible(wxDC& WXUNUSED(dc), int WXUNUSED(x), int WXUNUSED(y))
+{
+    int absx = 0, absy = 0, stx, sty;
+    wxHtmlCell *c = this;
+
+    while (c)
+    {
+        absx += c->GetPosX();
+        absy += c->GetPosY();
+        c = c->GetParent();
+    }
+
+    ((wxScrolledWindow*)(m_Wnd->GetParent()))->GetViewStart(&stx, &sty);
+    m_Wnd->Move(absx - wxHTML_SCROLL_STEP * stx, absy  - wxHTML_SCROLL_STEP * sty);
+}
+
+
+
+void wxHtmlAppletCell::Layout(int w)
+{
+    int sx, sy;
+    m_Wnd->GetSize(&sx, &sy);
+    m_Width = sx, m_Height = sy;
+
+    wxHtmlCell::Layout(w);
+}
+
+
+
+
 // This is our little forcelink hack.
 FORCE_LINK(loadpage)