зеркало из https://github.com/mozilla/gecko-dev.git
395 строки
11 KiB
C++
395 строки
11 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (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.mozilla.org/NPL/
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
|
*/
|
|
|
|
|
|
#include "TypeInState.h"
|
|
|
|
/********************************************************************
|
|
* XPCOM cruft
|
|
*******************************************************************/
|
|
|
|
NS_IMPL_ADDREF(TypeInState)
|
|
NS_IMPL_RELEASE(TypeInState)
|
|
|
|
NS_IMETHODIMP
|
|
TypeInState::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|
{
|
|
if (nsnull == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
|
*aInstancePtr = (void*)(nsISupports*)this;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
if (aIID.Equals(NS_GET_IID(nsIDOMSelectionListener))) {
|
|
*aInstancePtr = (void*)(nsIDOMSelectionListener*)this;
|
|
NS_ADDREF_THIS();
|
|
return NS_OK;
|
|
}
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
/********************************************************************
|
|
* public methods
|
|
*******************************************************************/
|
|
|
|
TypeInState::TypeInState() :
|
|
mSetArray()
|
|
,mClearedArray()
|
|
,mRelativeFontSize(0)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
Reset();
|
|
}
|
|
|
|
TypeInState::~TypeInState()
|
|
{
|
|
}
|
|
|
|
NS_IMETHODIMP TypeInState::NotifySelectionChanged(nsIDOMDocument *, nsIDOMSelection *,short)
|
|
{
|
|
Reset();
|
|
return NS_OK;
|
|
}
|
|
|
|
void TypeInState::Reset()
|
|
{
|
|
PRInt32 count;
|
|
PropItem *propItemPtr;
|
|
|
|
while ((count = mClearedArray.Count()))
|
|
{
|
|
// go backwards to keep nsVoidArray from memmoving everything each time
|
|
count--; // nsVoidArray is zero based
|
|
propItemPtr = (PropItem*)mClearedArray.ElementAt(count);
|
|
mClearedArray.RemoveElementAt(count);
|
|
if (propItemPtr) delete propItemPtr;
|
|
}
|
|
while ((count = mSetArray.Count()))
|
|
{
|
|
// go backwards to keep nsVoidArray from memmoving everything each time
|
|
count--; // nsVoidArray is zero based
|
|
propItemPtr = (PropItem*)mSetArray.ElementAt(count);
|
|
mSetArray.RemoveElementAt(count);
|
|
if (propItemPtr) delete propItemPtr;
|
|
}
|
|
}
|
|
|
|
|
|
nsresult TypeInState::SetProp(nsIAtom *aProp)
|
|
{
|
|
return SetProp(aProp,nsAutoString(),nsAutoString());
|
|
}
|
|
|
|
nsresult TypeInState::SetProp(nsIAtom *aProp, const nsString &aAttr)
|
|
{
|
|
return SetProp(aProp,aAttr,nsAutoString());
|
|
}
|
|
|
|
nsresult TypeInState::SetProp(nsIAtom *aProp, const nsString &aAttr, const nsString &aValue)
|
|
{
|
|
// special case for big/small, these nest
|
|
if (nsIEditProperty::big == aProp)
|
|
{
|
|
mRelativeFontSize++;
|
|
return NS_OK;
|
|
}
|
|
if (nsIEditProperty::small == aProp)
|
|
{
|
|
mRelativeFontSize--;
|
|
return NS_OK;
|
|
}
|
|
|
|
// if it's already set we are done
|
|
if (IsPropSet(aProp,aAttr,nsnull)) return NS_OK;
|
|
|
|
// make a new propitem
|
|
PropItem *item = new PropItem(aProp,aAttr,aValue);
|
|
if (!item) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
// remove it from the list of cleared properties, if we have a match
|
|
RemovePropFromClearedList(aProp,aAttr);
|
|
|
|
// add it to the list of set properties
|
|
mSetArray.AppendElement((void*)item);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult TypeInState::ClearAllProps()
|
|
{
|
|
// null prop means "all" props
|
|
return ClearProp(nsnull,nsAutoString());
|
|
}
|
|
|
|
nsresult TypeInState::ClearProp(nsIAtom *aProp)
|
|
{
|
|
return ClearProp(aProp,nsAutoString());
|
|
}
|
|
|
|
nsresult TypeInState::ClearProp(nsIAtom *aProp, const nsString &aAttr)
|
|
{
|
|
// if it's already cleared we are done
|
|
if (IsPropCleared(aProp,aAttr)) return NS_OK;
|
|
|
|
// make a new propitem
|
|
PropItem *item = new PropItem(aProp,aAttr,nsAutoString());
|
|
if (!item) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
// remove it from the list of set properties, if we have a match
|
|
RemovePropFromSetList(aProp,aAttr);
|
|
|
|
// add it to the list of cleared properties
|
|
mClearedArray.AppendElement((void*)item);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
* TakeClearProperty: hands back next poroperty item on the clear list.
|
|
* caller assumes ownership of PropItem and must delete it.
|
|
*/
|
|
nsresult TypeInState::TakeClearProperty(PropItem **outPropItem)
|
|
{
|
|
if (!outPropItem) return NS_ERROR_NULL_POINTER;
|
|
*outPropItem = nsnull;
|
|
PRInt32 count = mClearedArray.Count();
|
|
if (count) // go backwards to keep nsVoidArray from memmoving everything each time
|
|
{
|
|
count--; // nsVoidArray is zero based
|
|
*outPropItem = (PropItem*)mClearedArray[count];
|
|
mClearedArray.RemoveElementAt(count);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
/***************************************************************************
|
|
* TakeSetProperty: hands back next poroperty item on the set list.
|
|
* caller assumes ownership of PropItem and must delete it.
|
|
*/
|
|
nsresult TypeInState::TakeSetProperty(PropItem **outPropItem)
|
|
{
|
|
if (!outPropItem) return NS_ERROR_NULL_POINTER;
|
|
*outPropItem = nsnull;
|
|
PRInt32 count = mSetArray.Count();
|
|
if (count) // go backwards to keep nsVoidArray from memmoving everything each time
|
|
{
|
|
count--; // nsVoidArray is zero based
|
|
*outPropItem = (PropItem*)mSetArray[count];
|
|
mSetArray.RemoveElementAt(count);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
//**************************************************************************
|
|
// TakeRelativeFontSize: hands back relative font value, which is then
|
|
// cleared out.
|
|
nsresult TypeInState::TakeRelativeFontSize(PRInt32 *outRelSize)
|
|
{
|
|
if (!outRelSize) return NS_ERROR_NULL_POINTER;
|
|
*outRelSize = mRelativeFontSize;
|
|
mRelativeFontSize = 0;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult TypeInState::GetTypingState(PRBool &isSet, PRBool &theSetting, nsIAtom *aProp)
|
|
{
|
|
return GetTypingState(isSet, theSetting, aProp, nsAutoString(), nsnull);
|
|
}
|
|
|
|
nsresult TypeInState::GetTypingState(PRBool &isSet,
|
|
PRBool &theSetting,
|
|
nsIAtom *aProp,
|
|
const nsString &aAttr)
|
|
{
|
|
return GetTypingState(isSet, theSetting, aProp, aAttr, nsnull);
|
|
}
|
|
|
|
|
|
nsresult TypeInState::GetTypingState(PRBool &isSet,
|
|
PRBool &theSetting,
|
|
nsIAtom *aProp,
|
|
const nsString &aAttr,
|
|
nsString *aValue)
|
|
{
|
|
if (IsPropSet(aProp, aAttr, aValue))
|
|
{
|
|
isSet = PR_TRUE;
|
|
theSetting = PR_TRUE;
|
|
}
|
|
else if (IsPropCleared(aProp, aAttr))
|
|
{
|
|
isSet = PR_TRUE;
|
|
theSetting = PR_FALSE;
|
|
}
|
|
else
|
|
{
|
|
isSet = PR_FALSE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
* protected methods
|
|
*******************************************************************/
|
|
|
|
nsresult TypeInState::RemovePropFromSetList(nsIAtom *aProp,
|
|
const nsString &aAttr)
|
|
{
|
|
PRInt32 index;
|
|
PropItem *item;
|
|
if (!aProp)
|
|
{
|
|
// clear _all_ props
|
|
mRelativeFontSize=0;
|
|
while ((index = mSetArray.Count()))
|
|
{
|
|
// go backwards to keep nsVoidArray from memmoving everything each time
|
|
index--; // nsVoidArray is zero based
|
|
item = (PropItem*)mSetArray.ElementAt(index);
|
|
mSetArray.RemoveElementAt(index);
|
|
if (item) delete item;
|
|
}
|
|
}
|
|
else if (FindPropInList(aProp, aAttr, nsnull, mSetArray, index))
|
|
{
|
|
item = (PropItem*)mSetArray.ElementAt(index);
|
|
mSetArray.RemoveElementAt(index);
|
|
if (item) delete item;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult TypeInState::RemovePropFromClearedList(nsIAtom *aProp,
|
|
const nsString &aAttr)
|
|
{
|
|
PRInt32 index;
|
|
if (FindPropInList(aProp, aAttr, nsnull, mClearedArray, index))
|
|
{
|
|
PropItem *item = (PropItem*)mClearedArray.ElementAt(index);
|
|
mClearedArray.RemoveElementAt(index);
|
|
if (item) delete item;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
PRBool TypeInState::IsPropSet(nsIAtom *aProp,
|
|
const nsString &aAttr,
|
|
nsString* outValue)
|
|
{
|
|
PRInt32 i;
|
|
return IsPropSet(aProp, aAttr, outValue, i);
|
|
}
|
|
|
|
|
|
PRBool TypeInState::IsPropSet(nsIAtom *aProp,
|
|
const nsString &aAttr,
|
|
nsString *outValue,
|
|
PRInt32 &outIndex)
|
|
{
|
|
// linear search. list should be short.
|
|
PRInt32 i, count = mSetArray.Count();
|
|
for (i=0; i<count; i++)
|
|
{
|
|
PropItem *item = (PropItem*)mSetArray[i];
|
|
if ( (item->tag == aProp) &&
|
|
(item->attr == aAttr) )
|
|
{
|
|
if (outValue) *outValue = item->value;
|
|
outIndex = i;
|
|
return PR_TRUE;
|
|
}
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
|
|
PRBool TypeInState::IsPropCleared(nsIAtom *aProp,
|
|
const nsString &aAttr)
|
|
{
|
|
PRInt32 i;
|
|
return IsPropCleared(aProp, aAttr, i);
|
|
}
|
|
|
|
|
|
PRBool TypeInState::IsPropCleared(nsIAtom *aProp,
|
|
const nsString &aAttr,
|
|
PRInt32 &outIndex)
|
|
{
|
|
if (FindPropInList(aProp, aAttr, nsnull, mClearedArray, outIndex))
|
|
return PR_TRUE;
|
|
if (FindPropInList(0, nsAutoString(), nsnull, mClearedArray, outIndex))
|
|
{
|
|
// special case for all props cleared
|
|
outIndex = -1;
|
|
return PR_TRUE;
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
PRBool TypeInState::FindPropInList(nsIAtom *aProp,
|
|
const nsString &aAttr,
|
|
nsString *outValue,
|
|
nsVoidArray &aList,
|
|
PRInt32 &outIndex)
|
|
{
|
|
// linear search. list should be short.
|
|
PRInt32 i, count = aList.Count();
|
|
for (i=0; i<count; i++)
|
|
{
|
|
PropItem *item = (PropItem*)aList[i];
|
|
if ( (item->tag == aProp) &&
|
|
(item->attr == aAttr) )
|
|
{
|
|
if (outValue) *outValue = item->value;
|
|
outIndex = i;
|
|
return PR_TRUE;
|
|
}
|
|
}
|
|
return PR_FALSE;
|
|
}
|
|
|
|
|
|
|
|
/********************************************************************
|
|
* PropItem: helper struct for TypeInState
|
|
*******************************************************************/
|
|
|
|
PropItem::PropItem(nsIAtom *aTag, const nsString &aAttr, const nsString &aValue) :
|
|
tag(aTag)
|
|
,attr(aAttr)
|
|
,value(aValue)
|
|
{
|
|
}
|
|
|
|
PropItem::~PropItem()
|
|
{
|
|
}
|