use Win32::GUI; use Win32::Internet; require Win32::Sound; require Mail::Sender; ($DOShwnd, $DOShinstance) = GUI::GetPerlWindow(); my $screen_width = Win32::GUI::GetSystemMetrics(0); # get screen width my $screen_height = Win32::GUI::GetSystemMetrics(1); # get screen height my $minwidth = 600; my $minheight = 240; if (@ARGV[0] eq "-t") { # read command line parameters $test = 1; # if a '-t' is used then we are testing } else { GUI::CloseWindow($DOShwnd); # if not testing then GUI::Hide($DOShwnd); # hide DOS window } my $dbv_icon = new Win32::GUI::Icon("gator.ico"); # replace default camel icon with my own my $dbv_class = new Win32::GUI::Class( # set up a class to use my icon throughout the program -name => "DatabaseViewer Class", -icon => $dbv_icon, ); my $DataMenu = new Win32::GUI::Menu( # define a menu with File, Search, and Tools headings "&File" => "File", " > Retrieve &Data" => "GetData", " > -" => 0, " > E&xit" => "FileExit", "&Search" => "Search", " > Find &Name" => "FindName", " > Find &Building" => "FindBuilding", " > Find &Adapter" => "FindAdapter", "&Tools" => "Tools", " > Report &Problem" => "ReportProblem", ); $DataWindow = new Win32::GUI::Window( # define main window -name => "DataWindow", -top => ($screen_height - $minheight)/2, # center on screen vertically -left => ($screen_width - $minwidth)/2, # center on screen horizontally -width => $minwidth, -height => $minheight, -title => "GatorNet Database Information", -menu => $DataMenu, -class => $dbv_class, ); $Status = $DataWindow->AddStatusBar( # add a status bar to the window -name => "Status", -text => "GatorNet Database : Ready", ); $DataTab = $DataWindow->AddTabStrip( # add a tabstrip to the window -left => 10, -top => 10, -width => $DataWindow->ScaleWidth - 105, -height => 175, -name => "DataTab", ); # these are the titles that go on the tabs $DataTab->InsertItem(-text => "Name"); $DataTab->InsertItem(-text => "Building"); $DataTab->InsertItem(-text => "Adapter"); $DataWindow->AddLabel( # add a label (this will be used for the first tab) -name => "FN_Label", -text => "First Name: ", -top => 55, -left => 25, ); $FirstName = $DataWindow->AddTextfield( # add a textfield to go with the first label -top => 52, -left => 90, -width => 115, -height => 23, -tabstop => 1, ); $DataWindow->AddLabel( # add another label (this will be used for the first tab) -name => "LN_Label", -text => "Last Name: ", -top => 85, -left => 25, ); $LastName = $DataWindow->AddTextfield( # add a textfield to go with the second label -top => 82, -left => 90, -width => 115, -height => 23, -tabstop => 1, ); $DataWindow->AddLabel( # add another label (this will be used for the second tab) -name => "Bld_Label", -text => "Building: ", -top => 55, -left => 25, ); $Building = $DataWindow->AddCombobox( # add a combobox (dropdown style) to go with the third label -name => "Dropdown", -top => 52, -left => 90, -width => 125, -height => 110, -tabstop => 1, -style => WS_VISIBLE | 3 | WS_VSCROLL | WS_TABSTOP, ); # add the following items to the combobox dropdown list $Building->InsertItem("Baldwin"); $Building->InsertItem("Brooks"); $Building->InsertItem("Caflish"); $Building->InsertItem("College Court"); $Building->InsertItem("Crawford"); $Building->InsertItem("Edwards"); $Building->InsertItem("PKP"); $Building->InsertItem("Ravine"); $Building->InsertItem("Schultz"); $Building->InsertItem("South Highland"); $Building->InsertItem("Walker"); $Building->InsertItem("Walker Annex"); $DataWindow->AddLabel( # add another label (this one will be used on the third and final tab) -name => "Adapt_Label", -text => "Adapter: ", -top => 55, -left => 25, ); $Adapter = $DataWindow->AddTextfield( # add a textfield for the final label -top => 52, -left => 90, -width => 115, -height => 23, -tabstop => 1, ); $FindNow = $DataWindow->AddButton( # add a button to the main window -name => "FindNow", -text => "F&ind Now", -top => 30, -left => $DataWindow->ScaleWidth - 83, -width => 71, -height => 25, ); $Stop = $DataWindow->AddButton( # add another button to the main window -name => "Stop", -text => "Sto&p", -top => 60, -left => $DataWindow->ScaleWidth - 83, -width => 71, -height => 25, ); $NewSearch = $DataWindow->AddButton( # add a final button for the main window) -name => "NewSearch", -text => "Ne&w Search", -top => 90, -left => $DataWindow->ScaleWidth - 83, -width => 71, -height => 25, ); $DataView = new Win32::GUI::ListView($DataWindow, # add a listview to the main window -name => "DataView", -top => $DataWindow->ScaleHeight, -left => 0, -width => $DataWindow->ScaleWidth, -height => $DataWindow->ScaleHeight - 213, ); # define the columns for the listview $DataView->InsertColumn( -index => 0, -width => 95, -text => "First Name", ); # define the columns for the listview $DataView->InsertColumn( -index => 1, -subitem=> 1, # this is a subitem -width => 95, -text => "Last Name", ); # define the columns for the listview $DataView->InsertColumn( -index => 2, -subitem=> 1, # this is a subitem -width => 100, -text => "Building", ); # define the columns for the listview $DataView->InsertColumn( -index => 3, -subitem=> 1, # this is a subitem -width => 55, -text => "Room", ); # define the columns for the listview $DataView->InsertColumn( -index => 4, -subitem=> 1, # this is a subitem -width => 114, -text => "Adapter Address", ); # define the columns for the listview $DataView->InsertColumn( -index => 5, -subitem=> 1, # this is a subitem -width => 117, -text => "IP Address", ); $Report = new Win32::GUI::Window( # define a new window for reporting errors -name => "Report", -top => 100, -left => 100, -width => $minwidth - 50, -height => $minheight + 100, -title => "Report Problem", -class => $dbv_class, ); $Report->AddLabel( # add a label to the Report window -name => "YN_Label", -text => "Your Name: ", -top => 5, -left => 5, ); $YourName = $Report->AddTextfield( # add a textfield for the Report window label -name => "YourName", -top => 2, -left => 70, -width => 300, -height => 23, -tabstop=> 1, ); $ReportMessage = $Report->AddRichEdit( # add a RichEdit box to the Report window -name => "Text", -text => $text, -left => 2, -top => 27, -width => $Report->ScaleWidth - 5, -height => $Report->ScaleHeight - 65, -style => WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, -exstyle => WS_EX_CLIENTEDGE, ); $Send = $Report->AddButton( # add a button to the Report window -name => "Send", -text => "&Send", -top => $Report->ScaleHeight - 30, -left => ($Report->ScaleWidth - 71)/2, -width => 71, -height => 25, ); $DataView->Hide(); # do not show the listview box initially $Status->Hide(); # do not show the status bar initially $Building->Select(-1); # initially set the dropdown box to no selection $Stop->Disable(); # disable the Stop button until data is being searched for $NewSearch->Disable(); # disable the New Search button until data has been retrieved $DataTab->Select(0); # initially set the first tab as the selected tab &DataTab_Click; # perform a 'click' on the tab $resized = 0; # tells us the window has not been resized yet $DataWindow->Show(); # show the main window Win32::GUI::Dialog(); # allow for interaction sub GetData_Click { # this checks to see if the menu File, Retrieve Data has been clicked $FindNow->Enable(); # enable the Find Now button $NewSearch->Enable(); # enable the New Search button if ($test != 1) { # if not in a testing phase # the following will connect to an FTP server named "server" and will log on using "userid" and "password" # then change to the directory where data is stored, set to ASCII mode, retrieve the file "filename" # and close the connection to the FTP server $connect = new Win32::Internet(); $connect->FTP($FTP, "server", "userid", "password"); $FTP->Cd("directory"); $FTP->Ascii(); $FTP->Get("filename"); ($FTPErrNumb, $FTPErrText) = $FTP->Error(); $FTP->Close(); } $dataretrieved = 1; # okay, we have retrieved data } sub FileExit_Click { # this checks to see if the menu File, Exit has been clicked exit(0); } sub FindName_Click { # this checks to see if the menu Search, Find Name has been clicked $DataTab->Select(0); # select the tab and perform a "click" on it &DataTab_Click; } sub FindBuilding_Click { # this checks to see if the menu Search, Find Building has been clicked $DataTab->Select(1); # select the tab and perform a "click" on it &DataTab_Click; } sub FindAdapter_Click { # this checks to see if the menu Search, Find Adapter has been clicked $DataTab->Select(2); # select the tab and perform a "click" on it &DataTab_Click; } sub ReportProblem_Click { # this checks to see if the menu Tools, Report Problem has been clicked $Send->Disable(); # disable the Send button $Report->Show(); # show the Report window $Report->BringToFront(); # bring the report window to the front $ReportMessage->Text(""); # empty out the RichEdit field $YourName->Text(""); # empty out the sender's name } # the following sub will check to see iff the main window has been resized and if it has # it will move buttons and resize the status bar and tab strip accordingly sub DataWindow_Resize { $DataView->Resize($DataWindow->ScaleWidth, $DataWindow->ScaleHeight - 213); $Status->Resize($DataWindow->ScaleWidth, $Status->Height); $Status->Move(0, $DataWindow->ScaleHeight-$Status->Height); $DataTab->Resize($DataWindow->ScaleWidth - 105, 175); $FindNow->Move($DataWindow->ScaleWidth - 83, 30); $Stop->Move($DataWindow->ScaleWidth - 83, 60); $NewSearch->Move($DataWindow->ScaleWidth - 83, 90); } # the following sub will check to see iff the Report window has been resized and if it has # it will move the button and resize the RichEdit field accordingly sub Report_Resize { $ReportMessage->Resize($Report->ScaleWidth - 5, $Report->ScaleHeight - 65); $Send->Move(($Report->ScaleWidth - 71)/2, $Report->ScaleHeight - 30); } sub DataTab_Click { # check to see what tab has been clicked # if the first tab is clicked, hide the irrelavant labels and textfields # and show the relevant ones if ($DataTab->SelectedItem == 0) { $DataWindow->Bld_Label->Hide(); $Building->Hide(); $DataWindow->Adapt_Label->Hide(); $Adapter->Hide(); $DataWindow->FN_Label->Show(); $FirstName->Show(); $DataWindow->LN_Label->Show(); $LastName->Show(); $FirstName->SetFocus(); } # if the second tab is clicked, hide the irrelavant labels and textfields # and show the relevant ones if ($DataTab->SelectedItem == 1) { $DataWindow->FN_Label->Hide(); $FirstName->Hide(); $DataWindow->LN_Label->Hide(); $LastName->Hide(); $DataWindow->Adapt_Label->Hide(); $Adapter->Hide(); $DataWindow->Bld_Label->Show(); $Building->Show(); $Building->SetFocus(); } # if the third tab is clicked, hide the irrelavant labels and textfields # and show the relevant ones if ($DataTab->SelectedItem == 2) { $DataWindow->FN_Label->Hide(); $FirstName->Hide(); $DataWindow->LN_Label->Hide(); $LastName->Hide(); $DataWindow->Bld_Label->Hide(); $Building->Hide(); $DataWindow->Adapt_Label->Show(); $Adapter->Show(); $Adapter->SetFocus(); } } # has the 'x' button in the top right hand corner of the main window been clicked? sub DataWindow_Terminate { return -1; # exit the program } # this doesn't work and I don't know why but it checks to see if the Stop button has # been clicked and set a variable telling us it has, and then disable the Stop button sub Stop_Click { $Stop->Disable(); $breakloop = 1; return; } # this checks to see if the Find Now button has been clicked sub FindNow_Click { my ($index,$fname,$lname,$build,$room,$adap,$ip); $lastcolumn = ""; if ($dataretrieved == 1) { # if data has been retrieved go ahead if ($resized == 0) { $DataWindow->Resize($minwidth, $minheight + 118); } $DataView->View(1); # sets the dataview box to detail view $DataView->Clear(); # clear it $DataView->Show(); # show it $Status->Show(); # show the status bar $Stop->Enable(); # allow user to push the Stop button $index = 0; %data = ""; open (DATABASE, "database.txt"); # open the database containg the information while () { # do this until end of file is reached chomp; ($id,$fname,$lname,$build,$room,$adap,$ip) = split(/,/); # read in data and separate data if ($breakloop == 1) { # if Stop button is clciked break out of loop (but it doesn't work) last; } # determine which tab we are on and compare according to that if ((($DataTab->SelectedItem == 0) && (lc(substr($fname,0,length($FirstName->Text))) eq lc($FirstName->Text)) && (lc(substr($lname,0,length($LastName->Text))) eq lc($LastName->Text))) || (($DataTab->SelectedItem == 1) && (lc($build) eq lc($Building->Text))) || (($DataTab->SelectedItem == 2) && (lc(substr($adap,0,length($Adapter->Text))) eq lc($Adapter->Text)))) { # store data so we can sort it later my @temp = split/,/,$_; s/^\d{1,3},//; $data{$temp[0]} = $_; # display the data in the listview box, as a detailed view $DataView->InsertItem(-item => $index, -text => "$fname"); $DataView->SetItem(-item => $index, -subitem => 1, -text => "$lname"); $DataView->SetItem(-item => $index, -subitem => 2, -text => "$build"); $DataView->SetItem(-item => $index, -subitem => 3, -text => "$room"); $DataView->SetItem(-item => $index, -subitem => 4, -text => "$adap"); $DataView->SetItem(-item => $index, -subitem => 5, -text => "$ip"); ++$index; } $DataView->Update(); # update the view (for smoothness) # if a record matches what we are looking for, tell us in the staus bar $Status->Text("$index record(s) found"); } close DATABASE; # close the database $Stop->Disable(); # disable the Stop button $resized = 1; # main window has been resized (because listview has been added) } # if data has not been retrieved, tell us in a Message Box else { Win32::Sound::Play("SystemDefault", SND_ASYNC); Win32::GUI::MessageBox(0,"You must retrieve the data from the network\r\nfirst. Goto File, Retrieve Data.","Error: No Data Loaded",64); } } # if New Search button has been clicked, clear all data, set main window to default sub NewSearch_Click { $FirstName->Text(""); $LastName->Text(""); $Building->Text(""); $Building->Select(-1); $Adapter->Text(""); $DataWindow->Resize($minwidth, $minheight); $DataView->Hide(); $DataView->Clear(); $Status->Hide(); $resized = 0; } # if dropdown box is changed assign value to appropriate string sub Dropdown_Change { $Building->Text($Building->GetString($Building->SelectedItem)); } # sort data based on column clicked sub DataView_ColumnClick { my $column = shift; # if you 'toggle" click on a column switch from ascending to descending order if ($lastcolumn == $column) { $sortorder = 1 - $sortorder; } # otherwise sort on ascending order else { $sortorder = 0; } my %sortcol = &NewList($column, %data); &SortListItem(\%data,\%sortcol); $lastcolumn = $column; } sub SortListItem { my ($data,$sortcol) = @_; my $check; my %data = %$data; my %sortcol = %$sortcol; $check = "$_" foreach (values %sortcol); $DataView->Clear(); # clear out the dataview for redisplaying sorted data $index = 0; if ($sortorder == 0) { # ascending order foreach (sort { uc($sortcol{$a}) cmp uc($sortcol{$b}) } keys %sortcol) { my @newdata = split/,/,$data{$_}; ($fname,$lname,$build,$room,$adap,$ip) = @newdata; if ($fname ne "") { # display sorted data $DataView->InsertItem(-item => $index, -text => "$fname"); $DataView->SetItem(-item => $index, -subitem => 1, -text => "$lname"); $DataView->SetItem(-item => $index, -subitem => 2, -text => "$build"); $DataView->SetItem(-item => $index, -subitem => 3, -text => "$room"); $DataView->SetItem(-item => $index, -subitem => 4, -text => "$adap"); $DataView->SetItem(-item => $index, -subitem => 5, -text => "$ip"); $DataView->Update(); ++$index; } } } else { # descending order foreach (sort { uc($sortcol{$b}) cmp uc($sortcol{$a}) } keys %sortcol) { my @newdata = split/,/,$data{$_}; ($fname,$lname,$build,$room,$adap,$ip) = @newdata; if ($fname ne "") { # display sorted data $DataView->InsertItem(-item => $index, -text => "$fname"); $DataView->SetItem(-item => $index, -subitem => 1, -text => "$lname"); $DataView->SetItem(-item => $index, -subitem => 2, -text => "$build"); $DataView->SetItem(-item => $index, -subitem => 3, -text => "$room"); $DataView->SetItem(-item => $index, -subitem => 4, -text => "$adap"); $DataView->SetItem(-item => $index, -subitem => 5, -text => "$ip"); $DataView->Update(); ++$index; } } } } sub NewList { ## This creates another hash to use only for sorting purposes. my ($column,%sortcol) = @_; my $sortthis; foreach (keys %sortcol) { my @info = split /,/, $sortcol{$_}; $sortthis = $info[$column]; $sortcol{$_} = "$sortthis"; } return(%sortcol); } # has the 'x' button in the top right hand corner of the Report window been clicked? sub Report_Terminate { $ReportMessage->Text(""); # clear out the richEdit field $YourName->Text(""); # clear the sender's name $Report->Hide(); # hide the Report window return; } sub YourName_Change { if ($YourName->Text() ne "") { $Send->Enable(); # enable the Send button if sender has entered their name } else { $Send->Disable(); # if the sender didn't enter their name disbale Send button } } sub Send_Click { # if Send button has been clicked # if no message has been entered, inform the user if ($ReportMessage->Text() eq "") { Win32::Sound::Play("SystemDefault", SND_ASYNC); Win32::GUI::MessageBox(0,"Message can not be left blank. Please\r\nenter a message and try again.",64); } # otherwise send message and name of sender else { $name = $YourName->Text; # name of sender $message = $ReportMessage->Text; # message to be sent # if we aren't testing if ($test != 1) { # $name = sender's name, $smtp = outgoing mail sever ref ($sender = new Mail::Sender ({ from => $name, smtp => "mailserver"})); # $ recipient = receiver $sender->OpenMultipart({to => "recipient", subject => "Problem in Database"}); $sender->Body; $sender->Send($message); $sender->Send(<<'*END*'); *END* $sender->SendLine("\n$name"); $sender->Close; } $Report->Hide(); # hide the Report window } }