aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ag_render.f9021
-rw-r--r--favorites.f90353
-rw-r--r--gemini-windows.prj11
-rw-r--r--main.F9055
-rw-r--r--platform.F9075
-rw-r--r--render.f9013
6 files changed, 520 insertions, 8 deletions
diff --git a/ag_render.f90 b/ag_render.f90
index fc80295..383be04 100644
--- a/ag_render.f90
+++ b/ag_render.f90
@@ -43,6 +43,7 @@ implicit none
integer, parameter::ag_render_event_scroll = 5
integer, parameter::ag_render_event_resize = 6
integer, parameter::ag_render_event_mousemove = 7
+ integer, parameter::ag_render_event_favorite = 8
type :: link
integer, dimension(4)::location
@@ -55,6 +56,7 @@ implicit none
integer::address_id
integer::go_button_id
integer::back_button_id
+ integer::fave_button_id
integer::scroll_id
integer::font_size
@@ -153,6 +155,15 @@ contains
end subroutine go_button_callback
+ subroutine fave_button_callback()
+ use appgraphics, only: stopidle
+ implicit none
+
+ ag_render_event = ag_render_event_favorite
+ call stopidle()
+
+ end subroutine fave_button_callback
+
subroutine mouse_button_callback(x, y)
use appgraphics, only: stopidle
implicit none
@@ -264,6 +275,13 @@ contains
call setbuttonposition(self%go_button_id, x, 2, 40, 20)
end if
+ x = x + 50
+ if(self%fave_button_id < 0) then
+ self%fave_button_id = createbutton(x, 2, 40, 20, "Wow!", fave_button_callback)
+ else
+ call setbuttonposition(self%fave_button_id, x, 2, 40, 20)
+ end if
+
! Clears any drawing operations for controls quickly
ignored = switch_to_thread()
@@ -805,6 +823,9 @@ contains
self%y = 0
ag_action = render_action_rewrap
+
+ case(ag_render_event_favorite)
+ ag_action = render_action_favorite
end select
diff --git a/favorites.f90 b/favorites.f90
new file mode 100644
index 0000000..d1ba7d1
--- /dev/null
+++ b/favorites.f90
@@ -0,0 +1,353 @@
+module favorite_handling
+implicit none
+
+ private
+
+ public :: favorite, sort_added, sort_alpha, read_favorites, &
+ write_favorites, add_favorite, remove_favorite
+
+ type :: favorite
+
+ character(80)::name
+ character(1024)::link
+ integer::added
+
+ end type favorite
+
+contains
+
+ pure function string_compare(s1, s2) result(res)
+ implicit none
+
+ character(*), intent(in)::s1, s2
+ integer::res
+
+ integer::n1, n2
+ integer::i
+
+ n1 = len_trim(s1)
+ n2 = len_trim(s2)
+
+ res = 0
+ do i = 1, min(n1, n2)
+
+ if(s1(i:i) < s2(i:i)) then
+ res = -1
+ exit
+ else if(s1(i:i) > s2(i:i)) then
+ res = 1
+ exit
+ end if
+
+ end do
+
+ end function string_compare
+
+ pure function string_location(array, minsearch) result(res)
+ implicit none
+
+ character(*), dimension(:), intent(in)::array
+ logical, intent(in), optional::minsearch
+ integer::res
+
+ logical::mymin
+ integer::i
+
+ mymin = .false.
+ if(present(minsearch)) then
+ mymin = minsearch
+ end if
+
+ res = 1
+ do i = 2, size(array)
+ if(mymin .and. string_compare(array(res), array(i)) < 0) then
+ res = i
+ else if((.not. mymin) .and. string_compare(array(res), array(i)) > 0) then
+ res = i
+ end if
+ end do
+
+ end function string_location
+
+ subroutine sort_added(favorites, latest)
+ implicit none
+
+ type(favorite), dimension(:), intent(inout)::favorites
+ logical, intent(in)::latest
+
+ integer::i_loc
+ integer::i, n
+
+ type(favorite)::swapper
+
+ n = size(favorites)
+ do i=1, n-1
+
+ if(latest) then
+ i_loc = maxloc(favorites(i:n)%added, 1)
+ else
+ i_loc = minloc(favorites(i:n)%added, 1)
+ end if
+
+ i_loc = i_loc + i - 1
+
+ if(i /= i_loc) then
+ swapper = favorites(i)
+ favorites(i) = favorites(i_loc)
+ favorites(i_loc) = swapper
+ end if
+
+ end do
+
+ end subroutine sort_added
+
+ subroutine sort_alpha(favorites, descending)
+ implicit none
+
+ type(favorite), dimension(:), intent(inout)::favorites
+ logical, intent(in)::descending
+
+ integer::i_loc
+ integer::i, n
+
+ type(favorite)::swapper
+
+ n = size(favorites)
+ do i=1, n-1
+
+ if(descending) then
+ i_loc = string_location(favorites(i:n)%name)
+ else
+ i_loc = string_location(favorites(i:n)%name, minsearch=.true.)
+ end if
+
+ i_loc = i_loc + i - 1
+
+ if(i /= i_loc) then
+ swapper = favorites(i)
+ favorites(i) = favorites(i_loc)
+ favorites(i_loc) = swapper
+ end if
+
+ end do
+
+ end subroutine sort_alpha
+
+ function read_favorite(unit_number) result(res)
+ implicit none
+
+ type(favorite)::res
+ integer, intent(in)::unit_number
+
+ character::c
+ character(len=10)::text_date
+ integer::i, ios
+
+ ! Leading spaces...
+ read(unit_number, '(A1)', advance='no') c
+ do while(c == ' ' .or. c == char(9))
+ read(unit_number, '(A1)', advance='no') c
+ end do
+
+ ! Link
+ res%link = " "
+ i = 1
+ do while(c /= ' ' .and. c /= char(9))
+ res%link(i:i) = c
+ read(unit_number, '(A1)', advance='no') c
+ end do
+
+ ! Separating spaces...
+ do while(c == ' ' .or. c == char(9))
+ read(unit_number, '(A1)', advance='no') c
+ end do
+
+ ! Name...
+ res%name = " "
+ ios = 0
+ do while(c /= ' ' .and. c /= char(9))
+ res%name(i:i) = c
+ read(unit_number, '(A1)', advance='no', iostat=ios) c
+ end do
+
+ ! The date should be at the end of the link
+ i = index(res%name, "(", .true.)
+ text_date = res%name(i+1:i+10)
+ do i = 5, 9
+ text_date(i:i) = text_date(i+1:i+1)
+ end do
+ do i = 7, 8
+ text_date(i:i) = text_date(i+1:i+1)
+ end do
+ read(text_date, '(I8)') res%added
+
+ end function read_favorite
+
+ function read_favorites(unit_number) result(faves)
+ implicit none
+
+ integer, intent(in)::unit_number
+ type(favorite), dimension(:), allocatable::faves
+
+ character(80)::temp
+ integer::n, i
+
+ ! Title
+ read(unit_number, *) temp
+
+ ! Blank
+ read(unit_number, *) temp
+
+ ! Count
+ read(unit_number, *) n
+
+ ! Blank
+ read(unit_number, *) temp
+
+ allocate(faves(n))
+
+ do i = 1, n
+ read(unit_number, '(A2)', advance='no') temp
+ faves(i) = read_favorite(unit_number)
+ end do
+
+ end function read_favorites
+
+ subroutine write_favorite(unit_number, f)
+ implicit none
+
+ integer, intent(in)::unit_number
+ type(favorite), intent(in)::f
+
+ write(unit_number, *) "=> "//trim(f%link)//" "//f%name
+
+ end subroutine write_favorite
+
+ subroutine write_favorites(unit_number, faves)
+ implicit none
+
+ integer, intent(in)::unit_number
+ type(favorite), dimension(:), intent(in)::faves
+
+ integer::i
+ character(8)::n_text
+
+ write(unit_number, *) "Favorites"
+ write(unit_number, *)
+
+ write(n_text, '(I8)') size(faves)
+
+ write(unit_number, *) trim(adjustl(n_text))//" Links Are Marked As Favorites"
+ write(unit_number, *)
+
+ do i = 1, size(faves)
+ call write_favorite(unit_number, faves(i))
+ end do
+
+ end subroutine write_favorites
+
+ pure function find_favorite(faves, link)
+ implicit none
+
+ integer::find_favorite
+ type(favorite), dimension(:), allocatable, intent(in)::faves
+ character(*), intent(in)::link
+
+ if(.not. allocated(faves)) then
+ find_favorite = -1
+ else
+ do find_favorite = 1, size(faves)
+ if(trim(link) == trim(faves(find_favorite)%link)) then
+ exit
+ end if
+ end do
+
+ if(find_favorite > size(faves)) then
+ find_favorite = -1
+ end if
+ end if
+
+ end function find_favorite
+
+ subroutine add_favorite(faves, link, name)
+ implicit none
+
+ type(favorite), dimension(:), intent(inout), allocatable::faves
+ character(*), intent(in)::link
+ character(*), intent(in)::name
+ character(8)::now
+
+ integer::n
+ type(favorite), dimension(:), allocatable::holding
+
+ n = -1
+
+ if(.not. allocated(faves)) then
+
+ n = 1
+ allocate(faves(1))
+
+ else if(find_favorite(faves, link) < 0) then
+
+ n = size(faves)
+ allocate(holding(n))
+ holding = faves
+
+ deallocate(faves)
+
+ allocate(faves(n+1))
+ faves(1:n) = holding
+
+ n = n + 1
+
+ end if
+
+ if(n > 0) then
+ faves(n)%link = trim(link)
+
+ call date_and_time(date=now)
+ faves(n)%name = trim(name)//" ("//now(1:4)//"-"//now(5:6)//"-"//now(7:8)//")"
+ read(now, '(I8)') faves(n)%added
+ end if
+
+ end subroutine add_favorite
+
+ subroutine remove_favorite(faves, link)
+ implicit none
+
+ type(favorite), dimension(:), intent(inout), allocatable::faves
+ character(*), intent(in)::link
+
+ integer::i, n
+ type(favorite), dimension(:), allocatable::holding
+
+ i = find_favorite(faves, link)
+ if(i > 0) then
+
+ if(size(faves) == 1) then
+
+ deallocate(faves)
+
+ else
+
+ n = size(faves)
+ allocate(holding(n-1))
+ if(i > 1) then
+ holding(1:i-1) = faves(1:i-1)
+ end if
+ if(i < n) then
+ holding(i:n-1) = faves(i+1:n)
+ end if
+ deallocate(faves)
+
+ allocate(faves(n-1))
+ faves = holding
+ deallocate(holding)
+
+ end if
+
+ end if
+
+ end subroutine remove_favorite
+
+end module favorite_handling \ No newline at end of file
diff --git a/gemini-windows.prj b/gemini-windows.prj
index ad734ad..8e32881 100644
--- a/gemini-windows.prj
+++ b/gemini-windows.prj
@@ -47,6 +47,9 @@
"filename":".\\escape.f90",
"enabled":"1"
},{
+ "filename":".\\favorites.f90",
+ "enabled":"1"
+ },{
"filename":".\\files.f90",
"enabled":"1"
},{
@@ -62,6 +65,9 @@
"filename":".\\main.F90",
"enabled":"1"
},{
+ "filename":".\\platform.F90",
+ "enabled":"1"
+ },{
"filename":".\\protocol.f90",
"enabled":"1"
},{
@@ -111,12 +117,13 @@
},
"Build Dependencies":1,
"Launch Options":{
+ "Build Before Launch":"true",
"Working Directory":"",
"Launch Using MPI":"false",
"Keep Console":"true",
- "External Console":"false",
+ "Executable":"",
"Command Line Arguments":"",
- "Build Before Launch":"true"
+ "External Console":"false"
},
"Build Options":{
"Makefile":"Makefile",
diff --git a/main.F90 b/main.F90
index 7021195..fd618c3 100644
--- a/main.F90
+++ b/main.F90
@@ -42,6 +42,8 @@ use history
use wsa_network, only: windows_network_startup => startup
#endif
+use favorite_handling
+
implicit none
character(256)::initial_site
@@ -69,6 +71,8 @@ implicit none
type(line), pointer::first_line
type(location), pointer::locations_visited
+ type(favorite), dimension(:), allocatable::faves
+
#ifdef WINDOWS
call windows_network_startup()
#endif
@@ -101,6 +105,9 @@ implicit none
redo_layout = .false.
call r%initialize()
+ ! Load in any favorites
+ faves = load_favorites()
+
locations_visited => null()
desired_url = initial_site
current_url = " "
@@ -231,6 +238,10 @@ implicit none
loaded = .false.
+ case (render_action_favorite)
+ call add_favorite(faves, current_url, current_url)
+ call save_favorites(faves)
+
end select
end do
@@ -286,4 +297,48 @@ contains
end subroutine update_status
+ function load_favorites() result(faves)
+ use platform, only: get_favorites_file
+ use favorite_handling, only: read_favorites, favorite
+ implicit none
+
+ type(favorite), dimension(:), allocatable::faves
+
+ character(260)::filename
+ integer::ios, loadunit
+
+ call get_favorites_file(filename)
+
+ open(newunit=loadunit, file=filename, status='old', action='read', iostat=ios)
+ if(ios == 0) then
+
+ faves = read_favorites(loadunit)
+ close(loadunit)
+
+ end if
+
+ end function load_favorites
+
+ subroutine save_favorites(faves)
+ use platform, only: get_favorites_file
+ use favorite_handling, only: write_favorites, favorite
+ implicit none
+
+ type(favorite), dimension(:), allocatable::faves
+
+ character(260)::filename
+ integer::ios, loadunit
+
+ call get_favorites_file(filename)
+
+ open(newunit=loadunit, file=filename, status='unknown', action='write', iostat=ios)
+ if(ios == 0) then
+
+ call write_favorites(loadunit, faves)
+ close(loadunit)
+
+ end if
+
+ end subroutine save_favorites
+
end program gemini
diff --git a/platform.F90 b/platform.F90
new file mode 100644
index 0000000..e10ca64
--- /dev/null
+++ b/platform.F90
@@ -0,0 +1,75 @@
+module platform
+implicit none
+
+#ifdef WINDOWS
+ character, parameter::dir_sep = '\'
+#else
+ character, parameter::dir_sep = '/'
+#endif
+
+ character(*), parameter::favorites_file = "favorites.gmi"
+
+contains
+
+ subroutine get_settings_directory(dir)
+ use iso_c_binding
+ implicit none
+
+ character(*), intent(out)::dir
+#ifdef WINDOWS
+
+ interface
+ function SHGetFolderPath(hwnd, csidl, htoken, dwflags, path) bind(c, name="SHGetFolderPathA")
+ use iso_c_binding
+ type(c_ptr), value::hwnd
+ integer(kind=c_int), value::csidl
+ type(c_ptr), value::htoken
+ integer(kind=c_int32_t), value::dwflags
+ character(kind=c_char), dimension(260)::path
+ integer(kind=c_intptr_t)::SHGetFolderPath
+ end function SHGetFolderPath
+ end interface
+
+ integer(kind=c_intptr_t), parameter::S_OK = 0
+ integer(kind=c_int), parameter::CSIDL_APPDATA = 26
+
+ character(kind=c_char), dimension(260)::path
+ integer::i
+
+ if(SHGetFolderPath(c_null_ptr, CSIDL_APPDATA, c_null_ptr, 0, path) == S_OK) then
+ dir = " "
+ i = 1
+ do while(path(i) /= c_null_char .and. i < 260)
+ dir(i:i) = path(i)
+ i = i + 1
+ end do
+ else
+ Print *, "Warning: Could not access CSIDL_APPDATA"
+ call get_environment_variable("HOME", value=dir)
+ end if
+
+ if(dir(len_trim(dir):len_trim(dir)) /= dir_sep) then
+ dir = trim(dir)//dir_sep
+ end if
+ dir = trim(dir)//"LR-87"
+#else
+ call get_environment_variable("HOME", value=dir)
+ if(dir(len_trim(dir):len_trim(dir)) /= dir_sep) then
+ dir = trim(dir)//dir_sep
+ end if
+ dir = trim(dir)//".lr87"
+#endif
+
+ end subroutine get_settings_directory
+
+ subroutine get_favorites_file(filename)
+ implicit none
+
+ character(*), intent(out)::filename
+
+ call get_settings_directory(filename)
+ filename = trim(filename)//dir_sep//favorites_file
+
+ end subroutine get_favorites_file
+
+end module platform \ No newline at end of file
diff --git a/render.f90 b/render.f90
index 54f50e4..3cbb2bc 100644
--- a/render.f90
+++ b/render.f90
@@ -23,12 +23,13 @@
module render
implicit none
- integer, parameter::render_action_none = 1
- integer, parameter::render_action_goto = 2
- integer, parameter::render_action_layout = 3
- integer, parameter::render_action_back = 4
- integer, parameter::render_action_rewrap = 5
- integer, parameter::render_action_quit = 6
+ integer, parameter::render_action_none = 1
+ integer, parameter::render_action_goto = 2
+ integer, parameter::render_action_layout = 3
+ integer, parameter::render_action_back = 4
+ integer, parameter::render_action_rewrap = 5
+ integer, parameter::render_action_quit = 6
+ integer, parameter::render_action_favorite = 7
integer, parameter::last_break = -1