NetSurf
stringview.c
Go to the documentation of this file.
1/*
2 * Copyright 2009 Rene W. Olsen <ac@rebels.com>
3 * Copyright 2009 Stephen Fellner <sf.amiga@gmail.com>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifdef __amigaos4__
21/// Include
22
23#include <proto/dos.h>
24#include <proto/exec.h>
25#include <proto/intuition.h>
26#include <proto/layout.h>
27#include <proto/listbrowser.h>
28#include <proto/utility.h>
29#include <proto/string.h>
30#include <proto/window.h>
31
32#include <classes/window.h>
33#include <gadgets/layout.h>
34#include <gadgets/listbrowser.h>
35
36#include "amiga/libs.h"
37
38#include "stringview.h"
39#include "urlhistory.h"
40
41#include <string.h>
42#include <stdio.h>
43
44#define End TAG_END)
45
46///
47
48/// Proto
49
50static void myStringOpenListview( Class *cl, Object *obj, struct gpInput *msg );
51static void myStringCloseListview( Class *cl, Object *obj );
52static uint32 myStringSearch( Class *cl, Object *obj );
53static void myStringArrowUp( Class *cl, Object *obj );
54static void myStringArrowDown( Class *cl, Object *obj );
55static void myStringHandleListview( Class *cl, Object *obj );
56
57///
58
59/* -- Internal -- */
60
61/// myStringOpenListview
62
63static void myStringOpenListview( Class *cl, Object *obj, struct gpInput *msg )
64{
65struct myStringClassData *data;
66struct Gadget *gad;
67
68 data = INST_DATA( cl, obj );
69
70 gad = (struct Gadget *)obj;
71
72 SetAttrs( data->WindowObject,
73 WA_CustomScreen, msg->gpi_GInfo->gi_Window->WScreen,
74 WA_Left, data->WinXPos,
75 WA_Top, data->WinYPos,
76 WA_Width, data->WinWidth,
77 WA_Height, data->WinHeight,
78 TAG_END
79 );
80
81// IDoMethod( data->WindowObject, WM_RETHINK );
82
83 data->Window = (struct Window *)IDoMethod( data->WindowObject, WM_OPEN );
84
85 if ( data->Window == NULL )
86 {
87 goto bailout;
88 }
89
90// GetAttr( WINDOW_SigMask, MainWindowObject, &MainWindowBits );
91
92bailout:
93
94 return;
95}
96
97///
98/// myStringCloseListview
99
100static void myStringCloseListview( Class *cl, Object *obj )
101{
102struct myStringClassData *data;
103struct Node *node;
104
105 data = INST_DATA( cl, obj );
106
107 if ( data->Window )
108 {
109 IDoMethod( data->WindowObject, WM_CLOSE );
110 data->Window = NULL;
111 }
112
113 while(( node = RemHead( &data->ListviewHeader )))
114 {
115 FreeListBrowserNode( node );
116 }
117}
118
119///
120/// myStringSearch
121
122static uint32 myStringSearch( Class *cl, Object *obj )
123{
124 struct myStringClassData *data;
125 struct Window *win;
126 struct Node *node;
127 struct Node *n;
128 uint32 found;
129 uint32 bufpos;
130 STRPTR searchString;
131 STRPTR compString;
132
133 found = 0;
134
135 data = INST_DATA( cl, obj );
136
137 win = data->Window;
138
139 // Remove List and Free Nodes
140
141 SetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
142 LISTBROWSER_Labels, ~0,
143 TAG_END
144 );
145
146 while(( node = RemHead( &data->ListviewHeader )))
147 {
148 FreeListBrowserNode( node );
149 }
150
151 GetAttr( STRINGA_BufferPos, obj, &bufpos );
152
153 if ( bufpos == 0 )
154 {
155 goto bailout;
156 }
157
158//-------------
159
160 searchString = strstr(data->SearchBuffer, "://");
161 if(searchString)
162 {
163 searchString += 3;
164 if (bufpos >= (uint32)(searchString - data->SearchBuffer))
165 bufpos -= searchString - data->SearchBuffer;
166 }
167 else
168 searchString = data->SearchBuffer;
169
170 node = GetHead( data->SearchHeader );
171
172 while( node )
173 {
174 uint32 srcpos;
175 BOOL possible;
176
177 possible = FALSE;
178 srcpos = 0;
179
180 compString = strstr(node->ln_Name, "://");
181 if(compString)
182 compString += 3;
183 else
184 compString = node->ln_Name;
185
186 if( 0 == strncasecmp( compString, searchString, bufpos ) )
187 {
188 // found match after protocol
189 possible = TRUE;
190 }
191 else
192 {
193 // no match after protocol, see if there's a match after www
194 if( 0 == strncasecmp( compString, "www.", 4) ) {
195 // got www, compare it!
196 if( 0 == strncasecmp( &compString[4], searchString, bufpos ) )
197 possible = TRUE;
198 }
199 }
200
201 if ( possible == TRUE )
202 {
203 n = AllocListBrowserNode( 1,
204 LBNA_Column, 0,
205 LBNCA_CopyText, TRUE,
206 LBNCA_Text, node->ln_Name,
207 TAG_END
208 );
209
210 if ( n )
211 {
212 AddTail( &data->ListviewHeader, n );
213 found++;
214 }
215 }
216
217 node = GetSucc( node );
218 }
219
220//-------------
221
222bailout:
223
224 data->ListviewCount = found;
225 data->ListviewSelected = -1;
226
227 // Add List Again
228
229 RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
230 LISTBROWSER_Labels, &data->ListviewHeader,
231 LISTBROWSER_Selected, data->ListviewSelected,
232 LISTBROWSER_MakeVisible, 0,
233 TAG_END
234 );
235
236 return( found );
237}
238
239///
240/// myStringArrowUp
241
242static void myStringArrowUp( Class *cl, Object *obj )
243{
244struct myStringClassData *data;
245struct Window *win;
246//struct Node *node;
247//uint32 cnt;
248
249 data = INST_DATA( cl, obj );
250
251 win = data->Window;
252
253 if ( data->ListviewCount == 0 )
254 {
255 data->ListviewSelected = -1;
256 goto bailout;
257 }
258 else if (( data->ListviewSelected != -1 ) && ( data->ListviewSelected != 0 ))
259 {
260 data->ListviewSelected--;
261 }
262
263 RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
264 LISTBROWSER_Selected, data->ListviewSelected,
265 LISTBROWSER_MakeVisible, data->ListviewSelected,
266 TAG_END
267 );
268
269// cnt = data->ListviewSelected;
270// node = GetHead( data->SearchHeader );
271//
272// while( cnt-- > 0 )
273// {
274// node = GetSucc( node );
275// }
276//
277// if ( node )
278// {
279// ISetSuperAttrs( obj,
280//
281// TAG_END
282// );
283// }
284
285bailout:
286
287 return;
288}
289
290///
291/// myStringArrowDown
292
293static void myStringArrowDown( Class *cl, Object *obj )
294{
295struct myStringClassData *data;
296struct Window *win;
297
298 data = INST_DATA( cl, obj );
299
300 win = data->Window;
301
302 if ( data->ListviewCount == 0 )
303 {
304 data->ListviewSelected = -1;
305 }
306 else if ( data->ListviewSelected == -1 )
307 {
308 data->ListviewSelected = 0;
309 }
310 else if ( data->ListviewSelected != data->ListviewCount - 1 )
311 {
312 data->ListviewSelected++;
313 }
314
315 RefreshSetGadgetAttrs( (struct Gadget *)data->ListviewObject, win, NULL,
316 LISTBROWSER_Selected, data->ListviewSelected,
317 LISTBROWSER_MakeVisible, data->ListviewSelected,
318 TAG_END
319 );
320}
321
322///
323/// myStringHandleListview
324
325static void myStringHandleListview( Class *cl, Object *obj )
326{
327struct myStringClassData *data;
329uint16 code;
330
331 data = INST_DATA( cl, obj );
332
333 while(( result = IDoMethod( data->WindowObject, WM_HANDLEINPUT, &code )) != WMHI_LASTMSG )
334 {
335// switch( result & WMHI_CLASSMASK )
336// {
337// case WMHI_CLOSEWINDOW:
338// {
339// running = FALSE;
340// break;
341// }
342//
343// default:
344// {
345// break;
346// }
347// }
348 }
349}
350
351///
352
353/* BOOPSI methods */
354
355/// myStringClass_OM_New
356
357static uint32 myStringClass_OM_New( Class *cl, Object *obj, struct opSet *msg )
358{
359 struct myStringClassData *data;
360 struct List *header;
361 struct TagItem *tag, *tags;
362 STRPTR buffer;
363
364 buffer = NULL;
365 header = NULL;
366
367 tags = msg->ops_AttrList;
368
369 while(( tag = NextTagItem( &tags )))
370 {
371 switch ( tag->ti_Tag )
372 {
374 {
375 header = (struct List *)tag->ti_Data;
376 break;
377 }
378
379 case STRINGA_Buffer:
380 {
381 buffer = (STRPTR)tag->ti_Data;
382 break;
383 }
384
385 default:
386 {
387 break;
388 }
389 }
390 }
391
392 if (( header == NULL ) || ( buffer == NULL ))
393 {
394 return( 0 );
395 }
396
397 obj = (Object *)IDoSuperMethodA( cl, obj, (APTR)msg );
398
399 if ( obj == NULL )
400 {
401 goto bailout;
402 }
403
404 if ( obj )
405 {
406 data = INST_DATA( cl, obj );
407
408 data->SearchHeader = header;
409 data->SearchBuffer = buffer;
410
411 NewList( &data->ListviewHeader );
412
413 InitSemaphore( &data->Semaphore );
414
415 data->WindowObject = NewObject( WindowClass, NULL,
416 WA_Activate, FALSE,
417 WA_Borderless, TRUE,
418 WINDOW_ParentGroup, NewObject( LayoutClass, NULL,
419 LAYOUT_SpaceInner, FALSE,
420 LAYOUT_SpaceOuter, FALSE,
421 LAYOUT_AddChild, data->ListviewObject = NewObject( ListBrowserClass, NULL,
422 LISTBROWSER_Labels, &data->ListviewHeader,
423 LISTBROWSER_MakeVisible, TRUE,
424 LISTBROWSER_ShowSelected, TRUE,
425 End,
426 End,
427 End;
428
429 if ( data->WindowObject == NULL )
430 {
431 goto bailout;
432 }
433 }
434
435 return( (uint32)obj );
436
437bailout:
438
439 if ( obj )
440 {
441 ICoerceMethod( cl, obj, OM_DISPOSE );
442 }
443
444 return( FALSE );
445}
446
447///
448/// myStringClass_OM_Dispose
449
450static uint32 myStringClass_OM_Dispose( Class *cl, Object *obj, struct opSet *msg )
451{
452struct myStringClassData *data;
453
454 data = INST_DATA( cl, obj );
455
456 if ( data->Window )
457 {
458 IDoMethod( data->WindowObject, WM_CLOSE );
459 data->Window = NULL;
460 }
461
462 if ( data->WindowObject )
463 {
464 DisposeObject( data->WindowObject );
465 data->WindowObject = NULL;
466 }
467
468 return( IDoSuperMethodA( cl, obj, (APTR)msg ));
469}
470
471///
472/// myStringClass_OM_Set
473
474//--uint32 myStringClass_OM_Set( Class *cl, Object *obj, struct opSet *msg )
475//--{
476//--struct TorrentClassData *data;
477//--struct TagItem *tag, *tags;
478//--tr_stat_t *tor_s;
479//--
480//-- data = INST_DATA( cl, obj );
481//--
482//-- tags = msg->ops_AttrList;
483//--
484//-- while(( tag = NextTagItem( &tags )))
485//-- {
486//-- switch ( tag->ti_Tag )
487//-- {
488//-- case RAA_Torrent_Stats:
489//-- {
490//-- tor_s = (tr_stat_t *)tag->ti_Data;
491//--
492//-- switch( data->Type )
493//-- {
494//-- case TorType_BitTorrent5:
495//-- {
496//-- BitTorrent5_Stat( data, tor_s );
497//-- break;
498//-- }
499//--
500//-- case TorType_Transmission:
501//-- {
502//-- Transmission_Stat( data, tor_s );
503//-- break;
504//-- }
505//--
506//-- default:
507//-- {
508//-- break;
509//-- }
510//-- }
511//-- break;
512//-- }
513//--
514//-- case RAA_Torrent_Activate:
515//-- {
516//-- switch( data->Type )
517//-- {
518//-- case TorType_BitTorrent5:
519//-- {
520//-- if ( tag->ti_Data == TRUE )
521//-- {
522//-- BitTorrent5_Enable( data );
523//-- }
524//-- else
525//-- {
526//-- BitTorrent5_Disable( data );
527//-- }
528//-- break;
529//-- }
530//--
531//-- case TorType_Transmission:
532//-- {
533//-- if ( tag->ti_Data == TRUE )
534//-- {
535//-- Transmission_Enable( data );
536//-- }
537//-- else
538//-- {
539//-- Transmission_Disable( data );
540//-- }
541//-- break;
542//-- }
543//--
544//-- default:
545//-- {
546//-- break;
547//-- }
548//-- }
549//-- break;
550//-- }
551//--
552//-- default:
553//-- {
554//-- break;
555//-- }
556//-- }
557//-- }
558//--
559//-- return( IDoSuperMethodA( cl, obj, (Msg)msg ));
560//--}
561
562///
563
564/// myStringClass_GM_HandleInput
565
566static uint32 myStringClass_GM_HandleInput( Class *cl, Object *obj, struct gpInput *msg )
567{
568 struct myStringClassData *data;
569 struct Gadget *gad;
570 uint32 retval;
571
572 data = INST_DATA( cl, obj );
573
574 gad = (struct Gadget *)obj;
575
576 //IDoMethod( data->ListviewObject, (APTR)msg );
577
578 if (( gad->Flags & GFLG_SELECTED ) == 0 )
579 {
580 return( GMR_NOREUSE );
581 }
582
583 switch( msg->gpi_IEvent->ie_Class )
584 {
585 case IECLASS_RAWKEY:
586 {
587 switch( msg->gpi_IEvent->ie_Code )
588 {
589 case 0x48: // Page Up (DownKey)
590 case 0x4c: // Up Arrow (DownKey)
591 {
592 myStringArrowUp( cl, obj );
593
594 retval = GMR_MEACTIVE;
595
596 break;
597 }
598
599 case 0x49: // Page Down (DownKey)
600 case 0x4d: // Down Arrow (DownKey)
601 {
602 myStringArrowDown( cl, obj );
603
604 retval = GMR_MEACTIVE;
605
606 break;
607 }
608
609// case 70: // Del
610// case 65: // Backspace
611// {
612// myStringCloseListview( cl, obj );
613//
614// retval = IDoSuperMethodA( cl, obj, (APTR)msg );
615// break;
616// }
617
618 case 68: // Return
619 {
620 // If listview open, and an item is selected, copy selected node's text to the string gadget
621 if( data->Window != NULL && data->ListviewCount > 0 )
622 {
623 struct Node *selected = NULL;
624 STRPTR pText;
625 GetAttr( LISTBROWSER_SelectedNode, data->ListviewObject, (uint32 *) ( &selected ) );
626 if( selected != NULL )
627 {
628 GetListBrowserNodeAttrs( selected, LBNA_Column, 0, LBNCA_Text, &pText, TAG_END );
629 SetGadgetAttrs( (struct Gadget *)obj, data->Window, NULL, STRINGA_TextVal, pText, TAG_DONE );
630 }
631 }
632
633 retval = IDoSuperMethodA( cl, obj, (APTR)msg );
634 break;
635 }
636
637 default:
638 {
639 uint32 oldpos;
640 uint32 newpos;
641
642 GetAttr( STRINGA_BufferPos, obj, &oldpos );
643
644 retval = IDoSuperMethodA( cl, obj, (APTR)msg );
645
646 GetAttr( STRINGA_BufferPos, obj, &newpos );
647
648 if ( oldpos != newpos )
649 {
650 if ( myStringSearch( cl, obj ))
651 {
652 // Atleast one entry found, open window if not open
653 if ( data->Window == NULL )
654 {
655 myStringOpenListview( cl, obj, msg );
656 }
657 }
658 else
659 {
660 // No matches, migth aswell close the window
661 myStringCloseListview( cl, obj );
662 }
663 }
664 break;
665 }
666 }
667
668 myStringHandleListview( cl, obj );
669 break;
670 }
671#ifdef __amigaos4__
672 case IECLASS_MOUSEWHEEL:
673 {
674 struct InputEvent *ie = msg->gpi_IEvent;
675
676 if ( ie->ie_Y < 0 )
677 {
678 myStringArrowUp( cl, obj );
679 }
680 else if ( ie->ie_Y > 0 )
681 {
682 myStringArrowDown( cl, obj );
683 }
684
685 myStringHandleListview( cl, obj );
686
687 retval = GMR_MEACTIVE;
688 break;
689 }
690#endif
691 default:
692 {
693 retval = IDoSuperMethodA( cl, obj, (APTR)msg );
694 break;
695 }
696 }
697
698 return( retval );
699}
700
701///
702/// myStringClass_GM_GoActive
703
704static uint32 myStringClass_GM_GoActive( Class *cl, Object *obj, struct gpInput *msg )
705{
706struct myStringClassData *data;
707struct Window *win;
708struct Gadget *gad;
709uint32 retval;
710
711 data = INST_DATA( cl, obj );
712
713 gad = (struct Gadget *)obj;
714
715 if ( gad->Flags & GFLG_DISABLED )
716 {
717 myStringCloseListview( cl, obj );
718
719 retval = GMR_NOREUSE;
720 }
721 else
722 {
723 // If were not Disabled then set Selected flag
724 gad->Flags |= GFLG_SELECTED;
725
726 win = msg->gpi_GInfo->gi_Window;
727
728 if ( win )
729 {
730 data->WinXPos = win->LeftEdge + gad->LeftEdge;
731 data->WinYPos = win->TopEdge + gad->TopEdge + gad->Height - 1;
732 data->WinWidth = gad->Width;
733 data->WinHeight = 150;
734 }
735
736 if ( myStringSearch( cl, obj ))
737 {
738 // Atleast one entry found, open window if not open
739 if ( data->Window == NULL )
740 {
741 myStringOpenListview( cl, obj, msg );
742 }
743 }
744 else
745 {
746 // No matches, migth aswell close the window
747 myStringCloseListview( cl, obj );
748 }
749
750 retval = IDoSuperMethodA( cl, obj, (APTR)msg );
751 }
752
753 return( retval );
754}
755
756///
757/// myStringClass_GM_GoInactive
758
759static uint32 myStringClass_GM_GoInactive( Class *cl, Object *obj, struct gpGoInactive *msg )
760{
761struct myStringClassData *data;
762
763 data = INST_DATA( cl, obj );
764
765 myStringCloseListview( cl, obj );
766
767 return( IDoSuperMethodA( cl, obj, (APTR)msg ));
768}
769
770///
771
772/* Dispatcher */
773
774/// myStringClassDispatcher
775
776static uint32 myStringClassDispatcher( Class *cl, Object *obj, Msg msg )
777{
778struct myStringClassData *data;
779uint32 ret;
780
781 if ( msg->MethodID == OM_NEW )
782 {
783 return( myStringClass_OM_New( cl, obj, (APTR)msg ));
784 }
785 else if ( msg->MethodID == OM_DISPOSE )
786 {
787 return( myStringClass_OM_Dispose( cl, obj, (APTR)msg ));
788 }
789 else
790 {
791 data = INST_DATA( cl, obj );
792
793 ObtainSemaphore( &data->Semaphore );
794
795 switch( msg->MethodID )
796 {
797 /* BOOPSI methods */
798 case OM_SET:
799 {
800 struct TagItem *tag, *tags;
801 struct opSet *opSet = (struct opSet *)msg;
802 tags = opSet->ops_AttrList;
803 while ((tag = NextTagItem(&tags)))
804 {
805 if (STRINGA_TextVal == tag->ti_Tag)
806 {
807 URLHistory_AddPage((const char *)tag->ti_Data);
808 }
809 }
810
811 ret = IDoSuperMethodA(cl, obj, (APTR)msg);
812 }
813 break;
814
815// case OM_SET: ret = TorrentClass_OM_Set( cl, obj, (APTR)msg ); break;
816
817 /* Only used for Gadgets */
818// case GM_DOMAIN: ret = myStringClass_GM_Domain( cl, obj, (APTR)msg ); break;
819// case GM_LAYOUT: ret = myStringClass_GM_Layout( cl, obj, (APTR)msg ); break;
820// case GM_CLIPRECT: ret = myStringClass_GM_ClipRect( cl, obj, (APTR)msg ); break;
821// case GM_EXTENT: ret = myStringClass_GM_Extent( cl, obj, (APTR)msg ); break;
822// case GM_RENDER: ret = myStringClass_GM_Render( cl, obj, (APTR)msg ); break;
823// case GM_HITTEST: ret = myStringClass_GM_HitTest( cl, obj, (APTR)msg ); break;
824 case GM_HANDLEINPUT: ret = myStringClass_GM_HandleInput( cl, obj, (APTR)msg ); break;
825 case GM_GOACTIVE: ret = myStringClass_GM_GoActive( cl, obj, (APTR)msg ); break;
826 case GM_GOINACTIVE: ret = myStringClass_GM_GoInactive( cl, obj, (APTR)msg ); break;
827
828 /* Unknown method -> delegate to SuperClass */
829 default: ret = IDoSuperMethodA( cl, obj, (APTR)msg ); break;
830 }
831
832 ReleaseSemaphore( &data->Semaphore );
833
834 return( ret );
835 }
836}
837
838///
839
840/* Create Class */
841
842/// Make String Class
843
844Class *MakeStringClass( void )
845{
846 Class *cl;
847 cl = MakeClass( NULL, NULL, StringClass, sizeof(struct myStringClassData), 0 );
848
849 if ( cl )
850 {
851 cl->cl_Dispatcher.h_Entry = (uint32(*)(void))myStringClassDispatcher;
852 }
853
855
856 return( cl );
857}
858
859/// Free String Class
860
861void FreeStringClass(Class *cl)
862{
864 FreeClass(cl);
865}
866
867///
868
869/* The End */
870#endif //__amigaos4__
871
STATIC char result[100]
Definition: arexx.c:77
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
Class * LayoutClass
Class * WindowClass
Class * ListBrowserClass
Class * StringClass
APTR NewObject(struct IClass *classPtr, CONST_STRPTR classID, ULONG tagList,...)
Definition: os3support.c:434
struct Node * GetHead(struct List *list)
Definition: os3support.c:364
ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1,...)
Definition: os3support.c:429
struct Node * GetSucc(struct Node *node)
Definition: os3support.c:381
#define IDoSuperMethodA
Definition: os3support.h:171
#define IDoMethod
Definition: os3support.h:169
#define ICoerceMethod
Definition: os3support.h:168
uint16_t uint16
Definition: os3support.h:182
uint32_t uint32
Definition: os3support.h:184
Interface to utility string handling.
Class * MakeStringClass(void)
#define STRINGVIEW_Header
Definition: stringview.h:50
void FreeStringClass(Class *)
Object * ListviewObject
Definition: stringview.h:42
struct List ListviewHeader
Definition: stringview.h:43
struct Window * Window
Definition: stringview.h:40
struct List * SearchHeader
Definition: stringview.h:46
int32 ListviewSelected
Definition: stringview.h:45
STRPTR SearchBuffer
Definition: stringview.h:47
struct SignalSemaphore Semaphore
Definition: stringview.h:35
Object * WindowObject
Definition: stringview.h:41
void URLHistory_Free(void)
void URLHistory_Init(void)
void URLHistory_AddPage(const char *urlString)