1package App::ZFSCurses::WidgetFactory; 2 3use 5.10.1; 4use strict; 5use warnings; 6 7=head1 NAME 8 9App::ZFSCurses::WidgetFactory - Create widgets. 10 11=head1 METHODS 12 13=head1 VERSION 14 15Version 1.212. 16 17=cut 18 19our $VERSION = '1.212'; 20 21=head2 new 22 23Create an instance of App::ZFSCurses::WidgetFactory. 24 25=cut 26 27sub new { 28 my $class = shift; 29 30 my %args = ( 31 container => {}, 32 properties => {}, 33 ro_properties => [ 34 'available', 'compressratio', 35 'createtxg', 'creation', 36 'clones', 'defer_destroy', 37 'encryption_root', 'filesystem_count', 38 'keystatus', 'guid', 39 'logicalreferenced', 'logicalused', 40 'mounted', 'objsetid', 41 'origin', 'refcompressratio', 42 'referenced', 'receive_resume_token', 43 'snapshot_count', 'type', 44 'used', 'usedbychildren', 45 'usedbydataset', 'usedbyrefreservation', 46 'usedbysnapshots', 'userrefs', 47 'volsize', 'written', 48 'utf8only' 49 ] 50 ); 51 52 my $this = bless \%args, $class; 53 $this->fill_property_hash(); 54 55 return $this; 56} 57 58=head2 search_value 59 60Search a value in an array. Return the value index if found. Return -1 if not 61found. 62 63=cut 64 65sub search_value { 66 my $self = shift; 67 my ( $element, $array ) = @_; 68 69 foreach ( 0 .. $#$array ) { 70 if ( $array->[$_] eq $element ) { 71 return $_; 72 } 73 } 74 75 return -1; 76} 77 78=head2 widget_selector 79 80Select the right widget to create. This method expects a property list as first 81argument. It will then check for its type, create the widget accordingly and 82return it. 83 84=cut 85 86sub widget_selector { 87 my $self = shift; 88 my $property_values = shift; 89 90 my $ref = ref $property_values; 91 my $widget = {}; 92 93 if ( $ref =~ /ARRAY/ ) { 94 $widget->{type} = 'Radiobuttonbox'; 95 $widget->{values} = { 96 -height => -1, 97 -width => -1, 98 -y => 3, 99 -padleft => 1, 100 -padright => 1, 101 -padbottom => 2, 102 -fg => 'blue', 103 -bg => 'black', 104 -vscrollbar => 1, 105 -wraparound => 1, 106 -intellidraw => 1, 107 -selected => 108 $self->search_value( $self->{current_value}, $property_values ), 109 -values => $property_values 110 }; 111 } 112 elsif ( $ref =~ /SCALAR/ ) { 113 $widget->{type} = 'TextEntry'; 114 $widget->{values} = { 115 -y => 3, 116 -ipadleft => 1, 117 -sbborder => 1, 118 -width => 10 119 }; 120 } 121 else { 122 $widget->{type} = ''; 123 } 124 125 return $widget; 126} 127 128=head2 make_widget 129 130Make a widget depending on the property type. This method expects a property 131and, sometimes, the current value (selected in the UI). This method is called 132from the UI module when a user selects a property and wants to change it. 133 134=cut 135 136sub make_widget { 137 my $self = shift; 138 my ( $property, $current_value ) = @_; 139 140 $self->{current_value} = $current_value; 141 my $property_values = $self->{properties}->{$property}; 142 my $widget = $self->widget_selector($property_values); 143 144 my $property_widget = $self->{container} 145 ->add( 'property_widget', $widget->{type}, %{ $widget->{values} } ); 146 147 $property_widget->draw(); 148 return $property_widget; 149} 150 151=head2 set_container 152 153Set the container that will contain the created widget. 154 155=cut 156 157sub set_container { 158 my $self = shift; 159 my $container = shift; 160 $self->{container} = $container; 161} 162 163=head2 fill_property_hash 164 165Read the DATA handle and fill the property hash. __DATA__ contains a list of 166key value pairs that represent a property and its possible values. Note: the 167ALNUM value means the property is alphanumerical and a textfield has to be 168created to be shown to the user. Otherwise, a radio button box is created with 169the possible values. See the widget_selector function. 170 171=cut 172 173sub fill_property_hash { 174 my $self = shift; 175 176 while (<DATA>) { 177 chomp; 178 179 my ( $property, $values ) = split /%/; 180 my @values = split /,/, $values; 181 182 if ( $property =~ /compression/ ) { 183 push @values, do { 184 my $gzip = []; 185 push @$gzip, "gzip-$_", for ( 1 .. 9 ); 186 @$gzip; 187 }; 188 } 189 190 if ( $values eq 'ALNUM' ) { 191 $self->{properties}->{$property} = \$values; 192 } 193 else { 194 $self->{properties}->{$property} = [ sort @values ]; 195 } 196 } 197} 198 199=head2 properties 200 201Return the properties hash. 202 203=cut 204 205sub properties { 206 my $self = shift; 207 return $self->{properties}; 208} 209 210=head2 is_property_ro 211 212Check whether a property is read only (cannot be changed). 213 214=cut 215 216sub is_property_ro { 217 my $self = shift; 218 my $property = shift; 219 my $array = $self->{ro_properties}; 220 221 # 1 -> true. property is read only. 222 # 0 -> false. property is not read only. 223 my $is_ro = 1; 224 225 foreach ( 0 .. $#$array ) { 226 if ( $array->[$_] eq $property ) { 227 $is_ro = 0; 228 last; 229 } 230 } 231 232 return $is_ro; 233} 234 235=head1 AUTHOR 236 237Patrice Clement <monsieurp at cpan.org> 238 239=head1 LICENSE AND COPYRIGHT 240 241This software is copyright (c) 2020 by Patrice Clement. 242 243This is free software, licensed under the (three-clause) BSD License. 244 245See the LICENSE file. 246 247=cut 248 2491; 250 251__DATA__ 252aclinherit%discard,noallow,restricted,passthrough,passthrough-x 253aclmode%discard,groupmask,passthrough,restricted 254atime%on,off 255canmount%on,off,noauto 256checksum%on,off,fletcher2,fletcher4,sha256,noparity,sha512,skein 257compression%on,off,lzjb,zle,lz4,gzip 258copies%1,2,3 259casesensitivity%sensitive,insensitive,mixed 260dedup%on,off,verify,sha256,sha256verify,sha512,sha512verify,skein,skeinverify 261devices%on,off 262dnodesize%legacy,auto,1k,2k,4k,8k,16k 263exec%on,off 264jailed%off,on 265logbias%latency,throughput 266mlslabel%label,none 267nbmand%on,off 268normalization%none,formC,formD,formKC,formKD 269primarycache%all,none,metadata 270readonly%on,off 271redundant_metadata%all,most 272secondarycache%all,none,metadata 273setuid%on,off 274sharenfs%on,off,opts 275sharesmb%on,off,opts 276version%1,2,3,4,5,current 277snapdir%hidden,visible 278sync%standard,always,disabled 279volmode%default,geom,dev,none 280vscan%off,on 281xattr%off,on 282snapshot_limit%ALNUM 283filesystem_limit%ALNUM 284quota%ALNUM 285recordsize%ALNUM 286refquota%ALNUM 287refreservation%ALNUM 288reservation%ALNUM 289mountpoint%ALNUM 290volsize%ALNUM 291