Back to index

lightning-sunbird  0.9+nobinonly
nsFileControlFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsFileControlFrame.h"
00039 
00040 
00041 #include "nsIContent.h"
00042 #include "prtypes.h"
00043 #include "nsIAtom.h"
00044 #include "nsPresContext.h"
00045 #include "nsHTMLAtoms.h"
00046 #include "nsWidgetsCID.h"
00047 #include "nsIComponentManager.h"
00048 #include "nsIView.h"
00049 #include "nsHTMLParts.h"
00050 #include "nsIDOMHTMLInputElement.h"
00051 #include "nsIFormControl.h"
00052 #include "nsINameSpaceManager.h"
00053 #include "nsCOMPtr.h"
00054 #include "nsISupportsArray.h"
00055 #include "nsIDOMElement.h"
00056 #include "nsIDOMDocument.h"
00057 #include "nsIDocument.h"
00058 #include "nsIDOMMouseListener.h"
00059 #include "nsIPresShell.h"
00060 #include "nsIDOMHTMLInputElement.h"
00061 #include "nsXPCOM.h"
00062 #include "nsISupportsPrimitives.h"
00063 #include "nsIComponentManager.h"
00064 #include "nsIDOMWindowInternal.h"
00065 #include "nsIFilePicker.h"
00066 #include "nsIDOMMouseEvent.h"
00067 #include "nsINodeInfo.h"
00068 #include "nsIDOMEventReceiver.h"
00069 #include "nsIScriptGlobalObject.h"
00070 #include "nsILocalFile.h"
00071 #include "nsIFileControlElement.h"
00072 #include "nsNodeInfoManager.h"
00073 #include "nsContentCreatorFunctions.h"
00074 #include "nsContentUtils.h"
00075 
00076 #define SYNC_TEXT 0x1
00077 #define SYNC_BUTTON 0x2
00078 #define SYNC_BOTH 0x3
00079 
00080 nsresult
00081 NS_NewFileControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00082 {
00083   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00084   if (nsnull == aNewFrame) {
00085     return NS_ERROR_NULL_POINTER;
00086   }
00087   nsFileControlFrame* it = new (aPresShell) nsFileControlFrame();
00088   if (!it) {
00089     return NS_ERROR_OUT_OF_MEMORY;
00090   }
00091   *aNewFrame = it;
00092   return NS_OK;
00093 }
00094 
00095 nsFileControlFrame::nsFileControlFrame():
00096   mTextFrame(nsnull), 
00097   mCachedState(nsnull)
00098 {
00099     //Shrink the area around it's contents
00100   SetFlags(NS_BLOCK_SHRINK_WRAP);
00101 }
00102 
00103 nsFileControlFrame::~nsFileControlFrame()
00104 {
00105   if (mCachedState) {
00106     delete mCachedState;
00107     mCachedState = nsnull;
00108   }
00109 }
00110 
00111 NS_IMETHODIMP
00112 nsFileControlFrame::Init(nsPresContext*  aPresContext,
00113                          nsIContent*      aContent,
00114                          nsIFrame*        aParent,
00115                          nsStyleContext*  aContext,
00116                          nsIFrame*        aPrevInFlow)
00117 {
00118   mPresContext = aPresContext;
00119   nsresult rv = nsAreaFrame::Init(aPresContext, aContent, aParent, aContext,
00120                                   aPrevInFlow);
00121   NS_ENSURE_SUCCESS(rv, rv);
00122 
00123   mMouseListener = new MouseListener(this);
00124   NS_ENSURE_TRUE(mMouseListener, NS_ERROR_OUT_OF_MEMORY);
00125 
00126   return rv;
00127 }
00128 
00129 NS_IMETHODIMP
00130 nsFileControlFrame::Destroy(nsPresContext* aPresContext)
00131 {
00132   mTextFrame = nsnull;
00133   // remove mMouseListener as a mouse event listener (bug 40533, bug 355931)
00134   if (mBrowse) {
00135     nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(mBrowse));
00136     receiver->RemoveEventListenerByIID(mMouseListener,
00137                                        NS_GET_IID(nsIDOMMouseListener));
00138   }
00139 
00140   mMouseListener->ForgetFrame();
00141   return nsAreaFrame::Destroy(aPresContext);
00142 }
00143 
00144 NS_IMETHODIMP
00145 nsFileControlFrame::CreateAnonymousContent(nsPresContext* aPresContext,
00146                                            nsISupportsArray& aChildList)
00147 {
00148   // Get the NodeInfoManager and tag necessary to create input elements
00149   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
00150 
00151   nsCOMPtr<nsINodeInfo> nodeInfo;
00152   doc->NodeInfoManager()->GetNodeInfo(nsHTMLAtoms::input, nsnull,
00153                                       kNameSpaceID_None,
00154                                       getter_AddRefs(nodeInfo));
00155 
00156   // Create the text content
00157   nsCOMPtr<nsIContent> content;
00158   nsresult rv = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo);
00159   NS_ENSURE_SUCCESS(rv, rv);
00160 
00161   content.swap(mTextContent);
00162 
00163   nsCOMPtr<nsIDOMHTMLInputElement> fileContent = do_QueryInterface(mContent);
00164 
00165   if (mTextContent) {
00166     mTextContent->SetAttr(kNameSpaceID_None, nsHTMLAtoms::type, NS_LITERAL_STRING("text"), PR_FALSE);
00167     nsCOMPtr<nsIFileControlElement> fileControl = do_QueryInterface(mContent);
00168     nsCOMPtr<nsIDOMHTMLInputElement> textControl = do_QueryInterface(mTextContent);
00169     if (fileControl && fileContent && textControl) {
00170       // Initialize value when we create the content in case the value was set
00171       // before we got here
00172       nsAutoString value;
00173       nsAutoString accessKey;
00174       fileControl->GetFileName(value);
00175       textControl->SetValue(value);
00176 
00177       PRInt32 tabIndex;
00178       fileContent->GetTabIndex(&tabIndex);
00179       textControl->SetTabIndex(tabIndex);
00180       fileContent->GetAccessKey(accessKey);
00181       textControl->SetAccessKey(accessKey);
00182     }
00183     aChildList.AppendElement(mTextContent);
00184   }
00185 
00186   // Create the browse button
00187   rv = NS_NewHTMLElement(getter_AddRefs(content), nodeInfo);
00188   NS_ENSURE_SUCCESS(rv, rv);
00189 
00190   mBrowse = do_QueryInterface(content);
00191   if (mBrowse) {
00192     mBrowse->SetAttr(kNameSpaceID_None, nsHTMLAtoms::type, NS_LITERAL_STRING("button"), PR_FALSE);
00193     nsCOMPtr<nsIDOMHTMLInputElement> browseControl = do_QueryInterface(mBrowse);
00194     if (fileContent && browseControl) {
00195       PRInt32 tabIndex;
00196       fileContent->GetTabIndex(&tabIndex);
00197       browseControl->SetTabIndex(tabIndex);
00198     }
00199 
00200     aChildList.AppendElement(mBrowse);
00201 
00202     // register as an event listener of the button to open file dialog on mouse click
00203     nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(mBrowse));
00204     receiver->AddEventListenerByIID(mMouseListener,
00205                                     NS_GET_IID(nsIDOMMouseListener));
00206   }
00207 
00208   SyncAttr(kNameSpaceID_None, nsHTMLAtoms::size,     SYNC_TEXT);
00209   SyncAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, SYNC_BOTH);
00210 
00211   return NS_OK;
00212 }
00213 
00214 // Frames are not refcounted, no need to AddRef
00215 NS_IMETHODIMP
00216 nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
00217 {
00218   NS_PRECONDITION(0 != aInstancePtr, "null ptr");
00219   if (NULL == aInstancePtr) {
00220     return NS_ERROR_NULL_POINTER;
00221   } else if (aIID.Equals(NS_GET_IID(nsIAnonymousContentCreator))) {
00222     *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
00223     return NS_OK;
00224   } else if (aIID.Equals(NS_GET_IID(nsIFormControlFrame))) {
00225     *aInstancePtr = (void*) ((nsIFormControlFrame*) this);
00226     return NS_OK;
00227   }
00228   return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
00229 }
00230 
00231 NS_IMETHODIMP_(PRInt32)
00232 nsFileControlFrame::GetFormControlType() const
00233 {
00234   return NS_FORM_INPUT_FILE;
00235 }
00236 
00237 
00238 void 
00239 nsFileControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
00240 {
00241   // Fix for Bug 6133 
00242   if (mTextFrame) {
00243     nsIContent* content = mTextFrame->GetContent();
00244     if (content) {
00245       content->SetFocus(mPresContext);
00246     }
00247   }
00248 }
00249 
00250 void
00251 nsFileControlFrame::ScrollIntoView(nsPresContext* aPresContext)
00252 {
00253   if (aPresContext) {
00254     nsIPresShell *presShell = aPresContext->GetPresShell();
00255     if (presShell) {
00256       presShell->ScrollFrameIntoView(this,
00257                    NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE,NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE);
00258     }
00259   }
00260 }
00261 
00265 nsresult 
00266 nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent)
00267 {
00268   // only allow the left button
00269   nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
00270   if (mouseEvent) {
00271     PRUint16 whichButton;
00272     if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) {
00273       if (whichButton != 0) {
00274         return NS_OK;
00275       }
00276     }
00277   }
00278 
00279 
00280   nsresult result;
00281 
00282   // Get parent nsIDOMWindowInternal object.
00283   nsIContent* content = GetContent();
00284   if (!content)
00285     return NS_ERROR_FAILURE;
00286 
00287   nsCOMPtr<nsIDocument> doc = content->GetDocument();
00288   if (!doc)
00289     return NS_ERROR_FAILURE;
00290 
00291   nsCOMPtr<nsIDOMWindow> parentWindow =
00292     do_QueryInterface(doc->GetScriptGlobalObject());
00293 
00294   // Get Loc title
00295   nsXPIDLString title;
00296   nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
00297                                      "FileUpload", title);
00298 
00299   nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
00300   if (!filePicker)
00301     return NS_ERROR_FAILURE;
00302 
00303   result = filePicker->Init(parentWindow, title, nsIFilePicker::modeOpen);
00304   if (NS_FAILED(result))
00305     return result;
00306 
00307   // Set filter "All Files"
00308   filePicker->AppendFilters(nsIFilePicker::filterAll);
00309 
00310   // Set default directry and filename
00311   nsAutoString defaultName;
00312   GetProperty(nsHTMLAtoms::value, defaultName);
00313 
00314   nsCOMPtr<nsILocalFile> currentFile = do_CreateInstance("@mozilla.org/file/local;1");
00315   if (currentFile && !defaultName.IsEmpty()) {
00316     result = currentFile->InitWithPath(defaultName);
00317     if (NS_SUCCEEDED(result)) {
00318       nsAutoString leafName;
00319       currentFile->GetLeafName(leafName);
00320       if (!leafName.IsEmpty()) {
00321         filePicker->SetDefaultString(leafName);
00322       }
00323 
00324       // set directory
00325       nsCOMPtr<nsIFile> parentFile;
00326       currentFile->GetParent(getter_AddRefs(parentFile));
00327       if (parentFile) {
00328         nsCOMPtr<nsILocalFile> parentLocalFile = do_QueryInterface(parentFile, &result);
00329         if (parentLocalFile)
00330           filePicker->SetDisplayDirectory(parentLocalFile);
00331       }
00332     }
00333   }
00334 
00335   // Tell our textframe to remember the currently focused value
00336   mTextFrame->InitFocusedValue();
00337 
00338   // Open dialog
00339   PRInt16 mode;
00340   result = filePicker->Show(&mode);
00341   if (NS_FAILED(result))
00342     return result;
00343   if (mode == nsIFilePicker::returnCancel)
00344     return NS_OK;
00345 
00346   if (!mTextFrame) {
00347     // We got destroyed while the filepicker was up.  Don't do anything here.
00348     return NS_OK;
00349   }
00350   
00351   // Set property
00352   nsCOMPtr<nsILocalFile> localFile;
00353   result = filePicker->GetFile(getter_AddRefs(localFile));
00354   if (localFile) {
00355     nsAutoString unicodePath;
00356     result = localFile->GetPath(unicodePath);
00357     if (!unicodePath.IsEmpty()) {
00358       mTextFrame->SetProperty(mPresContext, nsHTMLAtoms::value, unicodePath);
00359       nsCOMPtr<nsIFileControlElement> fileControl = do_QueryInterface(mContent);
00360       if (fileControl) {
00361         fileControl->SetFileName(unicodePath, PR_FALSE);
00362       }
00363       
00364       // May need to fire an onchange here
00365       mTextFrame->CheckFireOnChange();
00366       return NS_OK;
00367     }
00368   }
00369 
00370   return NS_FAILED(result) ? result : NS_ERROR_FAILURE;
00371 }
00372 
00373 
00374 NS_IMETHODIMP nsFileControlFrame::Reflow(nsPresContext*          aPresContext, 
00375                                          nsHTMLReflowMetrics&     aDesiredSize,
00376                                          const nsHTMLReflowState& aReflowState, 
00377                                          nsReflowStatus&          aStatus)
00378 {
00379   DO_GLOBAL_REFLOW_COUNT("nsFileControlFrame", aReflowState.reason);
00380   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
00381 
00382   aStatus = NS_FRAME_COMPLETE;
00383 
00384   if (eReflowReason_Initial == aReflowState.reason) {
00385     mTextFrame = GetTextControlFrame(aPresContext, this);
00386     if (!mTextFrame) return NS_ERROR_UNEXPECTED;
00387     if (mCachedState) {
00388       mTextFrame->SetProperty(aPresContext, nsHTMLAtoms::value, *mCachedState);
00389       delete mCachedState;
00390       mCachedState = nsnull;
00391     }
00392   }
00393 
00394   // The Areaframe takes care of all our reflow 
00395   // except for when style is used to change its size.
00396   nsresult rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
00397   if (NS_SUCCEEDED(rv) && mTextFrame != nsnull) {
00398     nsIFrame* child = GetFirstChild(nsnull);
00399     if (child == mTextFrame) {
00400       child = child->GetNextSibling();
00401     }
00402     if (child) {
00403       nsRect buttonRect = child->GetRect();
00404       nsRect txtRect = mTextFrame->GetRect();
00405 
00406       // check to see if we must reflow just the area frame again 
00407       // in order for the text field to be the correct height
00408       // reflowing just the textfield (for some reason) 
00409       // messes up the button's rect
00410       if (txtRect.width + buttonRect.width != aDesiredSize.width ||
00411           txtRect.height != aDesiredSize.height) {
00412         nsHTMLReflowMetrics txtKidSize(PR_TRUE);
00413         nsSize txtAvailSize(aReflowState.availableWidth, aDesiredSize.height);
00414         nsHTMLReflowState   txtKidReflowState(aPresContext,
00415                                               *aReflowState.parentReflowState,
00416                                               this, txtAvailSize,
00417                                               eReflowReason_Resize);
00418         txtKidReflowState.mComputedHeight = aDesiredSize.height;
00419         rv = nsAreaFrame::WillReflow(aPresContext);
00420         NS_ASSERTION(NS_SUCCEEDED(rv), "Should have succeeded");
00421         rv = nsAreaFrame::Reflow(aPresContext, txtKidSize, txtKidReflowState, aStatus);
00422         NS_ASSERTION(NS_SUCCEEDED(rv), "Should have succeeded");
00423         rv = nsAreaFrame::DidReflow(aPresContext, &txtKidReflowState, aStatus);
00424         NS_ASSERTION(NS_SUCCEEDED(rv), "Should have succeeded");
00425 
00426         // Re-calc and set the correct rect
00427         txtRect.y      = aReflowState.mComputedBorderPadding.top;
00428         txtRect.height = aDesiredSize.height;
00429         mTextFrame->SetRect(txtRect);
00430 
00431         if (aDesiredSize.mComputeMEW) {
00432            aDesiredSize.SetMEWToActualWidth(aReflowState.mStylePosition->mWidth.GetUnit());
00433         }
00434       }
00435     }
00436   }
00437   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
00438   return rv;
00439 }
00440 
00441 /*
00442 NS_IMETHODIMP
00443 nsFileControlFrame::SetInitialChildList(nsPresContext* aPresContext,
00444                                               nsIAtom*        aListName,
00445                                               nsIFrame*       aChildList)
00446 {
00447   nsresult r = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList);
00448 
00449   // given that the CSS frame constuctor created all our frames. We need to find the text field
00450   // so we can get info from it.
00451   mTextFrame = GetTextControlFrame(this);
00452 }
00453 */
00454 
00455 nsNewFrame*
00456 nsFileControlFrame::GetTextControlFrame(nsPresContext* aPresContext, nsIFrame* aStart)
00457 {
00458   nsNewFrame* result = nsnull;
00459 #ifndef DEBUG_NEWFRAME
00460   // find the text control frame.
00461   nsIFrame* childFrame = aStart->GetFirstChild(nsnull);
00462 
00463   while (childFrame) {
00464     // see if the child is a text control
00465     nsCOMPtr<nsIFormControl> formCtrl =
00466       do_QueryInterface(childFrame->GetContent());
00467 
00468     if (formCtrl && formCtrl->GetType() == NS_FORM_INPUT_TEXT) {
00469       result = (nsNewFrame*)childFrame;
00470     }
00471 
00472     // if not continue looking
00473     nsNewFrame* frame = GetTextControlFrame(aPresContext, childFrame);
00474     if (frame)
00475        result = frame;
00476      
00477     childFrame = childFrame->GetNextSibling();
00478   }
00479 
00480   return result;
00481 #else
00482   return nsnull;
00483 #endif
00484 }
00485 
00486 PRIntn
00487 nsFileControlFrame::GetSkipSides() const
00488 {
00489   return 0;
00490 }
00491 
00492 
00493 NS_IMETHODIMP
00494 nsFileControlFrame::GetName(nsAString* aResult)
00495 {
00496   return nsFormControlHelper::GetName(mContent, aResult);
00497 }
00498 
00499 void
00500 nsFileControlFrame::SyncAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
00501                              PRInt32 aWhichControls)
00502 {
00503   nsAutoString value;
00504   nsresult rv = mContent->GetAttr(aNameSpaceID, aAttribute, value);
00505   if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
00506     if (aWhichControls & SYNC_TEXT && mTextContent) {
00507       mTextContent->SetAttr(aNameSpaceID, aAttribute, value, PR_TRUE);
00508     }
00509     if (aWhichControls & SYNC_BUTTON && mBrowse) {
00510       mBrowse->SetAttr(aNameSpaceID, aAttribute, value, PR_TRUE);
00511     }
00512   } else {
00513     if (aWhichControls & SYNC_TEXT && mTextContent) {
00514       mTextContent->UnsetAttr(aNameSpaceID, aAttribute, PR_TRUE);
00515     }
00516     if (aWhichControls & SYNC_BUTTON && mBrowse) {
00517       mBrowse->UnsetAttr(aNameSpaceID, aAttribute, PR_TRUE);
00518     }
00519   }
00520 }
00521 
00522 NS_IMETHODIMP
00523 nsFileControlFrame::AttributeChanged(nsIContent*     aChild,
00524                                      PRInt32         aNameSpaceID,
00525                                      nsIAtom*        aAttribute,
00526                                      PRInt32         aModType)
00527 {
00528   // propagate disabled to text / button inputs
00529   if (aNameSpaceID == kNameSpaceID_None &&
00530       aAttribute == nsHTMLAtoms::disabled) {
00531     SyncAttr(aNameSpaceID, aAttribute, SYNC_BOTH);
00532   // propagate size to text
00533   } else if (aNameSpaceID == kNameSpaceID_None &&
00534              aAttribute == nsHTMLAtoms::size) {
00535     SyncAttr(aNameSpaceID, aAttribute, SYNC_TEXT);
00536   }
00537 
00538   return nsAreaFrame::AttributeChanged(aChild, aNameSpaceID, aAttribute, aModType);
00539 }
00540 
00541 PRBool
00542 nsFileControlFrame::IsLeaf() const
00543 {
00544   return PR_TRUE;
00545 }
00546 
00547 NS_IMETHODIMP
00548 nsFileControlFrame::GetFrameForPoint(const nsPoint& aPoint,
00549                                      nsFramePaintLayer aWhichLayer,
00550                                      nsIFrame** aFrame)
00551 {
00552 #ifndef DEBUG_NEWFRAME
00553   if ( nsFormControlHelper::GetDisabled(mContent) && mRect.Contains(aPoint) ) {
00554     if (GetStyleVisibility()->IsVisible()) {
00555       *aFrame = this;
00556       return NS_OK;
00557     }
00558   } else {
00559     return nsAreaFrame::GetFrameForPoint(aPoint, aWhichLayer, aFrame);
00560   }
00561 #endif
00562   return NS_ERROR_FAILURE;
00563 }
00564 
00565 #ifdef NS_DEBUG
00566 NS_IMETHODIMP
00567 nsFileControlFrame::GetFrameName(nsAString& aResult) const
00568 {
00569   return MakeFrameName(NS_LITERAL_STRING("FileControl"), aResult);
00570 }
00571 #endif
00572 
00573 NS_IMETHODIMP
00574 nsFileControlFrame::GetFormContent(nsIContent*& aContent) const
00575 {
00576   aContent = GetContent();
00577   NS_IF_ADDREF(aContent);
00578   return NS_OK;
00579 }
00580 
00581 nscoord 
00582 nsFileControlFrame::GetVerticalInsidePadding(nsPresContext* aPresContext,
00583                                              float aPixToTwip, 
00584                                              nscoord aInnerHeight) const
00585 {
00586    return 0;
00587 }
00588 
00589 nscoord 
00590 nsFileControlFrame::GetHorizontalInsidePadding(nsPresContext* aPresContext,
00591                                                float aPixToTwip, 
00592                                                nscoord aInnerWidth,
00593                                                nscoord aCharWidth) const
00594 {
00595   return 0;
00596 }
00597 
00598 NS_IMETHODIMP nsFileControlFrame::SetProperty(nsPresContext* aPresContext,
00599                                               nsIAtom* aName,
00600                                               const nsAString& aValue)
00601 {
00602   nsresult rv = NS_OK;
00603   if (nsHTMLAtoms::value == aName || nsHTMLAtoms::filename == aName) {
00604     if (mTextFrame) {
00605       mTextFrame->SetValue(aValue);
00606     } else {
00607       if (mCachedState) delete mCachedState;
00608       mCachedState = new nsString(aValue);
00609       if (!mCachedState) rv = NS_ERROR_OUT_OF_MEMORY;
00610     }
00611   }
00612   return rv;
00613 }      
00614 
00615 NS_IMETHODIMP nsFileControlFrame::GetProperty(nsIAtom* aName, nsAString& aValue)
00616 {
00617   aValue.Truncate();  // initialize out param
00618 
00619   if (nsHTMLAtoms::value == aName || nsHTMLAtoms::filename == aName) {
00620     if (mTextFrame) {
00621       mTextFrame->GetValue(aValue, PR_FALSE);
00622     }
00623     else if (mCachedState) {
00624       aValue.Assign(*mCachedState);
00625     }
00626   }
00627   return NS_OK;
00628 }
00629 
00630 
00631 
00632 
00633 NS_METHOD
00634 nsFileControlFrame::Paint(nsPresContext*      aPresContext,
00635                           nsIRenderingContext& aRenderingContext,
00636                           const nsRect&        aDirtyRect,
00637                           nsFramePaintLayer    aWhichLayer,
00638                           PRUint32             aFlags)
00639 {
00640   if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
00641     // Our background is inherited to the text input.  And we never have
00642     // padding or borders, per styles in forms.css.  So don't paint anything
00643     // here -- doing it just makes us look ugly in some cases and has no effect
00644     // in others.
00645     return NS_OK;
00646   }
00647   PRBool isVisible;
00648   if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) {
00649     return NS_OK;
00650   }
00651   nsresult rv = nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00652   if (NS_FAILED(rv)) return rv;
00653   
00654   return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00655 }
00656 
00657 NS_IMETHODIMP
00658 nsFileControlFrame::OnContentReset()
00659 {
00660   return NS_OK;
00661 }
00662 
00664 // Mouse listener implementation
00665 
00666 NS_IMPL_ISUPPORTS1(nsFileControlFrame::MouseListener, nsIDOMMouseListener)
00667 
00668 NS_IMETHODIMP
00669 nsFileControlFrame::MouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
00670 {
00671   if (mFrame) {
00672     return mFrame->MouseClick(aMouseEvent);
00673   }
00674 
00675   return NS_OK;
00676 }
00677