Handle hostnames with upper-case letters
[webmin.git] / Webmin / LinkTable.pm
1 package Webmin::LinkTable;
2 use Webmin::Table;
3 use WebminCore;
4
5 =head2 new Webmin::LinkTable(heading, [columns], [width], [name])
6 Creates a new table that just displays links, like in the Users and Groups module
7 =cut
8 sub new
9 {
10 if (defined(&Webmin::Theme::LinkTable::new) &&
11     caller() !~ /Webmin::Theme::LinkTable/) {
12         return new Webmin::Theme::LinkTable(@_[1..$#_]);
13         }
14 my ($self, $heading, $columns, $width, $name) = @_;
15 $self = { 'sorter' => \&Webmin::Table::default_sorter,
16           'columns' => 4,
17           'sortable' => 1 };
18 bless($self);
19 $self->set_heading($heading);
20 $self->set_name($name) if (defined($name));
21 $self->set_width($width) if (defined($width));
22 $self->set_columns($columns) if (defined($columns));
23 return $self;
24 }
25
26 =head2 add_entry(name, link)
27 Adds one item to appear in the table
28 =cut
29 sub add_entry
30 {
31 my ($self, $name, $link) = @_;
32 push(@{$self->{'entries'}}, [ $name, $link ]);
33 }
34
35 =head2 html()
36 Returns the HTML for this table.
37 =cut
38 sub html
39 {
40 my ($self) = @_;
41
42 # Prepare the selector
43 my @srows = @{$self->{'entries'}};
44 my %selmap;
45 if (defined($self->{'selectinput'})) {
46         my $i = 0;
47         foreach my $r (@srows) {
48                 $selmap{$r} = $self->{'selectinput'}->one_html($i);
49                 $i++;
50                 }
51         }
52
53 # Sort the entries
54 my $sortdir = $self->get_sortdir();
55 if (defined($sortdir)) {
56         my $func = $self->{'sorter'};
57         @srows = sort { my $so = &$func($a->[0], $b->[0]);
58                         $sortdir ? -$so : $so } @srows;
59         }
60
61 # Build the sorter
62 my $head;
63 my $thisurl = $self->{'form'}->{'page'}->get_myurl();
64 $thisurl .= $thisurl =~ /\?/ ? "&" : "?";
65 my $name = $self->get_name();
66 if ($self->get_sortable()) {
67         $head = "<table cellpadding=0 cellspacing=0 width=100%><tr>";
68         $head .= "<td><b>".$self->get_heading()."</b></td> <td align=right>";
69         if (!defined($sortdir)) {
70                 # Not sorting .. show grey button
71                 $head .= "<a href='${thisurl}ui_sortdir_${name}=0'>".
72                          "<img src=/images/nosort.gif border=0></a>";
73                 }
74         else {
75                 # Sorting .. show button to switch mode
76                 my $notsort = !$sortdir;
77                 $head .= "<a href='${thisurl}ui_sortdir_${name}=$notsort'>".
78                          "<img src=/images/sort.gif border=0></a>";
79                 }
80         $head .= "</td></tr></table>";
81         }
82 else {
83         $head = $self->get_heading();
84         }
85
86 # Find any errors
87 my $rv;
88 if ($self->{'selectinput'}) {
89         # Get any errors for inputs
90         my @errs = $self->{'form'}->field_errors(
91                         $self->{'selectinput'}->get_name());
92         if (@errs) {
93                 foreach my $e (@errs) {
94                         $rv .= "<font color=#ff0000>$e</font><br>\n";
95                         }
96                 }
97         }
98
99 # Create the actual table
100 $rv .= &ui_table_start($head,
101                              defined($self->{'width'}) ? "width=$self->{'width'}"
102                                                        : undef, 1);
103 $rv .= "<td colspan=2><table width=100%>";
104 my $i = 0;
105 my $cols = $self->get_columns();
106 my $pc = 100/$cols;
107 foreach my $r (@srows) {
108         $rv .= "<tr>\n" if ($i%$cols == 0);
109         $rv .= "<td width=$pc%>".$selmap{$r}."<a href='$r->[1]'>".
110                &html_escape($r->[0])."</a></td>\n";
111         $rv .= "<tr>\n" if ($i%$cols == $cols-1);
112         $i++;
113         }
114 if ($i%$cols) {
115         # Finish off row
116         while($i++%$cols != $cols-1) {
117                 $rv .= "<td width=$pc%></td>\n";
118                 }
119         $rv .= "</tr>\n";
120         }
121 $rv .= "</table></td>";
122 $rv .= &ui_table_end();
123 return $rv;
124 }
125
126 =head2 set_heading(text)
127 Sets the heading text to appear above the table
128 =cut
129 sub set_heading
130 {
131 my ($self, $heading) = @_;
132 $self->{'heading'} = $heading;
133 }
134
135 sub get_heading
136 {
137 my ($self) = @_;
138 return $self->{'heading'};
139 }
140
141 sub set_name
142 {
143 my ($self, $name) = @_;
144 $self->{'name'} = $name;
145 }
146
147 =head2 get_name()
148 Returns the name for indentifying this table in HTML
149 =cut
150 sub get_name
151 {
152 my ($self) = @_;
153 if (defined($self->{'name'})) {
154         return $self->{'name'};
155         }
156 elsif ($self->{'form'}) {
157         my $secs = $self->{'form'}->{'sections'};
158         for(my $i=0; $i<@$secs; $i++) {
159                 return "table".$i if ($secs->[$i] eq $self);
160                 }
161         }
162 return "table";
163 }
164
165 =head2 set_sorter(function)
166 Sets a function used for sorting fields. Will be called with two values to compare
167 =cut
168 sub set_sorter
169 {
170 my ($self, $func) = @_;
171 $self->{'sorter'} = $func;
172 }
173
174 =head2 default_sorter(value1, value2)
175 =cut
176 sub default_sorter
177 {
178 my ($value1, $value2, $col) = @_;
179 return lc($value1) cmp lc($value2);
180 }
181
182 =head2 set_sortable(sortable?)
183 Tells the table if sorting is allowed or not. By default, it is.
184 =cut
185 sub set_sortable
186 {
187 my ($self, $sortable) = @_;
188 $self->{'sortable'} = $sortable;
189 }
190
191 sub get_sortable
192 {
193 my ($self) = @_;
194 return $self->{'sortable'};
195 }
196
197 =head2 get_sortdir()
198 Returns the order to sort in (1 for descending)
199 =cut
200 sub get_sortdir
201 {
202 my ($self) = @_;
203 my $in = $self->{'form'} ? $self->{'form'}->{'in'} : undef;
204 my $name = $self->get_name();
205 if ($in && defined($in->{"ui_sortdir_".$name})) {
206         return ( $in->{"ui_sortdir_".$name} );
207         }
208 else {
209         return ( $self->{'sortdir'} );
210         }
211 }
212
213 =head2 set_sortdir(descending?)
214 Sets the default sort direction, unless overridden by the user.
215 =cut
216 sub set_sortcolumn
217 {
218 my ($self, $desc) = @_;
219 $self->{'sortdir'} = $desc;
220 }
221
222 =head2 set_width([number|number%])
223 Sets the width of this entire table. Can be called with 100%, 500 or undef to use
224 the minimum possible width.
225 =cut
226 sub set_width
227 {
228 my ($self, $width) = @_;
229 $self->{'width'} = $width;
230 }
231
232 =head2 set_columns(cols)
233 Sets the number of columns to display
234 =cut
235 sub set_columns
236 {
237 my ($self, $columns) = @_;
238 $self->{'columns'} = $columns;
239 }
240
241 sub get_columns
242 {
243 my ($self) = @_;
244 return $self->{'columns'};
245 }
246
247 =head2 set_form(form)
248 Called by the Webmin::Form object when this table is added to it
249 =cut
250 sub set_form
251 {
252 my ($self, $form) = @_;
253 $self->{'form'} = $form;
254 if ($self->{'selectinput'}) {
255         $self->{'selectinput'}->set_form($form);
256         }
257 }
258
259 =head2 set_selector(input)
260 Takes a Webmin::Checkboxes or Webmin::Radios object, and uses it to add checkboxes
261 to all the entries
262 =cut
263 sub set_selector
264 {
265 my ($self, $input) = @_;
266 $self->{'selectinput'} = $input;
267 $input->set_form($form);
268 }
269
270 =head2 get_selector()
271 Returns the UI element used for selecting rows
272 =cut
273 sub get_selector
274 {
275 my ($self) = @_;
276 return $self->{'selectinput'};
277 }
278
279 =head2 validate()
280 Validates the selector input
281 =cut
282 sub validate
283 {
284 my ($self) = @_;
285 my $seli = $self->{'selectinput'};
286 if ($seli) {
287         return map { [ $seli->get_name(), $_ ] } $seli->validate();
288         }
289 return ( );
290 }
291
292 =head2 get_value(input-name)
293 Returns the value of the input with the given name.
294 =cut
295 sub get_value
296 {
297 my ($self, $name) = @_;
298 if ($self->{'selectinput'} && $self->{'selectinput'}->get_name() eq $name) {
299         return $self->{'selectinput'}->get_value();
300         }
301 return undef;
302 }
303
304 =head2 list_inputs()
305 Returns all inputs in all form sections
306 =cut
307 sub list_inputs
308 {
309 my ($self) = @_;
310 return $self->{'selectinput'} ? ( $self->{'selectinput'} ) : ( );
311 }
312
313 1;
314