dialog-fu 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +3 -0
- data/README.adoc +53 -0
- data/Rakefile +25 -0
- data/dialog-fu.gemspec +22 -0
- data/lgpl-3.0.txt +165 -0
- data/lib/dialog-fu.rb +1 -0
- data/lib/dialog.rb +10 -0
- data/lib/dialog/cocoadialog.rb +2 -0
- data/lib/dialog/dialog.rb +2 -0
- data/lib/dialog/kdialog.rb +344 -0
- data/lib/dialog/main.rb +53 -0
- data/lib/dialog/yad.rb +2 -0
- data/lib/dialog/zenity.rb +2 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 546f459f27e812bb284a2afeda60a26995655286
|
4
|
+
data.tar.gz: b7398666b2b26e12512143fec0afe4c5ae1526b1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 98327730998009bf20e0302ed6dccba9c7ae3849f64e234fab4024dcd88ea878c8f51fd4cadaf4c6781a17540bddb81b0c6458c93ab9c2bb926cebd650204f62
|
7
|
+
data.tar.gz: c94b88165cef7049f2a5d1bc618271b4cb83f5d0a05391db06d4738ff9ffa1b4f6a3d74629af8faff6fb57acb6261ce852c81f1e6407e688595e5c182572d5c7
|
data/.yardopts
ADDED
data/README.adoc
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
= Dialog-fu
|
2
|
+
Chris Riddoch <riddochc@gmail.com>
|
3
|
+
:language: ruby
|
4
|
+
|
5
|
+
Version 0.2, 2014-06-27
|
6
|
+
|
7
|
+
== Description
|
8
|
+
|
9
|
+
This library provides a high-level API for simple user interfaces with
|
10
|
+
kdialog (forthcoming: dialog/zenity/yad/cocoadialog)
|
11
|
+
|
12
|
+
Sometimes, being usable matters. In addition to providing the world's most
|
13
|
+
intricate command suite and option parsing for expert users, it might be nice
|
14
|
+
to just give a little interface. Not so much that you have to restructure
|
15
|
+
your whole program around some GUI framework, but if you need a filename
|
16
|
+
or a little text entry box or a confirmation box, the "dialog"-like programs
|
17
|
+
can make the job a lot easier.
|
18
|
+
|
19
|
+
This is intended to make it easy for you, as a programmer, to make your
|
20
|
+
programs easier to use. Everyone wins, right?
|
21
|
+
|
22
|
+
Further documentation can be generated with by running 'rake'
|
23
|
+
|
24
|
+
== Requirements
|
25
|
+
|
26
|
+
Ruby 2.0 or newer
|
27
|
+
|
28
|
+
One of:
|
29
|
+
|
30
|
+
* kdialog
|
31
|
+
|
32
|
+
In the future, other variations of the 'dialog' program will be supported.
|
33
|
+
|
34
|
+
== Installation
|
35
|
+
|
36
|
+
gem install dialog-fu
|
37
|
+
|
38
|
+
== Use
|
39
|
+
|
40
|
+
----
|
41
|
+
require 'dialog-fu'
|
42
|
+
|
43
|
+
Dialog.autosetup # Figure out what implementation to use
|
44
|
+
|
45
|
+
Dialog.messagebox("Hello, world")
|
46
|
+
----
|
47
|
+
|
48
|
+
== License
|
49
|
+
|
50
|
+
Copyright © 2011-14 Chris Riddoch
|
51
|
+
|
52
|
+
See lgpl-3.0.txt for license details
|
53
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'yard'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require_relative './lib/dialog.rb'
|
4
|
+
|
5
|
+
task :doc => :yard
|
6
|
+
YARD::Rake::YardocTask.new do |t|
|
7
|
+
t.files = ['lib/**/*.rb']
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Builds the gem"
|
11
|
+
task :gem do
|
12
|
+
sh "gem build dialog-fu.gemspec"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Installs the gem"
|
16
|
+
task :install => :gem do
|
17
|
+
sh "gem install dialog-fu-#{Dialog::VERSION}.gem"
|
18
|
+
end
|
19
|
+
|
20
|
+
Rake::TestTask.new do |t|
|
21
|
+
t.libs << "test"
|
22
|
+
t.test_files = FileList['test/*_test.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => [:test]
|
data/dialog-fu.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require './lib/dialog'
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'dialog-fu'
|
5
|
+
s.version = Dialog::VERSION
|
6
|
+
s.author = 'Chris Riddoch'
|
7
|
+
s.email = 'riddochc@gmail.com'
|
8
|
+
s.homepage = 'http://syntacticsugar.org/software/dialog-fu/'
|
9
|
+
s.description = "A high-level API for simple user interfaces with dialog programs"
|
10
|
+
s.license = 'LGPL-3.0'
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
s.summary = 'Extracts information from tables in documents'
|
13
|
+
s.files = Dir.glob("{docs,bin,lib,spec,templates,benchmarks}/**/*") +
|
14
|
+
['lgpl-3.0.txt', 'README.adoc', 'Rakefile', '.yardopts', __FILE__]
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.has_rdoc = 'yard'
|
17
|
+
s.extra_rdoc_files = ['README.adoc']
|
18
|
+
s.required_ruby_version = '>= 2.0.0'
|
19
|
+
s.add_development_dependency('rake', '~> 10.0', '>= 10.0.0')
|
20
|
+
s.add_development_dependency('yard', '~> 0.8', '>= 0.8.7.3')
|
21
|
+
end
|
22
|
+
|
data/lgpl-3.0.txt
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/lib/dialog-fu.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'dialog'
|
data/lib/dialog.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Dialog
|
2
|
+
VERSION='0.2'
|
3
|
+
end
|
4
|
+
|
5
|
+
require_relative "dialog/dialog"
|
6
|
+
require_relative "dialog/kdialog"
|
7
|
+
require_relative "dialog/zenity"
|
8
|
+
require_relative "dialog/yad"
|
9
|
+
require_relative "dialog/cocoadialog"
|
10
|
+
require_relative "dialog/main" # needs to be loaded last, so things can be imported properly.
|
@@ -0,0 +1,344 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Dialog::KDialog
|
5
|
+
|
6
|
+
# Standard dialog boxes
|
7
|
+
#
|
8
|
+
# The valid combinations of boolean parameters specifying the type of buttons available are as follows:
|
9
|
+
#
|
10
|
+
# [cols="4"]
|
11
|
+
# |===
|
12
|
+
# |*YesNo*
|
13
|
+
# |*Cancel*
|
14
|
+
# |*Warning*
|
15
|
+
# |*Continue*
|
16
|
+
#
|
17
|
+
# | true
|
18
|
+
# | true
|
19
|
+
# | true
|
20
|
+
# | false
|
21
|
+
#
|
22
|
+
# | true
|
23
|
+
# | true
|
24
|
+
# | false
|
25
|
+
# | false
|
26
|
+
#
|
27
|
+
# | true
|
28
|
+
# | false
|
29
|
+
# | false
|
30
|
+
# | false
|
31
|
+
#
|
32
|
+
# | true
|
33
|
+
# | false
|
34
|
+
# | true
|
35
|
+
# | false
|
36
|
+
#
|
37
|
+
# | false
|
38
|
+
# | true
|
39
|
+
# | true
|
40
|
+
# | true
|
41
|
+
# |===
|
42
|
+
#
|
43
|
+
# @param text [String] The text presented to the user above buttons.
|
44
|
+
# @param yesno [Boolean] If true, show "Yes" and "No" buttons.
|
45
|
+
# @param cancel [Boolean] If true, show a "Cancel" button.
|
46
|
+
# @param continue_btn [Boolean] If true, show a "Continue" button.
|
47
|
+
# @param warning [Boolean] If true, the icon shown is a warning icon, not a standard question icon
|
48
|
+
# @yield [] If the user makes a positive selection (yes or continue), the given
|
49
|
+
# block is called. If not, the block is ignored.
|
50
|
+
def dialogbox(text, yesno: true, cancel: false, continue_btn: false, warning: false)
|
51
|
+
valid_dialogs = {"warningyesnocancel" => true, "yesnocancel" => true,
|
52
|
+
"yesno" => true, "warningyesno" => true,
|
53
|
+
"warningcontinuecancel" => true}
|
54
|
+
cmd = ""
|
55
|
+
cmd += "warning" if warning == true
|
56
|
+
cmd += "yesno" if yesno == true
|
57
|
+
cmd += "continue" if continue_btn == true
|
58
|
+
cmd += "cancel" if cancel == true
|
59
|
+
unless valid_dialogs.has_key?(cmd)
|
60
|
+
raise "Can't make that kind of dialog box"
|
61
|
+
end
|
62
|
+
cmd = "--#{cmd}"
|
63
|
+
out, status = *run([cmd, text])
|
64
|
+
if block_given? and status == true
|
65
|
+
yield()
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# A message box, for displaying a little text to the user.
|
70
|
+
# For longer, multi-line text, you may prefer to use #textbox.
|
71
|
+
# Contrasting with the standard dialog boxes, the button presented to the user
|
72
|
+
# only has the effect of closing the box.
|
73
|
+
#
|
74
|
+
# @param type [:msgbox :sorry :error] The type of message box, affects the choice of icon shown in the box
|
75
|
+
# @!macro [new] runreturn
|
76
|
+
# @return [Array<(String, Boolean)>] the textual output of running kdialog, and whether it exited successfully
|
77
|
+
def messagebox(text, type: :msgbox)
|
78
|
+
unless {:msgbox => 1, :sorry => 1, :error => 1}.has_key?(type)
|
79
|
+
raise "Can't make that kind of message box"
|
80
|
+
end
|
81
|
+
cmdtype = "--#{type}"
|
82
|
+
run([cmdtype, text])
|
83
|
+
end
|
84
|
+
|
85
|
+
# A window for showing the user a large amount of text, potentially using
|
86
|
+
# horizontal and vertical scrollbars. For small amounts of text, use #messagebox
|
87
|
+
#
|
88
|
+
# @param text [String IO] The text to send to the user, or a readable IO object.
|
89
|
+
# @param height [Integer] The height of the textbox area, defaults to 10
|
90
|
+
# @param width [Integer] The width of the textbox area, defaults to 40
|
91
|
+
# @macro runreturn
|
92
|
+
def textbox(text, height: 10, width: 40)
|
93
|
+
Tempfile.open('dialogfu') do |tf|
|
94
|
+
if text.respond_to?(:read)
|
95
|
+
tf.print(text.read)
|
96
|
+
else
|
97
|
+
tf.print(text)
|
98
|
+
end
|
99
|
+
tf.close
|
100
|
+
run(["--textbox", path, "--height", height, "--width", width])
|
101
|
+
tf.unlink
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Present an input box. It may be a one-line field, a password field, or a larger text-entry area potentially with scrollbars.
|
106
|
+
#
|
107
|
+
# @param prompt [String] The text to prompt the user, above the input fields
|
108
|
+
# @param content [String] The initial value in the input box
|
109
|
+
# @param height [Integer] The height of the input field. If 1, presents a single-line input field.
|
110
|
+
# If larger, presents a text box that can potentially scroll vertically and horizontally. Defaults to 1
|
111
|
+
# @param width [Integer] The width of the input field. Note that this does not limit the amount of text
|
112
|
+
# the user may return, only how much can be seen on the screen at once.
|
113
|
+
# @param password [Boolean] When true, use a 'key' icon and only show dots in place of input characters.
|
114
|
+
# When this is true, the height parameter is required to be 1, otherwise this option has no effect.
|
115
|
+
# @yieldparam input [String] the text provided by the user
|
116
|
+
# @macro runreturn
|
117
|
+
def inputbox(prompt: "Input some text", content: nil, height: 1, width: 40, password: false, &blk)
|
118
|
+
if height == 1
|
119
|
+
if password == true
|
120
|
+
cmd = ["--password"]
|
121
|
+
else
|
122
|
+
cmd = ["--inputbox"]
|
123
|
+
end
|
124
|
+
elsif height > 1
|
125
|
+
cmd = ["--textinputbox"]
|
126
|
+
end
|
127
|
+
cmd << prompt
|
128
|
+
if password == false
|
129
|
+
cmd << content if content
|
130
|
+
if height > 1
|
131
|
+
cmd += ["--height", height]
|
132
|
+
end
|
133
|
+
cmd += ["--width", 40]
|
134
|
+
end
|
135
|
+
|
136
|
+
run(cmd, &blk)
|
137
|
+
end
|
138
|
+
|
139
|
+
# @!macro [new] labelparam
|
140
|
+
# @param label [String] The text to display above input fields
|
141
|
+
# @!macro [new] choiceparam
|
142
|
+
# @param choices [#members] An object with an attribute for each choice, and a +#members+ method which
|
143
|
+
# returns a list of those attributes to be used.
|
144
|
+
|
145
|
+
# A dropdown box
|
146
|
+
#
|
147
|
+
# This is similar to a radio button selection; only one selection can be made.
|
148
|
+
#
|
149
|
+
# @macro choiceparam
|
150
|
+
# @macro labelparam
|
151
|
+
#
|
152
|
+
def combobox(choices, label: "")
|
153
|
+
cmd = ["--combobox", label] + choices.members.map {|k| k.to_s}
|
154
|
+
run(cmd) {|sel|
|
155
|
+
selected = (sel + '=').to_sym
|
156
|
+
(choices.members - [selected]).each {|c| choices.send((c.to_s + '=').to_sym, false)}
|
157
|
+
choices.send(selected, true)
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
# Present a set of checkboxes to the user
|
162
|
+
#
|
163
|
+
# Using this method may be easier than using #selection, as you don't need to indicate you want checkboxes.
|
164
|
+
#
|
165
|
+
# @macro choiceparam
|
166
|
+
# @macro labelparam
|
167
|
+
# @!macro [new] defaultparam
|
168
|
+
# @param default [Array<String> String] The name of the attribute to be pre-selected for the user,
|
169
|
+
# or a list of such names, in the case of checkboxes. If not provided, the attribute's value is
|
170
|
+
# tested, and if true, is selected.
|
171
|
+
# @example Using a Struct for checkboxes
|
172
|
+
# Foodselection = Struct.new(:salad, :soup, :sandwich, :cookie, :drink)
|
173
|
+
# choices = Foodselection.new(false, false, true, false, true) # sandwich and drink preselected
|
174
|
+
# checkboxes(choices, label: "What would you like for lunch?")
|
175
|
+
# @macro runreturn
|
176
|
+
#
|
177
|
+
def checkboxes(choices, label: "", default: nil)
|
178
|
+
selection(choices, label: label, type: :check, default: default)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Present a set of radio buttons to the user
|
182
|
+
#
|
183
|
+
# Using this method may be easier than using #selection, as you don't need to indicate you want radio buttons.
|
184
|
+
#
|
185
|
+
# @macro choiceparam
|
186
|
+
# @macro labelparam
|
187
|
+
# @macro defaultparam
|
188
|
+
# @macro runreturn
|
189
|
+
# @note It's the caller's responsibility to either specify a default,
|
190
|
+
# or make sure only one of the 'choices' attributes is true in the +choices+ parameter.
|
191
|
+
def radiobuttons(choices, label: "", default: nil)
|
192
|
+
selection(choices, label: label, type: :radio, default: default)
|
193
|
+
end
|
194
|
+
|
195
|
+
# @macro choiceparam
|
196
|
+
# @macro labelparam
|
197
|
+
# @macro defaultparam
|
198
|
+
# @param type [Symbol] Either :check (for checkboxes, multiple selections allowed) or :radio, (for
|
199
|
+
# radio buttons, only one selection)
|
200
|
+
# @raise UnknownSelectionType If type is something other than :check or :radio
|
201
|
+
# @macro runreturn
|
202
|
+
#
|
203
|
+
# @note If +type+ is +:radio+, it's the caller's responsibility to either specify a default,
|
204
|
+
# or make sure only one of the 'choices' attributes is true in the +choices+ parameter.
|
205
|
+
def selection(choices, label: "", type: :check, default: nil)
|
206
|
+
cmd = ["--separate-output"]
|
207
|
+
cmd << case type
|
208
|
+
when :check
|
209
|
+
"--checklist"
|
210
|
+
when :radio
|
211
|
+
"--radiolist"
|
212
|
+
else
|
213
|
+
raise UnknownSelectionType, "Unknown selection type", caller
|
214
|
+
end
|
215
|
+
cmd << label
|
216
|
+
choices.members.each_with_index {|c, i|
|
217
|
+
if ((default.nil? and choices.send(c)) or (default == c) or (default.include?(c)))
|
218
|
+
cmd += [i.to_s, c.to_s, 'on']
|
219
|
+
else
|
220
|
+
cmd += [i.to_s, c.to_s, 'off']
|
221
|
+
end
|
222
|
+
}
|
223
|
+
run(cmd) do |sel|
|
224
|
+
selected = sel.each_line.map{|l| l.chomp.to_i}
|
225
|
+
choices.members.each.with_index do |box, i|
|
226
|
+
method = (box.to_s + '=').to_sym
|
227
|
+
if selected.include?(i)
|
228
|
+
choices.send(method, true)
|
229
|
+
else
|
230
|
+
choices.send(method, false)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Raise a notification for the user. This doesn't bring up a window that takes focus,
|
237
|
+
# just a little box (usually above the taskbar) in the notification area that goes away by itself.
|
238
|
+
#
|
239
|
+
# @param text [String] The text to show in the notification
|
240
|
+
# @param timeout [Integer] The number of seconds to show the notification for
|
241
|
+
def notification(text, timeout: 3)
|
242
|
+
run(["--passivepopup", text, timeout.to_s])
|
243
|
+
end
|
244
|
+
|
245
|
+
# Present a file-picker box, for getting filenames or URLs from the user, for saving or opening.
|
246
|
+
#
|
247
|
+
# @param action [Symbol] One of :save or :open
|
248
|
+
# @param type [Symbol] One of :url, :file, or :directory, indicating what kind of input is expected from the user
|
249
|
+
# @param dir [String] Directory to start the UI in, defaults to ENV['HOME']
|
250
|
+
# @param multiple [Boolean] If true, allow the user to select multiple files. Only works when action is :open.
|
251
|
+
# @param filter [String] A description of what types of files should be displayed in directory listings
|
252
|
+
# @yieldparam path [Array<String> String] The path (or paths) selected by the user
|
253
|
+
# @return [Array<String> String] The path (or paths) selected by the user
|
254
|
+
# @todo Figure out what kinds of strings are expected of the filter parameter, write code to validate
|
255
|
+
def filepicker(action: :save, type: :file, dir: ENV['HOME'], multiple: false, filter: nil, &blk)
|
256
|
+
cmd = ["--separate-output"]
|
257
|
+
cmd << "--multiple" if (multiple and action == :open)
|
258
|
+
cmd << case [action, type]
|
259
|
+
when [:save, :file]
|
260
|
+
"--getsavefilename"
|
261
|
+
when [:save, :url]
|
262
|
+
"--getsaveurl"
|
263
|
+
when [:open, :file]
|
264
|
+
"--getopenfilename"
|
265
|
+
when [:open, :url]
|
266
|
+
"--getopenurl"
|
267
|
+
else
|
268
|
+
if type == :directory
|
269
|
+
"--getexistingdirectory"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
cmd << dir
|
273
|
+
cmd << filter unless (type == :directory or filter.nil?)
|
274
|
+
if block_given?
|
275
|
+
run(cmd) do |input|
|
276
|
+
if multiple
|
277
|
+
param = input.split(/\n/)
|
278
|
+
else
|
279
|
+
param = input
|
280
|
+
end
|
281
|
+
yield(param)
|
282
|
+
end
|
283
|
+
else
|
284
|
+
input, status = run(cmd)
|
285
|
+
if multiple
|
286
|
+
input.split(/\n/)
|
287
|
+
else
|
288
|
+
input
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# @todo Implement
|
294
|
+
# Known groups for iconloader (on my system, anyway):
|
295
|
+
#
|
296
|
+
# * Desktop, Toolbar, MainToolbar, Small, Panel, Dialog, User, Action, Application, Device, FileSystem, MimeType, Animation, Category, Emblem, Emote, International, Place, StatusIcon
|
297
|
+
# * From KDE3: Devices, MimeTypes, Applications, Actions
|
298
|
+
def icon()
|
299
|
+
end
|
300
|
+
|
301
|
+
# @todo Design and implement API for using progressbar
|
302
|
+
def progressbar()
|
303
|
+
require 'dbus' unless DBus
|
304
|
+
steps = 10
|
305
|
+
out, status = Open3.capture2("kdialog", "--progressbar", "Titlebar Text", steps.to_s)
|
306
|
+
if status != 0
|
307
|
+
raise "kdialog exited unexpectedly"
|
308
|
+
end
|
309
|
+
servicename, path = *out.split(/\s+/)
|
310
|
+
|
311
|
+
bus = DBus::SessionBus.instance
|
312
|
+
dialogservice = bus.service(servicename)
|
313
|
+
dialogobj = dialogservice.object(path)
|
314
|
+
d = dialogobj["org.kde.kdialog.ProgressDialog"]
|
315
|
+
|
316
|
+
d.showCancelButton(true) # or false...
|
317
|
+
r = d.wasCancelled
|
318
|
+
r.first # the boolean. Why it's in an array? Dunno.
|
319
|
+
d["maximum"] # => 10
|
320
|
+
d["autoClose"] # => false, by default
|
321
|
+
d.setLabelText("Test")
|
322
|
+
d["value"] # Can be assigned! Yay! Ignored if out of range.
|
323
|
+
d.close # When done!
|
324
|
+
end
|
325
|
+
|
326
|
+
# @api private
|
327
|
+
# @param arglist [Array<String>] List of command-line arguments for kdialog
|
328
|
+
# @raise [StandardError] Any exception raised by Open3#capture2
|
329
|
+
# @yieldparam output [String] The output of running kdialog
|
330
|
+
# @macro runreturn
|
331
|
+
def run(arglist, &blk)
|
332
|
+
cmd = ["kdialog"] + arglist
|
333
|
+
output, code = Open3.capture2(*cmd)
|
334
|
+
status = case code.exitstatus
|
335
|
+
when 0 then true
|
336
|
+
when 1 then false
|
337
|
+
else false
|
338
|
+
end
|
339
|
+
if block_given? and status == true
|
340
|
+
yield(output.chomp)
|
341
|
+
end
|
342
|
+
return output.chomp, status
|
343
|
+
end
|
344
|
+
end
|
data/lib/dialog/main.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module Dialog
|
2
|
+
|
3
|
+
# Figure out which implementation of dialog to use, based on platform detection.
|
4
|
+
# This loads the methods from more specific submodules into this Dialog module, so that
|
5
|
+
# you can just call (for example) Dialog.messagebox("Hello, world.")
|
6
|
+
def self.autosetup
|
7
|
+
case RUBY_PLATFORM
|
8
|
+
when /linux/
|
9
|
+
if ENV.fetch('DISPLAY', "").length > 0
|
10
|
+
kdepid = IO.popen(["pidof", "-s", "kdeinit", "kdeinit4"], 'r') do |io|
|
11
|
+
io.read
|
12
|
+
end
|
13
|
+
to_run = ["kdialog", "yad", "zenity", "dialog"].map {|name|
|
14
|
+
name if ENV['PATH'].split(/:/).detect {|dir| File.exists?(File.join(dir, name)) }
|
15
|
+
}.compact
|
16
|
+
|
17
|
+
if kdepid != "" and to_run.include?("kdialog")
|
18
|
+
extend KDialog # Already running KDE?
|
19
|
+
else
|
20
|
+
if to_run.include?("yad")
|
21
|
+
extend Yad
|
22
|
+
elsif to_run.include?("zenity")
|
23
|
+
extend Zenity
|
24
|
+
elsif to_run.include?("kdialog")
|
25
|
+
extend KDialog
|
26
|
+
elsif (to_run.include?("dialog") and $stdout.isatty)
|
27
|
+
extend Dialog
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
extend Dialog if ($stdout.isatty and $stdin.isatty)
|
32
|
+
end
|
33
|
+
when /darwin/
|
34
|
+
extend CocoaDialog
|
35
|
+
when /mingw/
|
36
|
+
to_run = ["yad", "zenity", "dialog"].map {|name|
|
37
|
+
name if ENV['PATH'].split(/;/).detect {|dir| File.exists?(File.join(dir, name)) }
|
38
|
+
}.compact
|
39
|
+
case to_run.first
|
40
|
+
when 'yad'
|
41
|
+
extend Yad
|
42
|
+
when 'zenity'
|
43
|
+
extend Zenity
|
44
|
+
when 'dialog'
|
45
|
+
extend Dialog
|
46
|
+
else
|
47
|
+
# Not sure here, any other way to get a dialog on windows?
|
48
|
+
end
|
49
|
+
else
|
50
|
+
# The user will just have to load it themselves.
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/dialog/yad.rb
ADDED
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dialog-fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Riddoch
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '10.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 10.0.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '10.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 10.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: yard
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.8'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.8.7.3
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0.8'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.8.7.3
|
53
|
+
description: A high-level API for simple user interfaces with dialog programs
|
54
|
+
email: riddochc@gmail.com
|
55
|
+
executables: []
|
56
|
+
extensions: []
|
57
|
+
extra_rdoc_files:
|
58
|
+
- README.adoc
|
59
|
+
files:
|
60
|
+
- ".yardopts"
|
61
|
+
- README.adoc
|
62
|
+
- Rakefile
|
63
|
+
- dialog-fu.gemspec
|
64
|
+
- lgpl-3.0.txt
|
65
|
+
- lib/dialog-fu.rb
|
66
|
+
- lib/dialog.rb
|
67
|
+
- lib/dialog/cocoadialog.rb
|
68
|
+
- lib/dialog/dialog.rb
|
69
|
+
- lib/dialog/kdialog.rb
|
70
|
+
- lib/dialog/main.rb
|
71
|
+
- lib/dialog/yad.rb
|
72
|
+
- lib/dialog/zenity.rb
|
73
|
+
homepage: http://syntacticsugar.org/software/dialog-fu/
|
74
|
+
licenses:
|
75
|
+
- LGPL-3.0
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 2.0.0
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.2.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Extracts information from tables in documents
|
97
|
+
test_files: []
|
98
|
+
has_rdoc: yard
|