зеркало из https://github.com/mozilla/pjs.git
Fixing bug 171605. Implementing deletion of individual autocomplete results by pressing Shift+Delete on a selected autocomplete item. r=ben@bengoodger.com
This commit is contained in:
Родитель
d2d084d7db
Коммит
067a1fb904
|
@ -116,6 +116,12 @@ interface nsIAutoCompleteController : nsISupports
|
|||
*/
|
||||
boolean handleKeyNavigation(in unsigned short key);
|
||||
|
||||
/*
|
||||
* Notify the controller that the user chose to delete the current
|
||||
* auto-complete result.
|
||||
*/
|
||||
boolean handleDelete();
|
||||
|
||||
/*
|
||||
* Get the value of the result at a given index in the last completed search
|
||||
*/
|
||||
|
|
|
@ -73,7 +73,7 @@ interface nsIAutoCompleteMdbResult : nsIAutoCompleteBaseResult
|
|||
|
||||
void addRow(in nsIMdbRow row);
|
||||
|
||||
void removeRowAt(in unsigned long rowIndex);
|
||||
void removeRowAt(in unsigned long rowIndex, in boolean removeFromDb);
|
||||
|
||||
nsIMdbRow getRowAt(in unsigned long rowIndex);
|
||||
|
||||
|
|
|
@ -29,12 +29,13 @@ MODULE = autocomplete
|
|||
LIBRARY_NAME = autocomplete_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
dom \
|
||||
layout \
|
||||
mork \
|
||||
$(NULL)
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
dom \
|
||||
layout \
|
||||
mork \
|
||||
unicharutil \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsAutoCompleteController.cpp \
|
||||
nsAutoCompleteMdbResult.cpp \
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
|
@ -20,6 +21,8 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Joe Hewitt <hewitt@netscape.com> (Original Author)
|
||||
* Dean Tessman <dean_tessman@hotmail.com>
|
||||
* Johnny Stenback <jst@mozilla.jstenback.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,12 +40,12 @@
|
|||
|
||||
#include "nsAutoCompleteController.h"
|
||||
|
||||
#include "nsIAutoCompleteResultTypes.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIAtomService.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
static const char *kAutoCompleteSearchCID = "@mozilla.org/autocomplete/search;1?name=";
|
||||
|
||||
|
@ -52,7 +55,6 @@ NS_IMPL_ISUPPORTS4(nsAutoCompleteController, nsIAutoCompleteController, nsIAutoC
|
|||
|
||||
nsAutoCompleteController::nsAutoCompleteController() :
|
||||
mEnterAfterSearch(PR_FALSE),
|
||||
mNeedToComplete(PR_FALSE),
|
||||
mDefaultIndexCompleted(PR_FALSE),
|
||||
mBackspaced(PR_FALSE),
|
||||
mSearchStatus(0),
|
||||
|
@ -120,7 +122,6 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput)
|
|||
// Reset all search state members to default values
|
||||
mSearchString = newValue;
|
||||
mEnterAfterSearch = PR_FALSE;
|
||||
mNeedToComplete = PR_FALSE;
|
||||
mDefaultIndexCompleted = PR_FALSE;
|
||||
mBackspaced = PR_FALSE;
|
||||
mSearchStatus = nsIAutoCompleteController::STATUS_NONE;
|
||||
|
@ -163,7 +164,7 @@ nsAutoCompleteController::StartSearch(const nsAString &aSearchString)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleText()
|
||||
{
|
||||
{
|
||||
// Stop current search in case it's async.
|
||||
StopSearch();
|
||||
// Stop the queued up search on a timer
|
||||
|
@ -173,8 +174,6 @@ nsAutoCompleteController::HandleText()
|
|||
mInput->GetDisableAutoComplete(&disabled);
|
||||
NS_ENSURE_TRUE(!disabled, NS_OK;);
|
||||
|
||||
mNeedToComplete = PR_TRUE;
|
||||
|
||||
nsAutoString newValue;
|
||||
mInput->GetTextValue(newValue);
|
||||
|
||||
|
@ -264,8 +263,6 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint16 aKey, PRBool *_retval)
|
|||
// By default, don't cancel the event
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
mNeedToComplete = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIAutoCompletePopup> popup;
|
||||
mInput->GetPopup(getter_AddRefs(popup));
|
||||
NS_ENSURE_TRUE(popup != nsnull, NS_ERROR_FAILURE);
|
||||
|
@ -325,6 +322,80 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint16 aKey, PRBool *_retval)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleDelete(PRBool *_retval)
|
||||
{
|
||||
*_retval = PR_FALSE;
|
||||
PRBool isOpen = PR_FALSE;
|
||||
mInput->GetPopupOpen(&isOpen);
|
||||
if (!isOpen || mRowCount <= 0) {
|
||||
// Nothing left to delete, proceed as normal
|
||||
HandleText();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAutoCompletePopup> popup;
|
||||
mInput->GetPopup(getter_AddRefs(popup));
|
||||
|
||||
PRInt32 index, searchIndex, rowIndex;
|
||||
popup->GetSelectedIndex(&index);
|
||||
RowIndexToSearch(index, &searchIndex, &rowIndex);
|
||||
NS_ENSURE_TRUE(searchIndex >= 0 && rowIndex >= 0, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteResult> result;
|
||||
mResults->GetElementAt(searchIndex, getter_AddRefs(result));
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString search;
|
||||
mInput->GetSearchParam(search);
|
||||
|
||||
nsAutoString value;
|
||||
result->GetValueAt(rowIndex, value);
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteMdbResult> mdbResult(do_QueryInterface(result));
|
||||
if (mdbResult) {
|
||||
// Clear the row in our result and in the DB.
|
||||
mdbResult->RemoveRowAt(rowIndex, PR_TRUE);
|
||||
|
||||
--mRowCount;
|
||||
}
|
||||
|
||||
// Unselect the current item.
|
||||
popup->SetSelectedIndex(-1);
|
||||
|
||||
// Tell the tree that the row count changed.
|
||||
if (mTree)
|
||||
mTree->RowCountChanged(mRowCount, -1);
|
||||
|
||||
// Adjust index, if needed.
|
||||
if (index >= (PRInt32)mRowCount)
|
||||
index = mRowCount - 1;
|
||||
|
||||
if (mRowCount > 0) {
|
||||
// There are still rows in the popup, select the current index again.
|
||||
popup->SetSelectedIndex(index);
|
||||
|
||||
// Complete to the new current value.
|
||||
nsAutoString value;
|
||||
if (NS_SUCCEEDED(GetResultValueAt(index, PR_TRUE, value))) {
|
||||
CompleteValue(value);
|
||||
|
||||
// Make sure we cancel the event that triggerd this call.
|
||||
*_retval = PR_TRUE;
|
||||
}
|
||||
|
||||
// Invalidate the popup.
|
||||
popup->Invalidate();
|
||||
} else {
|
||||
// Nothing left in the popup, clear any pending search timers and
|
||||
// close the popup.
|
||||
ClearSearchTimer();
|
||||
ClosePopup();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::GetValueAt(PRInt32 aIndex, nsAString & _retval)
|
||||
{
|
||||
|
@ -803,7 +874,7 @@ nsAutoCompleteController::EnterMatch()
|
|||
|
||||
if (!value.IsEmpty()) {
|
||||
mInput->SetTextValue(value);
|
||||
mInput->SelectTextRange(-1, -1);
|
||||
mInput->SelectTextRange(value.Length(), value.Length());
|
||||
mSearchString = value;
|
||||
}
|
||||
|
||||
|
@ -827,7 +898,6 @@ nsAutoCompleteController::RevertTextValue()
|
|||
mInput->SetTextValue(oldValue);
|
||||
|
||||
mSearchString.Truncate(0);
|
||||
mNeedToComplete = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -958,13 +1028,23 @@ nsAutoCompleteController::CompleteDefaultIndex(PRInt32 aSearchIndex)
|
|||
nsresult
|
||||
nsAutoCompleteController::CompleteValue(nsString &aValue)
|
||||
{
|
||||
PRInt32 findIndex = aValue.Find(mSearchString, PR_FALSE);
|
||||
if (findIndex == 0 || mSearchString.IsEmpty()) {
|
||||
// The textbox value matches the beginning of the default value, so we can just
|
||||
// append the latter portion
|
||||
nsString::const_iterator start, end, iter;
|
||||
aValue.BeginReading(start);
|
||||
aValue.EndReading(end);
|
||||
iter = start;
|
||||
|
||||
FindInReadable(mSearchString, iter, end,
|
||||
nsCaseInsensitiveStringComparator());
|
||||
|
||||
if (iter == start) {
|
||||
// The textbox value matches the beginning of the default value,
|
||||
// or the default value is empty, so we can just append the latter
|
||||
// portion
|
||||
mInput->SetTextValue(aValue);
|
||||
mInput->SelectTextRange(mSearchString.Length(), aValue.Length());
|
||||
} else {
|
||||
PRInt32 findIndex = iter.get() - start.get();
|
||||
|
||||
mInput->SetTextValue(mSearchString + Substring(aValue, mSearchString.Length()+findIndex, aValue.Length()));
|
||||
mInput->SelectTextRange(mSearchString.Length(), aValue.Length() - findIndex);
|
||||
|
||||
|
|
|
@ -102,7 +102,6 @@ protected:
|
|||
|
||||
nsString mSearchString;
|
||||
PRPackedBool mEnterAfterSearch;
|
||||
PRPackedBool mNeedToComplete;
|
||||
PRPackedBool mDefaultIndexCompleted;
|
||||
PRPackedBool mBackspaced;
|
||||
PRUint16 mSearchStatus;
|
||||
|
|
|
@ -210,9 +210,18 @@ nsAutoCompleteMdbResult::AddRow(nsIMdbRow *aRow)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteMdbResult::RemoveRowAt(PRUint32 aRowIndex)
|
||||
nsAutoCompleteMdbResult::RemoveRowAt(PRUint32 aRowIndex, PRBool aRemoveFromDb)
|
||||
{
|
||||
nsIMdbRow *row = (nsIMdbRow *)mResults.ElementAt(aRowIndex);
|
||||
NS_ENSURE_TRUE(row, NS_ERROR_INVALID_ARG);
|
||||
|
||||
mResults.RemoveElementAt(aRowIndex);
|
||||
|
||||
if (aRemoveFromDb && mTable && mEnv) {
|
||||
mdb_err err = mTable->CutRow(mEnv, row);
|
||||
NS_ENSURE_TRUE(!err, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -4154,7 +4154,7 @@ nsGlobalHistory::AutoCompleteSearch(const nsAString &aSearchString,
|
|||
aPrevResult->GetValueAt(i, url);
|
||||
|
||||
if (!AutoCompleteCompare(url, aSearchString, aExclude))
|
||||
aPrevResult->RemoveRowAt(i);
|
||||
aPrevResult->RemoveRowAt(i, PR_FALSE);
|
||||
}
|
||||
|
||||
*aResult = aPrevResult;
|
||||
|
|
|
@ -227,12 +227,12 @@ nsFormFillController::GetPopupOpen(PRBool *aPopupOpen)
|
|||
NS_IMETHODIMP
|
||||
nsFormFillController::SetPopupOpen(PRBool aPopupOpen)
|
||||
{
|
||||
if (aPopupOpen) {
|
||||
nsRect popupRect = GetScreenOrigin(mFocusedInput);
|
||||
if (mFocusedPopup)
|
||||
if (mFocusedPopup) {
|
||||
if (aPopupOpen) {
|
||||
nsRect popupRect = GetScreenOrigin(mFocusedInput);
|
||||
mFocusedPopup->OpenPopup(this, popupRect.x, popupRect.y+popupRect.height, popupRect.width);
|
||||
} else {
|
||||
mFocusedPopup->ClosePopup();
|
||||
} else
|
||||
mFocusedPopup->ClosePopup();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -562,8 +562,20 @@ nsFormFillController::KeyPress(nsIDOMEvent* aEvent)
|
|||
PRUint32 k;
|
||||
keyEvent->GetKeyCode(&k);
|
||||
switch (k) {
|
||||
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
|
||||
case nsIDOMKeyEvent::DOM_VK_DELETE:
|
||||
{
|
||||
PRBool isShift = PR_FALSE;
|
||||
keyEvent->GetShiftKey(&isShift);
|
||||
|
||||
if (isShift) {
|
||||
mController->HandleDelete(&cancel);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// fall through
|
||||
}
|
||||
case nsIDOMKeyEvent::DOM_VK_BACK_SPACE:
|
||||
mController->HandleText();
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_UP:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -704,7 +705,7 @@ nsFormHistory::AutoCompleteSearch(const nsAString &aInputName,
|
|||
nsIMdbRow *row;
|
||||
result->GetRowAt(i, &row);
|
||||
if (!RowMatch(row, aInputName, aInputValue, nsnull))
|
||||
result->RemoveRowAt(i);
|
||||
result->RemoveRowAt(i, PR_FALSE);
|
||||
}
|
||||
} else {
|
||||
result = do_CreateInstance("@mozilla.org/autocomplete/mdb-result;1");
|
||||
|
@ -790,11 +791,12 @@ nsFormHistory::SortComparison(const void *v1, const void *v2, void *closureVoid)
|
|||
PRBool
|
||||
nsFormHistory::RowMatch(nsIMdbRow *aRow, const nsAString &aInputName, const nsAString &aInputValue, PRUnichar **aValue)
|
||||
{
|
||||
nsAutoString name, value;
|
||||
nsAutoString name;
|
||||
GetRowValue(aRow, kToken_NameColumn, name);
|
||||
GetRowValue(aRow, kToken_ValueColumn, value);
|
||||
|
||||
|
||||
if (name.Equals(aInputName)) {
|
||||
nsAutoString value;
|
||||
GetRowValue(aRow, kToken_ValueColumn, value);
|
||||
if (value.Length() != aInputValue.Length() && // ignore exact matches
|
||||
Compare(Substring(value, 0, aInputValue.Length()), aInputValue, nsCaseInsensitiveStringComparator()) == 0)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче