#!/usr/bin/perl # DrakConnect $Id$ # Copyright (C) 1999-2005 Mandriva # Damien "Dam's" Krotkine # Damien "poulpy" Chaumette # Thierry Vignaud # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use strict; use lib qw(/usr/lib/libDrakX); use standalone; #- warning, standalone must be loaded very first, for 'explanations' use interactive; use common; use network::netconnect; use network::ethernet; use network::tools; use network::modem; use network::network; use detect_devices; use c; use modules; use network::isdn; use network::adsl; use network::tools; use network::test; use MDK::Common::Globals "network", qw($in); use POSIX ":sys_wait_h"; $ugtk2::wm_icon = "drakconnect"; my $in = 'interactive'->vnew('su'); if ($in->isa('interactive::gtk')) { require ugtk2; ugtk2->import(qw(:create :dialogs :helpers :wrappers)); } my ($netcnx, $netc, $intf) = ({}, {}, {}); network::netconnect::read_net_conf($netcnx, $netc, $intf); my $modules_conf = modules::any_conf->read; modules::load_category($modules_conf, 'net'); $::Wizard_title = N("Network & Internet Configuration"); $::Wizard_pix_up = "drakconnect.png"; MDK::Common::Globals::init(in => $in); local $_ = join '', @ARGV; /--skip-wizard/ and manage($netc, $intf); /--add/ and add_intf(); /--del/ and del_intf(); /--old/ and goto old; if (/--install/) { $::isInstall = 1; add_intf(); } /--internet/ and configure_net($netcnx, $netc, $intf); # default is to run wizard add_intf(); old: my @all_cards; my $window1 = ugtk2->new('drakconnect'); $window1->{rwindow}->signal_connect(delete_event => sub { ugtk2->exit(0) }); unless ($::isEmbedded) { $window1->{rwindow}->set_position('center'); $window1->{rwindow}->set_title(N("Network configuration (%d adapters)", scalar @all_cards)); $window1->{rwindow}->set_size_request(-1, -1); } $window1->{rwindow}->set_border_width(10); my $warning_label1; my $button_apply; my $hostname = chomp_(`hostname`); my $int_label = Gtk2::Label->new($netcnx->{type} eq 'lan' ? N("Gateway:") : N("Interface:")); my $int_name = Gtk2::Label->new($netcnx->{type} eq 'lan' ? $netc->{GATEWAY} : $netcnx->{NET_INTERFACE}); my $isconnected = -1; my $int_connect = Gtk2::Button->new(N("Wait please")); $int_connect->set_sensitive(0); $int_connect->signal_connect(clicked => sub { if (!$isconnected) { connect_backend($netc); } else { disconnect_backend($netc); } }); my $tree_model = Gtk2::TreeStore->new("Gtk2::Gdk::Pixbuf", map { "Glib::String" } 2..6); my $list = Gtk2::TreeView->new_with_model($tree_model); $list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererPixbuf->new, 'pixbuf' => 0)); each_index { $list->append_column(my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i + 1)); $col->set_sort_column_id($::i); } (N("Interface"), N("IP address"), N("Protocol"), N("Driver"), N("State")); $list->signal_connect(button_press_event => sub { my (undef, $event) = @_; my (undef, $iter) = $list->get_selection->get_selected; return unless $iter; configure_lan() if $event->type eq '2button-press'; }); update_list($modules_conf); my ($label_host, $int_state); $window1->{window}->add( gtkpack_(Gtk2::VBox->new(0,10), 0, gtkpack(Gtk2::HBox->new, Gtk2::Label->new(N("Hostname: ")), $label_host = Gtk2::Label->new($hostname), gtksignal_connect(Gtk2::Button->new(N("Configure hostname...")), clicked => sub { local ($::isWizard, $::Wizard_finished) = (1, 1); eval { # For wizcancel network::netconnect::main($netcnx, $in, $modules_conf, $netc, undef, $intf); $button_apply->set_sensitive(1); update(); }; if ($@ =~ /wizcancel/) {} $::WizardWindow->destroy; undef $::WizardWindow; } ), ), 1, gtkadd(gtkcreate_frame(N("LAN configuration")), gtkpack_(gtkset_border_width(Gtk2::VBox->new(0,0), 5), 0, $list, 0, Gtk2::HBox->new(0,0), 0, gtkpack_(Gtk2::HBox->new(0, 0), 0, gtksignal_connect(Gtk2::Button->new(N("Configure Local Area Network...")), clicked => \&configure_lan), ), ) ), 0, gtkpack(Gtk2::HButtonBox->new, gtksignal_connect(Gtk2::Button->new(N("Help")), clicked => sub { exec("drakhelp --id internet-connection") unless fork() }), $button_apply = gtksignal_connect(gtkset_sensitive(Gtk2::Button->new(N("Apply")), 0), clicked => \&apply), gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => \&quit_global), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { if ($button_apply->get('sensitive')) { my $dialog = _create_dialog(N("Please wait")); gtkpack($dialog->vbox, Gtk2::Label->new(N("Please Wait... Applying the configuration"))); $dialog->show_all; gtkflush(); apply($netc, $intf); $dialog->destroy; } update(); quit_global(); }), ), ), ); $window1->{rwindow}->show_all; gtkflush(); $window1->main; ugtk2->exit(0); sub manage { my ($netc, $intf) = @_; my $p = {}; my ($interface_menu, $selected, $apply_button); my $window = ugtk2->new('Manage Connection'); unless ($::isEmbedded) { $window->{rwindow}->set_position('center'); $window->{rwindow}->set_title(N("Manage connections")); # translation availlable in mcc domain => we need merging } my $notebook = Gtk2::Notebook->new; $notebook->set_property('show-tabs', 0); $notebook->set_property('show-border', 0); @all_cards = network::ethernet::get_eth_cards($modules_conf); my %names = network::ethernet::get_eth_cards_names(@all_cards); foreach (keys %names) { my $dev = detect_devices::is_lan_interface($_) ? $names{$_} : $_; $p->{$dev} = { name => $_ , intf => $intf->{$_} }; } while (my ($device, $interface) = each %$intf) { exists $names{$device} and next; my $type = network::tools::get_interface_type($interface); $p->{"$type ($device)"} = { name => $device, intf => $interface }; } $window->{rwindow}->add(gtkpack_(Gtk2::VBox->new, 0, gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("Device selected")), $interface_menu = gtksignal_connect(Gtk2::ComboBox->new_text, changed => sub { $selected = $interface_menu->get_text; $notebook->set_current_page($p->{$selected}{gui}{index}); }, ), ), 1, $notebook, 0, create_okcancel(my $oc = { cancel_clicked => sub { $window->destroy; Gtk2->main_quit }, ok_clicked => sub { if ($apply_button->get_property('sensitive')) { save($netc, $p, $apply_button); } $window->destroy; Gtk2->main_quit; }, }, undef, undef, '', [ N("Help"), sub { exec("drakhelp --id internet-connection") unless fork() } ], [ N("Apply"), sub { save($netc, $p, $apply_button) }, 0, 1 ], ), ), ); $apply_button = $oc->{buttons}{N("Apply")}; each_index { my ($name, $interface, $protocol) = ($_, $p->{$_}{name}, $p->{$_}{protocol}); $p->{$name}{gui}{index} = $::i; $p->{$name}{intf} ||= { DEVICE => $interface }; build_tree($netc, $p->{$name}{intf}, $name, $interface, $protocol); build_notebook($netc, $p->{$name}{intf}, $p->{$name}{gui}, $apply_button, $name, $interface); $notebook->append_page(gtkpack(Gtk2::VBox->new(0,0), $p->{$name}{gui}{notebook})); } (sort keys %$p); $interface_menu->set_popdown_strings(sort keys %$p); $interface_menu->set_active(0); $apply_button->set_sensitive(0); $window->{rwindow}->show_all; $window->main; ugtk2->exit(0); } sub build_tree { my ($netc, $intf, $interface, $interface_name, $protocol) = @_; if ($interface eq 'adsl') { $intf->{pages} = { 'TCP/IP' => 1, 'DHCP' => 1, 'Account' => 1, 'Options' => 1, 'Information' => 1 }; network::adsl::adsl_probe_info($intf, $netc, $protocol, $interface_name); $intf->{save} = sub { $netc->{internet_cnx_choice} = 'adsl'; $netc->{at_boot} = $intf->{ONBOOT} eq 'yes' ? 1 : 0; network::adsl::adsl_conf_backend($in, $modules_conf, $netcnx, $netc, $intf, $interface_name, $protocol); }; } elsif ($interface eq 'modem') { $intf->{pages} = { 'TCP/IP' => 1, 'Account' => 1, 'Modem' => 1, 'Options' => 1 }; put_in_hash($intf, network::modem::ppp_read_conf({}, $netc)); $intf->{save} = sub { network::modem::ppp_configure($in, $intf) }; } elsif ($interface eq 'isdn') { $intf->{pages} = { 'TCP/IP' => 1, 'Account' => 1, 'Modem' => 1, 'Options' => 1 }; network::isdn::read_config($intf); $intf->{save} = sub { network::isdn::write_config($intf) }; } else { #- ethernet is default $intf->{pages} = { 'TCP/IP' => 1, 'DHCP' => 1, if_(network::tools::get_interface_type($intf) eq "wifi", 'Wireless' => 1), 'Options' => 1, 'Information' => 1 }; } } sub build_notebook { my ($netc, $intf, $gui, $apply_button, $interface, $interface_name) = @_; my $apply = sub { $apply_button->set_sensitive(1) }; my $is_ethernet = detect_devices::is_lan_interface($interface); if ($intf->{pages}{'TCP/IP'}) { gtkpack($gui->{sheet}{'TCP/IP'} = Gtk2::HBox->new, gtkadd(gtkcreate_frame(N("IP configuration")), gtkpack_(gtkset_border_width(Gtk2::VBox->new(0,10), 5), if_($is_ethernet, 0, gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("Protocol")), $gui->{intf}{BOOTPROTO} = gtksignal_connect(Gtk2::ComboBox->new_text, changed => sub { return if !$_[0]->realized; my $proto = $gui->{intf}{BOOTPROTO}; my $protocol = $intf->{BOOTPROTO} = { reverse %{$proto->{protocols}} }->{$proto->get_text}; foreach ($gui->{intf}{IPADDR}, $gui->{intf}{NETMASK}, $gui->{netc}{GATEWAY}) { $_->set_sensitive(to_bool($protocol eq "static")); } $gui->{sheet}{DHCP}->set_sensitive($intf->{BOOTPROTO} eq 'dhcp'); $apply->(); }, ), ), ), 0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("IP address"))), gtkpack__(Gtk2::HBox->new, gtksignal_connect($gui->{intf}{IPADDR} = Gtk2::Entry->new, key_press_event => $apply)), ), 0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("Netmask"))), gtkpack__(Gtk2::HBox->new, gtksignal_connect($gui->{intf}{NETMASK} = Gtk2::Entry->new, key_press_event => $apply)), ), if_($is_ethernet, 0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("Gateway"))), gtkpack__(Gtk2::HBox->new, gtksignal_connect($gui->{netc}{GATEWAY} = Gtk2::Entry->new, key_press_event => $apply)), ), ), ), ), gtkpack_(Gtk2::VBox->new, 1, gtkadd(gtkcreate_frame(N("DNS servers")), gtkpack(Gtk2::VBox->new(0,0), Gtk2::Label->new($intf->{dns1} || $netc->{dnsServer}), if_($intf->{dns2} || $netc->{dnsServer2}, Gtk2::Label->new($intf->{dns2} || $netc->{dnsServer2})), if_($intf->{dns3} || $netc->{dnsServer3}, Gtk2::Label->new($intf->{dns3} || $netc->{dnsServer3}))), ), 1, gtkadd(gtkcreate_frame(N("Search Domain")), Gtk2::Label->new($intf->{domain} || $netc->{DOMAINNAME} || 'none'), ), ), ); if ($is_ethernet) { my $proto = $gui->{intf}{BOOTPROTO}; $proto->{protocols} = { none => N("none"), static => N("static"), dhcp => N("DHCP") }; $proto->set_popdown_strings(values %{$proto->{protocols}}); $proto->set_text($proto->{protocols}{$intf->{BOOTPROTO} || 'none'}); if ($intf->{BOOTPROTO} ne 'static') { $_->set_sensitive(0) foreach $gui->{intf}{IPADDR}, $gui->{intf}{NETMASK}, $gui->{netc}{GATEWAY}; } } else { $_->set_sensitive(0) foreach $gui->{intf}{IPADDR}, $gui->{intf}{NETMASK}, $gui->{netc}{GATEWAY}; delete $gui->{intf}{BOOTPROTO}; } !$intf->{IPADDR} and ($intf->{IPADDR}, $gui->{active}, $intf->{NETMASK}) = get_intf_ip($interface_name); $gui->{netc}{$_}->set_text($netc->{$_}) foreach keys %{$gui->{netc}}; } if ($intf->{pages}{DHCP}) { gtkpack(gtkset_border_width($gui->{sheet}{DHCP} = Gtk2::HBox->new(0,10), 5), gtkpack__(gtkset_border_width(Gtk2::VBox->new(0,10), 5), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("DHCP client")), gtksignal_connect($gui->{intf}{DHCP_CLIENT} = Gtk2::ComboBox->new_with_strings(\@network::ethernet::dhcp_clients, $intf->{DHCP_CLIENT} || $network::ethernet::dhcp_clients[0]), changed => $apply)), gtksignal_connect($gui->{intf_bool}{NEEDHOSTNAME} = Gtk2::CheckButton->new(N("Assign host name from DHCP address")), toggled => $apply), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("DHCP host name")), gtksignal_connect($gui->{intf}{DHCP_HOSTNAME} = Gtk2::Entry->new, key_press_event => $apply)), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("DHCP timeout (in seconds)")), gtksignal_connect($gui->{intf}{DHCP_TIMEOUT} = Gtk2::Entry->new, key_press_event => $apply)), gtksignal_connect($gui->{intf_bool}{PEERDNS} = Gtk2::CheckButton->new(N("Get DNS servers from DHCP")), toggled => $apply), gtksignal_connect($gui->{intf_bool}{PEERYP} = Gtk2::CheckButton->new(N("Get YP servers from DHCP")), toggled => $apply), gtksignal_connect($gui->{intf_bool}{PEERNTPD} = Gtk2::CheckButton->new(N("Get NTPD servers from DHCP")), toggled => $apply), ), ); foreach (qw(NEEDHOSTNAME PEERDNS)) { #- default these settings to yes defined $intf->{$_} or $intf->{$_} = "yes"; } $gui->{intf}{$_}->set_text($intf->{$_}) foreach qw(DHCP_HOSTNAME DHCP_TIMEOUT); $gui->{intf_bool}{$_}->set_active(text2bool($intf->{$_})) foreach qw(NEEDHOSTNAME PEERDNS PEERYP PEERNTPD); $gui->{intf}{DHCP_CLIENT}->set_text($intf->{DHCP_CLIENT}); $gui->{sheet}{DHCP}->set_sensitive($intf->{BOOTPROTO} eq 'dhcp'); } if ($intf->{pages}{Wireless}) { gtkpack(gtkset_border_width($gui->{sheet}{Wireless} = Gtk2::HBox->new(0,10), 5), gtkpack_(Gtk2::VBox->new(0,0), map { (0, gtkpack_(Gtk2::VBox->new(0,0), 1, Gtk2::Label->new($_->[0]), 0, gtksignal_connect($gui->{intf}{$_->[1]} = Gtk2::Entry->new, key_press_event => $apply), )); } ([ N("Operating Mode"), "WIRELESS_MODE" ], [ N("Network name (ESSID)"), "WIRELESS_ESSID" ], [ N("Network ID"), "WIRELESS_NWID" ], [ N("Operating frequency"), "WIRELESS_FREQ" ], [ N("Sensitivity threshold"), "WIRELESS_SENS" ], [ N("Bitrate (in b/s)"), "WIRELESS_RATE" ] ), ), Gtk2::VSeparator->new, gtkpack_(Gtk2::VBox->new(0,0), map { (0, gtkpack_(Gtk2::VBox->new(0,0), 1, Gtk2::Label->new($_->[0]), 0, gtksignal_connect($gui->{intf}{$_->[1]} = Gtk2::Entry->new, key_press_event => $apply), )); } ([ N("Encryption key"), 'WIRELESS_ENC_KEY' ], [ N("RTS/CTS"), 'WIRELESS_RTS' ], [ N("Fragmentation"), 'WIRELESS_FRAG' ], [ N("Iwconfig command extra arguments"), 'WIRELESS_IWCONFIG' ], [ N("Iwspy command extra arguments"), 'WIRELESS_IWSPY' ], [ N("Iwpriv command extra arguments"), 'WIRELESS_IWPRIV' ], ), ), ); } if ($intf->{pages}{Options}) { gtkpack__(gtkset_border_width($gui->{sheet}{Options} = Gtk2::VBox->new(0,10), 5), $gui->{intf_bool}{ONBOOT} = gtksignal_connect(Gtk2::CheckButton->new(N("Start at boot")), toggled => $apply), if_($is_ethernet, map { ($gui->{intf_bool}{$_->[0]} = gtksignal_connect(Gtk2::CheckButton->new($_->[1]), toggled => $apply)); } ([ "HWADDR", N("Track network card id (useful for laptops)") ], [ "MII_NOT_SUPPORTED", N("Network Hotplugging") ], ), ), if_($interface eq 'isdn', gtkpack(Gtk2::HBox->new(0,0), gtkpack__(Gtk2::VBox->new(0,0), Gtk2::Label->new(N("Dialing mode")), my @dialing_mode_radio = gtkradio(("auto") x 2, "manual"), ), Gtk2::VSeparator->new, gtkpack__(Gtk2::VBox->new(0,0), Gtk2::Label->new(N("Connection speed")), my @speed_radio = gtkradio(("64 Kb/s") x 2, "128 Kb/s"), ), ), gtkpack__(Gtk2::HBox->new(0,5), Gtk2::Label->new(N("Connection timeout (in sec)")), gtksignal_connect($gui->{intf}{huptimeout} = Gtk2::Entry->new, key_press_event => $apply), ), ), gtkpack__(Gtk2::HBox->new(0,5), Gtk2::Label->new(N("Metric")), gtksignal_connect(gtkset_text($gui->{intf}{METRIC} = Gtk2::Entry->new, $intf->{METRIC}), key_press_event => $apply)), ); $dialing_mode_radio[0]->signal_connect(toggled => sub { $gui->{intf_radio}{dialing_mode} = 'auto'; $apply->() }); $dialing_mode_radio[1]->signal_connect(toggled => sub { $gui->{intf_radio}{dialing_mode} = 'static'; $apply->() }); $speed_radio[0]->signal_connect(toggled => sub { $gui->{intf_radio}{speed} = '64'; $apply->() }); $speed_radio[1]->signal_connect(toggled => sub { $gui->{intf_radio}{speed} = '128'; $apply->() }); $gui->{intf_bool}{ONBOOT}->set_active($intf->{ONBOOT} eq 'yes' ? 1 : 0); $gui->{intf_bool}{MII_NOT_SUPPORTED}->set_active($intf->{MII_NOT_SUPPORTED} eq 'no' ? 1 : 0); $gui->{intf_bool}{HWADDR}->set_active($intf->{HWADDR}); } if ($intf->{pages}{Account}) { if ($interface_name =~ /^speedtouch|sagem$/) { $gui->{description} = $interface_name eq 'speedtouch' ? 'Alcatel|USB ADSL Modem (Speed Touch)' : 'Analog Devices Inc.|USB ADSL modem'; } gtkpack_(gtkset_border_width($gui->{sheet}{Account} = Gtk2::VBox->new(0,10), 5), if_($interface eq 'modem', 0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new(N("Authentication"))), gtkpack__(Gtk2::HBox->new, $gui->{intf}{auth} = gtksignal_connect(Gtk2::ComboBox->new_text, changed => $apply)), )), map { (0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new($_->[0])), gtkpack__(Gtk2::HBox->new, $gui->{intf}{$_->[1]} = gtksignal_connect(Gtk2::Entry->new, key_press_event => $apply)), ), ); } ([ N("Account Login (user name)"), 'login' ], [ N("Account Password"), 'passwd' ], if_($interface =~ /^(isdn|modem)$/, [ N("Provider phone number"), $1 eq 'modem' ? 'phone' : 'phone_out' ]), ), ); if ($interface eq 'modem') { my %auth_methods = map_index { $::i => $_ } N("PAP"), N("Terminal-based"), N("Script-based"), N("CHAP"), N("PAP/CHAP"); $gui->{intf}{auth}->set_popdown_strings(sort values %auth_methods); $gui->{intf}{auth}->set_text($auth_methods{$intf->{Authentication}}); } $gui->{intf}{passwd}->set_visibility(0); } if ($intf->{pages}{Modem}) { gtkpack(gtkset_border_width($gui->{sheet}{Modem} = Gtk2::HBox->new(0,10), 5), if_($interface eq 'modem', gtkpack__(Gtk2::VBox->new(0,5), (map { (gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new($_->[0])), gtkpack__(Gtk2::HBox->new, $gui->{intf}{$_->[1]} = gtksignal_connect(Gtk2::ComboBox->new_text, changed => $apply)), ), ); } ([ N("Flow control"), 'FlowControl' ], [ N("Line termination"), 'Enter' ], [ N("Connection speed"), 'Speed' ], )), # gtkpack(Gtk2::VBox->new(0,0), # no relative kppp option found :-( # Gtk2::Label->new(N("Dialing mode")), # gtkradio('', N("Tone dialing"), N("Pulse dialing")), # ), ), Gtk2::VSeparator->new, gtkpack__(Gtk2::VBox->new(0,10), gtkpack__(Gtk2::HBox->new(0,5), Gtk2::Label->new(N("Modem timeout")), $gui->{intf}{Timeout} = gtksignal_connect(Gtk2::SpinButton->new(Gtk2::Adjustment->new($intf->{Timeout}, 0, 120, 1, 5, 0), 0, 0), value_changed => $apply), ), gtksignal_connect($gui->{intf_bool}{UseLockFile} = Gtk2::CheckButton->new(N("Use lock file")), toggled => $apply), gtkpack__(Gtk2::HBox->new, gtksignal_connect($gui->{intf_bool}{WaitForDialTone} = Gtk2::CheckButton->new(N("Wait for dialup tone before dialing")), toggled => $apply)), gtkpack__(Gtk2::HBox->new(0,5), Gtk2::Label->new(N("Busy wait")), $gui->{intf}{BusyWait} = gtksignal_connect(Gtk2::SpinButton->new(Gtk2::Adjustment->new($intf->{BusyWait}, 0, 120, 1, 5, 0), 0, 0), value_changed => $apply), ), gtkpack__(Gtk2::HBox->new(0,5), Gtk2::Label->new(N("Modem sound")), gtkpack__(Gtk2::VBox->new(0,5), my @volume_radio = gtkradio('', N("Enable"), N("Disable"))), ), ), ), if_($interface eq 'isdn', gtkpack_(Gtk2::VBox->new(0,0), map { (0, gtkpack(Gtk2::VBox->new(1,0), gtkpack__(Gtk2::HBox->new, Gtk2::Label->new($_->[0])), gtkpack__(Gtk2::HBox->new, $gui->{intf}{$_->[1]} = gtksignal_connect(Gtk2::Entry->new, key_press_event => $apply)), ), ); } ([ N("Card IRQ"), 'irq' ], [ N("Card mem (DMA)"), 'mem' ], [ N("Card IO"), 'io' ], [ N("Card IO_0"), 'io0' ], ), ), Gtk2::VSeparator->new, gtkpack__(Gtk2::VBox->new(0,0), Gtk2::Label->new(N("Protocol")), my @protocol_radio = gtkradio('', N("European protocol (EDSS1)"), N("Protocol for the rest of the world\nNo D-Channel (leased lines)")), ), ), ); $protocol_radio[0]->signal_connect(toggled => sub { $gui->{intf_radio}{protocol} = 2; $apply->() }); $protocol_radio[1]->signal_connect(toggled => sub { $gui->{intf_radio}{protocol} = 3; $apply->() }); $volume_radio[0]->signal_connect(toggled => sub { $gui->{intf_radio}{Volume} = 1; $apply->() }); $volume_radio[1]->signal_connect(toggled => sub { $gui->{intf_radio}{Volume} = 0; $apply->() }); $gui->{intf}{FlowControl}->set_popdown_strings('Hardware [CRTSCTS]', 'Software [XON/XOFF]', 'None'); $gui->{intf}{Enter}->set_popdown_strings('CR', 'CF', 'CR/LF'); $gui->{intf}{Speed}->set_popdown_strings('2400', '9600', '19200', '38400', '57600', '115200'); } if ($intf->{pages}{Information}) { my ($info) = $gui->{description} ? find { $_->{description} eq $gui->{description} } detect_devices::probeall : network::ethernet::mapIntfToDevice($interface_name); my @intfs = grep { $interface_name eq $_->[0] } @all_cards; if (is_empty_hash_ref($info) && @intfs == 1) { my $driver = $intfs[0][1]; my @cards = grep { $_->{driver} eq $driver } detect_devices::probeall(); @cards == 1 and $info = $cards[0]; } gtkpack(gtkset_border_width($gui->{sheet}{Information} = Gtk2::VBox->new(0,10), 5), gtktext_insert(Gtk2::TextView->new, join('', map { $_->[0] . ": \x{200e}" . $_->[1] . "\n" } ( [ N("Vendor"), split('\|', $info->{description}) ], [ N("Description"), reverse split('\|', $info->{description}) ], [ N("Media class"), $info->{media_type} || '-' ], [ N("Module name"), $info->{driver} || '-' ], [ N("Mac Address"), c::get_hw_address($interface_name) || '-' ], [ N("Bus"), $info->{bus} || '-' ], [ N("Location on the bus"), $info->{pci_bus} || '-' ], ) ) ), ); } foreach (keys %{$gui->{intf}}) { next if ref($gui->{intf}{$_}) !~ /Gtk2::(ComboBox|Entry)/; # skip unset fields: next if !$intf->{$_}; # special case b/c of translation: next if member($_, qw(BOOTPROTO )); if ($_ eq "FlowControl") { # kppp is writing translated strings :-( (eg: s/Software/Logiciel/): # (let's hope that all translations use 'CRTSCTS' and 'XON/OFF' as substring) $gui->{intf}{$_}->set_text('Hardware [CRTSCTS]') if $intf->{$_} =~ /CRTSCTS/; $gui->{intf}{$_}->set_text('Software [XON/XOFF]') if $intf->{$_} =~ m!XON/XOFF!; } else { $gui->{intf}{$_}->set_text($intf->{$_}); } } $gui->{notebook} = Gtk2::Notebook->new; populate_notebook($gui->{notebook}, $gui); } sub populate_notebook { my ($notebook, $gui) = @_; foreach ('TCP/IP', 'DHCP', 'Account', 'Wireless', 'Modem', 'Options', 'Information') { !$gui->{sheet}{$_} and next; $notebook->append_page($gui->{sheet}{$_}, Gtk2::Label->new(translate($_))); } } sub save { my ($netc, $p, $apply_button) = @_; my $dialog = _create_dialog(N("Please wait")); gtkpack($dialog->vbox, gtkshow(Gtk2::Label->new(N("Please Wait... Applying the configuration")))); $dialog->show_all; gtkset_mousecursor_wait(); Glib::Timeout->add(200, sub { gtkflush(); foreach (keys %$p) { save_notebook($netc, $p->{$_}{intf}, $p->{$_}{gui}) or return; $p->{$_}{intf}{save} ? $p->{$_}{intf}{save}->() : apply($netc, $p->{$_}{intf}); } system("/etc/rc.d/init.d/network restart"); $dialog->response(0); }); $dialog->run; $apply_button->set_sensitive(0); gtkset_mousecursor_normal(); $dialog->destroy; } sub save_notebook { my ($netc, $intf, $gui) = @_; $netc->{$_} = $gui->{netc}{$_}->get_text foreach keys %{$gui->{netc}}; $gui->{intf}{$_} and $intf->{$_} = $gui->{intf}{$_}->get_text foreach keys %{$gui->{intf}}; $gui->{intf_radio}{$_} and $intf->{$_} = $gui->{intf_radio}{$_} foreach keys %{$gui->{intf_radio}}; $intf->{$_} = bool2yesno($gui->{intf_bool}{$_}->get_active) foreach keys %{$gui->{intf_bool}}; $gui->{intf_bool}{MII_NOT_SUPPORTED} and $intf->{MII_NOT_SUPPORTED} = bool2yesno(!$gui->{intf_bool}{MII_NOT_SUPPORTED}->get_active); $gui->{intf_bool}{HWADDR} and (bool2yesno($gui->{intf_bool}{HWADDR}->get_active) eq 'yes' ? ($intf->{HWADDR} = 'yes') : delete $intf->{HWADDR}); if (my $proto = $gui->{intf}{BOOTPROTO}) { $intf->{BOOTPROTO} = { reverse %{$proto->{protocols}} }->{$proto->get_text}; } if ($intf->{BOOTPROTO} eq 'static') { if (!is_ip($intf->{IPADDR})) { $in->ask_warn(N("Error"), N("IP address should be in format 1.2.3.4")); return 0; } if (!is_ip($intf->{NETMASK})) { $in->ask_warn(N("Error"), N("Netmask should be in format 255.255.224.0")); return 0; } } if ($netc->{GATEWAY} && !is_ip($netc->{GATEWAY})) { $in->ask_warn(N("Error"), N("Gateway address should be in format 1.2.3.4")); return 0; } 1; } sub add_intf() { $::isWizard = 1; network::netconnect::main($netcnx, $in, $modules_conf, $netc, undef, $intf); $in->exit(0); } sub del_intf() { my ($intf2delete, $failure); if (!keys %$intf) { $in->ask_warn(N("Error"), N("No ethernet network adapter has been detected on your system. Please run the hardware configuration tool.")); $in->exit(0); } @all_cards = network::ethernet::get_eth_cards($modules_conf); my %ethernet_names = network::ethernet::get_eth_cards_names(@all_cards); my $wiz = { defaultimage => "drakconnect.png", name => N("Remove a network interface"), pages => { welcome => { no_back => 1, name => N("Select the network interface to remove:"), data => [ { label => N("Net Device"), val => \$intf2delete, allow_empty_list => 1, list => [ keys %$intf ], format => sub { my $type = network::tools::get_interface_type($intf->{$_[0]}); $ethernet_names{$_[0]} || ($type ? "$type ($_[0])" : $_[0]); } } ], post => sub { !$::testing and eval { if (member($intf2delete, qw(adsl modem))) { eval { rm_rf("/etc/ppp/peers/ppp0") }; eval { rm_rf("/etc/sysconfig/network-scripts/ifcfg-ppp0") }; } if ($intf2delete eq 'adsl') { eval { rm_rf("/etc/sysconfig/network-scripts/ifcfg-sagem") }; } elsif ($intf2delete eq 'isdn') { eval { rm_rf("/etc/sysconfig/network-scripts/ifcfg-ippp0") }; } else { system("ifdown $intf2delete"); eval { rm_rf("/etc/sysconfig/network-scripts/$intf2delete") }; eval { rm_rf("/etc/sysconfig/network-scripts/ifcfg-$intf2delete") }; } }; $failure = $@; return "end"; }, }, end => { name => sub { $failure ? N("An error occurred while deleting the \"%s\" network interface:\n\n%s", $intf2delete, $failure) : N("Congratulations, the \"%s\" network interface has been successfully deleted", $intf2delete); }, end => 1, }, }, }; require wizards; wizards->new->safe_process($wiz, $in); $in->exit(0); } sub get_intf_ip { my ($interface) = @_; my ($ip, $state, $mask); if (-x "/sbin/ifconfig") { local $_ = `LC_ALL=C LANGUAGE=C /sbin/ifconfig $interface`; $ip = /inet addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/mso ? $1 : N("No IP"); $mask = /Mask:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/mso ? $1 : N("No Mask"); $state = /inet/ ? N("up") : N("down"); } else { $ip = $intf->{$interface}{IPADDR}; $state = "n/a"; } ($ip, $state, $mask); } my %intf; sub update_list { my ($modules_conf) = @_; @all_cards = network::ethernet::get_eth_cards($modules_conf); my %new_intf = map { @$_ } @all_cards; my @new_intf = sort keys %new_intf; foreach my $interface (difference2(\@new_intf, [ keys %intf ])) { $intf{$interface} = $tree_model->append(undef); } foreach my $interface (@new_intf) { my ($ip, $state) = get_intf_ip($interface); $tree_model->set($intf{$interface}, map_index { $::i => $_ } (gtkcreate_pixbuf("eth_card_mini2.png"), $interface, $ip , $intf->{$interface}{BOOTPROTO}, $new_intf{$interface}, $state)); } foreach my $i (difference2([ keys %intf ], \@new_intf)) { $tree_model->remove($intf{$i}); delete $intf{$i}; } } sub apply { my ($netc, $intf) = @_; my $dyn = $intf->{BOOTPROTO} ne 'static'; my $lintf = $intf; #- always delete NETWORK and BROADCAST fields so that they get automatically recomputed by write_interface_conf delete $lintf->{$_} foreach qw(NETWORK BROADCAST), if_($dyn, qw(IPADDR NETMASK)); network::network::sethostname($netc) if $dyn; network::network::configureNetwork2($in, $modules_conf, '', $netc, { $lintf->{DEVICE} => $lintf }); } sub ethisup { `LC_ALL=C LANGUAGE=C /sbin/ifconfig $_[0]` =~ /inet/ } sub chk_internet() { `LC_ALL=C LANGUAGE=C /sbin/chkconfig --list | grep internet` =~ /:on/ ? 1 : 0 } sub update_intbutt() { $int_state->set($isconnected ? N("Connected") : N("Not connected")); return if !$int_connect; $int_connect->child->set($isconnected ? N("Disconnect...") : N("Connect...")); $int_connect->set_sensitive(1); } my $to_update; sub update() { my $h = chomp_(`hostname`); $label_host->set_label($h); $int_label->set($netcnx->{type} eq 'lan' ? N("Gateway:") : N("Interface:")); $int_name->set($netcnx->{type} eq 'lan' ? $netc->{GATEWAY} : $netcnx->{NET_INTERFACE}); update_list($modules_conf); update_intbutt() if $isconnected != -1; 1; } sub in_ifconfig { my ($intf) = @_; -e '/sbin/ifconfig' or return 1; $intf eq '' and return 1; `/sbin/ifconfig` =~ /$intf/; } sub update2() { undef $to_update; connected_bg(\$to_update); if (defined $to_update) { $isconnected = $to_update; if ($isconnected != -1) { if ($isconnected && !in_ifconfig($netcnx->{NET_INTERFACE})) { $warning_label1->set(N("Warning, another Internet connection has been detected, maybe using your network")); $isconnected = 0; } else { $warning_label1->set("") } update_intbutt(); } } update(); 1; } my $net_test; sub update_network_status() { unless ($net_test) { $net_test = network::test->new; $net_test->start; } if ($net_test->is_done) { $isconnected = $net_test->is_connected; update_intbutt(); $net_test->start; } 1; } sub quit_global() { ugtk2->exit(0); } sub get_intf_status { my ($c) = @_; ethisup($c) ? N("Deactivate now") : N("Activate now"); } sub configure_lan() { my $window = _create_dialog(N("LAN configuration")); my @card_tab; if (@all_cards < 1) { $window->vbox->add(Gtk2::Label->new(N("You do not have any configured interface. Configure them first by clicking on 'Configure'"))); gtkpack(gtkset_layout($window->action_area, 'end'), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { Gtk2->main_quit }) ); $window->show_all; $window->run; $window->destroy; return; } $window->set_border_width(10); gtkpack($window->vbox, Gtk2::Label->new(N("LAN Configuration")), my $notebook = Gtk2::Notebook->new, ); foreach (0..$#all_cards) { my @infos; my @conf_data; $card_tab[2*$_] = \@infos; $card_tab[2*$_+1] = \@conf_data; my $vbox_local = Gtk2::VBox->new(0,0); $vbox_local->set_border_width(10); $vbox_local->pack_start(Gtk2::Label->new(N("Adapter %s: %s", $_+1 , $all_cards[$_][0])),1,1,0); # Eth${_}Hostname = $netc->{HOSTNAME} # Eth${_}HostAlias = " . do { $netc->{HOSTNAME} =~ /([^\.]*)\./; $1 } . " # Eth${_}Driver = $all_cards[$_]->[1] my $interface = $all_cards[$_][0]; my ($ip, undef, $mask) = get_intf_ip($interface); $mask ||= $intf->{$interface}{NETMASK}; @conf_data = ([ N("IP address"), \$ip ], [ N("Netmask"), \$mask ], [ N("Boot Protocol"), \$intf->{$interface}{BOOTPROTO}, ["static", "dhcp", "bootp"] ], [ N("Started on boot"), \$intf->{$interface}{ONBOOT} , ["yes", "no"] ], [ N("DHCP client"), \$intf->{$interface}{DHCP_CLIENT} ] ); my $i = 0; my $size_group = Gtk2::SizeGroup->new('horizontal'); foreach my $j (@conf_data) { my $l = Gtk2::Label->new($j->[0]); $l->set_justify('left'); $infos[2*$i] = gtkpack_(Gtk2::HBox->new, 1, $l); $vbox_local->pack_start($infos[2*$i], 1, 1, 0); my $c; if (defined $j->[2]) { $c = Gtk2::ComboBox->new_text; $c->set_popdown_strings(@{$j->[2]}); $infos[2*$i+1] = $c->entry; $infos[2*$i]->pack_start($c,0,0,0); } else { $infos[2*$i+1] = ($c = Gtk2::Entry->new); $infos[2*$i]->pack_start($infos[2*$i+1],0,0,0); } $size_group->add_widget($c); $infos[2*$i+1]->set_text(${$j->[1]}); $i++; } my $widget_temp; if (-e "/etc/sysconfig/network-scripts/ifcfg-$interface") { $widget_temp = gtksignal_connect(Gtk2::Button->new(get_intf_status($interface)), clicked => sub { system("/sbin/if" . (ethisup($interface) ? N("down") : N("up")) . " $interface"); $_[0]->set_label(get_intf_status($interface)); update(); }); } else { $widget_temp = N("This interface has not been configured yet.\nRun the \"Add an interface\" assistant from the Mandriva Linux Control Center"); } $vbox_local->pack_start(gtkpack__(Gtk2::HBox->new(0,0), $widget_temp ),0,0,0); # $list->append($_+1, $interface, $intf->{$interface}{IPADDR}, $intf->{$interface}{BOOTPROTO}, $all_cards[$_]->[1]); # $list->set_selectable($_, 0); $notebook->append_page($vbox_local, Gtk2::Label->new($interface)); } my $exit_dialogsub = sub { $window->destroy; Gtk2->main_quit; }; gtkpack($window->action_area, gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => $exit_dialogsub), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { foreach (0..$#all_cards) { my @infos = @{$card_tab[2*$_]}; each_index { ${$_->[1]} = $infos[2*$::i+1]->get_text } @{$card_tab[2*$_+1]}; my $interface = $all_cards[$_][0]; if ($intf->{$interface}{BOOTPROTO} ne "static") { delete @{$intf->{$interface}}{qw(IPADDR NETWORK NETMASK BROADCAST)}; } else { if ($infos[1]->get_text ne "No ip") { $intf->{$interface}{IPADDR} = $infos[1]->get_text; $intf->{$interface}{NETMASK} = $infos[3]->get_text; } } } update(); $button_apply->set_sensitive(1); $exit_dialogsub->(); }), ); $window->show_all; foreach (0..$#all_cards) { my @infos = @{$card_tab[2*$_]}; $intf->{$all_cards[$_][0]}{BOOTPROTO} eq "dhcp" or $infos[8]->hide; } $window->run; } sub configure_net { my ($netcnx, $netc, $_intf) = @_; my $dialog = ugtk2->new('drakconnect'); my $exit_dialogsub = sub { Gtk2->main_quit }; if (!$netcnx->{type}) { $in->ask_warn( N("Warning"), #-PO: here "Add Connection" should be translated the same was as in control-center N("You do not have any configured Internet connection. Run the \"%s\" assistant from the Mandriva Linux Control Center", N("Set up a new network interface (LAN, ISDN, ADSL, ...)"))); $in->exit; } my $cnx = {}; $cnx = $netcnx->{$netcnx->{type}}; unless ($::isEmbedded) { $dialog->{rwindow}->set_position('center'); $dialog->{rwindow}->set_title(N("Internet connection configuration")); $dialog->{rwindow}->set_size_request(-1, -1); $dialog->{rwindow}->set_icon(gtkcreate_pixbuf("drakconnect")); } $dialog->{rwindow}->signal_connect(delete_event => $exit_dialogsub); my $param_vbox = Gtk2::VBox->new(0,0); my $i = 0; #- duplicated code (waiting for 9.1 to be out to merge everything correctly, avoid bug elsewhere). if ($netcnx->{type} =~ /adsl/) { require network::adsl; network::adsl::adsl_probe_info($cnx, $netc, $intf); } my @conf_data = ( [ N("Host name (optional)"), \$netc->{HOSTNAME} ], [ N("First DNS Server (optional)"), \$netc->{dnsServer} ], # \$cnx->{dns1} [ N("Second DNS Server (optional)"), \$netc->{dnsServer2} ], #\$cnx->{dns2} [ N("Third DNS server (optional)"), \$netc->{dnsServer3} ], ); my @infos; gtkpack($param_vbox, create_packtable({}, map { my $c; if (defined $_->[2]) { $c = Gtk2::Combo->new; $c->set_popdown_strings(@{$_->[2]}); $infos[2*$i+1] = $c->entry; } else { $c = $infos[2*$i+1] = Gtk2::Entry->new; } $infos[2*$i+1]->set_text(${$_->[1]}); $i++; [ $_->[0], $c ]; } @conf_data ) ); $dialog->{rwindow}->add(gtkpack_(Gtk2::VBox->new, 0, Gtk2::Label->new(N("Internet Connection Configuration")), 1, gtkadd(gtkcreate_frame(N("Internet access")), gtkset_border_width(create_packtable({ col_spacings => 5, row_spacings => 5, homogenous => 1 }, [ Gtk2::Label->new(N("Connection type: ")), Gtk2::Label->new(translate($netcnx->{type})) ], [ $int_label, $int_name ], [ Gtk2::Label->new(N("Status:")), $int_state = Gtk2::Label->new(N("Testing your connection...")) ] ), 5), ), 1, gtkadd(gtkcreate_frame(N("Parameters")), gtkset_border_width($param_vbox, 5)), 0, gtkpack(create_hbox('edge'), gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => $exit_dialogsub), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { foreach my $i (0..$#conf_data) { ${$conf_data[$i][1]} = $infos[2*$i+1]->get_text; } # called from old GUI? if ($label_host) { update(); $button_apply->set_sensitive(1); } else { configureNetwork2($in, $modules_conf, '', $netc, $intf); write_resolv_conf("/etc/resolv.conf", $netc); } $exit_dialogsub->(); }), ), ), ); $dialog->{rwindow}->show_all; update_network_status(); Glib::Timeout->add(2000, \&update_network_status); $dialog->main; ugtk2->exit(0); } n1388' href='#n1388'>1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
package ugtk2;

