summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2009-07-23 11:23:34 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2009-07-23 11:23:34 +0000
commitb20949a35025b23da1bf0ac6003f4575eb94281d (patch)
treee40a951548d0224f1027c567ab621dd275f8c3bd
parentdffc8779ed8b1c1c2daa2f864897588df80e50b1 (diff)
downloadnetsurf-b20949a35025b23da1bf0ac6003f4575eb94281d.tar.gz
netsurf-b20949a35025b23da1bf0ac6003f4575eb94281d.tar.bz2
Replace URL bar with custom StringView class. Thanks to Stephen Fellner, Rene W Olsen
and Joerg Strohmayer. svn path=/trunk/netsurf/; revision=8723
-rw-r--r--Makefile.sources3
-rwxr-xr-xamiga/gui.c27
-rwxr-xr-xamiga/gui.h1
-rwxr-xr-xamiga/stringview/stringview.c868
-rwxr-xr-xamiga/stringview/stringview.h58
-rw-r--r--amiga/stringview/urlhistory.c116
-rw-r--r--amiga/stringview/urlhistory.h33
7 files changed, 1104 insertions, 2 deletions
diff --git a/Makefile.sources b/Makefile.sources
index 77f97a567..e3404739d 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -84,7 +84,8 @@ S_AMIGA := compat.c gui.c tree.c history.c hotlist.c schedule.c \
plotters.c object.c menu.c save_pdf.c arexx.c version.c \
cookies.c context_menu.c clipboard.c save_complete.c \
fetch_file.c fetch_mailto.c search.c history_local.c \
- download.c iff_dr2d.c sslcert.c gui_options.c
+ download.c iff_dr2d.c sslcert.c gui_options.c \
+ stringview/stringview.c stringview/urlhistory.c
S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
# S_FRAMEBUFFER are sources purely for the framebuffer build
diff --git a/amiga/gui.c b/amiga/gui.c
index 87801ee85..f36f4a5df 100755
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -77,6 +77,9 @@
#include "amiga/gui_options.h"
#include "amiga/bitmap.h"
+#include "amiga/stringview/stringview.h"
+#include "amiga/stringview/urlhistory.h"
+
#ifdef NS_AMIGA_CAIRO
#include <cairo/cairo-amigaos.h>
#endif
@@ -113,6 +116,8 @@ struct PopupMenuIFace *IPopupMenu = NULL;
struct Library *KeymapBase = NULL;
struct KeymapIFace *IKeymap = NULL;
+Class *urlStringClass;
+
struct BitMap *throbber = NULL;
ULONG throbber_width,throbber_height,throbber_frames,throbber_update_interval;
BOOL rmbtrapped;
@@ -261,6 +266,8 @@ void gui_init(int argc, char** argv)
IKeymap = (struct KeymapIFace *)GetInterface(KeymapBase,"main",1,NULL);
}
+ urlStringClass = MakeStringClass();
+
ami_clipboard_init();
win_destroyed = false;
@@ -1560,6 +1567,7 @@ void gui_quit(void)
FreeAslRequest(savereq);
ami_openurl_close();
+ FreeStringClass(urlStringClass);
if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu);
if(PopupMenuBase) CloseLibrary(PopupMenuBase);
@@ -1815,6 +1823,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
gwin->shared->tabs=1;
gwin->shared->next_tab=1;
+ gwin->shared->svbuffer = AllocVec(2000, MEMF_CLEAR);
+
ami_get_theme_filename(nav_west,"theme_nav_west");
ami_get_theme_filename(nav_west_s,"theme_nav_west_s");
ami_get_theme_filename(nav_west_g,"theme_nav_west_g");
@@ -1944,10 +1954,22 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
ButtonEnd,
CHILD_WeightedWidth,0,
CHILD_WeightedHeight,0,
- LAYOUT_AddChild, gwin->shared->gadgets[GID_URL] = StringObject,
+ LAYOUT_AddChild, gwin->shared->gadgets[GID_URL] =
+ NewObject(urlStringClass, NULL,
+ STRINGA_MaxChars, 2000,
+ GA_ID, GID_URL,
+ GA_RelVerify, TRUE,
+ GA_TabCycle, TRUE,
+ STRINGA_Buffer, gwin->shared->svbuffer,
+ STRINGVIEW_Header, URLHistory_GetList(),
+// STRINGA_TextVal, NULL,
+ StringEnd,
+/*
+ StringObject,
GA_ID,GID_URL,
GA_RelVerify,TRUE,
StringEnd,
+*/
LAYOUT_AddChild, gwin->shared->gadgets[GID_THROBBER] = SpaceObject,
GA_ID,GID_THROBBER,
SPACE_MinWidth,throbber_width,
@@ -2152,6 +2174,9 @@ void gui_window_destroy(struct gui_window *g)
curbw = NULL;
DisposeObject(g->shared->objects[OID_MAIN]);
+
+ FreeVec(g->shared->svbuffer);
+
DelObject(g->shared->node);
if(g->tab_node)
{
diff --git a/amiga/gui.h b/amiga/gui.h
index 51b18230c..801be5751 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -97,6 +97,7 @@ struct gui_window_2 {
ULONG oldv;
bool redraw_scroll;
bool new_content;
+ char *svbuffer;
};
struct gui_window
diff --git a/amiga/stringview/stringview.c b/amiga/stringview/stringview.c
new file mode 100755
index 000000000..2d99c1751
--- /dev/null
+++ b/amiga/stringview/stringview.c
@@ -0,0 +1,868 @@
+/*
+ * Copyright 2009 Rene W. Olsen <ac@rebels.com>
+ * Copyright 2009 Stephen Fellner <sf.amiga@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/// Include
+
+#include <proto/dos.h>
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/layout.h>
+#include <proto/listbrowser.h>
+#include <proto/utility.h>
+#include <proto/string.h>
+#include <proto/window.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/listbrowser.h>
+
+#include "stringview.h"
+#include "urlhistory.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define End TAG_END)
+
+///
+
+/// Proto
+
+static void myStringOpenListview( Class *cl, Object *obj, struct gpInput *msg );
+static void myStringCloseListview( Class *cl, Object *obj );
+static uint32 myStringSearch( Class *cl, Object *obj );
+static void myStringArrowUp( Class *cl, Object *obj );
+static void myStringArrowDown( Class *cl, Object *obj );
+static void myStringHandleListview( Class *cl, Object *obj );
+
+///
+
+/* -- Internal -- */
+
+/// myStringOpenListview
+
+static void myStringOpenListview( Class *cl, Object *obj, struct gpInput *msg )
+{
+struct myStringClassData *data;
+struct Gadget *gad;
+
+ data = INST_DATA( cl, obj );
+
+ gad = (struct Gadget *)obj;
+
+ SetAttrs( data->WindowObject,
+ WA_CustomScreen, msg->gpi_GInfo->gi_Window->WScreen,
+ WA_Left, data->WinXPos,
+ WA_Top, data->WinYPos,
+ WA_Width, data->WinWidth,
+ WA_Height, data->WinHeight,
+ TAG_END
+ );
+
+// IDoMethod( data->WindowObject, WM_RETHINK );
+
+ data->Window = (struct Window *)IDoMethod( data->WindowObject, WM_OPEN );
+
+ if ( data->Window == NULL )
+ {
+ goto bailout;
+ }
+
+// GetAttr( WINDOW_SigMask, MainWindowObject, &MainWindowBits );
+
+bailout:
+
+ return;
+}
+
+///
+/// myStringCloseListview
+
+static void myStringCloseListview( Class *cl, Object *obj )
+{
+struct myStringClassData *data;
+struct Node *node;
+
+ data = INST_DATA( cl, obj );
+
+ if ( data->Window )
+ {
+ IDoMethod( data->WindowObject, WM_CLOSE );
+ data->Window = NULL;
+ }
+
+ while(( node = RemHead( &data->ListviewHeader )))
+ {
+ FreeListBrowserNode( node );
+ }
+}
+
+///
+/// myStringSearch
+
+static uint32 myStringSearch( Class *cl, Object *obj )
+{
+ struct myStringClassData *data;
+ struct Window *win;
+ struct Node *node;
+ struct Node *n;
+ uint32 found;
+ uint32 bufpos;
+ STRPTR searchString;
+ STRPTR compString;
+
+ found = 0;
+
+ data = INST_DATA( cl, obj );
+
+ win = data->Window;
+
+ // Remove List and Free Nodes
+
+ SetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
+ LISTBROWSER_Labels, ~0,
+ TAG_END
+ );
+
+ while(( node = RemHead( &data->ListviewHeader )))
+ {
+ FreeListBrowserNode( node );
+ }
+
+ GetAttr( STRINGA_BufferPos, obj, &bufpos );
+
+ if ( bufpos == 0 )
+ {
+ goto bailout;
+ }
+
+//-------------
+
+ searchString = strstr(data->SearchBuffer, "://");
+ if(searchString)
+ {
+ searchString += 3;
+ if (bufpos >= searchString - data->SearchBuffer)
+ bufpos -= searchString - data->SearchBuffer;
+ }
+ else
+ searchString = data->SearchBuffer;
+
+ node = GetHead( data->SearchHeader );
+
+ while( node )
+ {
+ uint32 srcpos;
+ BOOL possible;
+
+ possible = FALSE;
+ srcpos = 0;
+
+ compString = strstr(node->ln_Name, "://");
+ if(compString)
+ compString += 3;
+ else
+ compString = node->ln_Name;
+
+ if( 0 == strncasecmp( compString, searchString, bufpos ) )
+ {
+ // found match after protocol
+ possible = TRUE;
+ }
+ else
+ {
+ // no match after protocol, see if there's a match after www
+ if( 0 == strncasecmp( compString, "www.", 4) ) {
+ // got www, compare it!
+ if( 0 == strncasecmp( &compString[4], searchString, bufpos ) )
+ possible = TRUE;
+ }
+ }
+
+ if ( possible == TRUE )
+ {
+ n = AllocListBrowserNode( 1,
+ LBNA_Column, 0,
+ LBNCA_CopyText, TRUE,
+ LBNCA_Text, node->ln_Name,
+ TAG_END
+ );
+
+ if ( n )
+ {
+ AddTail( &data->ListviewHeader, n );
+ found++;
+ }
+ }
+
+ node = GetSucc( node );
+ }
+
+//-------------
+
+bailout:
+
+ data->ListviewCount = found;
+ data->ListviewSelected = -1;
+
+ // Add List Again
+
+ RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
+ LISTBROWSER_Labels, &data->ListviewHeader,
+ LISTBROWSER_Selected, data->ListviewSelected,
+ LISTBROWSER_MakeVisible, 0,
+ TAG_END
+ );
+
+ return( found );
+}
+
+///
+/// myStringArrowUp
+
+static void myStringArrowUp( Class *cl, Object *obj )
+{
+struct myStringClassData *data;
+struct Window *win;
+//struct Node *node;
+//uint32 cnt;
+
+ data = INST_DATA( cl, obj );
+
+ win = data->Window;
+
+ if ( data->ListviewCount == 0 )
+ {
+ data->ListviewSelected = -1;
+ goto bailout;
+ }
+ else if (( data->ListviewSelected != -1 ) && ( data->ListviewSelected != 0 ))
+ {
+ data->ListviewSelected--;
+ }
+
+ RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
+ LISTBROWSER_Selected, data->ListviewSelected,
+ LISTBROWSER_MakeVisible, data->ListviewSelected,
+ TAG_END
+ );
+
+// cnt = data->ListviewSelected;
+// node = GetHead( data->SearchHeader );
+//
+// while( cnt-- > 0 )
+// {
+// node = GetSucc( node );
+// }
+//
+// if ( node )
+// {
+// ISetSuperAttrs( obj,
+//
+// TAG_END
+// );
+// }
+
+bailout:
+
+ return;
+}
+
+///
+/// myStringArrowDown
+
+static void myStringArrowDown( Class *cl, Object *obj )
+{
+struct myStringClassData *data;
+struct Window *win;
+
+ data = INST_DATA( cl, obj );
+
+ win = data->Window;
+
+ if ( data->ListviewCount == 0 )
+ {
+ data->ListviewSelected = -1;
+ }
+ else if ( data->ListviewSelected == -1 )
+ {
+ data->ListviewSelected = 0;
+ }
+ else if ( data->ListviewSelected != data->ListviewCount - 1 )
+ {
+ data->ListviewSelected++;
+ }
+
+ RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
+ LISTBROWSER_Selected, data->ListviewSelected,
+ LISTBROWSER_MakeVisible, data->ListviewSelected,
+ TAG_END
+ );
+}
+
+///
+/// myStringHandleListview
+
+static void myStringHandleListview( Class *cl, Object *obj )
+{
+struct myStringClassData *data;
+uint32 result;
+uint16 code;
+
+ data = INST_DATA( cl, obj );
+
+ while(( result = IDoMethod( data->WindowObject, WM_HANDLEINPUT, &code )) != WMHI_LASTMSG )
+ {
+// switch( result & WMHI_CLASSMASK )
+// {
+// case WMHI_CLOSEWINDOW:
+// {
+// running = FALSE;
+// break;
+// }
+//
+// default:
+// {
+// break;
+// }
+// }
+ }
+}
+
+///
+
+/* BOOPSI methods */
+
+/// myStringClass_OM_New
+
+uint32 myStringClass_OM_New( Class *cl, Object *obj, struct opSet *msg )
+{
+ struct myStringClassData *data;
+ struct List *header;
+ struct TagItem *tag, *tags;
+ STRPTR buffer;
+
+ buffer = NULL;
+ header = NULL;
+
+ tags = msg->ops_AttrList;
+
+ while(( tag = NextTagItem( &tags )))
+ {
+ switch ( tag->ti_Tag )
+ {
+ case STRINGVIEW_Header:
+ {
+ header = (struct List *)tag->ti_Data;
+ break;
+ }
+
+ case STRINGA_Buffer:
+ {
+ buffer = (STRPTR)tag->ti_Data;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if (( header == NULL ) || ( buffer == NULL ))
+ {
+ return( 0 );
+ }
+
+ obj = (Object *)IDoSuperMethodA( cl, obj, (APTR)msg );
+
+ if ( obj == NULL )
+ {
+ goto bailout;
+ }
+
+ if ( obj )
+ {
+ data = INST_DATA( cl, obj );
+
+ data->SearchHeader = header;
+ data->SearchBuffer = buffer;
+
+ NewList( &data->ListviewHeader );
+
+ InitSemaphore( &data->Semaphore );
+
+ data->WindowObject = NewObject( WINDOW_GetClass(), NULL,
+ WA_Activate, FALSE,
+ WA_Borderless, TRUE,
+ WINDOW_ParentGroup, NewObject( LAYOUT_GetClass(), NULL,
+ LAYOUT_SpaceInner, FALSE,
+ LAYOUT_SpaceOuter, FALSE,
+ LAYOUT_AddChild, data->ListviewObject = NewObject( LISTBROWSER_GetClass(), NULL,
+ LISTBROWSER_Labels, &data->ListviewHeader,
+ LISTBROWSER_MakeVisible, TRUE,
+ LISTBROWSER_ShowSelected, TRUE,
+ End,
+ End,
+ End;
+
+ if ( data->WindowObject == NULL )
+ {
+ goto bailout;
+ }
+ }
+
+ return( (uint32)obj );
+
+bailout:
+
+ if ( obj )
+ {
+ ICoerceMethod( cl, obj, OM_DISPOSE );
+ }
+
+ return( FALSE );
+}
+
+///
+/// myStringClass_OM_Dispose
+
+uint32 myStringClass_OM_Dispose( Class *cl, Object *obj, struct opSet *msg )
+{
+struct myStringClassData *data;
+
+ data = INST_DATA( cl, obj );
+
+ if ( data->Window )
+ {
+ IDoMethod( data->WindowObject, WM_CLOSE );
+ data->Window = NULL;
+ }
+
+ if ( data->WindowObject )
+ {
+ DisposeObject( data->WindowObject );
+ data->WindowObject = NULL;
+ }
+
+ return( IDoSuperMethodA( cl, obj, (APTR)msg ));
+}
+
+///
+/// myStringClass_OM_Set
+
+//--uint32 myStringClass_OM_Set( Class *cl, Object *obj, struct opSet *msg )
+//--{
+//--struct TorrentClassData *data;
+//--struct TagItem *tag, *tags;
+//--tr_stat_t *tor_s;
+//--
+//-- data = INST_DATA( cl, obj );
+//--
+//-- tags = msg->ops_AttrList;
+//--
+//-- while(( tag = NextTagItem( &tags )))
+//-- {
+//-- switch ( tag->ti_Tag )
+//-- {
+//-- case RAA_Torrent_Stats:
+//-- {
+//-- tor_s = (tr_stat_t *)tag->ti_Data;
+//--
+//-- switch( data->Type )
+//-- {
+//-- case TorType_BitTorrent5:
+//-- {
+//-- BitTorrent5_Stat( data, tor_s );
+//-- break;
+//-- }
+//--
+//-- case TorType_Transmission:
+//-- {
+//-- Transmission_Stat( data, tor_s );
+//-- break;
+//-- }
+//--
+//-- default:
+//-- {
+//-- break;
+//-- }
+//-- }
+//-- break;
+//-- }
+//--
+//-- case RAA_Torrent_Activate:
+//-- {
+//-- switch( data->Type )
+//-- {
+//-- case TorType_BitTorrent5:
+//-- {
+//-- if ( tag->ti_Data == TRUE )
+//-- {
+//-- BitTorrent5_Enable( data );
+//-- }
+//-- else
+//-- {
+//-- BitTorrent5_Disable( data );
+//-- }
+//-- break;
+//-- }
+//--
+//-- case TorType_Transmission:
+//-- {
+//-- if ( tag->ti_Data == TRUE )
+//-- {
+//-- Transmission_Enable( data );
+//-- }
+//-- else
+//-- {
+//-- Transmission_Disable( data );
+//-- }
+//-- break;
+//-- }
+//--
+//-- default:
+//-- {
+//-- break;
+//-- }
+//-- }
+//-- break;
+//-- }
+//--
+//-- default:
+//-- {
+//-- break;
+//-- }
+//-- }
+//-- }
+//--
+//-- return( IDoSuperMethodA( cl, obj, (Msg)msg ));
+//--}
+
+///
+
+/// myStringClass_GM_HandleInput
+
+static uint32 myStringClass_GM_HandleInput( Class *cl, Object *obj, struct gpInput *msg )
+{
+ struct myStringClassData *data;
+ struct Gadget *gad;
+ uint32 retval;
+
+ data = INST_DATA( cl, obj );
+
+ gad = (struct Gadget *)obj;
+
+ //IDoMethod( data->ListviewObject, (APTR)msg );
+
+ if (( gad->Flags & GFLG_SELECTED ) == 0 )
+ {
+ return( GMR_NOREUSE );
+ }
+
+ switch( msg->gpi_IEvent->ie_Class )
+ {
+ case IECLASS_RAWKEY:
+ {
+ switch( msg->gpi_IEvent->ie_Code )
+ {
+ case 0x48: // Page Up (DownKey)
+ case 0x4c: // Up Arrow (DownKey)
+ {
+ myStringArrowUp( cl, obj );
+
+ retval = GMR_MEACTIVE;
+
+ break;
+ }
+
+ case 0x49: // Page Down (DownKey)
+ case 0x4d: // Down Arrow (DownKey)
+ {
+ myStringArrowDown( cl, obj );
+
+ retval = GMR_MEACTIVE;
+
+ break;
+ }
+
+// case 70: // Del
+// case 65: // Backspace
+// {
+// myStringCloseListview( cl, obj );
+//
+// retval = IDoSuperMethodA( cl, obj, (APTR)msg );
+// break;
+// }
+
+ case 68: // Return
+ {
+ // If listview open, and an item is selected, copy selected node's text to the string gadget
+ if( data->Window != NULL && data->ListviewCount > 0 )
+ {
+ struct Node *selected = NULL;
+ STRPTR pText;
+ GetAttr( LISTBROWSER_SelectedNode, data->ListviewObject, (uint32 *) ( &selected ) );
+ if( selected != NULL )
+ {
+ GetListBrowserNodeAttrs( selected, LBNA_Column, 0, LBNCA_Text, &pText, TAG_END );
+ SetGadgetAttrs( (struct Gadget *)obj, data->Window, NULL, STRINGA_TextVal, pText, TAG_DONE );
+ }
+ }
+
+ retval = IDoSuperMethodA( cl, obj, (APTR)msg );
+ break;
+ }
+
+ default:
+ {
+ uint32 oldpos;
+ uint32 newpos;
+
+ GetAttr( STRINGA_BufferPos, obj, &oldpos );
+
+ retval = IDoSuperMethodA( cl, obj, (APTR)msg );
+
+ GetAttr( STRINGA_BufferPos, obj, &newpos );
+
+ if ( oldpos != newpos )
+ {
+ if ( myStringSearch( cl, obj ))
+ {
+ // Atleast one entry found, open window if not open
+ if ( data->Window == NULL )
+ {
+ myStringOpenListview( cl, obj, msg );
+ }
+ }
+ else
+ {
+ // No matches, migth aswell close the window
+ myStringCloseListview( cl, obj );
+ }
+ }
+ break;
+ }
+ }
+
+ myStringHandleListview( cl, obj );
+ break;
+ }
+
+ case IECLASS_MOUSEWHEEL:
+ {
+ struct InputEvent *ie = msg->gpi_IEvent;
+
+ if ( ie->ie_Y < 0 )
+ {
+ myStringArrowUp( cl, obj );
+ }
+ else if ( ie->ie_Y > 0 )
+ {
+ myStringArrowDown( cl, obj );
+ }
+
+ myStringHandleListview( cl, obj );
+
+ retval = GMR_MEACTIVE;
+ break;
+ }
+
+ default:
+ {
+ retval = IDoSuperMethodA( cl, obj, (APTR)msg );
+ break;
+ }
+ }
+
+ return( retval );
+}
+
+///
+/// myStringClass_GM_GoActive
+
+static uint32 myStringClass_GM_GoActive( Class *cl, Object *obj, struct gpInput *msg )
+{
+struct myStringClassData *data;
+struct Window *win;
+struct Gadget *gad;
+uint32 retval;
+
+ data = INST_DATA( cl, obj );
+
+ gad = (struct Gadget *)obj;
+
+ if ( gad->Flags & GFLG_DISABLED )
+ {
+ myStringCloseListview( cl, obj );
+
+ retval = GMR_NOREUSE;
+ }
+ else
+ {
+ // If were not Disabled then set Selected flag
+ gad->Flags |= GFLG_SELECTED;
+
+ win = msg->gpi_GInfo->gi_Window;
+
+ if ( win )
+ {
+ data->WinXPos = win->LeftEdge + gad->LeftEdge;
+ data->WinYPos = win->TopEdge + gad->TopEdge + gad->Height - 1;
+ data->WinWidth = gad->Width;
+ data->WinHeight = 150;
+ }
+
+ if ( myStringSearch( cl, obj ))
+ {
+ // Atleast one entry found, open window if not open
+ if ( data->Window == NULL )
+ {
+ myStringOpenListview( cl, obj, msg );
+ }
+ }
+ else
+ {
+ // No matches, migth aswell close the window
+ myStringCloseListview( cl, obj );
+ }
+
+ retval = IDoSuperMethodA( cl, obj, (APTR)msg );
+ }
+
+ return( retval );
+}
+
+///
+/// myStringClass_GM_GoInactive
+
+static uint32 myStringClass_GM_GoInactive( Class *cl, Object *obj, struct gpGoInactive *msg )
+{
+struct myStringClassData *data;
+
+ data = INST_DATA( cl, obj );
+
+ myStringCloseListview( cl, obj );
+
+ return( IDoSuperMethodA( cl, obj, (APTR)msg ));
+}
+
+///
+
+/* Dispatcher */
+
+/// myStringClassDispatcher
+
+uint32 myStringClassDispatcher( Class *cl, Object *obj, Msg msg )
+{
+struct myStringClassData *data;
+uint32 ret;
+
+ if ( msg->MethodID == OM_NEW )
+ {
+ return( myStringClass_OM_New( cl, obj, (APTR)msg ));
+ }
+ else if ( msg->MethodID == OM_DISPOSE )
+ {
+ return( myStringClass_OM_Dispose( cl, obj, (APTR)msg ));
+ }
+ else
+ {
+ data = INST_DATA( cl, obj );
+
+ ObtainSemaphore( &data->Semaphore );
+
+ switch( msg->MethodID )
+ {
+ /* BOOPSI methods */
+ case OM_SET:
+ {
+ struct TagItem *tag, *tags;
+ struct opSet *opSet = (struct opSet *)msg;
+ tags = opSet->ops_AttrList;
+ while ((tag = NextTagItem(&tags)))
+ {
+ if (STRINGA_TextVal == tag->ti_Tag)
+ {
+ URLHistory_AddPage((const char *)tag->ti_Data);
+ }
+ }
+
+ ret = IDoSuperMethodA(cl, obj, (APTR)msg);
+ }
+ break;
+
+// case OM_SET: ret = TorrentClass_OM_Set( cl, obj, (APTR)msg ); break;
+
+ /* Only used for Gadgets */
+// case GM_DOMAIN: ret = myStringClass_GM_Domain( cl, obj, (APTR)msg ); break;
+// case GM_LAYOUT: ret = myStringClass_GM_Layout( cl, obj, (APTR)msg ); break;
+// case GM_CLIPRECT: ret = myStringClass_GM_ClipRect( cl, obj, (APTR)msg ); break;
+// case GM_EXTENT: ret = myStringClass_GM_Extent( cl, obj, (APTR)msg ); break;
+// case GM_RENDER: ret = myStringClass_GM_Render( cl, obj, (APTR)msg ); break;
+// case GM_HITTEST: ret = myStringClass_GM_HitTest( cl, obj, (APTR)msg ); break;
+ case GM_HANDLEINPUT: ret = myStringClass_GM_HandleInput( cl, obj, (APTR)msg ); break;
+ case GM_GOACTIVE: ret = myStringClass_GM_GoActive( cl, obj, (APTR)msg ); break;
+ case GM_GOINACTIVE: ret = myStringClass_GM_GoInactive( cl, obj, (APTR)msg ); break;
+
+ /* Unknown method -> delegate to SuperClass */
+ default: ret = IDoSuperMethodA( cl, obj, (APTR)msg ); break;
+ }
+
+ ReleaseSemaphore( &data->Semaphore );
+
+ return( ret );
+ }
+}
+
+///
+
+/* Create Class */
+
+/// Make String Class
+
+Class *MakeStringClass( void )
+{
+ Class *cl;
+ cl = MakeClass( NULL, NULL, STRING_GetClass(), sizeof(struct myStringClassData), 0 );
+
+ if ( cl )
+ {
+ cl->cl_Dispatcher.h_Entry = (uint32(*)())myStringClassDispatcher;
+ }
+
+ URLHistory_Init();
+
+ return( cl );
+}
+
+/// Free String Class
+
+void FreeStringClass(Class *cl)
+{
+ struct Library *libbase;
+ URLHistory_Free();
+ FreeClass(cl);
+}
+
+///
+
+/* The End */
+
diff --git a/amiga/stringview/stringview.h b/amiga/stringview/stringview.h
new file mode 100755
index 000000000..b9786ecb0
--- /dev/null
+++ b/amiga/stringview/stringview.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 Rene W. Olsen <ac@rebels.com>
+ * Copyright 2009 Stephen Fellner <sf.amiga@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <exec/semaphores.h>
+#include <intuition/classes.h>
+#include <intuition/classusr.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- */
+
+struct myStringClassData
+{
+ struct SignalSemaphore Semaphore;
+ uint32 WinXPos;
+ uint32 WinYPos;
+ uint32 WinWidth;
+ uint32 WinHeight;
+ struct Window * Window;
+ Object * WindowObject;
+ Object * ListviewObject;
+ struct List ListviewHeader;
+ uint32 ListviewCount;
+ uint32 ListviewSelected;
+ struct List * SearchHeader;
+ STRPTR SearchBuffer;
+};
+
+#define STRINGVIEW_Header 0x50000001
+
+/* protos */
+
+Class * MakeStringClass( void );
+void FreeStringClass(Class *);
+
+/* The End */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/amiga/stringview/urlhistory.c b/amiga/stringview/urlhistory.c
new file mode 100644
index 000000000..6494f1161
--- /dev/null
+++ b/amiga/stringview/urlhistory.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2009 Rene W. Olsen <ac@rebels.com>
+ * Copyright 2009 Stephen Fellner <sf.amiga@gmail.com>
+ * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "proto/exec.h"
+
+#include "urlhistory.h"
+
+#include "content/urldb.h"
+
+struct List PageList;
+
+static int InTag_urlhistory = 0;
+
+void URLHistory_Init( void )
+{
+ // Initialise page list
+ NewList( &PageList );
+}
+
+
+void URLHistory_Free( void )
+{
+ struct Node *node;
+
+ while(( node = RemHead( &PageList )))
+ {
+ if( node->ln_Name) FreeVec( node->ln_Name );
+ FreeVec( node );
+ }
+}
+
+
+void URLHistory_ClearList( void )
+{
+ struct Node *node;
+
+ while(( node = RemHead( &PageList )))
+ {
+ if( node->ln_Name) FreeVec( node->ln_Name );
+ FreeVec( node );
+ }
+}
+
+
+struct List * URLHistory_GetList( void )
+{
+ return &PageList;
+}
+
+static bool URLHistoryFound(const char *url, const struct url_data *data)
+{
+ struct Node *node;
+
+ node = AllocVec( sizeof( struct Node ), MEMF_SHARED|MEMF_CLEAR );
+
+ if ( node )
+ {
+ STRPTR urladd = (STRPTR) AllocVec( strlen ( url ) + 1, MEMF_SHARED|MEMF_CLEAR );
+ if ( urladd )
+ {
+ strcpy(urladd, url);
+ node->ln_Name = urladd;
+ AddTail( &PageList, node );
+ }
+ else
+ {
+ FreeVec(node);
+ }
+ }
+ return true;
+}
+
+struct Node * URLHistory_FindPage( const char *urlString )
+{
+ struct Node *node = PageList.lh_Head;
+ while( node->ln_Succ )
+ {
+ //printf("compare %s to %s\n", node->ln_Name, urlString);
+ if(strcasecmp(node->ln_Name, urlString) == 0) return node;
+ node = node->ln_Succ;
+ }
+
+ return NULL;
+}
+
+
+void URLHistory_AddPage( const char * urlString )
+{
+ // Only add if not already in list and length > 0
+ if( !URLHistory_FindPage( urlString ) && strlen( urlString ) > 0 )
+ {
+ urldb_iterate_partial(urlString, URLHistoryFound);
+ }
+}
+
diff --git a/amiga/stringview/urlhistory.h b/amiga/stringview/urlhistory.h
new file mode 100644
index 000000000..b72792db4
--- /dev/null
+++ b/amiga/stringview/urlhistory.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009 Rene W. Olsen <ac@rebels.com>
+ * Copyright 2009 Stephen Fellner <sf.amiga@gmail.com>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void URLHistory_Init( void );
+void URLHistory_Free( void );
+struct List * URLHistory_GetList( void );
+void URLHistory_ClearList( void );
+struct Node * URLHistory_FindPage( const char *urlString );
+void URLHistory_AddPage( const char * urlString );
+
+#ifdef __cplusplus
+}
+#endif