require 'dbus' require 'pathname' #class DBus::Base # def initialize object # @object = object # @object.interfaces.each do |intname| # int = @object[intname] # int.methods do |name, | # meth # end # end # end #end module ProgressBar @klasses ||= [] class < unless 0 == l or 100 == l @outfd.printf "\r\e[J%s / %s [%-*s] %s", format_time(dd), format_time(td), 100, b, text end alias change_progress change_text def error text @errfd.printf "\r\e[J%s\n", text @errfd.flush end def finish @outfd.puts @outfd.flush end end class ProgressBar::KDE < ProgressBar::Base attr_reader :bus, :service, :view def initialize max, text = nil, title: nil, app_name: nil, app_icon_name: nil, unit: nil, is_cancable: nil, is_suspendable: nil, **_options super max, text text = @text text = nil if text.nil? or text.empty? title = nil if title.nil? or title.empty? unit = '' if unit.nil? or unit.empty? @title, @text, @unit, @app_name, @app_icon_name, @is_cancable, @is_suspendable = title, text, unit, app_name || $0, app_icon_name || '', is_cancable, is_suspendable @errors = [] end def possible? 'KDE' == ENV['XDG_CURRENT_DESKTOP'] end def start @finished = false @bus = DBus::SessionBus.instance @service = @bus['org.kde.JobViewServer'] jvs = @service['/JobViewServer']['org.kde.JobViewServer'] flags = (@is_cancable ? 0x1 : 0) | (@is_suspendable ? 0x2 : 0) view_path = jvs.requestView @app_name, @app_icon_name, flags @view = @service[view_path]['org.kde.JobViewV2'] super @view.setTotalAmount @max, @unit end def change_text @view.setInfoMessage text end def change_progress @view.setProcessedAmount i, @unit @view.setPercent done_rel end def error text #STDERR.puts @view.object.introspect #@view.setError text @view.setDescriptionField 0, "Error", text #@view.setInfoMessage "#{text}\nError: #{error}" end def finish return if @finished @view.terminate '' @finished = true end def max= value super value @view.setTotalAmount value, @unit end end class ProgressBar::KDialog < ProgressBar::Base attr_reader :dialog_service_path, :dialog_object_path, :errors, :dialog_object def initialize max, text = nil, title: nil, **_options super max, text text = @text text = nil if text.nil? or text.empty? title = nil if title.nil? or title.empty? @title = title @errors = [] end def possible? path = Pathname.new `which kdialog`.chomp $?.exitstatus and path.executable? end def start @finished = false args = ['kdialog', @title ? ['--title', @title] : [], '--progressbar', @text || '.', @max].flatten.compact.map &:to_s @dialog_service_path, @dialog_object_path = IO.popen( args, 'r', &:readlines).join( "\n").split ' ' @dialog_bus = DBus.session_bus @dialog_service = @dialog_bus[@dialog_service_path] @dialog_object = @dialog_service[ @dialog_object_path] #STDERR.puts "%p" % @dialog_object.introspect @dialog_object.showCancelButton 1 super change_text if text.nil? change_progress rescue DBus::Error raise Interrupt if $!.name == 'org.freedesktop.DBus.Error.ServiceUnknown' raise end def self.kdialog *a windowid = ENV['WINDOWID'] windowid = (windowid.is_a?(String) && !windowid.empty?) ? ['--attach', windowid] : [] system 'kdialog', *windowid, *a end def kdialog(*a) self.class.kdialog *a end def change_progress() #@dialog_object.Set 'org.kde.kdialog.ProgressDialog', 'value', i @dialog_object['value'] = i raise Interrupt if @dialog_object.wasCancelled rescue DBus::Error raise Interrupt if $!.name == 'org.freedesktop.DBus.Error.ServiceUnknown' raise end def change_text() @dialog_object.setLabelText text raise Interrupt if @dialog_object.wasCancelled rescue DBus::Error raise Interrupt if $!.name == 'org.freedesktop.DBus.Error.ServiceUnknown' raise end def error text kdialog '--error', text end def finish() return if @finished @dialog_object.close rescue DBus::Error @finished = true end def max= val super val @dialog_object['maximum'] = val end end ProgressBar.register ProgressBar::Console ProgressBar.register ProgressBar::KDE ProgressBar.register ProgressBar::KDialog