Browse Source

Improve autocomplete result display.

master
boisso 7 years ago
parent
commit
7b03053731
  1. 53
      k-meleon/AutoComplete.h
  2. 199
      k-meleon/urlbar.cpp
  3. 72
      k-meleon/urlbar.h

53
k-meleon/AutoComplete.h

@ -27,7 +27,8 @@
#include "MozUtils.h"
typedef void (CALLBACK* AutoCompleteCallback)(_AutoCompleteResult*, int, void*) ;
typedef void (CALLBACK* AutoCompleteCallback)(ACResult*, void*) ;
class CACListener : public nsIAutoCompleteObserver
{
@ -35,40 +36,19 @@ class CACListener : public nsIAutoCompleteObserver
NS_DECL_NSIAUTOCOMPLETEOBSERVER
CACListener::CACListener(AutoCompleteCallback callback, void* data) {
m_ACIt = NULL;
m_Callback = callback;
m_data = data;
gACResults = nullptr;
gACCountResults = 0;
}
CACListener::~CACListener() {
FreeResult();
}
static void AutoCompleteStop();
static void AutoComplete(const CString& aSearchString, AutoCompleteCallback callback, void* data);
protected:
void FreeResult() {
if (gACCountResults > 0) {
m_ACIt = gACResults;
while (gACCountResults--){
free(m_ACIt->value);
free(m_ACIt->comment);
m_ACIt++;
}
free(gACResults);
gACResults = NULL;
gACCountResults = 0;
}
}
PRBool AddEltToList(nsISupports* aElement);
nsCOMPtr<nsIAutoCompleteResult> m_oldResult;
AutoCompleteResult* gACResults ;
unsigned int gACCountResults;
AutoCompleteResult* m_ACIt;
AutoCompleteCallback m_Callback;
void* m_data;
static nsString previousSearch;
@ -83,8 +63,6 @@ NS_IMETHODIMP CACListener::OnUpdateSearchResult(nsIAutoCompleteSearch *search, n
NS_IMETHODIMP CACListener::OnSearchResult(nsIAutoCompleteSearch *search, nsIAutoCompleteResult *result)
{
FreeResult();
uint16_t status;
result->GetSearchResult(&status);
int32_t defaultIndex;
@ -92,28 +70,17 @@ NS_IMETHODIMP CACListener::OnSearchResult(nsIAutoCompleteSearch *search, nsIAuto
if (status == nsIAutoCompleteResult::RESULT_SUCCESS || status == nsIAutoCompleteResult::RESULT_NOMATCH)
{
m_oldResult = result; // Keep the old result for optimization
result->GetMatchCount(&gACCountResults);
gACResults = (AutoCompleteResult*)calloc(gACCountResults, sizeof(AutoCompleteResult));
m_ACIt = gACResults;
for (PRUint32 i = 0; i<gACCountResults; i++)
uint32_t count;
result->GetMatchCount(&count);
ACResult* acresult = count ? new ACResult(count) : nullptr;
for (PRUint32 i = 0; i<count; i++)
{
nsString nsStr;
nsCString nsCStr;
nsString nsStr, nsCStr;
result->GetValueAt(i, nsStr);
NS_UTF16ToCString(nsStr,NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,nsCStr);
m_ACIt->value = strdup(nsCStr.get());
result->GetCommentAt(i, nsStr);
NS_UTF16ToCString(nsStr,NS_CSTRING_ENCODING_NATIVE_FILESYSTEM,nsCStr);
m_ACIt->comment = strdup(nsCStr.get());
m_ACIt->score = 0;
m_ACIt++;
result->GetCommentAt(i, nsCStr);
acresult->AddTail(ACResultItem(NSStringToCString(nsStr), NSStringToCString(nsCStr)));
}
(*m_Callback)(gACResults, gACCountResults, m_data);
(*m_Callback)(acresult, m_data);
}
else
m_oldResult = nullptr;

199
k-meleon/urlbar.cpp

@ -98,6 +98,12 @@ void CACListBox::OnKillFocus(CWnd* pNewWnd)
ShowWindow(SW_HIDE);
((CUrlBarEdit*)m_edit)->StopACSession();
}
void CACListBox::ResetContent()
{
CListBox::ResetContent();
mResult.Free();
}
/*
void CACListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
@ -166,22 +172,26 @@ void CACListBox::OnMouseMove(UINT nFlags, CPoint point)
SetCurSel(ItemFromPoint(point, b));
}
void CACListBox::OnResult(AutoCompleteResult* results, int count)
void CACListBox::OnResult(ACResult* results)
{
ResetContent();
if (count && results)
mResult.Free();
mResult.Attach(results);
if (results && results->GetCount())
{
USES_CONVERSION;
if (theApp.preferences.GetBool("browser.urlbar.autoFill", false) && !m_bBack)
{
CString text,toSelect;
m_edit->GetWindowText(text);
AutoCompleteResult* r = results;
for (int i=0; i<count; i++) {
toSelect = A2CT(results[i].value);
POSITION pos = mResult.m_p->GetHeadPosition();
while (pos) {
ACResultItem& result = mResult.m_p->GetNext(pos);
toSelect = result.value;
if (toSelect.Left(7+text.GetLength()).Compare(CString(_T("http://")) + text) != 0)
continue;
int i;
toSelect.Delete(0, 7+text.GetLength());
if ( (i = toSelect.FindOneOf(_T("/?&=#"))) != -1) {
toSelect.GetBuffer(0);
@ -193,16 +203,26 @@ void CACListBox::OnResult(AutoCompleteResult* results, int count)
}
}
for (int i=0; i<count; i++)
{
AddString(A2CT(results->value));
if(i>100) break; // deadlock: prevent quiet crash at > 3800 lines
// TODO Limit size of autocomplete result
results++;
int i = 0;
POSITION pos = mResult->GetHeadPosition();
while (pos) {
POSITION tmp = pos;
ACResultItem& result = mResult->GetNext(pos);
int idx = AddString(W2CT(result.value));
SetItemDataPtr(idx, tmp);
if(i++>100) break;
}
int nLine = GetCount();
int height = GetItemHeight(0);
/*SIZE size;
CDC* pDC = GetDC();
HGDIOBJ old = pDC->SelectObject(m_font);
GetTextExtentPoint32(pDC->m_hDC, L"X", 1, &size);
height = size.cy;//pDC->DrawText(strText, -1, rect, DT_WORDBREAK | DT_CALCRECT);
pDC->SelectObject(old);
ReleaseDC(pDC);*/
CRect rec;
m_edit->GetParent()->GetWindowRect(rec);
@ -219,14 +239,14 @@ void CACListBox::OnResult(AutoCompleteResult* results, int count)
}
// I'm not sure what I'm missing but it works with that
nLine++;
//nLine++;
// Prevent the mouse to select an element when the
// autocomplete list popup.
if (!IsWindowVisible())
m_ignoreMousemove = 2;
SetWindowPos(&(CWnd::wndTop),rec.left,rec.bottom,rec.Width(),height*nLine,SWP_SHOWWINDOW);
SetWindowPos(&(CWnd::wndTop),rec.left,rec.bottom,rec.Width(),height*nLine+2,SWP_SHOWWINDOW);
}
else
{
@ -239,13 +259,102 @@ void CACListBox::OnResult(AutoCompleteResult* results, int count)
void CACListBox::AutoComplete(CString& text)
{
CACListener::AutoComplete(text, (AutoCompleteCallback)&CACListBox::ACCallback, this);
return;
}
USES_CONVERSION;
AutoCompleteResult *results = NULL;
int count = theApp.plugins.SendMessage("*", "Urlbar", "AutoComplete", (long)T2CA(text), (long)&results);
ResetContent();
OnResult(results, count);
void CACListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// TODO: Add your code to determine the size of specified item
ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);
CString strText;
GetText(lpMeasureItemStruct->itemID, strText);
ASSERT(TRUE != strText.IsEmpty());
CRect rect;
GetItemRect(lpMeasureItemStruct->itemID, &rect);
SIZE size;
CDC* pDC = GetDC();
HGDIOBJ old = pDC->SelectObject(m_font);
GetTextExtentPoint32(pDC->m_hDC, strText, wcslen(strText), &size);
int iconHeight = theApp.skin.GetDefHeight() + 4;
lpMeasureItemStruct->itemHeight = size.cy >= iconHeight ? size.cy : iconHeight;
pDC->SelectObject(old);
ReleaseDC(pDC);
}
void CACListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);
if (lpDrawItemStruct->itemAction == ODA_FOCUS)
return;
CString strText;
GetText(lpDrawItemStruct->itemID, strText);
//AutoCompleteResult* acResult = (AutoCompleteResult*)GetItemDataPtr(lpDrawItemStruct->itemID);
//ASSERT(NULL != acResult);
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);
//HGDIOBJ old = dc.SelectObject(m_font);
// Save these value to restore them when done drawing.
COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();
// If this item is selected, set the background color
// and the text color to appropriate values. Also, erase
// rect by filling it with the background color.
if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
(lpDrawItemStruct->itemState & ODS_SELECTED))
{
dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
dc.FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_HIGHLIGHT));
}
else
{
dc.SetTextColor(GetSysColor(COLOR_MENUTEXT));
dc.SetBkColor(GetSysColor(COLOR_MENU));
dc.FillSolidRect(&lpDrawItemStruct->rcItem, GetSysColor(COLOR_MENU));
}
// Draw Icon
lpDrawItemStruct->rcItem.left += 2;
CImageList* iconList = theApp.favicons.GetSizedList();
int topMargin = (lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top - theApp.skin.GetDefHeight()) / 2;
iconList->Draw(&dc, theApp.favicons.GetIcon(strText),
CPoint(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top + topMargin),
ILD_TRANSPARENT);
lpDrawItemStruct->rcItem.left += theApp.skin.GetDefWidth() + 2;
// Draw Url
RECT rc = lpDrawItemStruct->rcItem;
rc.right = (rc.right-rc.left)*7/10+rc.left;
dc.DrawText(strText, -1, &rc, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE|DT_WORD_ELLIPSIS);
// Draw Title
int urlSize = (lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left) * 66 / 100;
if (lpDrawItemStruct->itemData) {
ACResultItem& item = mResult->GetAt((POSITION)lpDrawItemStruct->itemData);
if (item.comment.GetLength()) {
rc.left = rc.right + 2;
rc.right = (lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left)*34/100+rc.left;
//SIZE size;
//GetTextExtentPoint32(dc.m_hDC, strText, strText.GetLength(), &size);
//rc.left += ((size.cx + 4) / 100 + 1) * 100;
//if (rc.left < rc.right) {
dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
dc.DrawText(item.comment, -1, &rc, DT_NOCLIP|DT_NOPREFIX|DT_SINGLELINE);
//}
}
}
// Reset the background color and the text color back to their
// original values.
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);
//dc.SelectObject(old);
dc.Detach();
}
/////////////////////////////////////////////////////////////////////////////
@ -339,7 +448,7 @@ void CUrlBarEdit::PreSubclassWindow()
if (!m_list->CreateEx(
WS_EX_TOPMOST|WS_EX_CONTROLPARENT|WS_EX_WINDOWEDGE,
_T("ListBox"),_T("AutoComplete List"),
LBS_NOTIFY|WS_VISIBLE|WS_CHILD|WS_BORDER|WS_VSCROLL,
LBS_OWNERDRAWVARIABLE|LBS_HASSTRINGS|LBS_NOTIFY|WS_VISIBLE|WS_CHILD|WS_BORDER|WS_VSCROLL,
CRect(0,0,0,0),
//GetDesktopWindow(),
GetParentFrame(),
@ -657,6 +766,54 @@ BEGIN_MESSAGE_MAP(CUrlBar, CComboBoxEx)
ON_CONTROL_REFLECT(CBN_SELCHANGE, OnCbnSelchange)
END_MESSAGE_MAP()
#include <locale.h>
int CUrlBar::Create(DWORD style, RECT &rect, CWnd *parentWnd, UINT id)
{
int ret = CComboBoxEx::Create(style | CBS_AUTOHSCROLL, rect, parentWnd, id);
SetExtendedStyle(/*CBES_EX_PATHWORDBREAKPROC|*/CBES_EX_CASESENSITIVE, CBES_EX_PATHWORDBREAKPROC|CBES_EX_CASESENSITIVE);
COMBOBOXEXITEM ci;
ci.mask = CBEIF_IMAGE;
ci.iItem = -1;
#ifdef INTERNAL_SITEICONS
ci.iImage = theApp.favicons.GetDefaultIcon();
#endif
SetItem(&ci);
LimitText(0);
CEdit *edit = GetEditCtrl();
if (!edit) return -1;
m_hwndEdit = edit->m_hWnd;
CString s = theApp.preferences.GetString("kmeleon.display.urlbar_fontsize", _T("1"));
char* old = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
double f = _wtof(s);
setlocale(LC_NUMERIC, old);
if (f != 1 && f>.5) {
ScaleFontSize(f);
}
// Bug #783
#ifdef URLBAR_USE_SETWORDBREAKPROC
edit->SendMessage(EM_SETWORDBREAKPROC, 0,
(LPARAM)&(CUrlBarEdit::UrlBreakProc));
// Subclassing edit box for autocomplete
if (theApp.preferences.GetBool("browser.urlbar.autocomplete.enabled", true))
m_UrlBarEdit.SubclassWindow(m_hwndEdit);
#else
//Subclassing edit box for autocomplete and ctrl navigation
//Making our own combo box would be better
m_UrlBarEdit.SubclassWindow(m_hwndEdit);
#endif
// Set the height of the dropdown
edit->GetClientRect(&rect);
int height = rect.bottom + 4 + GetItemHeight(0) * (theApp.preferences.GetInt("kmeleon.urlbar.dropdown_lines", 10));
GetComboBoxCtrl()->SetWindowPos(0,0,0,50,height,SWP_NOMOVE|SWP_NOZORDER);
return ret;
}
HBRUSH CUrlBar::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//pDC->SetBkMode(TRANSPARENT);

72
k-meleon/urlbar.h

@ -21,7 +21,15 @@
#pragma once
#include "mfcembed.h"
struct _AutoCompleteResult;
typedef struct _ACResultItem {
CString value;
CString comment;
int score;
_ACResultItem() {}
_ACResultItem(CString val, CString com, int s = 0) : value(val), comment(com), score(s) {}
} ACResultItem;
typedef CList<ACResultItem, ACResultItem&> ACResult;
extern CMfcEmbedApp theApp;
class CACListener;
@ -29,9 +37,12 @@ class CACListener;
class CACListBox : public CListBox
{
public:
CACListBox() {}
~CACListBox() {}
void Scroll(short dir, short q = 0);
void AutoComplete(CString&);
void OnResult(_AutoCompleteResult* result, int count);
void OnResult(ACResult* result);
void ResetContent();
BOOL m_bBack;
DECLARE_MESSAGE_MAP()
@ -39,16 +50,20 @@ public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
public:
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
protected:
CAutoPtr<ACResult> mResult;
CEdit *m_edit;
CFont m_font;
int m_ignoreMousemove;
static void CALLBACK ACCallback(_AutoCompleteResult* result, int count, void* self) {
((CACListBox*)self)->OnResult(result, count);
static void CALLBACK ACCallback(ACResult* result, void* self) {
((CACListBox*)self)->OnResult(result);
}
};
@ -110,44 +125,19 @@ public:
~CUrlBar(){
}
HWND m_hwndEdit;
int Create(DWORD style, RECT &rect, CWnd *parentWnd, UINT id) {
int ret = CComboBoxEx::Create(style | CBS_AUTOHSCROLL, rect, parentWnd, id);
SetExtendedStyle(/*CBES_EX_PATHWORDBREAKPROC|*/CBES_EX_CASESENSITIVE, CBES_EX_PATHWORDBREAKPROC|CBES_EX_CASESENSITIVE);
COMBOBOXEXITEM ci;
ci.mask = CBEIF_IMAGE;
ci.iItem = -1;
#ifdef INTERNAL_SITEICONS
ci.iImage = theApp.favicons.GetDefaultIcon();
#endif
SetItem(&ci);
LimitText(0);
CEdit *edit = GetEditCtrl();
if (!edit) return -1;
m_hwndEdit = edit->m_hWnd;
// Bug #783
#ifdef URLBAR_USE_SETWORDBREAKPROC
edit->SendMessage(EM_SETWORDBREAKPROC, 0,
(LPARAM)&(CUrlBarEdit::UrlBreakProc));
// Subclassing edit box for autocomplete
if (theApp.preferences.GetBool("browser.urlbar.autocomplete.enabled", true))
m_UrlBarEdit.SubclassWindow(m_hwndEdit);
#else
//Subclassing edit box for autocomplete and ctrl navigation
//Making our own combo box would be better
m_UrlBarEdit.SubclassWindow(m_hwndEdit);
#endif
void ScaleFontSize(float f) {
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
ncm.lfMenuFont.lfHeight = (LONG)floor(ncm.lfMenuFont.lfHeight*f);
m_font.DeleteObject();
m_font.CreateFontIndirect(&ncm.lfMenuFont);
SendMessage(WM_SETFONT, (WPARAM)(HFONT)m_font,1);
}
// Set the height of the dropdown
edit->GetClientRect(&rect);
int height = rect.bottom + 4 + GetItemHeight(0) * (theApp.preferences.GetInt("kmeleon.urlbar.dropdown_lines", 10));
GetComboBoxCtrl()->SetWindowPos(0,0,0,50,height,SWP_NOMOVE|SWP_NOZORDER);
return ret;
HWND m_hwndEdit;
}
int Create(DWORD style, RECT &rect, CWnd *parentWnd, UINT id);
inline CString GetEnteredURL(BOOL ignoreTyped = FALSE) {
if (!ignoreTyped) {
@ -267,7 +257,7 @@ protected:
BOOL m_changed;
CString m_currentURL;
CFont m_font;
CUrlBarEdit m_UrlBarEdit;
public:
DECLARE_MESSAGE_MAP()

Loading…
Cancel
Save