From 46c2934be0198ef5299c600320a8943fe2d13530 Mon Sep 17 00:00:00 2001 From: Jared Wahlstrand Date: Fri, 14 Jul 2023 22:09:39 -0400 Subject: [PATCH] GFile convenience functions, misc. other fixes --- src/GLib/GLib.jl | 1 + src/GLib/gio.jl | 34 ++++++++++++++++ src/text.jl | 50 ++++++----------------- src/tree.jl | 104 +++++++++++++++++++++++------------------------ test/gfile.jl | 12 +++--- 5 files changed, 106 insertions(+), 95 deletions(-) create mode 100644 src/GLib/gio.jl diff --git a/src/GLib/GLib.jl b/src/GLib/GLib.jl index b06a9428..9ba33cac 100644 --- a/src/GLib/GLib.jl +++ b/src/GLib/GLib.jl @@ -193,6 +193,7 @@ include("gobject.jl") include("listmodel.jl") include("loop.jl") include("actions.jl") +include("gio.jl") const exiting = Ref(false) function __init__() diff --git a/src/GLib/gio.jl b/src/GLib/gio.jl new file mode 100644 index 00000000..da9949ab --- /dev/null +++ b/src/GLib/gio.jl @@ -0,0 +1,34 @@ +# Misc. libgio functions + +GFile(p::AbstractString) = GFile(G_.new_for_path(p)) +Base.ispath(f::GFile) = G_.query_exists(f,nothing) +Base.isdir(f::GFile) = (G_.query_file_type(f,FileQueryInfoFlags_NONE,nothing)==FileType_DIRECTORY) +Base.isfile(f::GFile) = (G_.query_file_type(f,FileQueryInfoFlags_NONE,nothing)==FileType_REGULAR) +Base.islink(f::GFile) = (G_.query_file_type(f,FileQueryInfoFlags_NONE,nothing)==FileType_SYMBOLIC_LINK) +Base.basename(f::GFile) = G_.get_basename(f) +path(f::GFile) = G_.get_path(f) + +Base.keys(fi::GFileInfo) = G_.list_attributes(fi,nothing) +function getindex(fi::GFileInfo,att::AbstractString) + typ = G_.get_attribute_type(fi,att) + if typ == FileAttributeType_STRING + return G_.get_attribute_string(fi,att) + elseif typ == FileAttributeType_BYTE_STRING + return G_.get_attribute_byte_string(fi,att) + elseif typ == FileAttributeType_BOOLEAN + return G_.get_attribute_boolean(fi,att) + elseif typ == FileAttributeType_UINT32 + return G_.get_attribute_uint32(fi,att) + elseif typ == FileAttributeType_INT32 + return G_.get_attribute_int32(fi,att) + elseif typ == FileAttributeType_UINT64 + return G_.get_attribute_uint64(fi,att) + elseif typ == FileAttributeType_INT64 + return G_.get_attribute_int64(fi,att) + elseif typ == FileAttributeType_OBJECT + return G_.get_attribute_object(fi,att) + else + error("unsupported FileAttributeType: $typ") + end +end + diff --git a/src/text.jl b/src/text.jl index 7f30a8c1..4a8e4b6a 100644 --- a/src/text.jl +++ b/src/text.jl @@ -434,8 +434,7 @@ in(x::TI, r::GtkTextRange) = Bool(ccall((:gtk_text_iter_in_range, libgtk4), Cint #TODO: clipboard, selection/cursor, user_action_groups iterate(text::GtkTextBuffer, iter=start_(_GtkTextIter(text))) = iterate(iter, iter) -length(text::GtkTextBuffer) = ccall((:gtk_text_buffer_get_char_count, libgtk4), Cint, - (Ptr{GObject},), text) +length(text::GtkTextBuffer) = G_.get_char_count(text) #get_line_count(text::GtkTextBuffer) = ccall((:gtk_text_buffer_get_line_count, libgtk4), Cint, (Ptr{GObject},), text) function insert!(text::GtkTextBuffer, index::TI, str::AbstractString) ccall((:gtk_text_buffer_insert, libgtk4), Nothing, @@ -443,8 +442,7 @@ function insert!(text::GtkTextBuffer, index::TI, str::AbstractString) text end function insert!(text::GtkTextBuffer, str::AbstractString) - ccall((:gtk_text_buffer_insert_at_cursor, libgtk4), Nothing, - (Ptr{GObject}, Ptr{UInt8}, Cint), text, bytestring(str), sizeof(str)) + G_.insert_at_cursor(text, str, sizeof(str)) text end function splice!(text::GtkTextBuffer, index::TI) @@ -453,13 +451,11 @@ function splice!(text::GtkTextBuffer, index::TI) text end function splice!(text::GtkTextBuffer) - ccall((:gtk_text_buffer_delete_selection, libgtk4), Cint, - (Ptr{GObject}, Cint, Cint), text, false, true) + G_.delete_selection(text, false, true) text end -setindex!(buffer::GtkTextBuffer, content::String, ::Type{String}) = - ccall((:gtk_text_buffer_set_text, libgtk4), Nothing, (Ptr{GObject}, Ptr{UInt8}, Cint), buffer, content, -1) +setindex!(buffer::GtkTextBuffer, content::String, ::Type{String}) = G_.set_text(buffer, content, -1) """ selection_bounds(buffer::GtkTextBuffer) @@ -502,11 +498,8 @@ place_cursor(buffer::GtkTextBuffer, it::_GtkTextIter) = place_cursor(buffer::GtkTextBuffer, pos::Int) = place_cursor(buffer, _GtkTextIter(buffer, pos)) place_cursor(buffer::GtkTextBuffer, it::Ref{_GtkTextIter}) = place_cursor(buffer, it[]) -begin_user_action(buffer::GtkTextBuffer) = - ccall((:gtk_text_buffer_begin_user_action, libgtk4), Nothing, (Ptr{GObject},), buffer) - -end_user_action(buffer::GtkTextBuffer) = - ccall((:gtk_text_buffer_end_user_action, libgtk4), Nothing, (Ptr{GObject},), buffer) +begin_user_action(buffer::GtkTextBuffer) = G_.begin_user_action(buffer) +end_user_action(buffer::GtkTextBuffer) = G_.end_user_action(buffer) function user_action(f::Function, buffer::GtkTextBuffer) begin_user_action(buffer) @@ -563,11 +556,11 @@ create_mark(buffer::GtkTextBuffer, it::TI) = create_mark(buffer, C_NULL, it, fa function getindex(text::GtkTextView, sym::Symbol, ::Type{GtkTextBuffer}) sym === :buffer || error("must supply :buffer, got ", sym) - return convert(GtkTextBuffer, G_.get_buffer(text))::GtkTextBuffer + return G_.get_buffer(text) end function getindex(text::GtkTextView, sym::Symbol, ::Type{Bool}) sym === :editable || error("must supply :editable, got ", sym) - return convert(Bool, G_.get_editable(text))::Bool + return G_.get_editable(text) end function insert!(text::GtkTextView, index::TI, child::GtkWidget) @@ -611,15 +604,11 @@ Implements `gtk_text_view_scroll_to_mark` and `gtk_text_view_scroll_to_iter`. """ function scroll_to(view::GtkTextView, mark::GtkTextMark, within_margin::Real, use_align::Bool, xalign::Real, yalign::Real) - - ccall((:gtk_text_view_scroll_to_mark, libgtk4), Nothing, - (Ptr{GObject}, Ptr{GObject}, Cdouble, Cint, Cdouble, Cdouble), - view, mark, within_margin, use_align, xalign, yalign) + G_.scroll_to_mark(view, mark, within_margin, use_align, xalign, yalign) end function scroll_to(view::GtkTextView, iter::TI, within_margin::Real, use_align::Bool, xalign::Real, yalign::Real) - ccall((:gtk_text_view_scroll_to_iter, libgtk4), Nothing, (Ptr{GObject}, Ptr{_GtkTextIter}, Cdouble, Cint, Cdouble, Cdouble), view, iter, within_margin, use_align, xalign, yalign) @@ -631,14 +620,8 @@ end Implements `gtk_text_view_buffer_to_window_coords`. """ -function buffer_to_window_coords(view::GtkTextView, buffer_x::Integer, buffer_y::Integer, wintype::Integer = 0) - window_x, window_y = Ref{Cint}(), Ref{Cint}() - ccall( - (:gtk_text_view_buffer_to_window_coords, libgtk4), Cvoid, - (Ptr{GObject}, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}), - view, Int32(wintype), buffer_x, buffer_y, window_x, window_y - ) - return (window_x[], window_y[]) +function buffer_to_window_coords(view::GtkTextView, buffer_x::Integer, buffer_y::Integer, wintype = TextWindowType_WIDGET) + G_.buffer_to_window_coords(view, wintype, buffer_x, buffer_y) end """ @@ -646,14 +629,8 @@ end Implements `gtk_text_view_window_to_buffer_coords`. """ -function window_to_buffer_coords(view::GtkTextView, window_x::Integer, window_y::Integer, wintype::Integer = 2) - buffer_x, buffer_y = Ref{Cint}(), Ref{Cint}() - ccall( - (:gtk_text_view_window_to_buffer_coords, libgtk4), Cvoid, - (Ptr{GObject}, Cint, Cint, Cint, Ptr{Cint}, Ptr{Cint}), - view, Int32(wintype), window_x, window_y, buffer_x, buffer_y - ) - return (buffer_x[],buffer_y[]) +function window_to_buffer_coords(view::GtkTextView, window_x::Integer, window_y::Integer, wintype = TextWindowType_LEFT) + G_.window_to_buffer_coords(view, wintype, window_x, window_y) end """ @@ -690,5 +667,4 @@ end #### GtkTextMark #### -visible(w::GtkTextMark, state::Bool) = G_.set_visible(w,state) show(w::GtkTextMark) = visible(w, true) diff --git a/src/tree.jl b/src/tree.jl index 17c2e3e9..87faa98a 100644 --- a/src/tree.jl +++ b/src/tree.jl @@ -34,7 +34,7 @@ end function GtkListStore(types::Type...) gtypes = GLib.gtypes(types...) handle = ccall((:gtk_list_store_newv, libgtk4), Ptr{GObject}, (Cint, Ptr{GLib.GType}), length(types), gtypes) - GtkListStoreLeaf(handle) + GtkListStoreLeaf(handle,true) end function GtkListStore(combo::GtkComboBoxText) @@ -45,16 +45,16 @@ end ## index is integer for a liststore, vector of ints for tree iter_from_index(store::GtkListStore, index::Int) = iter_from_string_index(store, string(index - 1)) function index_from_iter(store::GtkListStore, iter::TRI) - s = get_string_from_iter(GtkTreeModel(store), iter) - s !== nothing ? parse(Int, s) + 1 : 0 + s = get_string_from_iter(GtkTreeModel(store), iter) + s !== nothing ? parse(Int, s) + 1 : 0 end function list_store_set_values(store::GtkListStore, iter, values) - G_.set(store, Ref(iter), 0:(length(values)-1), GLib.gvalues(values...)) + G_.set(store, Ref(iter), 0:(length(values)-1), GLib.gvalues(values...)) end function push!(listStore::GtkListStore, values::Tuple) - iter = G_.append(listStore) + iter = G_.append(listStore) list_store_set_values(listStore, iter, values) iter end @@ -67,10 +67,10 @@ end ## insert before function insert!(listStore::GtkListStoreLeaf, iter::TRI, values) - if isa(iter,_GtkTreeIter) - iter=Ref(iter) - end - newiter = Ref{_GtkTreeIter}() + if isa(iter,_GtkTreeIter) + iter=Ref(iter) + end + newiter = Ref{_GtkTreeIter}() ccall((:gtk_list_store_insert_before, libgtk4), Nothing, (Ptr{GObject}, Ptr{_GtkTreeIter}, Ref{_GtkTreeIter}), listStore, newiter, iter) list_store_set_values(listStore, newiter[], values) newiter @@ -79,10 +79,10 @@ end function delete!(listStore::GtkListStore, iter::TRI) # not sure what to do with the return value here - if isa(iter,_GtkTreeIter) - iter=Ref(iter) - end - ret = ccall(("gtk_list_store_remove", libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}), listStore, iter) + if isa(iter,_GtkTreeIter) + iter=Ref(iter) + end + ret = ccall(("gtk_list_store_remove", libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}), listStore, iter) listStore end @@ -107,14 +107,14 @@ popfirst!(listStore::GtkListStoreLeaf) = deleteat!(listStore, 1) function isvalid(listStore::GtkListStore, iter::_GtkTreeIter) - _iter = Ref(iter) - ret = ccall(("gtk_list_store_iter_is_valid", libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}), listStore, _iter) - ret2 = convert(Bool, ret) + _iter = Ref(iter) + ret = ccall(("gtk_list_store_iter_is_valid", libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}), listStore, _iter) + ret2 = convert(Bool, ret) end function length(listStore::GtkListStore) _len = G_.iter_n_children(GtkTreeModel(listStore), nothing) - return convert(Int, _len) + return convert(Int, _len) end size(listStore::GtkListStore) = (length(listStore), ncolumns(GtkTreeModel(listStore))) @@ -131,29 +131,29 @@ end function GtkTreeStore(types::Type...) gtypes = GLib.gtypes(types...) handle = ccall((:gtk_tree_store_newv, libgtk4), Ptr{GObject}, (Cint, Ptr{GLib.GType}), length(types), gtypes) - GtkTreeStoreLeaf(handle) + GtkTreeStoreLeaf(handle,true) end iter_from_index(store::GtkTreeStoreLeaf, index::Vector{Int}) = iter_from_string_index(store, join(index.-1, ":")) function tree_store_set_values(treeStore::GtkTreeStoreLeaf, iter, values) - G_.set(treeStore, Ref(iter), 0:(length(values)-1), GLib.gvalues(values...)) + G_.set(treeStore, Ref(iter), 0:(length(values)-1), GLib.gvalues(values...)) iter end # FIXME: push! and pushfirst! return iters, not the collection, which is inconsistent # getting the iters is pretty useful, the question is what should these methods be renamed to? function push!(treeStore::GtkTreeStore, values::Tuple, parent = nothing) - if isa(parent,_GtkTreeIter) - parent=Ref(parent) - end - G_.insert_with_values(treeStore, parent, -1, 0:(length(values)-1), GLib.gvalues(values...)) + if isa(parent,_GtkTreeIter) + parent=Ref(parent) + end + G_.insert_with_values(treeStore, parent, -1, 0:(length(values)-1), GLib.gvalues(values...)) end function pushfirst!(treeStore::GtkTreeStore, values::Tuple, parent = nothing) - if isa(parent,_GtkTreeIter) - parent=Ref(parent) - end + if isa(parent,_GtkTreeIter) + parent=Ref(parent) + end iter = G_.prepend(treeStore, parent) tree_store_set_values(treeStore, iter, values) @@ -243,7 +243,7 @@ end function setindex!(store::GtkTreeStore, value, index::Vector{Int}, column::Integer) - setindex!(store, value, iter_from_index(store, index), column) + setindex!(store, value, iter_from_index(store, index), column) end @@ -253,18 +253,18 @@ end GtkTreeModelFilter(child_model::GObject) = G_.filter_new(GtkTreeModel(child_model), nothing) function convert_iter_to_child_iter(model::Union{GtkTreeModelFilter,GtkTreeModelSort}, filter_iter::TRI) - if isa(filter_iter,_GtkTreeIter) - filter_iter = Ref(filter_iter) - end - child_iter = G_.convert_iter_to_child_iter(model, filter_iter) + if isa(filter_iter,_GtkTreeIter) + filter_iter = Ref(filter_iter) + end + child_iter = G_.convert_iter_to_child_iter(model, filter_iter) end function convert_child_iter_to_iter(model::Union{GtkTreeModelFilter,GtkTreeModelSort}, child_iter::TRI) - if isa(child_iter,_GtkTreeIter) - child_iter = Ref(child_iter) - end - b, filter_iter = G_.convert_child_iter_to_iter(model, child_iter) - b ? filter_iter : nothing + if isa(child_iter,_GtkTreeIter) + child_iter = Ref(child_iter) + end + b, filter_iter = G_.convert_child_iter_to_iter(model, child_iter) + b ? filter_iter : nothing end GtkTreeModelSort(child_model::GObject) = G_.TreeModelSort_new_with_model(GtkTreeModel(child_model)) @@ -273,9 +273,9 @@ GtkTreeModelSort(child_model::GObject) = G_.TreeModelSort_new_with_model(GtkTree function getindex(treeModel::GtkTreeModel, iter::TRI, column::Integer) val = Ref(GValue()) - if isa(iter,_GtkTreeIter) - iter = Ref(iter) - end + if isa(iter,_GtkTreeIter) + iter = Ref(iter) + end ccall((:gtk_tree_model_get_value, libgtk4), Nothing, (Ptr{GObject}, Ptr{_GtkTreeIter}, Cint, Ptr{GValue}), treeModel, iter, column - 1, val) val[Any] @@ -349,12 +349,12 @@ end ## string is of type "0:1:0" (0-based) function get_string_from_iter(treeModel::GtkTreeModel, iter::_GtkTreeIter) - ret = ccall(("gtk_tree_model_get_string_from_iter", libgtk4), Cstring, (Ptr{GObject}, Ptr{_GtkTreeIter}), treeModel, Ref(iter)) - ret2 = if ret == C_NULL - nothing - else - bytestring(ret, true) - end + ret = ccall(("gtk_tree_model_get_string_from_iter", libgtk4), Cstring, (Ptr{GObject}, Ptr{_GtkTreeIter}), treeModel, Ref(iter)) + ret2 = if ret == C_NULL + nothing + else + bytestring(ret, true) + end end ## these mutate iter to point to new object. @@ -368,8 +368,8 @@ string(treeModel::GtkTreeModel, iter::TRI) = get_string_from_iter(treeModel, ite ## index is Int[] 1-based function index_from_iter(treeModel::GtkTreeModel, iter::TRI) - s = get_string_from_iter(treeModel, iter) - s !== nothing ? (parse.(Int32, split(s, ":")) .+ 1) : nothing + s = get_string_from_iter(treeModel, iter) + s !== nothing ? (parse.(Int32, split(s, ":")) .+ 1) : nothing end ## An iterator to walk a tree, e.g., @@ -386,7 +386,7 @@ Base.IteratorSize(::TreeIterator) = Base.SizeUnknown() ## iterator interface for depth first search function start_(x::TreeIterator) - i = x.iter + i = x.iter i === nothing ? nothing : Ref(copy(i)) end @@ -444,14 +444,14 @@ iterate(x::TreeIterator, state=start_(x)) = done_(x, state) ? nothing : next_(x, function iter(treeModel::GtkTreeModel, path::GtkTreePath) - it = Ref{_GtkTreeIter}() - ret = ccall((:gtk_tree_model_get_iter, libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}, Ptr{GtkTreePath}), + it = Ref{_GtkTreeIter}() + ret = ccall((:gtk_tree_model_get_iter, libgtk4), Cint, (Ptr{GObject}, Ptr{_GtkTreeIter}, Ptr{GtkTreePath}), treeModel, it, path) != 0 - ret, it[] + ret, it[] end function path(treeModel::GtkTreeModel, iter::TRI) - GtkTreePath( ccall((:gtk_tree_model_get_path, libgtk4), Ptr{GtkTreePath}, + GtkTreePath( ccall((:gtk_tree_model_get_path, libgtk4), Ptr{GtkTreePath}, (Ptr{GObject}, Ref{_GtkTreeIter}), treeModel, iter ) ) end diff --git a/test/gfile.jl b/test/gfile.jl index 03c32e8a..be235a0c 100644 --- a/test/gfile.jl +++ b/test/gfile.jl @@ -7,21 +7,21 @@ using Test path=pwd() -f=GLib.G_.new_for_path(path) -path2=GLib.G_.get_path(GFile(f)) +f=GLib.GFile(path) +path2=GLib.path(GFile(f)) @test path==path2 f2=GLib.G_.dup(GFile(f)) -@test path==GLib.G_.get_path(GFile(f2)) +@test path==GLib.path(GFile(f2)) -@test GLib.G_.query_exists(GFile(f),nothing) +@test ispath(GFile(f)) -@test GLib.FileType_DIRECTORY == GLib.G_.query_file_type(GFile(f),GLib.FileQueryInfoFlags_NONE,nothing) +@test isdir(GFile(f)) fi = GLib.G_.query_info(GFile(f),"*",GLib.FileQueryInfoFlags_NONE,nothing) attributes = GLib.G_.list_attributes(fi,nothing) -#println(attributes) + end