David Hedberg : shell32: Add a travellog to the ExplorerBrowser control.
Alexandre Julliard
julliard at winehq.org
Wed Aug 25 12:35:08 CDT 2010
Module: wine
Branch: master
Commit: fdccbd91af671a022b2e0b6f2d11c25c1b9cc906
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fdccbd91af671a022b2e0b6f2d11c25c1b9cc906
Author: David Hedberg <david.hedberg at gmail.com>
Date: Wed Aug 25 15:24:33 2010 +0200
shell32: Add a travellog to the ExplorerBrowser control.
---
dlls/shell32/ebrowser.c | 138 +++++++++++++++++++++++++++++++++++++++-
dlls/shell32/tests/ebrowser.c | 24 +++++++-
2 files changed, 156 insertions(+), 6 deletions(-)
diff --git a/dlls/shell32/ebrowser.c b/dlls/shell32/ebrowser.c
index 0d11d13..e753a79 100644
--- a/dlls/shell32/ebrowser.c
+++ b/dlls/shell32/ebrowser.c
@@ -43,6 +43,11 @@ typedef struct _event_client {
DWORD cookie;
} event_client;
+typedef struct _travellog_entry {
+ struct list entry;
+ LPITEMIDLIST pidl;
+} travellog_entry;
+
typedef struct _ExplorerBrowserImpl {
const IExplorerBrowserVtbl *lpVtbl;
const IShellBrowserVtbl *lpsbVtbl;
@@ -57,6 +62,9 @@ typedef struct _ExplorerBrowserImpl {
struct list event_clients;
DWORD events_next_cookie;
+ struct list travellog;
+ travellog_entry *travellog_cursor;
+ int travellog_count;
IShellView *psv;
RECT sv_rc;
@@ -140,6 +148,99 @@ static void events_ViewCreated(ExplorerBrowserImpl *This, IShellView *psv)
}
/**************************************************************************
+ * Travellog functions.
+ */
+static void travellog_remove_entry(ExplorerBrowserImpl *This, travellog_entry *entry)
+{
+ TRACE("Removing %p\n", entry);
+
+ list_remove(&entry->entry);
+ HeapFree(GetProcessHeap(), 0, entry);
+ This->travellog_count--;
+}
+
+static void travellog_remove_all_entries(ExplorerBrowserImpl *This)
+{
+ travellog_entry *cursor, *cursor2;
+ TRACE("%p\n", This);
+
+ LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
+ travellog_remove_entry(This, cursor);
+
+ This->travellog_cursor = NULL;
+}
+
+static void travellog_add_entry(ExplorerBrowserImpl *This, LPITEMIDLIST pidl)
+{
+ travellog_entry *new, *cursor, *cursor2;
+ TRACE("%p (old count %d)\n", pidl, This->travellog_count);
+
+ /* Replace the old tail, if any, with the new entry */
+ if(This->travellog_cursor)
+ {
+ LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, &This->travellog, travellog_entry, entry)
+ {
+ if(cursor == This->travellog_cursor)
+ break;
+ travellog_remove_entry(This, cursor);
+ }
+ }
+
+ /* Create and add the new entry */
+ new = HeapAlloc(GetProcessHeap(), 0, sizeof(travellog_entry));
+ new->pidl = ILClone(pidl);
+ list_add_tail(&This->travellog, &new->entry);
+ This->travellog_cursor = new;
+ This->travellog_count++;
+
+ /* Remove the first few entries if the size limit is reached. */
+ if(This->travellog_count > 200)
+ {
+ UINT i = 0;
+ LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, &This->travellog, travellog_entry, entry)
+ {
+ if(i++ > 10)
+ break;
+ travellog_remove_entry(This, cursor);
+ }
+ }
+}
+
+static LPCITEMIDLIST travellog_go_back(ExplorerBrowserImpl *This)
+{
+ travellog_entry *prev;
+ TRACE("%p, %p\n", This, This->travellog_cursor);
+
+ if(!This->travellog_cursor)
+ return NULL;
+
+ prev = LIST_ENTRY(list_prev(&This->travellog, &This->travellog_cursor->entry),
+ travellog_entry, entry);
+ if(!prev)
+ return NULL;
+
+ This->travellog_cursor = prev;
+ return prev->pidl;
+}
+
+static LPCITEMIDLIST travellog_go_forward(ExplorerBrowserImpl *This)
+{
+ travellog_entry *next;
+ TRACE("%p, %p\n", This, This->travellog_cursor);
+
+ if(!This->travellog_cursor)
+ return NULL;
+
+ next = LIST_ENTRY(list_next(&This->travellog, &This->travellog_cursor->entry),
+ travellog_entry, entry);
+ if(!next)
+ return NULL;
+
+ This->travellog_cursor = next;
+ return next->pidl;
+}
+
+/**************************************************************************
* Helper functions
*/
static void update_layout(ExplorerBrowserImpl *This)
@@ -386,6 +487,7 @@ static HRESULT WINAPI IExplorerBrowser_fnDestroy(IExplorerBrowser *iface)
}
events_unadvise_all(This);
+ travellog_remove_all_entries(This);
ILFree(This->current_pidl);
This->current_pidl = NULL;
@@ -520,9 +622,6 @@ static HRESULT WINAPI IExplorerBrowser_fnGetOptions(IExplorerBrowser *iface,
return S_OK;
}
-static const UINT unsupported_browse_flags =
- SBSP_NAVIGATEBACK | SBSP_NAVIGATEFORWARD | SBSP_NEWBROWSER |
- EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
PCUIDLIST_RELATIVE pidl,
UINT uFlags)
@@ -530,6 +629,8 @@ static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
ExplorerBrowserImpl *This = (ExplorerBrowserImpl*)iface;
LPITEMIDLIST absolute_pidl = NULL;
HRESULT hr;
+ static const UINT unsupported_browse_flags =
+ SBSP_NEWBROWSER | EBF_SELECTFROMDATAOBJECT | EBF_NODROPTARGET;
TRACE("%p (%p, 0x%x)\n", This, pidl, uFlags);
if(!This->hwnd_main)
@@ -547,7 +648,27 @@ static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
if(uFlags & unsupported_browse_flags)
FIXME("Argument 0x%x contains unsupported flags.\n", uFlags);
- if(uFlags & SBSP_PARENT)
+ if(uFlags & SBSP_NAVIGATEBACK)
+ {
+ TRACE("SBSP_NAVIGATEBACK\n");
+ absolute_pidl = ILClone(travellog_go_back(This));
+ if(!absolute_pidl && !This->current_pidl)
+ return E_FAIL;
+ else if(!absolute_pidl)
+ return S_OK;
+
+ }
+ else if(uFlags & SBSP_NAVIGATEFORWARD)
+ {
+ TRACE("SBSP_NAVIGATEFORWARD\n");
+ absolute_pidl = ILClone(travellog_go_forward(This));
+ if(!absolute_pidl && !This->current_pidl)
+ return E_FAIL;
+ else if(!absolute_pidl)
+ return S_OK;
+
+ }
+ else if(uFlags & SBSP_PARENT)
{
if(This->current_pidl)
{
@@ -618,6 +739,14 @@ static HRESULT WINAPI IExplorerBrowser_fnBrowseToIDList(IExplorerBrowser *iface,
IShellItem_Release(psi);
return E_FAIL;
}
+
+ /* Add to travellog */
+ if( !(This->eb_options & EBO_NOTRAVELLOG) &&
+ !(uFlags & (SBSP_NAVIGATEFORWARD|SBSP_NAVIGATEBACK)) )
+ {
+ travellog_add_entry(This, absolute_pidl);
+ }
+
IShellItem_Release(psi);
}
}
@@ -928,6 +1057,7 @@ HRESULT WINAPI ExplorerBrowser_Constructor(IUnknown *pUnkOuter, REFIID riid, voi
eb->lpsbVtbl = &vt_IShellBrowser;
list_init(&eb->event_clients);
+ list_init(&eb->travellog);
ret = IExplorerBrowser_QueryInterface((IExplorerBrowser*)eb, riid, ppv);
IExplorerBrowser_Release((IExplorerBrowser*)eb);
diff --git a/dlls/shell32/tests/ebrowser.c b/dlls/shell32/tests/ebrowser.c
index 442d8dc..809a7fc 100644
--- a/dlls/shell32/tests/ebrowser.c
+++ b/dlls/shell32/tests/ebrowser.c
@@ -811,14 +811,34 @@ static void test_navigation(void)
test_browse_pidl_sb(peb2, &ebev, 0, SBSP_RELATIVE, E_FAIL, 0, 0, 0, 0);
test_browse_pidl(peb, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
test_browse_pidl_sb(peb2, &ebev, 0, SBSP_PARENT, E_FAIL, 0, 0, 0, 0);
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEFORWARD, E_FAIL, 0, 0, 0, 0);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEFORWARD, E_FAIL, 0, 0, 0, 0);
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEBACK, E_FAIL, 0, 0, 0, 0);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEBACK, E_FAIL, 0, 0, 0, 0);
/* "The first browse is synchronous" */
test_browse_pidl(peb, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
test_browse_pidl_sb(peb2, &ebev, pidl_child, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+ /* Navigate empty history */
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEFORWARD, S_OK, 0, 0, 0, 0);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEFORWARD, S_OK, 0, 0, 0, 0);
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEBACK, S_OK, 0, 0, 0, 0);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEBACK, S_OK, 0, 0, 0, 0);
+
+ /* Navigate history */
+ test_browse_pidl(peb, &ebev, 0, SBSP_PARENT, S_OK, 1, 1, 0, 1);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_PARENT, S_OK, 1, 1, 0, 1);
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEBACK, S_OK, 1, 1, 0, 1);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEBACK, S_OK, 1, 1, 0, 1);
+ test_browse_pidl(peb, &ebev, 0, SBSP_NAVIGATEFORWARD, S_OK, 1, 1, 0, 1);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_NAVIGATEFORWARD, S_OK, 1, 1, 0, 1);
+ test_browse_pidl(peb, &ebev, 0, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
+ test_browse_pidl_sb(peb2, &ebev, 0, SBSP_ABSOLUTE, S_OK, 0, 0, 0, 0);
+
/* Relative navigation */
- test_browse_pidl(peb, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
- test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 1, 0, 1);
+ test_browse_pidl(peb, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 0, 0, 1);
+ test_browse_pidl_sb(peb2, &ebev, pidl_current, SBSP_ABSOLUTE, S_OK, 1, 0, 0, 1);
hr = IExplorerBrowser_GetCurrentView(peb, &IID_IFolderView, (void**)&pfv);
ok(hr == S_OK, "Got 0x%08x\n", hr);
More information about the wine-cvs
mailing list