home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / fmrdonly.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.6 KB  |  363 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20.  
  21. #include "fmrdonly.h"
  22. #include "odctrl.h"
  23. #include "intl_csi.h"
  24. //    This file is dedicated to form type read only elements
  25. //        otherwise known as edit fields on windows and
  26. //        their implementation as requried by the XP layout
  27. //        library.
  28.  
  29. //    Construction simply clears all members.
  30. CFormReadOnly::CFormReadOnly()
  31. {
  32.     //    No widget yet.
  33.     m_pWidget = NULL;
  34. }
  35.  
  36. //    Destruction cleans out all members.
  37. CFormReadOnly::~CFormReadOnly()
  38. {
  39. }
  40.  
  41. //    How to set the LO form element.
  42. //    This may change during the lifetime of an instance, so use this
  43. //        to update all referencing values.
  44. void CFormReadOnly::SetElement(LO_FormElementStruct *pFormElement)
  45. {
  46.     //    Call the base.
  47.     CFormElement::SetElement(pFormElement);
  48.  
  49.     //    Let the widget know the element.
  50.     if(m_pWidget)    {
  51.         m_pWidget->SetContext(GetContext() ? GetContext()->GetContext() : NULL, GetElement());
  52.     }
  53. }
  54.  
  55. //    Set the owning context.
  56. //    Use this to determine what context we live in and how we should
  57. //        represent ourself (DC or window).
  58. void CFormReadOnly::SetContext(CAbstractCX *pCX)
  59. {
  60.     //    Call the base.
  61.     CFormElement::SetContext(pCX);
  62.  
  63.     //    Have our widget update if present.
  64.     if(m_pWidget)    {
  65.         m_pWidget->SetContext(GetContext() ? GetContext()->GetContext() : NULL, GetElement());
  66.     }
  67. }
  68.  
  69. //    Display the form element given the particular context we are in.
  70. //    Possibly only use a DC for representation, or have the
  71. //        window move.
  72. void CFormReadOnly::DisplayFormElement(LTRB& Rect)
  73. {
  74.     //    Display only has meaning if our context is a device context.
  75.     if(GetContext() && GetContext()->IsDCContext())    {
  76.         //    Further, need to detect how we're going to be drawing ourselves.
  77.         if(GetContext()->IsPureDCContext())    {
  78.             //    Only works from a DC, needs a GDI drawing representation.
  79.             CDCCX *pDCCX = VOID2CX(GetContext(), CDCCX);
  80.         }
  81.         else if(GetContext()->IsWindowContext())    {
  82.             MoveWindow(m_pWidget->m_hWnd, Rect.left, Rect.top + EDIT_SPACE / 2);
  83.         }
  84.         else    {
  85.             //    Is undefined....
  86.             ASSERT(0);
  87.         }
  88.     }
  89.  
  90.     //    Call the base.
  91.     CFormElement::DisplayFormElement(Rect);
  92. }
  93.  
  94. //    Destroy the widget (window) implemenation of the form.
  95. void CFormReadOnly::DestroyWidget()
  96. {
  97.     //    Get rid of the widget if around.
  98.     if(m_pWidget)    {
  99.         m_pWidget->DestroyWindow();
  100.         delete m_pWidget;
  101.         m_pWidget = NULL;
  102.     }
  103. }
  104.  
  105. //    Create the widget (window) implementation of the form
  106. //        but DO NOT DISPLAY.
  107. void CFormReadOnly::CreateWidget()
  108. {
  109.     if(GetContext() && GetElement())    {
  110.         if(GetContext()->IsWindowContext() && VOID2CX(GetContext(), CPaneCX)->GetPane())    {
  111.             //    Need a widget representation.
  112.             ASSERT(m_pWidget == NULL);
  113.             m_pWidget = new CODNetscapeEdit;
  114.             if(m_pWidget == NULL)    {
  115.                 return;
  116.             }
  117.  
  118.             //    Inform widget of context and element.
  119.             m_pWidget->SetContext(GetContext()->GetContext(), GetElement());
  120.  
  121. #ifdef XP_WIN16
  122.             //    On 16 bits, we need to set the segment of the widget before creation.
  123.             HINSTANCE hSegment = GetSegment();
  124.             if(hSegment)    {
  125.                 m_pWidget->SetInstance(hSegment);
  126.             }
  127.             else    {
  128.                 delete m_pWidget;
  129.                 m_pWidget = NULL;
  130.                 return;
  131.             }
  132. #endif
  133.  
  134.             //    The style of the widget to be created.
  135.             DWORD dwStyle = WS_CHILD | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL | ES_READONLY;
  136.  
  137.             //    Create the widget, hidden, and with a bad size.
  138.             BOOL bCreate =
  139. #ifdef XP_WIN32
  140.                 m_pWidget->CreateEx(WS_EX_CLIENTEDGE, 
  141.                      _T("EDIT"),
  142.                      NULL,
  143.                      dwStyle, 
  144.                      1, 1, 0, 0,
  145.                      VOID2CX(GetContext(), CPaneCX)->GetPane(), 
  146.                      (HMENU)GetDynamicControlID(),
  147.                      NULL);            
  148. #else
  149.                 m_pWidget->Create(dwStyle, CRect(1, 1, 0, 0), 
  150.                     CWnd::FromHandle(VOID2CX(GetContext(), CPaneCX)->GetPane()), 
  151.                     GetDynamicControlID());
  152. #endif
  153.  
  154.             if(!bCreate)    {
  155.                 delete m_pWidget;
  156.                 m_pWidget = NULL;
  157.                 return;
  158.             }
  159.  
  160.             //    Next, need to size the widget.
  161.             //    Obtain a font.
  162.             //    Measure some text.
  163.             CDC *pDC = m_pWidget->GetDC();
  164.             if(pDC)    {
  165.                 //    Textmetrics won't work unless we specifically select the font.
  166.                 CyaFont    *pMyFont;
  167.                 LO_TextAttr *text_attr = GetElement()->text_attr;
  168.                 VOID2CX(GetContext(), CWinCX)->SelectNetscapeFont( pDC->GetSafeHdc(), GetTextAttr(), pMyFont );
  169.                 //    Text metrics won't work unless we select the font.
  170.  
  171.                 if (pMyFont) {
  172.                     SetWidgetFont(pDC->GetSafeHdc(), m_pWidget->m_hWnd);
  173.                     text_attr->FE_Data = pMyFont;
  174.  
  175.                     //    Default length will be for "hi".
  176.                     int32 lLength = 2;
  177.  
  178.                     //    Now figure up the width and height we would like.
  179.                     int32 lWidgetWidth = pMyFont->GetMaxWidth();
  180.                     int32 lWidgetHeight = pMyFont->GetHeight() + pMyFont->GetHeight() / 2;
  181.  
  182.                     //    See if we can get the minimal data.
  183.                     if(GetElementMinimalData() && GetElementMinimalData()->value)    {
  184.                             //    Use length of text, exactly.
  185.                             char *pDefault = (char *)GetElementMinimalData()->value;
  186.  
  187.                             lLength = XP_STRLEN(pDefault);
  188.                             SIZE csz;
  189.                             CIntlWin::GetTextExtentPointWithCyaFont(pMyFont, 
  190.                                 INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(GetContext()->GetContext())),
  191.                                  pDC->GetSafeHdc(), pDefault, CASTINT(lLength), &csz);
  192.  
  193.                             //    Use this width.
  194.                             lWidgetWidth += csz.cx;
  195.                     }
  196.                     else    {
  197.                         //    Use an average width.
  198.                         lWidgetWidth += lLength * pMyFont->GetMeanWidth();
  199.                     }
  200.  
  201.                     VOID2CX(GetContext(), CWinCX)->ReleaseNetscapeFont( pDC->GetSafeHdc(), pMyFont );
  202.                     m_pWidget->MoveWindow(1, 1, CASTINT(lWidgetWidth), CASTINT(lWidgetHeight), FALSE);
  203.                     m_pWidget->ReleaseDC(pDC);
  204.                 }
  205.                 else {
  206.                     m_pWidget->ReleaseDC(pDC);
  207.                     DestroyWidget();
  208.                     return;
  209.                 }
  210.             }
  211.             else    {
  212.                 //    No DC, no widget.
  213.                 DestroyWidget();
  214.                 return;
  215.             }
  216.         }
  217.         else if(GetContext()->IsPureDCContext())    {
  218.             //    Need a drawn representation.
  219.         }
  220.     }
  221. }
  222.  
  223. //    Copy the current data out of the layout struct into the form
  224. //        widget, or mark that you should represent using the current data.
  225. void CFormReadOnly::UseCurrentData()
  226. {
  227.     //    Detect context type and do the right thing.
  228.     if(GetContext())    {
  229.         if(GetContext()->IsWindowContext())    {
  230.             //    Need a widget.
  231.             if(m_pWidget)    {
  232.                 //    Just set it to the value if present.
  233.                 //    No real concept of current or default data in a read only yet.
  234.                 char *pData = NULL;
  235.                 if(GetElementMinimalData())    {
  236.                     pData = (char *)GetElementMinimalData()->value;
  237.                 }
  238.                 if(pData)    {
  239.                     // We have to SetContext to the widget before we SetWindowText
  240.                     // Otherwise, the widget don't know what csid the text is.
  241.                     m_pWidget->SetContext(GetContext()->GetContext(), GetElement());
  242.  
  243.                     m_pWidget->SetWindowText(pData);
  244.                 }
  245.             }
  246.         }
  247.         else if(GetContext()->IsPureDCContext())    {
  248.             //    Printing/metafile
  249.         }
  250.     }
  251. }
  252.  
  253. //    Copy the default data out of the layout struct into the form
  254. //        widget, or mark that you should represent using the default data.
  255. void CFormReadOnly::UseDefaultData()
  256. {
  257.     //    Detect context type and do the right thing.
  258.     if(GetContext())    {
  259.         if(GetContext()->IsWindowContext())    {
  260.             //    Need a widget.
  261.             if(m_pWidget)    {
  262.                 //    Just set it to the value if present.
  263.                 //    No real concept of current or default data in a read only yet.
  264.                 char *pData = NULL;
  265.                 if(GetElementMinimalData())    {
  266.                     pData = (char *)GetElementMinimalData()->value;
  267.                 }
  268.                 if(pData)    {
  269.                     // We have to SetContext to the widget before we SetWindowText
  270.                     // Otherwise, the widget don't know what csid the text is.
  271.                     m_pWidget->SetContext(GetContext()->GetContext(), GetElement());
  272.  
  273.                     m_pWidget->SetWindowText(pData);
  274.                 }
  275.             }
  276.         }
  277.         else if(GetContext()->IsPureDCContext())    {
  278.             //    Printing/metafile
  279.         }
  280.     }
  281. }
  282.  
  283. //    Fill in the layout size information in the layout struct regarding
  284. //        the dimensions of the widget.
  285. void CFormReadOnly::FillSizeInfo()
  286. {
  287.     //    Detect context type and do the right thing.
  288.     if(GetContext() && GetElement())    {
  289.         if(GetContext()->IsWindowContext())    {
  290.             //    Need a widget.
  291.             if(m_pWidget)    {
  292.                 //    Determine our window position.
  293.                 CRect crRect;
  294.                 m_pWidget->GetWindowRect(crRect);
  295.  
  296.                 //    Munge the coordinate a little for layout.
  297.                 //    We'll have to know how to decode this information
  298.                 //        in the display routine (by half).
  299.                 GetElement()->width = crRect.Width();
  300.                 GetElement()->height = crRect.Height() + EDIT_SPACE;
  301.                 GetElement()->border_vert_space = EDIT_SPACE/2;
  302.  
  303.                 //    Baseline needs text metric information.
  304.                 GetElement()->baseline = GetElement()->height;    //    ugly default in case of failure below.
  305.                 CDC *pDC = m_pWidget->GetDC();
  306.                 if(pDC)    {
  307.                     //    Need to specifically select the font before calling GetTextMetrics.
  308.                     CyaFont    *pMyFont;
  309.                     VOID2CX(GetContext(), CPaneCX)->SelectNetscapeFont( pDC->GetSafeHdc(), GetTextAttr(), pMyFont );
  310.                     if (pMyFont) {
  311.                         SetWidgetFont(pDC->GetSafeHdc(), m_pWidget->m_hWnd);
  312.                         GetElement()->baseline -= (pMyFont->GetHeight() / 2 + pMyFont->GetDescent()) / 2;
  313.                         VOID2CX(GetContext(), CPaneCX)->ReleaseNetscapeFont( pDC->GetSafeHdc(), pMyFont );
  314.                         m_pWidget->ReleaseDC(pDC);
  315.                     }
  316.                     else {
  317.                         m_pWidget->ReleaseDC(pDC);
  318.                         DestroyWidget();
  319.                         return;
  320.                     }
  321.                 }
  322.             }
  323.             else    {
  324.                 //    No widget, tell layout nothing.
  325.                 GetElement()->width = 0;
  326.                 GetElement()->height = 0;
  327.                 GetElement()->baseline = 0;
  328.             }
  329.         }
  330.         else if(GetContext()->IsPureDCContext())    {
  331.             //    Do some printing specific stuff here...
  332.             GetElement()->width = 0;
  333.             GetElement()->height = 0;
  334.             GetElement()->baseline = 0;
  335.         }
  336.     }
  337. }
  338.  
  339. //    Copy the current data out of the form element back into the
  340. //        layout struct.
  341. void CFormReadOnly::UpdateCurrentData()
  342. {
  343.     //    There is literally no data to update for this element type right now.
  344.     //    Perhaps one day....
  345.     if(GetContext())    {
  346.         if(GetContext()->IsWindowContext())    {
  347.             //    Need a widget.
  348.             if(m_pWidget)    {
  349.             }
  350.             else    {
  351.             }
  352.         }
  353.         else if(GetContext()->IsPureDCContext())    {
  354.             //    Printing/metafile
  355.         }
  356.     }
  357. }
  358.  
  359. HWND CFormReadOnly::GetRaw()
  360. {
  361.     return(m_pWidget ? m_pWidget->m_hWnd : NULL);
  362. }
  363.