use diagnostics;
use strict;
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK @icon_paths $wm_icon $grab $border); #- leave it on one line, for automatic removal of the line at package creation
use locale;

@ISA = qw(Exporter);
%EXPORT_TAGS = (
    wrappers => [ qw(gtkadd gtkadd_widget gtkappend gtkappend_page gtkappenditems gtkcombo_setpopdown_strings gtkdestroy
                     gtkentry gtkflush gtkhide gtkmodify_font gtkmove gtkpack gtkpack2 gtkpack2_
                     gtkpack2__ gtkpack_ gtkpack__ gtkpowerpack gtkput gtkradio gtkresize gtkroot
                     gtkset_active gtkset_border_width gtkset_editable gtkset_justify gtkset_alignment gtkset_layout gtkset_line_wrap
                     gtkset_markup gtkset_modal gtkset_mousecursor gtkset_mousecursor_normal gtkset_mousecursor_wait gtkset_name
                     gtkset_property gtkset_relief gtkset_selectable gtkset_sensitive gtkset_shadow_type gtkset_size_request
                     gtkset_text gtkset_tip gtkset_visibility gtksetstyle gtkshow gtksignal_connect gtksize gtktext_append
                     gtktext_insert ) ],

    helpers => [ qw(add2notebook add_icon_path escape_text_for_TextView_markup_format gtkcolor gtkcreate_img
                    gtkcreate_pixbuf gtkfontinfo gtkset_background gtktreeview_children set_back_pixmap
                    get_default_step_items set_default_step_items
                    string_size string_width) ],

    create => [ qw(create_adjustment create_box_with_title create_dialog create_factory_menu create_factory_popup_menu
                   create_hbox create_hpaned create_menu create_notebook create_okcancel create_packtable
                   create_scrolled_window create_vbox create_vpaned _create_dialog gtkcreate_frame) ],

    ask => [ qw(ask_browse_tree_info ask_browse_tree_info_given_widgets ask_dir ask_from_entry ask_okcancel ask_warn
                ask_yesorno) ],
    dialogs => [ qw(err_dialog info_dialog warn_dialog) ],

);
$EXPORT_TAGS{all} = [ map { @$_ } values %EXPORT_TAGS ];
@EXPORT_OK = map { @$_ } values %EXPORT_TAGS;

use c;
use log;
use common;
use mygtk2 qw(gtknew); #- do not import gtkadd which conflicts with ugtk2 version

use Gtk2;


$border = 5;

sub wm_icon() { $wm_icon || $::Wizard_pix_up || "wiz_default_up.png" }

# -=-=---=-=---=-=---=-=---=-=---=-=---=-=---=-=---=-=---=-=---=-=---=-=---
#                 wrappers
#
# Functional-style wrappers to existing Gtk functions; allows to program in
# a more functional way, and especially, first, to avoid using temp
# variables, and second, to "see" directly in the code the user interface
# you're building.

sub gtkdestroy                { mygtk2::may_destroy($_[0]) }
sub gtkflush()                { mygtk2::flush() }
sub gtkhide                   { $_[0]->hide; $_[0] }
sub gtkmove                   { $_[0]->window->move($_[1], $_[2]); $_[0] }
sub gtkpack                   { gtkpowerpack(1, 1, @_) }
sub gtkpack_                  { gtkpowerpack('arg', 1, @_) }
sub gtkpack__                 { gtkpowerpack(0, 1, @_) }
sub gtkpack2                  { gtkpowerpack(1, 0, @_) }
sub gtkpack2_                 { gtkpowerpack('arg', 0, @_) }
sub gtkpack2__                { gtkpowerpack(0, 0, @_) }
sub gtkput                    { $_[0]->put(gtkshow($_[1]), $_[2], $_[3]); $_[0] }
sub gtkresize                 { $_[0]->window->resize($_[1], $_[2]); $_[0] }
sub gtkset_active             { $_[0]->set_active($_[1]); $_[0] }
sub gtkset_border_width       { $_[0]->set_border_width($_[1]); $_[0] }
sub gtkset_editable           { $_[0]->set_editable($_[1]); $_[0] }
sub gtkset_selectable         { $_[0]->set_selectable($_[1]); $_[0] }
sub gtkset_justify            { $_[0]->set_justify($_[1]); $_[0] }
sub gtkset_alignment          { $_[0]->set_alignment($_[1], $_[2]); $_[0] }
sub gtkset_layout             { $_[0]->set_layout($_[1]); $_[0] }
sub gtkset_modal              { $_[0]->set_modal($_[1]); $_[0] }
sub gtkset_mousecursor_normal { gtkset_mousecursor('left-ptr', @_) }
sub gtkset_mousecursor_wait   { gtkset_mousecursor('watch', @_) }
sub gtkset_relief             { $_[0]->set_relief($_[1]); $_[0] }
sub gtkset_sensitive          { $_[0]->set_sensitive($_[1]); $_[0] }
sub gtkset_visibility         { $_[0]->set_visibility($_[1]); $_[0] }
sub gtkset_tip                { $_[0]->set_tip($_[1], $_[2]) if $_[2]; $_[1] }
sub gtkset_shadow_type        { $_[0]->set_shadow_type($_[1]); $_[0] }