6662 lines (6399 with data), 309.4 kB
#!/usr/bin/perl
# Perl - v: 5.16.3
#------------------------------------------------------------------------------#
# Tool name : XL-Tools
# WebSite : http://le-tools.com/XL-Tools.html
# SourceForge : https://sourceforge.net/p/xl-tools
# GitHub : https://github.com/arioux/XL-Tools
# Documentation : http://le-tools.com/XL-ToolsDoc.html
# Description : Part of the XL-Toolkit, XL-Tools provides a bunch of functions
# for list of strings like sorting, converting, replacing, date
# and time utilities, etc.
# Creation : 2015-12-21
# Modified : 2020-01-12
my $VERSION = "3.9.1";
# Author : Alain Rioux (admin@le-tools.com)
#
# Copyright (C) 2015-2020 Alain Rioux (le-tools.com)
#
# 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
#
#------------------------------------------------------------------------------#
# Modules
#------------------------------------------------------------------------------#
use strict;
use warnings;
use Math::Int64 qw(string_to_int64);
use String::HexConvert qw(hex_to_ascii ascii_to_hex);
use URI::Escape;
use URI::Escape::JavaScript qw(unescape);
use Encode qw(encode decode);
use HTML::Entities;
use MIME::Base64 ();
use Convert::Base32;
use DateTime;
use DateTime::Format::Duration;
use DateTime::Format::Strptime;
use DateTime::TimeZone;
use Time::Seconds;
use Win32::API();
use Win32::GUI();
use Win32::GUI 1.06 qw(:toolbar ILC_MASK CW_USEDEFAULT);
use Win32::GUI::Grid;
use Win32::Process;
use LWP::UserAgent;
use DBI;
use File::Copy;
use JSON qw(decode_json);
use GIS::Distance::Lite qw(distance);
use threads;
use threads::shared;
use Scalar::Util;
require "XL-ToolsGraph.pl";
require "XL-ToolsLang.pl";
require "XL-ToolsConfig.pl";
require "XL-ToolsLists.pl";
require "XL-ToolsUtils.pl";
#------------------------------------------------------------------------------#
# Global variables
#------------------------------------------------------------------------------#
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;
my $PROGDIR = $0; # Program path
while (chop($PROGDIR) ne "\\") { } # Dir only
my $USERDIR; # User path
if (-d "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Tools") { $USERDIR = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Tools"; }
else { $USERDIR = $PROGDIR; }
my $LANG_FILE = "$USERDIR\\Lang.ini"; # Langage file
my $CONFIG_FILE = "$USERDIR\\XL-Tools.ini"; # Configuration file
my $URL_DOC = "http://le-tools.com/XL-ToolsDoc.html"; # Online documentation
my %CONFIG :shared; # Configuration
my %STR; # Strings for GUI
my $ARROW :shared; # Arrow pointer
my $HOURGLASS :shared; # Hourglass pointer
my $THR_PROCESS; # Thread for process
my $THR_UPDATE; # Thread for update
my $LISTNO = 0; # For CTRL+A
my $START = 0; # Indicate when program is started
my $LIST2_VISIBLE = 0; # Current state of List 2 (visible or not)
my $SPLIT1_CURR_POS; # Current pos of split 1, change when splitter is moved
my $SPLIT2_CURR_POS; # Current pos of split 2, change when splitter is moved
my $TOTAL_SIZE :shared = 0; # Total size for download
my %ZONE_MAP = ('ADT' => '-0300', # Atlantic Daylight Time # Ambiguous timezones
'AST' => '-0400', # Atlantic Standard Time
'BST' => '+0100', # British Summer Time
'BT' => '+0600', # Baghdad Time
'CAT' => '+0200', # Central Africa Time
'CCT' => '+0630', # Cocos Islands Time
'CDT' => '-0500', # Central Daylight Time
'CST' => '-0600', # Central Standard Time
'EAST' => '-0600', # Easter Island Standard Time
'ECT' => '-0500', # Ecuador Time
'EDT' => '-0400', # Eastern Daylight Time
'EST' => '-0500', # Eastern Standard Time
'FDT' => '-0100', # Fernando de Noronha Daylight Time
'FST' => '-0200', # Fernando de Noronha Standard Time
'GST' => '-0200', # South Georgia Time
'IDT' => '+0300', # Israel Daylight Time
'IST' => '+0200', # Israel Standard Time
'MET' => '+0100', # Middle European Time
'NFT' => '-0230', # Newfoundland Daylight Time
'NST' => '-0330', # Newfoundland Standard Time
'PST' => '-0800', # Pacific Standard Time
'SAST' => '+0200', # South Africa Standard Time
'SST' => '+0800', # Singapore Standard Time
'WAST' => '+0200', # West Africa Summer Time
'WST' => '+0800', # Western Standard Time}
);
#------------------------------------------------------------------------------#
# Graphic elements
#------------------------------------------------------------------------------#
my ($winICO, $logoBmp, $logo128Bmp, $fileOpenBmp, $deleteBmp, $viewReportBmp, $downloadBmp,
$processBmp, $stopBmp, $config32Bmp, $helpBmp, $aboutBmp, $config128Bmp, $fileNewBmp,
$database16, $import16Bmp, $addCFBmp, $remCFBmp, $editCFBmp, $newCFBmp, $saveCFBmp,
$cancelCFBmp, $checkBmp, $errorBmp, $left16Bmp, $help16Bmp, $datetime16Bmp, $guess16Bmp,
$datetimeAdd, $datetimeEdit, $datetimeDel, $useResBmp) = &loadGraph();
#------------------------------------------------------------------------------#
# Strings
#------------------------------------------------------------------------------#
&loadDefaultStr(\%STR); # Load default language (en)
&loadStr(\%STR, $LANG_FILE) if -e $LANG_FILE and -T $LANG_FILE; # If language file, load translated strings
#------------------------------------------------------------------------------#
# Main window
#------------------------------------------------------------------------------#
my $screen = Win32::GUI::GetDesktopWindow(); # Screen resolution
my $scrnX = Win32::GUI::Width($screen);
my $scrnY = Win32::GUI::Height($screen);
my $winWidth = 1080;
my $winHeight = 680;
my $winPosX = ($scrnX - $winWidth) / 2;
my $winPosY = ($scrnY - $winHeight) / 2;
# Keyboard shorcut
my $accel = new Win32::GUI::AcceleratorTable("Ctrl-A" => "selectAll",
"Ctrl-Down" => "fontSizeS",
"Ctrl-Up" => "fontSizeB", );
# Main Window
my $win = Win32::GUI::Window->new( -name => 'winMain' ,
-text => 'XL-Tools' ,
-background => [255, 255, 255] ,
-size => [$winWidth, $winHeight] ,
-pos => [$winPosX , $winPosY] ,
-minheight => $winHeight ,
-minwidth => $winWidth ,
-accel => $accel , );
$win->SetIcon($winICO);
# Fonts
sub LOGPIXELSX() {88}
sub getDPI { return(Win32::GUI::DC->new()->GetDeviceCaps(LOGPIXELSX)); }
my $DPI = &getDPI();
my ($fontGB, $fontGB2, $font10, $font10b, $font10u, $font12, $fontTF);
# Larger size (125% and 150%)
if ($DPI >= 120) {
$fontGB = new Win32::GUI::Font(-name => 'Arial', -size => 10, -bold => 1);
$fontGB2 = new Win32::GUI::Font(-name => 'Arial', -size => 10, -bold => 1, -underline => 1);
$font10 = new Win32::GUI::Font(-name => 'Arial', -size => 8);
$font10b = new Win32::GUI::Font(-name => 'Arial', -size => 8, -bold => 1);
$font10u = new Win32::GUI::Font(-name => 'Arial', -size => 8, -bold => 1, -underline => 1);
$font12 = new Win32::GUI::Font(-name => 'Arial', -size => 9);
$fontTF = new Win32::GUI::Font(-name => 'Arial', -size => 8);
# Normal size
} else {
$fontGB = new Win32::GUI::Font(-name => 'Arial', -size => 12, -bold => 1);
$fontGB2 = new Win32::GUI::Font(-name => 'Arial', -size => 12, -bold => 1, -underline => 1);
$font10 = new Win32::GUI::Font(-name => 'Arial', -size => 10);
$font10b = new Win32::GUI::Font(-name => 'Arial', -size => 10, -bold => 1);
$font10u = new Win32::GUI::Font(-name => 'Arial', -size => 10, -bold => 1, -underline => 1);
$font12 = new Win32::GUI::Font(-name => 'Arial', -size => 11);
$fontTF = new Win32::GUI::Font(-name => 'Arial', -size => 10);
}
# Load Pointers
my $loadImage = new Win32::API('user32', 'LoadImage', ['N','N','I','I','I','I'],'N');
$HOURGLASS = $loadImage->Call(0, 32514, 2, 0, 0, 0x8040);
$ARROW = $loadImage->Call(0, 32512, 2, 0, 0, 0x8040);
# Header
$win->AddLabel( -name => 'lblLogo' ,
-size => [310,100] ,
-pos => [ 0, 0] ,
-bitmap => $logoBmp ,
-background => [255, 255, 255] , );
$win->AddTabStrip( -name => 'Tab' ,
-size => [$winWidth-325,100] ,
-pos => [310, 0] ,
-fixedwidth => 1 ,
-tabstop => 1 ,
-background => [255, 255, 255] , );
$win->Tab->InsertItem(-text => $STR{'Tab1'} , );
$win->Tab->InsertItem(-text => $STR{'Tab2'} , );
$win->Tab->InsertItem(-text => $STR{'Tab3'} , );
$win->Tab->InsertItem(-text => $STR{'Tab4'} , );
$win->Tab->InsertItem(-text => $STR{'Tab5'} , );
$win->Tab->SetItemSize(116,20);
# Lists tab
$win->AddCombobox( -name => 'cbLists' ,
-size => [220,100] ,
-pos => [315, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$win->cbLists->Add( $STR{'cbLists1'} , $STR{'cbLists2'} ,
$STR{'cbLists3'} , $STR{'cbLists4'} ,
$STR{'cbLists5'} , $STR{'cbLists6'} ,
$STR{'cbLists7'} , $STR{'cbLists8'} ,
$STR{'cbLists9'} , $STR{'cbLists10'} ,
$STR{'cbLists11'} , $STR{'cbLists12'} ,
$STR{'cbLists19'} , $STR{'cbLists13'} ,
$STR{'cbLists14'} , $STR{'cbLists18'} ,
$STR{'cbLists15'} , $STR{'cbLists16'} ,
$STR{'cbLists17'} , );
$win->AddCheckbox( -name => 'chMatchCase' ,
-size => [ 90, 20] ,
-pos => [560, 32] ,
-text => $STR{'MatchCase'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 1 , );
$win->AddCheckbox( -name => 'chRegex' ,
-size => [ 80, 20] ,
-pos => [670, 32] ,
-text => $STR{'Regex'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 0 , );
$win->AddCheckbox( -name => 'chEval' ,
-size => [ 80, 20] ,
-pos => [760, 32] ,
-text => $STR{'Eval'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 0 ,
-disabled => 1 , );
$win->AddLabel( -name => 'lblWith' ,
-size => [ 40, 22] ,
-pos => [315, 67] ,
-background => [255, 255, 255] ,
-text => $STR{'With'}.':' ,
-font => $font10 , );
$win->AddTextfield( -name => 'tfWith' ,
-size => [ 95, 22] ,
-pos => [360, 65] , );
$win->AddLabel( -name => 'lblColumnsNo' ,
-size => [ 60, 22] ,
-pos => [475, 67] ,
-background => [255, 255, 255] ,
-text => $STR{'Columns'}.':' ,
-font => $font10 , );
$win->AddTextfield( -name => 'tfColumnsNo' ,
-size => [ 95, 22] ,
-pos => [540, 65] , );
$win->AddLabel( -name => 'lblReplace' ,
-size => [ 80, 22] ,
-pos => [315, 67] ,
-background => [255, 255, 255] ,
-text => $STR{'Replace'}.':' ,
-font => $font10 , );
$win->AddLabel( -name => 'lblReplaceREOk' ,
-size => [ 87, 24] ,
-pos => [399, 64] ,
-background => [ 0, 255, 0] ,
-visible => 0 , );
$win->AddLabel( -name => 'lblReplaceREErr' ,
-size => [ 87, 24] ,
-pos => [399, 64] ,
-background => [255, 0, 0] ,
-visible => 0 , );
$win->AddLabel( -name => 'lblReplaceREWarn' ,
-size => [ 87, 24] ,
-pos => [399, 64] ,
-background => [255, 255, 0] ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfReplace' ,
-size => [ 85, 22] ,
-pos => [400, 65] , );
$win->AddLabel( -name => 'lblReplBy' ,
-size => [ 30, 22] ,
-pos => [660, 67] ,
-background => [255, 255, 255] ,
-text => $STR{'By'}.':' ,
-font => $font10 , );
$win->AddLabel( -name => 'lblReplaceByREOk' ,
-size => [ 87, 24] ,
-pos => [694, 64] ,
-background => [ 0, 255, 0] ,
-visible => 0 , );
$win->AddLabel( -name => 'lblReplaceByREErr' ,
-size => [ 87, 24] ,
-pos => [694, 64] ,
-background => [255, 0, 0] ,
-visible => 0 , );
$win->AddLabel( -name => 'lblReplaceByREWarn' ,
-size => [ 87, 24] ,
-pos => [694, 64] ,
-background => [255, 255, 0] ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfReplBy' ,
-size => [ 85, 22] ,
-pos => [695, 65] ,
-disabled => 1 , );
$win->AddRadioButton( -name => 'rbAll' ,
-size => [140, 22] ,
-pos => [550, 30] ,
-background => [255, 255, 255] ,
-text => $STR{'all'} ,
-font => $font10 ,
-checked => 1 ,
-group => 1 ,
-visible => 0 , );
$win->AddRadioButton( -name => 'rbFirstOnly' ,
-size => [160, 22] ,
-pos => [700, 30] ,
-background => [255, 255, 255] ,
-text => $STR{'firstOnly'} ,
-font => $font10 ,
-visible => 0 , );
$win->AddRadioButton( -name => 'rbFirstEachWord' ,
-size => [200, 22] ,
-pos => [550, 60] ,
-background => [255, 255, 255] ,
-text => $STR{'firstEachWord'} ,
-font => $font10 ,
-visible => 0 , );
# Sort tab
$win->AddCombobox( -name => 'cbSorts' ,
-size => [220,100] ,
-pos => [315, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbSorts->Add( $STR{'cbSorts1'} , $STR{'cbSorts2'} ,
$STR{'cbSorts3'} , $STR{'cbSorts4'} ,
$STR{'cbSorts5'} , $STR{'cbSorts6'} , );
$win->AddRadioButton( -name => 'rbAsc' ,
-size => [100, 22] ,
-pos => [560, 30] ,
-background => [255, 255, 255] ,
-text => $STR{'Ascending'} ,
-font => $font10 ,
-checked => 1 ,
-group => 1 ,
-visible => 0 , );
$win->AddRadioButton( -name => 'rbDsc' ,
-size => [120, 22] ,
-pos => [660, 30] ,
-background => [255, 255, 255] ,
-text => $STR{'Descending'} ,
-font => $font10 ,
-visible => 0 , );
# Conversion tab
$win->AddCombobox( -name => 'cbConv' ,
-size => [220,100] ,
-pos => [315, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbConv->Add( $STR{'cbConv1'} , $STR{'cbConv2'} ,
$STR{'cbConv3'} , $STR{'cbConv4'} ,
$STR{'cbConv5'} , $STR{'cbConv6'} ,
$STR{'cbConv7'} , $STR{'cbConv8'} ,
$STR{'cbConv9'} , $STR{'cbConv10'} ,
$STR{'cbConv11'} , $STR{'cbConv12'} , );
# Time tab
$win->AddCombobox( -name => 'cbTime' ,
-size => [220,100] ,
-pos => [315, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbTime->Add($STR{'cbTime1'}, $STR{'cbTime2'}, $STR{'cbTime3'}, $STR{'cbTime4'});
# Parser
$win->AddLabel( -name => 'lblDTParser' ,
-size => [100, 22] ,
-pos => [$winWidth-287, 33] ,
-background => [255, 255, 255] ,
-text => $STR{'lblDTParser'}.':',
-font => $font10 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbDTParser' ,
-size => [ 80,100] ,
-pos => [$winWidth-227, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbDTParser->Add($STR{'None'} , $STR{'Before'}, $STR{'After'}, $STR{'Both'});
$win->cbDTParser->SetCurSel(0);
# Input format
$win->AddLabel( -name => 'lblInputType' ,
-size => [ 50, 22] ,
-pos => [315, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'Input'}.':' ,
-font => $font10 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbInputTimeType' ,
-size => [135,100] ,
-pos => [370, 65] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbInputDTFormat' ,
-size => [200,100] ,
-pos => [510, 65] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->AddButton( -name => 'btnOpenDTDB' ,
-size => [ 24, 24] ,
-pos => [712, 65] ,
-font => $font10 ,
-bitmap => $datetime16Bmp ,
-tip => "$STR{'Open'} $STR{'DTDB'}",
-disabled => 0 ,
-visible => 0 , );
$win->AddButton( -name => 'btnInputFormatGuess' ,
-size => [ 24, 24] ,
-pos => [738, 65] ,
-bitmap => $guess16Bmp ,
-tip => $STR{'btnInputFormatGuessTip'},
-disabled => 1 ,
-visible => 0 , );
# Output format
$win->AddLabel( -name => 'lblOutputDTFormat' ,
-size => [ 55, 22] ,
-pos => [$winWidth-287, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'Output'}.':' ,
-font => $font10 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbOutputDTFormat' ,
-size => [200,100] ,
-pos => [$winWidth-227, 65] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
# Time difference controls
$win->AddCheckbox( -name => 'chSingleDate' ,
-size => [130, 22] ,
-pos => [550, 30] ,
-text => $STR{'SingleDate'}.':' ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 0 ,
-visible => 0 , );
$win->AddDateTime( -name => 'dtTimeDiffDate' ,
-size => [ 90, 22] ,
-pos => [690, 30] ,
-font => $font10 ,
-background => [255, 255, 255] ,
-format => 'shortdate' ,
-visible => 0 , );
$win->AddDateTime( -name => 'dtTimeDiffTime' ,
-size => [ 80, 22] ,
-pos => [790, 30] ,
-font => $font10 ,
-background => [255, 255, 255] ,
-format => 'time' ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbOutputDTDiff' ,
-size => [100,100] ,
-pos => [$winWidth-227, 65] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbOutputDTDiff->Add($STR{'string'} , $STR{'years'}, $STR{'months'},
$STR{'weeks'} , $STR{'days'} , $STR{'hours'} ,
$STR{'minutes'}, $STR{'seconds'});
$win->cbOutputDTDiff->SetCurSel(0);
# Add-substract time controls
$win->AddLabel( -name => 'lblDeltaYears' ,
-size => [ 50, 22] ,
-pos => [540, 33] ,
-background => [255, 255, 255] ,
-text => ucfirst($STR{'years'}).':',
-font => $font10 ,
-align => 'right' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaYears' ,
-size => [ 45, 24] ,
-pos => [595, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaYears' ,
-visible => 0 , );
$win->upDownDeltaYears->SetRange(0,100);
$win->upDownDeltaYears->SetPos(0);
$win->AddLabel( -name => 'lblDeltaMonths' ,
-size => [ 50, 22] ,
-pos => [645, 33] ,
-background => [255, 255, 255] ,
-text => ucfirst($STR{'months'}).':',
-font => $font10 ,
-align => 'right' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaMonths' ,
-size => [ 45, 24] ,
-pos => [700, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaMonths' ,
-visible => 0 , );
$win->upDownDeltaMonths->SetRange(0,12);
$win->upDownDeltaMonths->SetPos(0);
$win->AddLabel( -name => 'lblDeltaDays' ,
-size => [ 50, 22] ,
-pos => [745, 33] ,
-background => [255, 255, 255] ,
-text => ucfirst($STR{'days'}).':',
-font => $font10 ,
-align => 'right' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaDays' ,
-size => [ 45, 24] ,
-pos => [800, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaDays' ,
-visible => 0 , );
$win->upDownDeltaDays->SetRange(0,365);
$win->upDownDeltaDays->SetPos(0);
$win->AddLabel( -name => 'lblDeltaTime' ,
-size => [ 50, 22] ,
-pos => [850, 33] ,
-background => [255, 255, 255] ,
-text => $STR{'Tab4'}.':' ,
-font => $font10 ,
-align => 'right' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaHours' ,
-size => [ 45, 24] ,
-pos => [905, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaHours' ,
-visible => 0 , );
$win->upDownDeltaHours->SetRange(0,24);
$win->upDownDeltaHours->SetPos(0);
$win->AddLabel( -name => 'lblSeparator1' ,
-size => [ 10, 22] ,
-pos => [950, 33] ,
-background => [255, 255, 255] ,
-text => ':' ,
-font => $fontGB ,
-align => 'center' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaMinutes' ,
-size => [ 45, 24] ,
-pos => [ 960, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaMinutes' ,
-visible => 0 , );
$win->upDownDeltaMinutes->SetRange(0,59);
$win->upDownDeltaMinutes->SetPos(0);
$win->AddLabel( -name => 'lblSeparator2' ,
-size => [ 10, 22] ,
-pos => [1005, 33] ,
-background => [255, 255, 255] ,
-text => ':' ,
-font => $fontGB ,
-align => 'center' ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfDeltaSecondes' ,
-size => [ 45, 24] ,
-pos => [1015, 30] ,
-number => 1 ,
-align => 'right' ,
-visible => 0 , );
$win->AddUpDown( -name => 'upDownDeltaSecondes' ,
-visible => 0 , );
$win->upDownDeltaSecondes->SetRange(0,59);
$win->upDownDeltaSecondes->SetPos(0);
# Utils tab
$win->AddCombobox( -name => 'cbUtils' ,
-size => [220,100] ,
-pos => [315, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbUtils->Add( $STR{'cbUtils1'} , $STR{'cbUtils2'} ,
$STR{'cbUtils3'} , $STR{'cbUtils4'} ,
$STR{'cbUtils5'} , $STR{'cbUtils6'} ,
$STR{'cbUtils7'} , $STR{'cbUtils8'} ,
$STR{'cbUtils9'} , $STR{'cbUtils10'} ,
$STR{'cbUtils11'} , $STR{'cbUtils13'} ,
$STR{'cbUtils15'} , $STR{'cbUtils14'} ,
$STR{'cbUtils12'} , );
# Resolve MAC Address Options
$win->AddLabel( -name => 'lblCurrMACOUIdbDate' ,
-size => [220, 22] ,
-pos => [315, 65] ,
-background => [255, 255, 255] ,
-foreground => [204, 0, 51] ,
-font => $font10 ,
-visible => 0 , );
$win->AddButton( -name => 'btnMACOUIdbUpdate' ,
-size => [100, 25] ,
-pos => [540, 60] ,
-font => $font10 ,
-visible => 0 , );
# GeoIP Options
$win->AddLabel( -name => 'lblGeoIPLang' ,
-size => [100, 22] ,
-pos => [315, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'Language'}.':' ,
-font => $font10 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbGeoIPLang' ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-size => [ 60, 80] ,
-pos => [420, 65] ,
-font => $font10 ,
-visible => 0 , );
$win->cbGeoIPLang->Add('en', 'de', 'es', 'fr', 'ja', 'pt-BR', 'ru', 'zh-CN');
$win->cbGeoIPLang->SetCurSel(0);
$win->AddCheckbox( -name => 'chGeoIPOptAll' ,
-size => [140, 22] ,
-pos => [545, 30] ,
-text => $STR{'AllDetails'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 1 ,
-visible => 0 , );
$win->AddCheckbox( -name => 'chAddHeaders' , # chGeoIPAddHeaders
-size => [140, 22] ,
-pos => [545, 55] ,
-text => $STR{'Addheaders'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 1 ,
-visible => 0 , );
$win->AddGrid( -name => 'gridGeoIPOpts' ,
-parent => $win ,
-pos => [690, 30] ,
-size => [300, 65] ,
-background => [255, 255, 255] ,
-columns => 5 ,
-rows => 2 ,
-fixedrows => 0 ,
-fixedcolumns => 0 ,
-editable => 1 ,
-visible => 0 , );
$win->gridGeoIPOpts->SetGridLines(0);
$win->gridGeoIPOpts->SetCellText( 0, 0, $STR{'Continent'});
$win->gridGeoIPOpts->SetCellType( 0, 0, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 0, 0, 1);
$win->gridGeoIPOpts->SetCellFormat( 0, 0, 4);
$win->gridGeoIPOpts->SetCellText( 1, 0, $STR{'Country'});
$win->gridGeoIPOpts->SetCellType( 1, 0, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 1, 0, 1);
$win->gridGeoIPOpts->SetCellFormat( 1, 0, 4);
$win->gridGeoIPOpts->SetCellText( 0, 1, $STR{'countryCode'});
$win->gridGeoIPOpts->SetCellType( 0, 1, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 0, 1, 1);
$win->gridGeoIPOpts->SetCellFormat( 0, 1, 4);
$win->gridGeoIPOpts->SetCellText( 1, 1, $STR{'Region'});
$win->gridGeoIPOpts->SetCellType( 1, 1, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 1, 1, 1);
$win->gridGeoIPOpts->SetCellFormat( 1, 1, 4);
$win->gridGeoIPOpts->SetCellText( 0, 2, $STR{'regionCode'});
$win->gridGeoIPOpts->SetCellType( 0, 2, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 0, 2, 1);
$win->gridGeoIPOpts->SetCellFormat( 0, 2, 4);
$win->gridGeoIPOpts->SetCellText( 1, 2, $STR{'City'});
$win->gridGeoIPOpts->SetCellType( 1, 2, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 1, 2, 1);
$win->gridGeoIPOpts->SetCellFormat( 1, 2, 4);
$win->gridGeoIPOpts->SetCellText( 0, 3, $STR{'postalCode'});
$win->gridGeoIPOpts->SetCellType( 0, 3, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 0, 3, 1);
$win->gridGeoIPOpts->SetCellFormat( 0, 3, 4);
$win->gridGeoIPOpts->SetCellText( 1, 3, $STR{'GPScoord'});
$win->gridGeoIPOpts->SetCellType( 1, 3, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 1, 3, 1);
$win->gridGeoIPOpts->SetCellFormat( 1, 3, 4);
$win->gridGeoIPOpts->SetCellText( 0, 4, $STR{'tzName'});
$win->gridGeoIPOpts->SetCellType( 0, 4, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 0, 4, 1);
$win->gridGeoIPOpts->SetCellFormat( 0, 4, 4);
$win->gridGeoIPOpts->SetCellText( 1, 4, $STR{'tzOffset'});
$win->gridGeoIPOpts->SetCellType( 1, 4, GVIT_CHECK );
$win->gridGeoIPOpts->SetCellCheck( 1, 4, 1);
$win->gridGeoIPOpts->SetCellFormat( 1, 4, 4);
$win->gridGeoIPOpts->AutoSize();
# User-Agent Options
$win->AddCheckbox( -name => 'chUAOptAll' ,
-size => [130, 22] ,
-pos => [545, 30] ,
-text => $STR{'AllDetails'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 1 ,
-visible => 0 , );
$win->AddGrid( -name => 'gridUAOpts' ,
-parent => $win ,
-pos => [690, 30] ,
-size => [300, 65] ,
-background => [255, 255, 255] ,
-columns => 3 ,
-rows => 2 ,
-fixedrows => 0 ,
-fixedcolumns => 0 ,
-editable => 1 ,
-visible => 0 , );
$win->gridUAOpts->SetGridLines(0);
$win->gridUAOpts->SetCellText( 0, 0, $STR{'Type'});
$win->gridUAOpts->SetCellType( 0, 0, GVIT_CHECK );
$win->gridUAOpts->SetCellCheck( 0, 0, 1);
$win->gridUAOpts->SetCellFormat(0, 0, 4);
$win->gridUAOpts->SetCellText( 1, 0, $STR{'uaOS'});
$win->gridUAOpts->SetCellType( 1, 0, GVIT_CHECK );
$win->gridUAOpts->SetCellCheck( 1, 0, 1);
$win->gridUAOpts->SetCellFormat(1, 0, 4);
$win->gridUAOpts->SetCellText( 0, 1, $STR{'uaBrowser'});
$win->gridUAOpts->SetCellType( 0, 1, GVIT_CHECK );
$win->gridUAOpts->SetCellCheck( 0, 1, 1);
$win->gridUAOpts->SetCellFormat(0, 1, 4);
$win->gridUAOpts->SetCellText( 1, 1, $STR{'uaDevice'});
$win->gridUAOpts->SetCellType( 1, 1, GVIT_CHECK );
$win->gridUAOpts->SetCellCheck( 1, 1, 1);
$win->gridUAOpts->SetCellFormat(1, 1, 4);
$win->gridUAOpts->SetCellText( 0, 2, $STR{'uaLang'});
$win->gridUAOpts->SetCellType( 0, 2, GVIT_CHECK );
$win->gridUAOpts->SetCellCheck( 0, 2, 1);
$win->gridUAOpts->SetCellFormat(0, 2, 4);
$win->gridUAOpts->AutoSize();
# Credit Card to Issuing Company Options
$win->AddRadioButton( -name => 'rbIINLocalDB' ,
-size => [200, 22] ,
-pos => [555, 30] ,
-background => [255, 255, 255] ,
-text => $STR{'IINLocalDB'} ,
-tip => $STR{'IINLocalDBTip'} ,
-font => $font10 ,
-checked => 1 ,
-group => 1 ,
-visible => 0 , );
$win->AddRadioButton( -name => 'rbBinlist' ,
-size => [200, 22] ,
-pos => [555, 60] ,
-background => [255, 255, 255] ,
-text => $STR{'use'}.' binlist.net',
-tip => $STR{'BinlistTip'} ,
-font => $font10 ,
-visible => 0 , );
# Address to GPS options
$win->AddCheckbox( -name => 'chAddr2GPSInc' ,
-size => [130, 22] ,
-pos => [545, 30] ,
-text => $STR{'incAddr'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 1 ,
-visible => 0 , );
# GPS to Address Options
$win->AddLabel( -name => 'lblGPS2AddrZL' ,
-size => [ 75, 22] ,
-pos => [315, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'ZoomLevel'}.':' ,
-font => $font10 ,
-visible => 0 , );
$win->AddCombobox( -name => 'cbGPS2AddrZL' ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-size => [140, 80] ,
-pos => [395, 65] ,
-font => $font10 ,
-visible => 0 , );
$win->cbGPS2AddrZL->Add($STR{'ZoomLevel3'} , $STR{'ZoomLevel5'} , $STR{'ZoomLevel8'} , $STR{'ZoomLevel10'},
$STR{'ZoomLevel14'}, $STR{'ZoomLevel16'}, $STR{'ZoomLevel17'}, $STR{'ZoomLevel18'});
$win->cbGPS2AddrZL->SetCurSel(7);
$win->AddCombobox( -name => 'cbGPS2AddrOutput' ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-size => [140, 80] ,
-pos => [545, 30] ,
-font => $font10 ,
-visible => 0 , );
$win->cbGPS2AddrOutput->Add($STR{'FullAddress'} , $STR{'AllDetails'} , $STR{'AddressEl'});
$win->cbGPS2AddrOutput->SetCurSel(0);
$win->AddGrid( -name => 'gridGPS2AddrOpts' ,
-parent => $win ,
-pos => [690, 30] ,
-size => [300, 65] ,
-background => [255, 255, 255] ,
-columns => 6 ,
-rows => 2 ,
-fixedrows => 0 ,
-fixedcolumns => 0 ,
-editable => 1 ,
-visible => 0 , );
$win->gridGPS2AddrOpts->SetGridLines(0);
$win->gridGPS2AddrOpts->SetCellText( 0, 0, lc($STR{'house_number'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 0, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 0, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 0, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 0, lc($STR{'road'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 0, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 0, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 0, 4);
$win->gridGPS2AddrOpts->SetCellText( 0, 1, lc($STR{'neighbourhood'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 1, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 1, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 1, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 1, lc($STR{'suburb'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 1, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 1, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 1, 4);
$win->gridGPS2AddrOpts->SetCellText( 0, 2, lc($STR{'city'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 2, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 2, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 2, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 2, lc($STR{'county'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 2, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 2, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 2, 4);
$win->gridGPS2AddrOpts->SetCellText( 0, 3, lc($STR{'region'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 3, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 3, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 3, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 3, lc($STR{'state'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 3, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 3, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 3, 4);
$win->gridGPS2AddrOpts->SetCellText( 0, 4, lc($STR{'postcode'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 4, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 4, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 4, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 4, lc($STR{'country'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 4, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 4, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 4, 4);
$win->gridGPS2AddrOpts->SetCellText( 0, 5, lc($STR{'country_code'}));
$win->gridGPS2AddrOpts->SetCellType( 0, 5, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 0, 5, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 0, 5, 4);
$win->gridGPS2AddrOpts->SetCellText( 1, 5, lc($STR{'boundingbox'}));
$win->gridGPS2AddrOpts->SetCellType( 1, 5, GVIT_CHECK );
$win->gridGPS2AddrOpts->SetCellCheck( 1, 5, 1);
$win->gridGPS2AddrOpts->SetCellFormat( 1, 5, 4);
$win->gridGPS2AddrOpts->AutoSize();
# Distance between locations
$win->AddCheckbox( -name => 'chSingleLocation' ,
-size => [180, 22] ,
-pos => [550, 30] ,
-text => $STR{'chSingleLocation'}.':',
-font => $font10 ,
-background => [255, 255, 255] ,
-checked => 0 ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfSingleLocation' ,
-size => [300, 24] ,
-pos => [735, 30] ,
-visible => 0 , );
# Customs Functions Options
$win->AddCombobox( -name => 'cbCFLists' ,
-size => [200,100] ,
-pos => [540, 30] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->cbCFLists->Add( $STR{'cbCFLists'}.'...' , );
$win->cbCFLists->SetCurSel(0);
$win->AddButton( -name => 'btnCFAdd' ,
-size => [ 24, 24] ,
-pos => [750, 30] ,
-bitmap => $addCFBmp ,
-tip => $STR{'btnCFAdd'} ,
-visible => 0 , );
$win->AddButton( -name => 'btnCFRem' ,
-size => [ 24, 24] ,
-pos => [776, 30] ,
-bitmap => $remCFBmp ,
-tip => $STR{'btnCFRem'} ,
-disabled => 1 ,
-visible => 0 , );
$win->AddButton( -name => 'btnCFEdit' ,
-size => [ 24, 24] ,
-pos => [802, 30] ,
-bitmap => $editCFBmp ,
-tip => $STR{'btnCFEdit'} ,
-disabled => 1 ,
-visible => 0 , );
$win->AddButton( -name => 'btnCFNew' ,
-size => [ 24, 24] ,
-pos => [828, 30] ,
-bitmap => $newCFBmp ,
-tip => $STR{'btnCFNew'} ,
-visible => 0 , );
$win->AddCheckbox( -name => 'chCFMatchCase' ,
-size => [ 90, 20] ,
-pos => [540, 68] ,
-text => $STR{'MatchCase'} ,
-font => $font10 ,
-background => [255, 255, 255] ,
-visible => 0 , );
$win->AddLabel( -name => 'lblCFTitle' ,
-size => [ 40, 22] ,
-pos => [315, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'Title'}.':' ,
-font => $font10 ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfCFTitle' ,
-size => [175, 24] ,
-pos => [360, 65] ,
-visible => 0 , );
$win->tfCFTitle->SetLimitText(24);
$win->AddButton( -name => 'btnCFSave' ,
-size => [ 24, 24] ,
-pos => [537, 65] ,
-bitmap => $saveCFBmp ,
-tip => $STR{'btnCFSave'} ,
-disabled => 1 ,
-visible => 0 , );
$win->AddButton( -name => 'btnCFCancel' ,
-size => [ 24, 24] ,
-pos => [563, 65] ,
-bitmap => $cancelCFBmp ,
-tip => $STR{'btnCFCancel'} ,
-visible => 0 , );
# Lists
$win->AddGroupbox( -name => 'gbList1' ,
-title => 'List 1' ,
-size => [$winWidth/3.18, $winHeight-200] ,
-pos => [ 3,105] ,
-font => $fontGB ,
-background => [255, 255, 255] , );
$win->AddButton( -name => 'btnList1File' ,
-size => [ 22, 22] ,
-pos => [ 7,125] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectFile'} , );
$win->AddButton( -name => 'btnList1Del' ,
-size => [ 22, 22] ,
-pos => [ 31,125] ,
-bitmap => $deleteBmp ,
-tip => $STR{'ResetContent'} , );
$win->AddButton( -name => 'btnList1UseRes' ,
-size => [ 22, 22] ,
-pos => [ 55,125] ,
-bitmap => $useResBmp ,
-tip => $STR{'btnList1UseRes'} ,
-disabled => 1 , );
$win->AddLabel( -name => 'lblList1Count' ,
-size => [ 60, 22] ,
-pos => [$winWidth/3.18-68, 128],
-background => [255, 255, 255] ,
-foreground => [204, 0, 51] ,
-text => '0' ,
-align => 'right' ,
-font => $font10b , );
$win->AddTextfield( -name => 'tfList1' ,
-size => [$winWidth/3.18-12, $winHeight-250] ,
-pos => [ 7, 150] ,
-background => [255, 255, 255] ,
-font => $fontTF ,
-multiline => 1 ,
-hscroll => 1 ,
-vscroll => 1 , );
$win->AddSplitter( -name => 'split1' ,
-vertical => 1 ,
-size => [ 2, $winHeight-190] ,
-pos => [$winWidth/3.2+7,100] ,
-min => 300 ,
-max => $win->ScaleWidth()/2 ,
- \&split1 ,
-visible => 0 , );
$win->AddGroupbox( -name => 'gbList2' ,
-title => 'List 2' ,
-size => [$winWidth/3.2, $winHeight-200] ,
-pos => [$winWidth/3.2+11,105] ,
-font => $fontGB ,
-background => [255, 255, 255] ,
-visible => 0 , );
$win->AddButton( -name => 'btnList2File' ,
-size => [ 22, 22] ,
-pos => [$winWidth/3.2+15,125] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectFile'} ,
-visible => 0 , );
$win->AddButton( -name => 'btnList2Del' ,
-size => [ 22, 22] ,
-pos => [$winWidth/3.2+38,125] ,
-bitmap => $deleteBmp ,
-tip => $STR{'ResetContent'} ,
-visible => 0 , );
$win->AddLabel( -name => 'lblList2Count' ,
-size => [ 60, 22] ,
-pos => [$winWidth/3.2+$winWidth/3.2-62, 128],
-background => [255, 255, 255] ,
-foreground => [204, 0, 51] ,
-text => '0' ,
-align => 'right' ,
-font => $font10b ,
-visible => 0 , );
$win->AddTextfield( -name => 'tfList2' ,
-size => [$winWidth/3.2-15, $winHeight-250] ,
-pos => [$winWidth/3.2+15, 150] ,
-background => [255, 255, 255] ,
-font => $fontTF ,
-multiline => 1 ,
-hscroll => 1 ,
-vscroll => 1 ,
-visible => 0 , );
$win->AddSplitter( -name => 'split2' ,
-vertical => 1 ,
-size => [ 2, $winHeight-190] ,
-pos => [$winWidth/3.2+$winWidth/3.2+12,100],
-min => $winWidth/2 ,
-max => $winWidth-200 ,
- \&split2 , );
$win->AddGroupbox( -name => 'gbList3' ,
-title => $STR{'Results'} ,
-size => [$winWidth/2.98, $winHeight-200] ,
-pos => [$winWidth/3.2+$winWidth/3.2+16,105],
-font => $fontGB ,
-background => [255, 255, 255] , );
$win->AddButton( -name => 'btnList3Open' ,
-size => [ 22, 22] ,
-pos => [$winWidth/3.2+$winWidth/3.2+17,125],
-bitmap => $viewReportBmp ,
-tip => $STR{'ViewReport'} , );
$win->AddCheckbox( -name => 'chList3InFile' ,
-size => [100, 22] ,
-pos => [$winWidth/3.2+$winWidth/3.2+46,125],
-text => $STR{'resInFile'} ,
-background => [255, 255, 255] ,
-font => $font10 , );
$win->AddLabel( -name => 'lblList3Count' ,
-size => [ 60, 22] ,
-pos => [$winWidth-87, 128] ,
-background => [255, 255, 255] ,
-foreground => [204, 0, 51] ,
-text => '0' ,
-align => 'right' ,
-font => $font10b , );
$win->AddTextfield( -name => 'tfList3' ,
-size => [$winWidth/2.98-5, $winHeight-250] ,
-pos => [$winWidth/3.2+$winWidth/3.2+17, 150] ,
-background => [255, 255, 255] ,
-font => $fontTF ,
-multiline => 1 ,
-hscroll => 1 ,
-vscroll => 1 , );
# Footer
$win->AddLabel( -name => 'lblFooter' ,
-size => [899, 80] ,
-pos => [ 2,$winHeight-95] ,
-valign => 'top' ,
-background => [250, 250, 250] ,
-foreground => [128, 128, 128] , );
$win->AddLabel( -name => 'lblNotReady' ,
-size => [170, 22] ,
-pos => [ 10, $winHeight-75] ,
-background => [250, 250, 250] ,
-foreground => [ 0, 102, 204] ,
-text => $STR{'lblNotReady'} ,
-font => $font10u ,
-notify => 1 , );
$win->AddLabel( -name => 'lblPbCurr' ,
-size => [690, 20] ,
-pos => [ 10, $winHeight-85] ,
-font => $font10 ,
-truncate => 1 ,
-background => [250, 250, 250] ,
-foreground => [204, 0, 51] ,
-visible => 0 , );
$win->AddProgressBar( -name => 'pb' ,
-size => [570, 20] ,
-pos => [ 10, $winHeight-65] ,
-smooth => 1 ,
-visible => 0 , );
$win->AddLabel( -name => 'lblPbCount' ,
-size => [105, 20] ,
-pos => [585, $winHeight-63] ,
-font => $font10 ,
-truncate => 1 ,
-background => [250, 250, 250] ,
-foreground => [204, 0, 51] ,
-visible => 0 , );
$win->AddButton( -name => 'btnProcess' ,
-size => [ 40, 40] ,
-pos => [710,$winHeight-85] ,
-bitmap => $processBmp ,
-background => [250, 250, 250] ,
-tip => $STR{'Process'} ,
-disabled => 1 , );
$win->AddButton( -name => 'btnStop' ,
-size => [ 40, 40] ,
-pos => [710,$winHeight-85] ,
-bitmap => $stopBmp ,
-background => [250, 250, 250] ,
-tip => $STR{'StopProcess'} ,
-visible => 0 , );
$win->AddButton( -name => 'btnWinConfig' ,
-size => [ 40, 40] ,
-pos => [755,$winHeight-85] ,
-bitmap => $config32Bmp ,
-background => [250, 250, 250] ,
-tip => $STR{'Configuration'} , );
$win->AddButton( -name => 'btnHelp' ,
-size => [ 40, 40] ,
-pos => [800,$winHeight-85] ,
-bitmap => $helpBmp ,
-background => [250, 250, 250] ,
-tip => $STR{'seeDoc'} , );
$win->AddButton( -name => 'btnAbout' ,
-size => [ 40, 40] ,
-pos => [845,$winHeight-85] ,
-bitmap => $aboutBmp ,
-background => [250, 250, 250] ,
-tip => $STR{'About'} , );
#------------------------------------------------------------------------------#
# Datetime database window
#------------------------------------------------------------------------------#
my $winDTDB = Win32::GUI::Window->new(-name => 'winDTDB' ,
-background => [255, 255, 255] ,
-parent => $win ,
-text => $STR{'DTDB'} ,
-pos => [$winPosX, $winPosY] ,
-size => [$winWidth, 450] ,
-hasmaximize => 1 ,
-hasminimize => 1 ,
-resizable => 1 ,
-dialogui => 1 , );
$winDTDB->SetIcon($winICO);
# Datetime grid
$winDTDB->AddGrid( -name => 'gridDT' ,
-size => [880,180] ,
-pos => [ 5, 5] ,
-background => [255, 255, 255] ,
-columns => 6 ,
-fixedrows => 1 ,
-fixedcolumns => 0 ,
-editable => 0 , );
$winDTDB->AddButton( -name => 'btnDTAdd' ,
-size => [ 30, 30] ,
-pos => [887, 5] ,
-bitmap => $datetimeAdd ,
-tip => $STR{'btnDTAdd'} ,
-tabstop => 1 , );
$winDTDB->AddButton( -name => 'btnDTEdit' ,
-size => [ 30, 30] ,
-pos => [887, 37] ,
-bitmap => $datetimeEdit ,
-tip => $STR{'btnDTEdit'} ,
-disabled => 1 ,
-tabstop => 1 , );
$winDTDB->AddButton( -name => 'btnDTDel' ,
-size => [ 30, 30] ,
-pos => [887, 69] ,
-bitmap => $datetimeDel ,
-tip => $STR{'btnDTDel'} ,
-disabled => 1 ,
-tabstop => 1 , );
$winDTDB->AddLabel( -name => 'lblDefaultOutput' ,
-size => [140, 22] ,
-pos => [ 5,303] ,
-background => [255, 255, 255] ,
-text => $STR{'defaultOutput'}.':',
-font => $font10 , );
$winDTDB->AddCombobox( -name => 'cbDefaultOutput' ,
-size => [230,100] ,
-pos => [150,300] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
#------------------------------------------------------------------------------#
# Datetime Object window
#------------------------------------------------------------------------------#
my $winDTObj = Win32::GUI::Window->new( -name => 'winDTObj' ,
-background => [255, 255, 255] ,
-parent => $win ,
-text => $STR{'winDTObj'} ,
-pos => [$winPosX, $winPosY] ,
-size => [690, 290] ,
-hasmaximize => 0 ,
-hasminimize => 0 ,
-resizable => 0 ,
-dialogui => 1 , );
$winDTObj->SetIcon($winICO);
$winDTObj->AddLabel( -name => 'lblDTObjSample' ,
-size => [ 95, 24] ,
-pos => [ 5, 8] ,
-background => [255, 255, 255] ,
-text => $STR{'sample'}.':' ,
-font => $font10 , );
$winDTObj->AddTextfield( -name => 'tfDTObjSample' ,
-size => [285, 24] ,
-pos => [100, 5] ,
-tabstop => 1 , );
$winDTObj->AddButton( -name => 'btnDTObjUseFirst' ,
-size => [120, 24] ,
-pos => [390, 5] ,
-text => '<- '.$STR{'useFirst'} ,
-font => $font10 ,
-disabled => 1 , );
$winDTObj->AddLabel( -name => 'lblDTObjPattern' ,
-size => [ 95, 24] ,
-pos => [ 5, 38] ,
-background => [255, 255, 255] ,
-text => $STR{'pattern'}.':' ,
-font => $font10 , );
$winDTObj->AddTextfield( -name => 'tfDTObjPattern' ,
-size => [260, 24] ,
-pos => [100, 35] ,
-tabstop => 1 ,
-disabled => 1 , );
$winDTObj->AddButton( -name => 'btnDTObjPatternInsert' ,
-size => [ 24, 24] ,
-pos => [362, 35] ,
-bitmap => $left16Bmp ,
-tip => $STR{'btnPatternAdd'} ,
-disabled => 1 , );
$winDTObj->AddCombobox( -name => 'cbDTObjPattern' ,
-size => [260,100] ,
-pos => [390, 35] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 ,
-disabled => 1 , );
$winDTObj->cbDTObjPattern->Add($STR{'pattern1'} , $STR{'pattern2'} , $STR{'pattern3'} ,
$STR{'pattern4'} , $STR{'pattern5'} , $STR{'pattern6'} ,
$STR{'pattern7'} , $STR{'pattern8'} , $STR{'pattern9'} ,
$STR{'pattern10'}, $STR{'pattern11'}, $STR{'pattern22'}, $STR{'pattern12'},
$STR{'pattern13'}, $STR{'pattern14'}, $STR{'pattern15'},
$STR{'pattern16'}, $STR{'pattern17'}, $STR{'pattern18'},
$STR{'pattern19'}, $STR{'pattern20'}, $STR{'pattern21'}, );
$winDTObj->cbDTObjPattern->SetCurSel(0);
$winDTObj->AddButton( -name => 'btnDTObjPatternHelp' ,
-size => [ 24, 24] ,
-pos => [652, 35] ,
-bitmap => $help16Bmp ,
-tip => $STR{'seeDoc'} , );
$winDTObj->AddLabel( -name => 'lblDTObjRegex' ,
-size => [ 95, 24] ,
-pos => [ 5, 68] ,
-background => [255, 255, 255] ,
-text => $STR{'Regex'}.':' ,
-font => $font10 , );
$winDTObj->AddLabel( -name => 'lblDTObjRegexOk' ,
-size => [287, 26] ,
-pos => [ 99, 64] ,
-background => [ 0, 255, 0] ,
-visible => 0 , );
$winDTObj->AddLabel( -name => 'lblDTObjRegexErr' ,
-size => [287, 26] ,
-pos => [ 99, 64] ,
-background => [255, 0, 0] ,
-visible => 0 , );
$winDTObj->AddLabel( -name => 'lblDTObjRegexWarn' ,
-size => [287, 26] ,
-pos => [ 99, 64] ,
-background => [255, 255, 0] ,
-visible => 0 , );
$winDTObj->AddTextfield( -name => 'tfDTObjRegex' ,
-size => [285, 24] ,
-pos => [100, 65] ,
-tabstop => 1 ,
-disabled => 1 , );
$winDTObj->AddCheckbox( -name => 'chDTObjRegexAuto' ,
-size => [150, 22] ,
-pos => [390, 65] ,
-text => $STR{'matchPattern'} ,
-background => [255, 255, 255] ,
-font => $font10 ,
-checked => 1 , );
$winDTObj->AddLabel( -name => 'lblDTObjTZ' ,
-size => [ 95, 22] ,
-pos => [ 5, 98] ,
-background => [255, 255, 255] ,
-text => $STR{'timezone'}.':' ,
-font => $font10 , );
$winDTObj->AddRadioButton( -name => 'rbDTObjTZLocal' ,
-size => [ 70, 22] ,
-pos => [100, 95] ,
-background => [255, 255, 255] ,
-text => $STR{'Local'} ,
-font => $font10 ,
-checked => 1 ,
-group => 1 , );
$winDTObj->AddRadioButton( -name => 'rbDTObjTZUTC' ,
-size => [ 70, 22] ,
-pos => [100,125] ,
-background => [255, 255, 255] ,
-text => $STR{'UTC'} ,
-font => $font10 , );
$winDTObj->AddRadioButton( -name => 'rbDTObjTZOtherOffset' ,
-size => [110, 22] ,
-pos => [175, 95] ,
-background => [255, 255, 255] ,
-text => $STR{'otherOffset'}.':' ,
-font => $font10 , );
$winDTObj->AddCombobox( -name => 'cbDTObjTZOffset' ,
-size => [ 65,100] ,
-pos => [290, 95] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winDTObj->cbDTObjTZOffset->Add('+1200','+1130','+1100','+1030','+1000','+0900','+0930','+0800','+0700',
'+0630','+0600','+0530','+0500','+0430','+0400','+0330','+0300','+0200',
'+0100','+0000','-0100','-0200','-0300','-0330','-0400','-0500','-0600',
'-0700','-0800','-0830','-0900','-0930','-1000','-1100','-1200', );
$winDTObj->cbDTObjTZOffset->SetCurSel(19);
$winDTObj->AddRadioButton( -name => 'rbDTObjTZOtherName' ,
-size => [110, 22] ,
-pos => [175,125] ,
-background => [255, 255, 255] ,
-text => $STR{'otherName'}.':' ,
-font => $font10 , );
$winDTObj->AddCombobox( -name => 'cbDTObjTZName' ,
-size => [260,100] ,
-pos => [290,125] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winDTObj->AddLabel( -name => 'lblDTObjParsed' ,
-size => [ 95, 22] ,
-pos => [ 5,158] ,
-background => [255, 255, 255] ,
-text => $STR{'Parsed'}.':' ,
-font => $font10 , );
$winDTObj->AddLabel( -name => 'lblDTObjParsedData' ,
-size => [400, 22] ,
-pos => [100,158] ,
-background => [255, 255, 255] ,
-foreground => [204, 0, 51] ,
-font => $font10 , );
$winDTObj->AddLabel( -name => 'lblDTObjUseAs' ,
-size => [ 95, 22] ,
-pos => [ 5,188] ,
-background => [255, 255, 255] ,
-text => $STR{'useAs'}.':' ,
-font => $font10 , );
$winDTObj->AddCombobox( -name => 'cbDTObjUseAs' ,
-size => [ 80,100] ,
-pos => [100,185] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winDTObj->cbDTObjUseAs->Add( $STR{'Input'}, $STR{'Output'}, $STR{'Both'}, $STR{'None'},);
$winDTObj->cbDTObjUseAs->SetCurSel(0);
$winDTObj->AddLabel( -name => 'lblDTObjComment' ,
-size => [ 95, 24] ,
-pos => [280,188] ,
-background => [255, 255, 255] ,
-text => $STR{'comment'}.':' ,
-font => $font10 , );
$winDTObj->AddTextfield( -name => 'tfDTObjComment' ,
-size => [285, 24] ,
-pos => [380,185] ,
-tabstop => 1 , );
$winDTObj->AddButton( -name => 'btnDTObjNotReady' ,
-size => [ 30, 30] ,
-pos => [255,220] ,
-text => '?' ,
-font => $font10 , );
$winDTObj->AddButton( -name => 'btnDTObjAdd' ,
-size => [ 60, 30] ,
-pos => [295,220] ,
-text => $STR{'Add'} ,
-font => $font10 ,
-disabled => 1 ,
-visible => 0 , );
$winDTObj->AddButton( -name => 'btnDTObjEdit' ,
-size => [ 60, 30] ,
-pos => [295,220] ,
-text => $STR{'Edit'} ,
-font => $font10 ,
-disabled => 1 ,
-visible => 0 , );
$winDTObj->AddButton( -name => 'btnDTObjCancel' ,
-size => [ 70, 30] ,
-pos => [360,220] ,
-text => $STR{'Cancel'} ,
-font => $font10 , );
#------------------------------------------------------------------------------#
# Config window
#------------------------------------------------------------------------------#
my $winConfig = Win32::GUI::DialogBox->new( -name => 'winConfig' ,
-parent => $win ,
-text => $STR{'Settings'} ,
-pos => [$winPosX, $winPosY] ,
-size => [750, 385] ,
-background => [255, 255, 255] ,
-hasmaximize => 0 ,
-hasminimize => 0 ,
-helpbutton => 0 ,
-resizable => 0 ,
-dialogui => 1 , );
$winConfig->SetIcon($winICO);
$winConfig->AddLabel( -name => 'lblLogo' ,
-size => [128,128] ,
-pos => [ 0, 5] ,
-bitmap => $config128Bmp ,
-background => [255, 255, 255] , );
# Tabstrip
$winConfig->AddTabStrip( -name => 'configTab' ,
-size => [605,350] ,
-pos => [140, 5] ,
-tabstop => 1 ,
-font => $font10 ,
-background => [255, 255, 255] , );
$winConfig->configTab->InsertItem( -text => $STR{'General'} , );
$winConfig->configTab->InsertItem( -text => $STR{'Databases'} , );
$winConfig->configTab->InsertItem( -text => 'XL-ToolKit '.$STR{'Databases'}, );
# General tab - Tool Section
$winConfig->AddLabel( -name => 'lblToolShadowT' ,
-size => [ 80, 22] ,
-pos => [151, 36] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'Tool'}.':' ,
-font => $fontGB2 , );
$winConfig->AddLabel( -name => 'lblToolT' ,
-size => [ 80, 22] ,
-pos => [150, 35] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'Tool'}.':' ,
-font => $fontGB2 , );
$winConfig->AddButton( -name => 'btnExportLang' ,
-size => [125, 24] ,
-pos => [150, 68] ,
-text => $STR{'Export'}.'Lang.ini',
-font => $font10 , );
$winConfig->AddButton( -name => 'btnOpenUserDir' ,
-size => [125, 24] ,
-pos => [285, 68] ,
-text => $STR{'OpenUserDir'}.'...',
-font => $font10 , );
$winConfig->AddButton( -name => 'btnCheckUpdate' ,
-size => [125, 24] ,
-pos => [150, 98] ,
-text => $STR{'checkUpdate'} ,
-font => $font10 , );
$winConfig->AddCheckbox( -name => 'chAutoUpdate' ,
-size => [200, 20] ,
-pos => [285,101] ,
-text => $STR{'AutoUpdateTip'} ,
-background => [255, 255, 255] ,
-font => $font10 ,
-tabstop => 1 ,
-checked => 1 , );
# General tab - Functions section
$winConfig->AddLabel( -name => 'lblOptFunctionsShadowT',
-size => [120, 22] ,
-pos => [151,141] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'OptFunctions'}.':',
-font => $fontGB2 , );
$winConfig->AddLabel( -name => 'lblOptFunctionsT' ,
-size => [120, 22] ,
-pos => [150,140] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'OptFunctions'}.':',
-font => $fontGB2 , );
$winConfig->AddCheckbox( -name => 'chFullScreen' ,
-size => [150, 20] ,
-pos => [285,142] ,
-text => $STR{'chFullScreen'} ,
-background => [255, 255, 255] ,
-font => $font10 , );
$winConfig->AddCheckbox( -name => 'chRememberPos' ,
-size => [195, 20] ,
-pos => [490,142] ,
-text => $STR{'chRememberPos'} ,
-background => [255, 255, 255] ,
-font => $font10 , );
$winConfig->AddLabel( -name => 'lblMaxSize1' ,
-size => [130, 22] ,
-pos => [150,173] ,
-background => [255, 255, 255] ,
-text => $STR{'MaxSize'}.':' ,
-font => $font10 , );
$winConfig->AddTextfield( -name => 'tfMaxSize' ,
-size => [ 60, 22] ,
-pos => [285,170] , );
$winConfig->AddLabel( -name => 'lblMaxSize2' ,
-size => [ 80, 22] ,
-pos => [350,173] ,
-background => [255, 255, 255] ,
-text => $STR{'chars'} ,
-font => $font10 , );
$winConfig->AddButton( -name => 'btnChooseFont' ,
-size => [125, 24] ,
-pos => [490,170] ,
-text => $STR{'chooseFont'}.'...',
-font => $font10 , );
$winConfig->AddLabel( -name => 'lblLocalTZ' ,
-size => [120, 22] ,
-pos => [150,203] ,
-background => [255, 255, 255] ,
-text => $STR{'localTimezone'}.':',
-font => $font10 , );
$winConfig->AddCombobox( -name => 'cbLocalTZ' ,
-size => [230,100] ,
-pos => [285,200] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winConfig->AddLabel( -name => 'lblOutputLang' ,
-size => [120, 22] ,
-pos => [150,233] ,
-background => [255, 255, 255] ,
-text => $STR{'defaultLang'}.':' ,
-font => $font10 , );
$winConfig->AddCombobox( -name => 'cbDefaultLang' ,
-size => [140,100] ,
-pos => [285,230] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winConfig->AddLabel( -name => 'lblOutputCharset' ,
-size => [120, 22] ,
-pos => [490,233] ,
-background => [255, 255, 255] ,
-text => $STR{'outputCharset'}.':',
-font => $font10 , );
$winConfig->AddCombobox( -name => 'cbOutputCharset' ,
-size => [100,100] ,
-pos => [615,230] ,
-font => $font10 ,
-dropdownlist => 1 ,
-vscroll => 1 , );
$winConfig->cbOutputCharset->Add( 'cp1252' , 'iso-8859-1' , 'iso-8859-2' , 'iso-8859-3' ,
'iso-8859-4' , 'iso-8859-5' , 'iso-8859-6' , 'iso-8859-7' ,
'iso-8859-8' , 'iso-8859-9' , 'iso-8859-10', 'iso-8859-11',
'iso-8859-13', 'iso-8859-14', 'iso-8859-15', 'iso-8859-16', );
$winConfig->AddLabel( -name => 'lblNsLookupTO1' ,
-size => [130, 22] ,
-pos => [150,263] ,
-background => [255, 255, 255] ,
-text => $STR{'NsLookupTO1'}.':' ,
-font => $font10 , );
$winConfig->AddTextfield( -name => 'tfLookupTO' ,
-size => [ 30, 22] ,
-pos => [285,260] , );
$winConfig->AddLabel( -name => 'lblNsLookupTO2' ,
-size => [ 70, 22] ,
-pos => [320,263] ,
-background => [255, 255, 255] ,
-text => lc($STR{'seconds'}) ,
-font => $font10 , );
$winConfig->AddLabel( -name => 'lblUserAgent' ,
-size => [130, 22] ,
-pos => [150,293] ,
-background => [255, 255, 255] ,
-text => $STR{'UserAgent'}.':' ,
-font => $font10 , );
$winConfig->AddTextfield( -name => 'tfUserAgent' ,
-size => [430, 22] ,
-pos => [285,290] , );
$winConfig->AddLabel( -name => 'lblNoResultOpt' ,
-size => [130, 22] ,
-pos => [150,323] ,
-background => [255, 255, 255] ,
-text => $STR{'NoResultOpt'}.':' ,
-font => $font10 , );
$winConfig->AddRadioButton( -name => 'rbNoResultOpt1' ,
-size => [150, 22] ,
-pos => [285,320] ,
-background => [255, 255, 255] ,
-text => $STR{'NoResultOpt1'} ,
-tip => $STR{'NoResultOpt1Tip'} ,
-font => $font10 ,
-checked => 1 ,
-group => 1 , );
$winConfig->AddRadioButton( -name => 'rbNoResultOpt2' ,
-size => [195, 22] ,
-pos => [440,320] ,
-background => [255, 255, 255] ,
-text => $STR{'NoResultOpt2'} ,
-tip => $STR{'NoResultOpt2Tip'} ,
-font => $font10 ,
-checked => 0 , );
# Database tab - MAC OUI Database section
$winConfig->AddLabel( -name => 'lblMACOUIDBShadowT' ,
-size => [250, 22] ,
-pos => [151, 36] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'OUIDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblMACOUIDBT' ,
-size => [250, 22] ,
-pos => [150, 35] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'OUIDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddCheckbox( -name => 'chMACOUIDBAutoUpt' ,
-size => [220, 20] ,
-pos => [495, 38] ,
-background => [255, 255, 255] ,
-text => $STR{'AutoUpdateTip'} ,
-font => $font10 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfMACOUIDB' ,
-size => [532, 22] ,
-pos => [150, 68] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnMACOUIDB' ,
-size => [ 22, 22] ,
-pos => [685, 68] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnMACOUIDBUpt' ,
-size => [ 22, 22] ,
-pos => [708, 68] ,
-bitmap => $downloadBmp ,
-tip => $STR{'downloadDB'} ,
-visible => 0 , );
# Database tab - GeoIP Database section
$winConfig->AddLabel( -name => 'lblGeoIPDBShadowT' ,
-size => [250, 22] ,
-pos => [151, 99] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'GeoIP'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblGeoIPDBT' ,
-size => [250, 22] ,
-pos => [150, 98] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'GeoIP'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfGeoIPDB' ,
-size => [532, 22] ,
-pos => [150,128] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnGeoIPDB' ,
-size => [ 22, 22] ,
-pos => [685,128] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblGeoIPNotice' ,
-size => [585, 22] ,
-pos => [150,155] ,
-background => [255, 255, 255] ,
-foreground => [ 80, 80, 80] ,
-text => $STR{'GeoIPNotice'} ,
-font => $font10 , );
# Database tab - Issuer Identification Number (IIN) Database section
$winConfig->AddLabel( -name => 'lblIINDBShadowT' ,
-size => [250, 22] ,
-pos => [151,180] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'IINLocalDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblIINDBT' ,
-size => [250, 22] ,
-pos => [150,179] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'IINLocalDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfIINDB' ,
-size => [532, 22] ,
-pos => [150,210] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnIINDB' ,
-size => [ 22, 22] ,
-pos => [685,210] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnIINDBUpt' ,
-size => [ 22, 22] ,
-pos => [708,210] ,
-bitmap => $downloadBmp ,
-tip => $STR{'downloadDB'} ,
-visible => 0 , );
# Database tab - OpenStreetMap (OSM) Database section
$winConfig->AddLabel( -name => 'lblOSMDBShadowT' ,
-size => [250, 22] ,
-pos => [151,241] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'OSMDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblOSMDBT' ,
-size => [250, 22] ,
-pos => [150,240] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'OSMDB'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfOSMDB' ,
-size => [532, 22] ,
-pos => [150,270] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnOSMDB' ,
-size => [ 22, 22] ,
-pos => [685,270] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnNewOSMDB' ,
-size => [ 22, 22] ,
-pos => [708,270] ,
-bitmap => $fileNewBmp ,
-tip => $STR{'createDBTable'} ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblOSMEmail' ,
-size => [ 75, 22] ,
-pos => [150,303] ,
-background => [255, 255, 255] ,
-text => $STR{'Email'}.':' ,
-font => $font10 , );
$winConfig->AddTextfield( -name => 'tfOSMEmailDB' ,
-size => [300, 22] ,
-pos => [230,300] ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblOSMNotice' ,
-size => [585, 22] ,
-pos => [150,328] ,
-background => [255, 255, 255] ,
-foreground => [ 80, 80, 80] ,
-text => $STR{'OSMNotice'} ,
-font => $font10 , );
# XL-ToolKit Database tab - XL-Whois database section
$winConfig->AddLabel( -name => 'lblXLWHOISDBShadowT' ,
-size => [250, 22] ,
-pos => [151, 36] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'XLWhois'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblXLWHOISDBT' ,
-size => [250, 22] ,
-pos => [150, 35] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'XLWhois'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfXLWHOISDB' ,
-size => [532, 22] ,
-pos => [150, 68] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnXLWHOISDB' ,
-size => [ 22, 22] ,
-pos => [685, 68] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
# XL-ToolKit Database tab - Datetime database section
$winConfig->AddLabel( -name => 'lblDTDBShadowT' ,
-size => [250, 22] ,
-pos => [151,104] ,
-foreground => [180, 180, 180] ,
-background => [255, 255, 255] ,
-text => $STR{'Datetime'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddLabel( -name => 'lblDTDBT' ,
-size => [250, 22] ,
-pos => [150,103] ,
-addstyle => 11 , # Transparent
-foreground => [204, 0, 51] ,
-text => $STR{'Datetime'}.':' ,
-font => $fontGB2 ,
-visible => 0 , );
$winConfig->AddTextfield( -name => 'tfDTDB' ,
-size => [532, 22] ,
-pos => [150,133] ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnDTDB' ,
-size => [ 22, 22] ,
-pos => [685,133] ,
-bitmap => $fileOpenBmp ,
-tip => $STR{'selectDBFile'} ,
-visible => 0 , );
$winConfig->AddButton( -name => 'btnDTDBUpt' ,
-size => [ 22, 22] ,
-pos => [708,133] ,
-bitmap => $downloadBmp ,
-tip => $STR{'downloadDB'} ,
-visible => 0 , );
#------------------------------------------------------------------------------#
# Simple Progress window
#------------------------------------------------------------------------------#
my $winPb = Win32::GUI::DialogBox->new(-name => 'winPb' ,
-parent => $winConfig ,
-text => $STR{'winPb'} ,
-pos => [$winPosX, $winPosY] ,
-size => [600, 170] ,
-background => [255, 255, 255] ,
-hasmaximize => 0 ,
-hasminimize => 1 ,
-helpbutton => 0 ,
-resizable => 0 ,
-dialogui => 1 , );
$winPb->SetIcon($winICO);
$winPb->AddLabel( -name => 'lblLogo2' ,
-size => [128,128] ,
-pos => [ 0, 5] ,
-bitmap => $logo128Bmp , );
$winPb->AddLabel( -name => 'lblPbCurr' ,
-size => [460, 22] ,
-pos => [140, 25] ,
-font => $font10 ,
-truncate => 1 ,
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] , );
$winPb->AddProgressBar( -name => 'pbWinPb' ,
-size => [355, 22] ,
-pos => [140, 50] ,
-smooth => 1 , );
$winPb->AddLabel( -name => 'lblCount' ,
-size => [100, 22] ,
-pos => [500, 52] ,
-font => $font10 ,
-truncate => 1 ,
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] , );
$winPb->AddButton( -name => 'btnCancel' ,
-text => $STR{'Cancel'} ,
-font => $font10 ,
-size => [ 80, 30] ,
-pos => [300, 95] ,
-cancel => 1 , );
#------------------------------------------------------------------------------#
# Starting program
#------------------------------------------------------------------------------#
$win->cbLists->SetCurSel(0);
&cbLists_Change();
# Set Datetime grid header
$winDTDB->gridDT->SetCellText(0, 0, $STR{'sample'} );
$winDTDB->gridDT->SetCellText(0, 1, $STR{'pattern'} );
$winDTDB->gridDT->SetCellText(0, 2, $STR{'Regex'} );
$winDTDB->gridDT->SetCellText(0, 3, $STR{'timezone'});
$winDTDB->gridDT->SetCellText(0, 4, $STR{'useAs'} );
$winDTDB->gridDT->SetCellText(0, 5, $STR{'comment'} );
# List of timezone
my @listTZ = DateTime::TimeZone->all_names;
foreach (@listTZ) { $winConfig->cbLocalTZ->Add($_); $winDTObj->cbDTObjTZName->Add($_); }
$winDTObj->cbDTObjTZName->SetCurSel(0);
# List of language
my @lang = DateTime::Locale->ids();
foreach (sort @lang) { $winConfig->cbDefaultLang->Add($_); }
# Load configuration and databases
if (-T $CONFIG_FILE) {
&loadConfig(\%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$win, \$fontTF);
# Load the Datetime Database
if ($CONFIG{'DT_DB_FILE'} and -f $CONFIG{'DT_DB_FILE'} and &validSQLiteDB($CONFIG{'DT_DB_FILE'}, 'DT')) {
&loadDTDB(\$winDTDB, \$winConfig, \$win, \%STR);
&cbInputDTFormatAddITems();
$win->cbInputDTFormat->SetCurSel(0);
&cbOutputDTFormatAddITems();
$win->cbOutputDTFormat->SetCurSel(0);
# Default output format
if (exists($CONFIG{'DEFAULT_OUTPUT'})) { $winDTDB->cbDefaultOutput->SetCurSel($CONFIG{'DEFAULT_OUTPUT'}); }
else { $winDTDB->cbDefaultOutput->SetCurSel(0); }
# If don't exist, ask to download it
} else {
threads->create(sub {
# Yes (6), No (7)
my $answer = Win32::GUI::MessageBox($win, "$STR{'DTDB'} (DT.db) $STR{'NotExistDownload'}?", $STR{'DTDB'}, 0x1024);
# Answer is Yes
if ($answer == 6) {
my ($status, $return) = &downloadDB(\$win, 'DT', $STR{'DTDB'}, "$USERDIR\\DT.db", 'le-tools.com', \$HOURGLASS,
\$ARROW, \%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { Win32::GUI::MessageBox($win, "$STR{'DTDB'} $STR{'HasBeenUpdated'}", "XL-Tools $VERSION", 0x40040); }
else { Win32::GUI::MessageBox($win, $return, $STR{'Error'}, 0x40010); }
}
});
}
# Create OSM database if it doesn't exist
if (!$CONFIG{'OSM_DB'} or !-f $CONFIG{'OSM_DB'} or !&validSQLiteDB($CONFIG{'OSM_DB'}, 'GPS2ADDR')) {
my $OSMDBFile = "$USERDIR\\OSM.db";
my $OSMDir = "$USERDIR\\osm";
if ($OSMDBFile and &createOSMDB($OSMDBFile)) {
mkdir($OSMDir) if !-d $OSMDir; # Create subfolder for JSON file
$winConfig->tfOSMDB->Text($OSMDBFile);
}
}
# Check update for tool and databases?
if ($CONFIG{'TOOL_AUTO_UPDATE'} or $CONFIG{'MACOUI_DB_AUTO_UPDATE'}) {
$THR_UPDATE = threads->create(sub { &updateAll($VERSION, $USERDIR, \$HOURGLASS, \$ARROW, \$winConfig,
\%CONFIG, $CONFIG_FILE, \$winDTDB, \$winPb, \$win, \%STR); });
}
# Position the window
if ($winConfig->chRememberPos->Checked() and exists($CONFIG{'SCREEN_LEFT'}) and exists($CONFIG{'SCREEN_TOP'})) {
$win->Left($CONFIG{'SCREEN_LEFT'});
$win->Top($CONFIG{'SCREEN_TOP'});
}
} else { # Configuration Wizard Window
my $refWinCW = &createCW();
# First start of the tool, Load configuration wizard
$THR_UPDATE = threads->create(sub { &firstStart($refWinCW); });
}
$START = 1;
if ($winConfig->chFullScreen->Checked()) { $win->Show(3); }
else { $win->Show(); }
Win32::GUI::Dialog();
#--------------------------#
sub winMain_Terminate
#--------------------------#
{
# Remember position
my $winLeft = $win->AbsLeft();
my $winTop = $win->AbsTop();
$CONFIG{'SCREEN_LEFT'} = $winLeft;
$CONFIG{'SCREEN_TOP'} = $winTop;
&saveConfig(\%CONFIG, $CONFIG_FILE);
# Close program
-1;
} #--- End winMain_Terminate
#--------------------------#
sub winMain_Resize
#--------------------------#
{
# Header
$win->Tab->Width($win->ScaleWidth()-308);
$win->tfWith->Width($win->ScaleWidth()/9.3);
$win->lblColumnsNo->Left($win->tfWith->Left()+$win->ScaleWidth()/9.3+20);
$win->tfColumnsNo->Left($win->lblColumnsNo->Left()+70);
$win->tfColumnsNo->Width($win->ScaleWidth()/9.3);
$win->lblReplaceREOk->Width($win->ScaleWidth()/5+2);
$win->lblReplaceREErr->Width($win->ScaleWidth()/5+2);
$win->lblReplaceREWarn->Width($win->ScaleWidth()/5+2);
$win->tfReplace->Width($win->ScaleWidth()/5);
$win->lblReplBy->Left($win->tfReplace->Left()+$win->ScaleWidth()/5+10);
$win->lblReplaceByREOk->Left($win->tfReplace->Left()+$win->ScaleWidth()/5+44);
$win->lblReplaceByREOk->Width($win->ScaleWidth()/5+2);
$win->lblReplaceByREErr->Left($win->tfReplace->Left()+$win->ScaleWidth()/5+44);
$win->lblReplaceByREErr->Width($win->ScaleWidth()/5+2);
$win->lblReplaceByREWarn->Left($win->tfReplace->Left()+$win->ScaleWidth()/5+44);
$win->lblReplaceByREWarn->Width($win->ScaleWidth()/5+2);
$win->tfReplBy->Left($win->tfReplace->Left()+$win->ScaleWidth()/5+45);
$win->tfReplBy->Width($win->ScaleWidth()/5);
$win->cbCFLists->Width($win->ScaleWidth()/4);
$win->lblDTParser->Left($win->ScaleWidth()-($win->ScaleWidth()/5.25)-65);
$win->cbDTParser->Left($win->ScaleWidth()-($win->ScaleWidth()/5.25)+40);
$win->cbInputTimeType->BringWindowToTop(); # Prevent box from disappearing
$win->cbInputTimeType->SetCurSel($win->cbInputTimeType->GetCurSel());
$win->cbInputDTFormat->Width($win->ScaleWidth()/4.8);
$win->cbInputDTFormat->BringWindowToTop(); # Prevent box from disappearing
$win->cbInputDTFormat->SetCurSel($win->cbInputDTFormat->GetCurSel());
$win->btnOpenDTDB->Left(510+($win->ScaleWidth()/4.8)+2);
$win->btnInputFormatGuess->Left(510+($win->ScaleWidth()/4.8)+26);
$win->lblOutputDTFormat->Left($win->ScaleWidth()-($win->ScaleWidth()/5.25)-65);
$win->cbOutputDTFormat->Left($win->ScaleWidth()-($win->ScaleWidth()/5.25)-5);
$win->cbOutputDTFormat->Width($win->ScaleWidth()/5.25);
$win->cbOutputDTFormat->BringWindowToTop(); # Prevent box from disappearing
$win->cbOutputDTFormat->SetCurSel($win->cbOutputDTFormat->GetCurSel());
$win->cbOutputDTDiff->Left($win->ScaleWidth()-($win->ScaleWidth()/5.25)-5);
$win->cbOutputDTDiff->Width($win->ScaleWidth()/8);
$win->cbOutputDTDiff->BringWindowToTop(); # Prevent box from disappearing
$win->cbOutputDTDiff->SetCurSel($win->cbOutputDTFormat->GetCurSel());
$win->gridGeoIPOpts->Width($win->ScaleWidth()-700);
$win->gridGeoIPOpts->AutoSize();
$win->gridGeoIPOpts->ExpandRowsToFit();
$win->gridGeoIPOpts->ExpandLastColumn();
$win->gridGPS2AddrOpts->Width($win->ScaleWidth()-700);
$win->gridGPS2AddrOpts->AutoSize();
$win->gridGPS2AddrOpts->ExpandRowsToFit();
$win->gridGPS2AddrOpts->ExpandLastColumn();
$win->gridUAOpts->Width($win->ScaleWidth()-700);
$win->gridUAOpts->AutoSize();
$win->gridUAOpts->ExpandRowsToFit();
$win->gridUAOpts->ExpandLastColumn();
$win->cbCFLists->BringWindowToTop(); # Prevent box from disappearing
$win->cbCFLists->SetCurSel($win->cbCFLists->GetCurSel());
$win->btnCFAdd->Left($win->cbCFLists->Left()+$win->ScaleWidth()/4+4);
$win->btnCFRem->Left($win->cbCFLists->Left()+$win->ScaleWidth()/4+30);
$win->btnCFEdit->Left($win->cbCFLists->Left()+$win->ScaleWidth()/4+56);
$win->btnCFNew->Left($win->cbCFLists->Left()+$win->ScaleWidth()/4+82);
$win->tfCFTitle->Width($win->ScaleWidth()/4);
$win->btnCFSave->Left($win->tfCFTitle->Left()+$win->ScaleWidth()/4+4);
$win->btnCFCancel->Left($win->tfCFTitle->Left()+$win->ScaleWidth()/4+30);
# Lists
# Adjusts splitter position
my $split1Pos;
if ($SPLIT1_CURR_POS) {
$split1Pos = $win->ScaleWidth()/$SPLIT1_CURR_POS;
$split1Pos = 300 if $split1Pos < 300;
}
else {
$split1Pos = $win->split1->Left();
$SPLIT1_CURR_POS = $win->ScaleWidth()/$split1Pos;
}
my $split2Pos;
if ($SPLIT2_CURR_POS) { $split2Pos = $win->ScaleWidth()/$SPLIT2_CURR_POS; }
else {
$split2Pos = $win->split2->Left();
$SPLIT2_CURR_POS = $win->ScaleWidth()/$split2Pos;
}
$win->split1->Max($win->ScaleWidth()/2);
if ($LIST2_VISIBLE) { $win->split2->Min($win->ScaleWidth()/2); }
else { $win->split2->Min(300); }
$win->split2->Max($win->ScaleWidth()-200);
$win->split1->Left($split1Pos);
$win->split1->Height($win->ScaleHeight()-150);
$win->split2->Left($split2Pos);
$win->split2->Height($win->ScaleHeight()-150);
# List 1
if ($LIST2_VISIBLE) {
$win->gbList1->Resize($split1Pos-6, $win->ScaleHeight()-162);
$win->tfList1->Resize($split1Pos-16, $win->ScaleHeight()-212);
$win->lblList1Count->Left($split1Pos-70);
} else {
$win->gbList1->Resize($split2Pos-6, $win->ScaleHeight()-162);
$win->tfList1->Resize($split2Pos-16, $win->ScaleHeight()-212);
$win->lblList1Count->Left($split2Pos-70);
}
# List 2
$win->gbList2->Left($split1Pos+5);
$win->gbList2->Resize($split2Pos-$split1Pos-7.5, $win->ScaleHeight()-162);
$win->btnList2File->Left($split1Pos+9);
$win->btnList2Del->Left($split1Pos+33);
$win->lblList2Count->Left($split2Pos-70);
$win->tfList2->Left($split1Pos+9);
$win->tfList2->Resize($split2Pos-$split1Pos-16, $win->ScaleHeight()-212);
# List 3
$win->gbList3->Left($split2Pos+5);
$win->gbList3->Resize($win->ScaleWidth()-$split2Pos-8, $win->ScaleHeight()-162);
$win->btnList3Open->Left($split2Pos+9);
$win->chList3InFile->Left($split2Pos+36);
$win->lblList3Count->Left($win->ScaleWidth()-70);
$win->tfList3->Left($split2Pos+9);
$win->tfList3->Resize($win->ScaleWidth()-$split2Pos-16, $win->ScaleHeight()-212);
# Footer
$win->lblFooter->Top($win->ScaleHeight()-55);
$win->lblFooter->Width($win->ScaleWidth());
$win->lblNotReady->Top($win->ScaleHeight()-40);
$win->lblPbCurr->Top($win->ScaleHeight()-48);
$win->lblPbCurr->Width($win->ScaleWidth()-200);
$win->pb->Top($win->ScaleHeight()-27);
$win->pb->Width($win->ScaleWidth()-310);
$win->lblPbCount->Top($win->ScaleHeight()-25);
$win->lblPbCount->Left($win->ScaleWidth()-295);
$win->btnProcess->Move($win->ScaleWidth()-180, $win->ScaleHeight()-45);
$win->btnStop->Move($win->ScaleWidth()-180, $win->ScaleHeight()-45);
$win->btnWinConfig->Move($win->ScaleWidth()-135, $win->ScaleHeight()-45);
$win->btnHelp->Move($win->ScaleWidth()-90, $win->ScaleHeight()-45);
$win->btnAbout->Move($win->ScaleWidth()-45, $win->ScaleHeight()-45);
} #--- End winMain_Resize
#--------------------------#
sub split1
#--------------------------#
{
# Local variables
my ($s, $left) = @_;
my $split2Pos = $win->split2->Left();
$SPLIT1_CURR_POS = $win->ScaleWidth()/$left;
# Resize and move
# List 1
$win->gbList1->Width($left - 6);
$win->tfList1->Width($left-16);
$win->lblList1Count->Left($left-70);
# List 2
if ($split2Pos - $left < 100) {
if ($LIST2_VISIBLE) {
# Hide List 2 (not enough space)
$win->gbList2->Hide();
$win->btnList2File->Hide();
$win->btnList2Del->Hide();
$win->lblList2Count->Hide();
$win->tfList2->Hide();
}
} else {
# Show List 2
if ($LIST2_VISIBLE) {
$win->gbList2->Show();
$win->btnList2File->Show();
$win->btnList2Del->Show();
$win->lblList2Count->Show();
$win->tfList2->Show();
}
$win->gbList2->Width($split2Pos - $left - 7.5);
$win->gbList2->Left($left + 5);
$win->btnList2File->Left($left+9);
$win->btnList2Del->Left($left+33);
$win->lblList2Count->Left($split2Pos-70);
$win->tfList2->Left($left+9);
$win->tfList2->Width($split2Pos-$left-16);
}
return(1);
} #--- End split1
#--------------------------#
sub split2
#--------------------------#
{
# Local variables
my ($s, $left) = @_;
my $split1Pos = $win->split1->Left();
$SPLIT2_CURR_POS = $win->ScaleWidth()/$left;
# Resize and move
# List 2
if ($left - $split1Pos < 100) {
if ($LIST2_VISIBLE) {
# Hide List 2 (not enough space)
$win->gbList2->Hide();
$win->btnList2File->Hide();
$win->btnList2Del->Hide();
$win->lblList2Count->Hide();
$win->tfList2->Hide();
}
} else {
# Show List 2
if ($LIST2_VISIBLE) {
$win->gbList2->Show();
$win->btnList2File->Show();
$win->btnList2Del->Show();
$win->lblList2Count->Show();
$win->tfList2->Show();
}
$win->gbList2->Width($left - $split1Pos - 7.5);
$win->lblList2Count->Left($left-70);
$win->tfList2->Left($split1Pos+9);
$win->tfList2->Width($left-$split1Pos-16);
}
# If List 2 is not visible, adjust List 1
if (!$LIST2_VISIBLE) {
$win->gbList1->Width($left - 6);
$win->tfList1->Width($left-16);
$win->lblList1Count->Left($left-70);
}
# List 3
$win->gbList3->Width($win->ScaleWidth() - $left - 9);
$win->gbList3->Left($left + 5);
$win->btnList3Open->Left($left+9);
$win->chList3InFile->Left($left+36);
$win->lblList3Count->Left($win->ScaleWidth()-70);
$win->tfList3->Left($left+9);
$win->tfList3->Width($win->ScaleWidth()-$left-16);
return(1);
} #--- End split2
#--------------------------#
sub showList2
#--------------------------#
{
$LIST2_VISIBLE = 1;
$win->gbList2->Show();
$win->btnList2File->Show();
$win->btnList2Del->Show();
$win->lblList2Count->Show();
$win->tfList2->Show();
$win->split1->Show();
$win->split1->Left($win->ScaleWidth()/3.07586206896552);
$win->split2->Left($win->ScaleWidth()/1.5405872193437);
&split1(undef, $win->ScaleWidth()/3.07586206896552);
&split2(undef, $win->ScaleWidth()/1.5405872193437);
$win->split2->Min($win->ScaleWidth()/2);
} #--- End showList2
#--------------------------#
sub hideList2
#--------------------------#
{
$LIST2_VISIBLE = 0;
$win->tfList2->Text('');
$win->gbList2->Hide();
$win->btnList2File->Hide();
$win->btnList2Del->Hide();
$win->lblList2Count->Hide();
$win->tfList2->Hide();
$win->split1->Hide();
$win->split1->Left($win->ScaleWidth()/2);
$win->split2->Left($win->ScaleWidth()/2);
&split1(undef, $win->ScaleWidth()/2);
&split2(undef, $win->ScaleWidth()/2);
$win->split2->Min(300);
} #--- End hideList2
#--------------------------#
sub Tab_Click
#--------------------------#
{
# Show Lists tab
if ($win->Tab->SelectedItem() == 0) {
$win->cbLists->Show();
$win->cbLists->SetCurSel(0) if $win->cbLists->GetCurSel() == -1;
&cbLists_Change();
# Hide Sorting tab
$win->cbSorts->Hide();
$win->rbAsc->Hide();
$win->rbDsc->Hide();
# Hide Conversion tab
$win->cbConv->Hide();
# Hide Time tab
$win->cbTime->Hide();
$win->lblDTParser->Hide();
$win->cbDTParser->Hide();
$win->lblOutputDTFormat->Hide();
$win->cbOutputDTFormat->Hide();
$win->chSingleDate->Hide();
$win->dtTimeDiffDate->Hide();
$win->dtTimeDiffTime->Hide();
$win->cbOutputDTDiff->Hide();
$win->lblDeltaYears->Hide();
$win->tfDeltaYears->Hide();
$win->upDownDeltaYears->Hide();
$win->lblDeltaMonths->Hide();
$win->tfDeltaMonths->Hide();
$win->upDownDeltaMonths->Hide();
$win->lblDeltaDays->Hide();
$win->tfDeltaDays->Hide();
$win->upDownDeltaDays->Hide();
$win->lblDeltaTime->Hide();
$win->tfDeltaHours->Hide();
$win->upDownDeltaHours->Hide();
$win->lblSeparator1->Hide();
$win->tfDeltaMinutes->Hide();
$win->upDownDeltaMinutes->Hide();
$win->lblSeparator2->Hide();
$win->tfDeltaSecondes->Hide();
$win->upDownDeltaSecondes->Hide();
$win->lblInputType->Hide();
$win->cbInputTimeType->Hide();
$win->cbInputDTFormat->Hide();
$win->btnOpenDTDB->Hide();
$win->btnInputFormatGuess->Hide();
# Hide Utils tab
$win->cbUtils->Hide();
$win->lblCurrMACOUIdbDate->Hide();
$win->btnMACOUIdbUpdate->Hide();
$win->lblGeoIPLang->Hide();
$win->cbGeoIPLang->Hide();
$win->chGeoIPOptAll->Hide();
$win->chAddHeaders->Hide();
$win->gridGeoIPOpts->Hide();
$win->chAddr2GPSInc->Hide();
$win->lblGPS2AddrZL->Hide();
$win->cbGPS2AddrZL->Hide();
$win->cbGPS2AddrOutput->Hide();
$win->gridGPS2AddrOpts->Hide();
$win->chSingleLocation->Hide();
$win->tfSingleLocation->Hide();
$win->chUAOptAll->Hide();
$win->gridUAOpts->Hide();
$win->rbIINLocalDB->Hide();
$win->rbBinlist->Hide();
$win->cbCFLists->Hide();
$win->btnCFAdd->Hide();
$win->btnCFRem->Hide();
$win->btnCFEdit->Hide();
$win->btnCFNew->Hide();
$win->chCFMatchCase->Hide();
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
# Show Sorting tab
} elsif ($win->Tab->SelectedItem() == 1) {
$win->lblInputType->Hide();
$win->cbInputTimeType->Hide();
$win->cbInputDTFormat->Hide();
$win->btnOpenDTDB->Hide();
$win->btnInputFormatGuess->Hide();
$win->cbInputTimeType->ResetContent();
$win->cbInputTimeType->Add($STR{'Datetime'});
$win->cbInputTimeType->SetCurSel(0);
$win->cbSorts->Show();
$win->cbSorts->SetCurSel(0) if $win->cbSorts->GetCurSel() == -1;
$win->rbAsc->Show();
$win->rbDsc->Show();
&cbSorts_Change();
# Hide Lists tab
$win->cbLists->Hide();
$win->chMatchCase->Hide();
$win->chRegex->Hide();
$win->chEval->Hide();
$win->lblWith->Hide();
$win->tfWith->Hide();
$win->lblColumnsNo->Hide();
$win->tfColumnsNo->Hide();
$win->lblReplace->Hide();
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->tfReplace->Hide();
$win->lblReplBy->Hide();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
$win->tfReplBy->Hide();
$win->rbAll->Hide();
$win->rbFirstOnly->Hide();
$win->rbFirstEachWord->Hide();
# Hide Conversion tab
$win->cbConv->Hide();
# Hide Time tab
$win->cbTime->Hide();
$win->lblDTParser->Hide();
$win->cbDTParser->Hide();
$win->lblOutputDTFormat->Hide();
$win->cbOutputDTFormat->Hide();
$win->chSingleDate->Hide();
$win->dtTimeDiffDate->Hide();
$win->dtTimeDiffTime->Hide();
$win->cbOutputDTDiff->Hide();
$win->lblDeltaYears->Hide();
$win->tfDeltaYears->Hide();
$win->upDownDeltaYears->Hide();
$win->lblDeltaMonths->Hide();
$win->tfDeltaMonths->Hide();
$win->upDownDeltaMonths->Hide();
$win->lblDeltaDays->Hide();
$win->tfDeltaDays->Hide();
$win->upDownDeltaDays->Hide();
$win->lblDeltaTime->Hide();
$win->tfDeltaHours->Hide();
$win->upDownDeltaHours->Hide();
$win->lblSeparator1->Hide();
$win->tfDeltaMinutes->Hide();
$win->upDownDeltaMinutes->Hide();
$win->lblSeparator2->Hide();
$win->tfDeltaSecondes->Hide();
$win->upDownDeltaSecondes->Hide();
# Hide Utils tab
$win->cbUtils->Hide();
$win->lblCurrMACOUIdbDate->Hide();
$win->btnMACOUIdbUpdate->Hide();
$win->lblGeoIPLang->Hide();
$win->cbGeoIPLang->Hide();
$win->chGeoIPOptAll->Hide();
$win->chAddHeaders->Hide();
$win->gridGeoIPOpts->Hide();
$win->chUAOptAll->Hide();
$win->gridUAOpts->Hide();
$win->rbIINLocalDB->Hide();
$win->rbBinlist->Hide();
$win->cbCFLists->Hide();
$win->btnCFAdd->Hide();
$win->btnCFRem->Hide();
$win->btnCFEdit->Hide();
$win->btnCFNew->Hide();
$win->chCFMatchCase->Hide();
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
$win->chAddr2GPSInc->Hide();
$win->lblGPS2AddrZL->Hide();
$win->cbGPS2AddrZL->Hide();
$win->cbGPS2AddrOutput->Hide();
$win->gridGPS2AddrOpts->Hide();
$win->chSingleLocation->Hide();
$win->tfSingleLocation->Hide();
# Show Conversion tab
} elsif ($win->Tab->SelectedItem() == 2) {
$win->cbConv->Show();
&cbConv_Change();
$win->cbConv->SetCurSel(0) if $win->cbConv->GetCurSel() == -1;
# Hide Lists tab
$win->cbLists->Hide();
$win->chMatchCase->Hide();
$win->chRegex->Hide();
$win->chEval->Hide();
$win->lblWith->Hide();
$win->tfWith->Hide();
$win->lblColumnsNo->Hide();
$win->tfColumnsNo->Hide();
$win->lblReplace->Hide();
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->tfReplace->Hide();
$win->lblReplBy->Hide();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
$win->tfReplBy->Hide();
$win->rbAll->Hide();
$win->rbFirstOnly->Hide();
$win->rbFirstEachWord->Hide();
# Hide Sorting tab
$win->cbSorts->Hide();
$win->rbAsc->Hide();
$win->rbDsc->Hide();
# Hide Time tab
$win->cbTime->Hide();
$win->lblDTParser->Hide();
$win->cbDTParser->Hide();
$win->lblOutputDTFormat->Hide();
$win->cbOutputDTFormat->Hide();
$win->chSingleDate->Hide();
$win->dtTimeDiffDate->Hide();
$win->dtTimeDiffTime->Hide();
$win->cbOutputDTDiff->Hide();
$win->lblDeltaYears->Hide();
$win->tfDeltaYears->Hide();
$win->upDownDeltaYears->Hide();
$win->lblDeltaMonths->Hide();
$win->tfDeltaMonths->Hide();
$win->upDownDeltaMonths->Hide();
$win->lblDeltaDays->Hide();
$win->tfDeltaDays->Hide();
$win->upDownDeltaDays->Hide();
$win->upDownDeltaHours->Hide();
$win->lblSeparator1->Hide();
$win->tfDeltaMinutes->Hide();
$win->upDownDeltaMinutes->Hide();
$win->lblSeparator2->Hide();
$win->tfDeltaSecondes->Hide();
$win->upDownDeltaSecondes->Hide();
$win->lblDeltaTime->Hide();
$win->tfDeltaHours->Hide();
$win->lblInputType->Hide();
$win->cbInputTimeType->Hide();
$win->cbInputDTFormat->Hide();
$win->btnOpenDTDB->Hide();
$win->btnInputFormatGuess->Hide();
# Hide Utils tab
$win->cbUtils->Hide();
$win->lblCurrMACOUIdbDate->Hide();
$win->btnMACOUIdbUpdate->Hide();
$win->lblGeoIPLang->Hide();
$win->cbGeoIPLang->Hide();
$win->chGeoIPOptAll->Hide();
$win->chAddHeaders->Hide();
$win->gridGeoIPOpts->Hide();
$win->chUAOptAll->Hide();
$win->gridUAOpts->Hide();
$win->rbIINLocalDB->Hide();
$win->rbBinlist->Hide();
$win->cbCFLists->Hide();
$win->btnCFAdd->Hide();
$win->btnCFRem->Hide();
$win->btnCFEdit->Hide();
$win->btnCFNew->Hide();
$win->chCFMatchCase->Hide();
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
$win->chAddr2GPSInc->Hide();
$win->lblGPS2AddrZL->Hide();
$win->cbGPS2AddrZL->Hide();
$win->cbGPS2AddrOutput->Hide();
$win->gridGPS2AddrOpts->Hide();
$win->chSingleLocation->Hide();
$win->tfSingleLocation->Hide();
# Show Time tab
} elsif ($win->Tab->SelectedItem() == 3) {
$win->cbTime->Show();
$win->cbTime->SetCurSel(0) if $win->cbTime->GetCurSel() == -1;
$win->cbInputTimeType->ResetContent();
$win->cbInputTimeType->Add($STR{'Datetime'} , $STR{'chromeTime'}, $STR{'LDAPTime'}, $STR{'Filetime'},
$STR{'SystemTime'}, $STR{'MacAbsTime'}, $STR{'MacHFS'});
$win->cbInputTimeType->SetCurSel(0);
$win->lblInputType->Show();
$win->cbInputTimeType->Show();
$win->lblOutputDTFormat->Show();
$win->cbInputDTFormat->Show();
$win->btnOpenDTDB->Show();
$win->btnInputFormatGuess->Show();
&cbTime_Change();
# Hide Lists tab
$win->cbLists->Hide();
$win->chMatchCase->Hide();
$win->chRegex->Hide();
$win->chEval->Hide();
$win->lblWith->Hide();
$win->tfWith->Hide();
$win->lblColumnsNo->Hide();
$win->tfColumnsNo->Hide();
$win->lblReplace->Hide();
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->tfReplace->Hide();
$win->lblReplBy->Hide();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
$win->tfReplBy->Hide();
$win->rbAll->Hide();
$win->rbFirstOnly->Hide();
$win->rbFirstEachWord->Hide();
# Hide Sorting tab
$win->cbSorts->Hide();
$win->rbAsc->Hide();
$win->rbDsc->Hide();
# Hide Conversion tab
$win->cbConv->Hide();
# Hide Utils tab
$win->cbUtils->Hide();
$win->lblCurrMACOUIdbDate->Hide();
$win->btnMACOUIdbUpdate->Hide();
$win->lblGeoIPLang->Hide();
$win->cbGeoIPLang->Hide();
$win->chGeoIPOptAll->Hide();
$win->chAddHeaders->Hide();
$win->gridGeoIPOpts->Hide();
$win->chUAOptAll->Hide();
$win->gridUAOpts->Hide();
$win->rbIINLocalDB->Hide();
$win->rbBinlist->Hide();
$win->cbCFLists->Hide();
$win->btnCFAdd->Hide();
$win->btnCFRem->Hide();
$win->btnCFEdit->Hide();
$win->btnCFNew->Hide();
$win->chCFMatchCase->Hide();
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
$win->chAddr2GPSInc->Hide();
$win->lblGPS2AddrZL->Hide();
$win->cbGPS2AddrZL->Hide();
$win->cbGPS2AddrOutput->Hide();
$win->gridGPS2AddrOpts->Hide();
$win->chSingleLocation->Hide();
$win->tfSingleLocation->Hide();
# Show Utils tab
} elsif ($win->Tab->SelectedItem() == 4) {
$win->cbUtils->Show();
$win->cbUtils->SetCurSel(0) if $win->cbUtils->GetCurSel() == -1;
&cbUtils_Change();
# Hide Lists tab
$win->cbLists->Hide();
$win->chMatchCase->Hide();
$win->chRegex->Hide();
$win->chEval->Hide();
$win->lblWith->Hide();
$win->tfWith->Hide();
$win->lblColumnsNo->Hide();
$win->tfColumnsNo->Hide();
$win->lblReplace->Hide();
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->tfReplace->Hide();
$win->lblReplBy->Hide();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
$win->tfReplBy->Hide();
$win->rbAll->Hide();
$win->rbFirstOnly->Hide();
$win->rbFirstEachWord->Hide();
# Hide Sorting tab
$win->cbSorts->Hide();
$win->rbAsc->Hide();
$win->rbDsc->Hide();
# Hide Conversion tab
$win->cbConv->Hide();
# Hide Time tab
$win->cbTime->Hide();
$win->lblDTParser->Hide();
$win->cbDTParser->Hide();
$win->lblOutputDTFormat->Hide();
$win->cbOutputDTFormat->Hide();
$win->chSingleDate->Hide();
$win->dtTimeDiffDate->Hide();
$win->dtTimeDiffTime->Hide();
$win->cbOutputDTDiff->Hide();
$win->lblDeltaYears->Hide();
$win->tfDeltaYears->Hide();
$win->upDownDeltaYears->Hide();
$win->lblDeltaMonths->Hide();
$win->tfDeltaMonths->Hide();
$win->upDownDeltaMonths->Hide();
$win->lblDeltaDays->Hide();
$win->tfDeltaDays->Hide();
$win->upDownDeltaDays->Hide();
$win->upDownDeltaHours->Hide();
$win->lblSeparator1->Hide();
$win->tfDeltaMinutes->Hide();
$win->upDownDeltaMinutes->Hide();
$win->lblSeparator2->Hide();
$win->tfDeltaSecondes->Hide();
$win->upDownDeltaSecondes->Hide();
$win->lblDeltaTime->Hide();
$win->tfDeltaHours->Hide();
$win->lblInputType->Hide();
$win->cbInputTimeType->Hide();
$win->cbInputDTFormat->Hide();
$win->btnOpenDTDB->Hide();
$win->btnInputFormatGuess->Hide();
}
&isProcessReady(0);
} #--- End Tab_Click
#--------------------------#
sub cbLists_Change
#--------------------------#
{
# Local variables
my $selFunc = $win->cbLists->GetCurSel();
# Possibles value are 0 = 'No duplicate', 1 = 'Only duplicates', 2 = 'Count items', 3 = 'Count characters',
# 4 = 'L1-L2', 5 = 'Column to row', 6 = 'Row to column', 7 = 'List to regex', 8 = 'Concat', 9 = 'Split strings',
# 10 = 'Split and extract', 11 = 'Merge lines', 12 = 'Split and merge', 13 = 'Replace', 14 = 'Reverse string',
# 15 = 'Transliterate', 16 = 'Lowercase', 17 = 'Uppercase', 18 = 'Add line number'
# Show available options
# Show List 2?
if ($selFunc == 1 or $selFunc == 4 or $selFunc == 8) { &showList2(); }
else { &hideList2(); }
# Show Match case option?
if ($selFunc < 3 or $selFunc == 4 or $selFunc == 13) {
$win->chMatchCase->Checked(1);
$win->chMatchCase->Show();
} else {
$win->chMatchCase->Checked(0);
$win->chMatchCase->Hide();
}
# Show Regex option
if ($selFunc == 9 or $selFunc == 10 or $selFunc == 12 or $selFunc == 13) { $win->chRegex->Show(); }
else {
$win->chRegex->Checked(0);
$win->chRegex->Hide();
}
# Show Eval option
if ($selFunc == 13) { $win->chEval->Show(); }
else {
$win->chEval->Checked(0);
$win->chEval->Hide();
}
# Show With textfield?
if ($selFunc == 5 or $selFunc == 6 or $selFunc == 8 or $selFunc == 9 or $selFunc == 10 or $selFunc == 12) {
$win->lblWith->Show();
$win->tfWith->Show();
} else {
$win->lblWith->Hide();
$win->tfWith->Hide();
}
# Show ColumnsNo textfield?
if ($selFunc == 10 or $selFunc == 11 or $selFunc == 12) {
$win->lblColumnsNo->Show();
$win->tfColumnsNo->Show();
} else {
$win->lblColumnsNo->Hide();
$win->tfColumnsNo->Hide();
}
# Show Replace-By textfields?
if ($selFunc == 13 or $selFunc == 15) {
$win->lblReplace->Show();
$win->tfReplace->Show();
$win->lblReplBy->Show();
$win->tfReplBy->Show();
} else {
$win->lblReplace->Hide();
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->tfReplace->Hide();
$win->tfReplace->Text('');
$win->lblReplBy->Hide();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
$win->tfReplBy->Hide();
$win->tfReplBy->Text('');
}
# Show lowercase-uppercase Options
if ($selFunc == 16 or $selFunc == 17) {
$win->rbAll->Show();
$win->rbFirstOnly->Show();
$win->rbFirstEachWord->Show();
} else {
$win->rbAll->Hide();
$win->rbFirstOnly->Hide();
$win->rbFirstEachWord->Hide();
}
&isProcessReady(0);
} #--- End cbLists_Change
#--------------------------#
sub tfWith_Change { &isProcessReady(0); }
sub tfColumnsNo_Change { &isProcessReady(0); }
#--------------------------#
#--------------------------#
sub tfReplace_Change
#--------------------------#
{
# Test Regex if necessary
&showReplaceREStatus(\$win) if $win->chRegex->Checked();
# Enable By textfield
if ($win->tfReplace->Text) {
$win->tfReplBy->Enable();
$win->chEval->Enable() if $win->chRegex->Checked();
} else {
$win->tfReplBy->Text('');
$win->tfReplBy->Disable();
$win->chEval->Checked(0);
$win->chEval->Disable();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
}
&isProcessReady(0);
} #--- End tfReplace_Change
#--------------------------#
sub chRegex_Click
#--------------------------#
{
# Test Regex if necessary
if ($win->chRegex->Checked()) {
&showReplaceREStatus(\$win);
$win->chEval->Enable();
} else {
$win->lblReplaceREOk->Hide();
$win->lblReplaceREErr->Hide();
$win->lblReplaceREWarn->Hide();
$win->chEval->Checked(0);
$win->chEval->Disable();
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
}
# Revaluate Replacement expression
&showReplaceByREStatus(\$win) if $win->tfReplBy->Text();
&isProcessReady(0);
} #--- End chRegex_Click
#--------------------------#
sub tfReplBy_Change
#--------------------------#
{
&showReplaceByREStatus(\$win);
&isProcessReady(0);
} #--- End tfReplBy_Change
#--------------------------#
sub chEval_Click
#--------------------------#
{
if ($win->chRegex->Checked()) { &showReplaceByREStatus(\$win); }
else {
$win->lblReplaceByREOk->Hide();
$win->lblReplaceByREErr->Hide();
$win->lblReplaceByREWarn->Hide();
}
&isProcessReady(0);
} #--- End chEval_Click
#--------------------------#
sub cbSorts_Change
#--------------------------#
{
# Local variables
my $selFunc = $win->cbSorts->GetCurSel();
# Possibles value are 0 = 'Alphabetical order', 1 = 'Numerical order', 2 = 'String length', 3 = 'IPv4 Address', 4 = 'Date and time', 5 = 'Random'
# Hide List 2
&hideList2();
# Date and time options
if ($selFunc == 4) {
$win->lblInputType->Show();
$win->cbInputTimeType->Show();
$win->cbInputDTFormat->Show();
$win->btnOpenDTDB->Show();
$win->btnInputFormatGuess->Show();
} else {
$win->lblInputType->Hide();
$win->cbInputTimeType->Hide();
$win->cbInputDTFormat->Hide();
$win->btnOpenDTDB->Hide();
$win->btnInputFormatGuess->Hide();
}
# Random
if ($selFunc == 5) {
$win->rbAsc->Hide();
$win->rbDsc->Hide();
} else {
$win->rbAsc->Show();
$win->rbDsc->Show();
}
&isProcessReady(0);
} #--- End cbSorts_Change
#--------------------------#
sub btnOpenDTDB_Click
#--------------------------#
{
if (my $selRow = ($winDTDB->gridDT->GetSelectedCellRange())[0]) {
$winDTDB->btnDTEdit->Enable();
$winDTDB->btnDTDel->Enable();
} else {
$winDTDB->btnDTEdit->Disable();
$winDTDB->btnDTDel->Disable();
}
$winDTDB->Center($win);
$winDTDB->Show();
$win->Disable();
return(1);
} #--- End btnOpenDTDB_Click
#--------------------------#
sub btnInputFormatGuess_Click
#--------------------------#
{
# Guess format of the first item
if (my $sample = (&findInputDTFormat($win->tfList1->GetLine(0)))[0]) {
$win->cbInputDTFormat->SetCurSel($win->cbInputDTFormat->FindStringExact($sample));
# If not found
} else { Win32::GUI::MessageBox($win, $STR{'formatNotFound'}.'...', $STR{'Error'}, 0x40010); }
} #--- End btnInputFormatGuess_Click
#--------------------------#
sub findInputDTFormat
#--------------------------#
{
# Local variables
my $item = shift;
# Guess format
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $regex = $winDTDB->gridDT->GetCellText($i, 2);
if ($item =~ /($regex)/i) {
my $pattern = $winDTDB->gridDT->GetCellText($i, 1);
# Format
my $partItem = $1 =~ s/ +/ /gr;
my $strp = DateTime::Format::Strptime->new(pattern => $pattern, zone_map => \%ZONE_MAP, locale => $CONFIG{'DEFAULT_LANG'},);
if (my $dt = $strp->parse_datetime($partItem)) {
my $timezone;
$timezone = $winConfig->cbLocalTZ->GetString($winConfig->cbLocalTZ->GetCurSel()) if $winDTDB->gridDT->GetCellText($i, 3) eq 'local';
return($winDTDB->gridDT->GetCellText($i, 0), $winDTDB->gridDT->GetCellText($i, 1),
$winDTDB->gridDT->GetCellText($i, 2), $timezone);
}
}
}
return(0);
} #--- End findInputDTFormat
#--------------------------#
sub infoDTFormat
#--------------------------#
{
# Local variables
my $sample = shift;
# Guess format
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $curSampleRow = $winDTDB->gridDT->GetCellText($i, 0);
return($winDTDB->gridDT->GetCellText($i, 0), $winDTDB->gridDT->GetCellText($i, 1),
$winDTDB->gridDT->GetCellText($i, 2), $winDTDB->gridDT->GetCellText($i, 3)) if $curSampleRow eq $sample;
}
return(0);
} #--- End infoDTFormat
#--------------------------#
sub gridDT_Click
#--------------------------#
{
$winDTDB->btnDTEdit->Enable();
$winDTDB->btnDTDel->Enable();
return(1);
} #--- End gridDT_Click
#--------------------------#
sub gridDT_DblClick
#--------------------------#
{
&btnDTEdit_Click();
return(1);
} #--- End gridDT_DblClick
#--------------------------#
sub sortGridDT
#--------------------------#
{
my ($a, $b) = @_;
return (length($a) <=> length($b));
} #--- End sortGridDT
#--------------------------#
sub btnDTAdd_Click
#--------------------------#
{
# Reset all values
$winDTObj->tfDTObjSample->Text('');
$winDTObj->tfDTObjSample->ReadOnly(0);
$winDTObj->tfDTObjPattern->Text('');
$winDTObj->cbDTObjPattern->SetCurSel(0);
$winDTObj->lblDTObjRegexOk->Hide();
$winDTObj->lblDTObjRegexErr->Hide();
$winDTObj->lblDTObjRegexWarn->Hide();
$winDTObj->tfDTObjRegex->Text('');
$winDTObj->chDTObjRegexAuto->Checked(1);
$winDTObj->rbDTObjTZLocal->Checked(1);
$winDTObj->rbDTObjTZUTC->Checked(0);
$winDTObj->rbDTObjTZOtherOffset->Checked(0);
$winDTObj->rbDTObjTZOtherName->Checked(0);
$winDTObj->cbDTObjTZOffset->SetCurSel(0);
$winDTObj->cbDTObjTZName->SetCurSel(0);
$winDTObj->lblDTObjParsedData->Text('');
$winDTObj->cbDTObjUseAs->SetCurSel(0);
$winDTObj->tfDTObjComment->Text('');
# Update controls
my $firstItem = $win->tfList1->GetLine(0);
if ($firstItem) { $winDTObj->btnDTObjUseFirst->Enable(); }
else { $winDTObj->btnDTObjUseFirst->Disable(); }
$winDTObj->btnDTObjAdd->Show();
$winDTObj->btnDTObjEdit->Hide();
$winDTObj->Center($win);
$winDTObj->Show();
$winDTDB->Disable();
return(1);
} #--- End btnDTAdd_Click
#--------------------------#
sub btnDTEdit_Click
#--------------------------#
{
# Local variables
my %useAsInd = ($STR{'Input'} => 0, $STR{'Output'} => 1, $STR{'Both'} => 2, $STR{'None'} => 3);
# Load the current values
my $selRow = ($winDTDB->gridDT->GetSelectedCellRange())[0];
$winDTObj->tfDTObjSample->Text($winDTDB->gridDT->GetCellText($selRow, 0));
$winDTObj->tfDTObjSample->ReadOnly(1);
$winDTObj->tfDTObjPattern->Text($winDTDB->gridDT->GetCellText($selRow, 1));
$winDTObj->tfDTObjRegex->Text($winDTDB->gridDT->GetCellText($selRow, 2));
my $timezone = $winDTDB->gridDT->GetCellText($selRow, 3);
if ($timezone eq 'local') {
$winDTObj->rbDTObjTZLocal->Checked(1);
$winDTObj->rbDTObjTZUTC->Checked(0);
$winDTObj->rbDTObjTZOtherOffset->Checked(0);
$winDTObj->rbDTObjTZOtherName->Checked(0);
} elsif ($timezone eq 'UTC') {
$winDTObj->rbDTObjTZLocal->Checked(0);
$winDTObj->rbDTObjTZUTC->Checked(1);
$winDTObj->rbDTObjTZOtherOffset->Checked(0);
$winDTObj->rbDTObjTZOtherName->Checked(0);
} elsif ($timezone =~ /[\+\-]?\d{4}/) {
$winDTObj->rbDTObjTZLocal->Checked(0);
$winDTObj->rbDTObjTZUTC->Checked(0);
$winDTObj->rbDTObjTZOtherOffset->Checked(1);
$winDTObj->rbDTObjTZOtherName->Checked(0);
$winDTObj->cbDTObjTZOffset->SetCurSel($winDTObj->cbDTObjTZOffset->FindStringExact($timezone));
} else {
$winDTObj->rbDTObjTZLocal->Checked(0);
$winDTObj->rbDTObjTZUTC->Checked(0);
$winDTObj->rbDTObjTZOtherOffset->Checked(0);
$winDTObj->rbDTObjTZOtherName->Checked(1);
$winDTObj->cbDTObjTZName->SetCurSel($winDTObj->cbDTObjTZName->FindStringExact($timezone));
}
my $useAsStr = $winDTDB->gridDT->GetCellText($selRow, 4); # 0 = Input, 1 = Output, 2 = Both, 3 = None
$winDTObj->cbDTObjUseAs->SetCurSel($useAsInd{$useAsStr}) if exists($useAsInd{$useAsStr});
if ($winDTDB->gridDT->GetCellText($selRow, 5)) { $winDTObj->tfDTObjComment->Text($winDTDB->gridDT->GetCellText($selRow, 5)); }
else { $winDTObj->tfDTObjComment->Text(''); }
# Update controls
$winDTObj->btnDTObjUseFirst->Disable();
$winDTObj->btnDTObjEdit->Show();
$winDTObj->btnDTObjAdd->Hide();
$winDTObj->Center($win);
$winDTObj->Show();
$winDTDB->Disable();
return(1);
} #--- End btnDTEdit_Click
#--------------------------#
sub tfDTObjSample_Change
#--------------------------#
{
&isDTObjReady(0);
} #--- End tfDTObjSample_Change
#--------------------------#
sub btnDTObjUseFirst_Click
#--------------------------#
{
$winDTObj->tfDTObjSample->Text($win->tfList1->GetLine(0));
&isDTObjReady(0);
} #--- End btnDTObjUseFirst_Click
#--------------------------#
sub btnDTObjPatternInsert_Click
#--------------------------#
{
# Local variables
my $patternObjSel = $winDTObj->cbDTObjPattern->GetCurSel();
my @patterns = ('%B', '%b', '%D', '%d', '%e', '%F', '%H', '%I', '%M', '%m', '%p',
'%P', '%R', '%r', '%S', '%T', '%v', '%w', '%Y', '%y', '%Z', '%z', );
$winDTObj->tfDTObjPattern->Append($patterns[$patternObjSel]);
&isDTObjReady(0);
} #--- End btnDTObjPatternInsert_Click
#--------------------------#
sub patternRE
#--------------------------#
{
# Local variables
my $formatREStr = shift;
# Possibles value are:
my %formatRE = ('%A' => '\w+', # full weekday name, since 3.3 (to fit any language)
#'%A' => '(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)', # full weekday name
'%a' => '\w+', # abbreviated weekday name, since 3.3 (to fit any language)
#'%a' => '(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)', # abbreviated weekday name
'%B' => '\w+', # full month name, since 3.3 (to fit any language)
#'%B' => '(?:January|February|March|April|May|June|July|August|September|October|November|December)', # full month name
'%b' => '\w{3,4}', # abbreviated weekday name, since 3.3 (to fit any language)
#'%b' => '(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)', # abbreviated month name
'%C' => '\d{2}', # (year / 100) as decimal number; single digits are preceded by a zero.
'%D' => '\d{2}\/\d{2}\/\d{2}', # %m/%d/%y
'%d' => '\d{2}', # day of the month as a decimal number (01-31)
'%e' => '\d{1,2}', # day of the month as a decimal number (1-31); single digits are preceded by a blank.
'%F' => '\d{4}\-\d{2}\-\d{2}', # %Y-%m-%d
'%H' => '\d{2}' , # hour (24-hour clock) as a decimal number (00-23)
'%I' => '\d{1,2}', # hour (12-hour clock) as a decimal number (01-12)
'%j' => '\d{3}' , # day of the year as a decimal number (001-366)
'%k' => '\d{1,2}', # hour (24-hour clock) as a decimal number (0-23); single digits are preceded by a blank.
'%l' => '\d{1,2}', # hour (12-hour clock) as a decimal number (1-12); single digits are preceded by a blank.
'%M' => '\d{2}' , # minute as a decimal number (00-59)
'%m' => '\d{1,2}', # month as a decimal number (01-12)
'%n' => '\n', # newline
'%p' => '[AP]\.?M\.?', # national representation of either "ante meridiem" (a.m.) or "post meridiem" (p.m.) as appropriate.
'%P' => '[ap]\.?m\.?', # national representation of either "ante meridiem" (a.m.) or "post meridiem" (p.m.) as appropriate.
'%R' => '\d{2}:\d{2}', # %H:%M
'%r' => '\d{1,2}:\d{2}:\d{2} [apAP]\.?[mM]\.?', # %I:%M:%S %p
'%S' => '\d{2}', # second as a decimal number (00-60)
'%s' => '\d{10,13}', # number of seconds since the Epoch
'%T' => '\d{2}:\d{2}:\d{2}', # %H:%M:%S
'%R' => '\d{2}:\d{2}', # %H:%M
'%t' => '\t', # tab
'%U' => '\d{2}', # week number of the year (Sunday as the first day of the week) as a decimal number (00-53).
'%u' => '[1-7]', # weekday (Monday as the first day of the week) as a decimal number (1-7).
'%V' => '\d{2}', # week number of the year (Monday as the first day of the week) as a decimal number (01-53)
'%v' => '\d{1,2}\-[a-zA-Z]{3}\-\d{4}', # %e-%b-%Y
'%W' => '\d{2}', # week number of the year as a decimal number (00-53).
'%w' => '[0-6]', # weekday (Sunday as the first day of the week) as a decimal number (0-6).
'%Y' => '\d{4}', # year with century as a decimal number
'%y' => '\d{2}', # year without century as a decimal number (00-99)
'%Z' => '[a-zA-Z\/]+', # time zone name
'%z' => '[\-\+]?\d{4}', # time zone offset from UTC
);
# Convert other format string from strftime format (%) to regex
foreach my $matchRE (keys %formatRE) { $formatREStr =~ s/$matchRE/$formatRE{$matchRE}/ge; }
return($formatREStr);
} #--- End patternRE
#--------------------------#
sub tfDTObjPattern_Change
#--------------------------#
{
# Local variables
my $pattern = $winDTObj->tfDTObjPattern->Text();
if ($pattern =~ /%\w/ and $winDTObj->chDTObjRegexAuto->Checked()) {
my $regex = patternRE($pattern);
$winDTObj->tfDTObjRegex->Text($regex);
}
&isDTObjReady(0);
} #--- End tfDTObjPattern_Change
#--------------------------#
sub btnDTObjPatternHelp_Click
#--------------------------#
{
# Open Default browser to a help page on Strftime
$win->ShellExecute('open', 'http://strftime.net/','','',1) or
Win32::GUI::MessageBox($win, Win32::FormatMessage(Win32::GetLastError()), $STR{'Error'}, 0x40010);
} #--- End btnDTObjPatternHelp_Click
#--------------------------#
sub tfDTObjRegex_Change { &isDTObjReady(0); }
#--------------------------#
#--------------------------#
sub chDTObjRegexAuto_Click
#--------------------------#
{
# Local variables
my $pattern = $winDTObj->tfDTObjPattern->Text();
if ($pattern =~ /%\w/ and $winDTObj->chDTObjRegexAuto->Checked()) {
my $regex = patternRE($pattern);
$winDTObj->tfDTObjRegex->Text($regex);
}
&isDTObjReady(0);
} #--- End chDTObjRegexAuto_Click
#--------------------------#
sub isDTObjReady
#--------------------------#
{
# Local variables
my $confirm = shift;
my $nextStep;
# Sample provided?
my $sample = $winDTObj->tfDTObjSample->Text();
if (!$sample) {
$winDTObj->tfDTObjPattern->Disable();
$winDTObj->btnDTObjPatternInsert->Disable();
$winDTObj->cbDTObjPattern->Disable();
$winDTObj->tfDTObjRegex->Disable();
$nextStep = $STR{'provideSample'};
} else {
$winDTObj->tfDTObjPattern->Enable();
$winDTObj->btnDTObjPatternInsert->Enable();
$winDTObj->cbDTObjPattern->Enable();
# Pattern provided?
my $pattern = $winDTObj->tfDTObjPattern->Text();
if ($pattern =~ /%\w/) {
$winDTObj->tfDTObjRegex->Enable();
# Regex provided?
my $regex = $winDTObj->tfDTObjRegex->Text();
if ($regex) {
my ($statusRegex, $msg) = &validRegex($regex);
# Warning
if ($statusRegex == 2) {
$winDTObj->lblDTObjRegexWarn->Show();
$winDTObj->lblDTObjRegexOk->Hide();
$winDTObj->lblDTObjRegexErr->Hide();
# Error
} elsif ($statusRegex == 1) {
$winDTObj->lblDTObjRegexErr->Show();
$winDTObj->lblDTObjRegexOk->Hide();
$winDTObj->lblDTObjRegexWarn->Hide();
$nextStep = $STR{'errRegex'};
# Ok
} else {
$winDTObj->lblDTObjRegexOk->Show();
$winDTObj->lblDTObjRegexErr->Hide();
$winDTObj->lblDTObjRegexWarn->Hide();
}
} else {
$winDTObj->lblDTObjRegexOk->Hide();
$winDTObj->lblDTObjRegexErr->Hide();
$winDTObj->lblDTObjRegexWarn->Hide();
$nextStep = $STR{'errRegex'};
}
# Test regex and pattern
if (!$nextStep) {
my $strp = DateTime::Format::Strptime->new(pattern => $pattern, zone_map => \%ZONE_MAP, locale => $CONFIG{'DEFAULT_LANG'},);
if ($sample =~ /$regex/i and my $parsedPattern = $strp->parse_datetime($sample)) {
$winDTObj->lblDTObjParsedData->Text($parsedPattern->strftime($pattern));
# Timezone?
if ($pattern =~ /%[Zzs]/) {
$winDTObj->rbDTObjTZLocal->Disable();
$winDTObj->rbDTObjTZUTC->Disable();
$winDTObj->rbDTObjTZOtherOffset->Disable();
$winDTObj->cbDTObjTZOffset->Disable();
$winDTObj->rbDTObjTZOtherName->Disable();
$winDTObj->cbDTObjTZName->Disable();
} else { # No timezone in pattern, must specify
$winDTObj->rbDTObjTZLocal->Enable();
$winDTObj->rbDTObjTZUTC->Enable();
$winDTObj->rbDTObjTZOtherOffset->Enable();
$winDTObj->cbDTObjTZOffset->Enable();
$winDTObj->rbDTObjTZOtherName->Enable();
$winDTObj->cbDTObjTZName->Enable();
}
} else { $winDTObj->lblDTObjParsedData->Text(''); }
}
} else {
$winDTObj->tfDTObjRegex->Disable();
$nextStep = $STR{'providePattern'};
}
}
# Return an error message or enable the button
if ($nextStep) {
$winDTObj->btnDTObjAdd->Disable();
$winDTObj->btnDTObjEdit->Disable();
$winDTObj->btnDTObjNotReady->Enable();
Win32::GUI::MessageBox($winDTObj, "$STR{'notReady'}?\n\n$STR{'nextStep'}: $nextStep", $STR{'notReady'}, 0x40040) if $confirm;
} else {
$winDTObj->btnDTObjAdd->Enable();
$winDTObj->btnDTObjEdit->Enable();
$winDTObj->btnDTObjNotReady->Disable();
}
} #--- End isDTObjReady
#--------------------------#
sub btnDTObjNotReady_Click { &isDTObjReady(1); }
#--------------------------#
#--------------------------#
sub btnDTObjAdd_Click
#--------------------------#
{
# Local variables
my $sample = $winDTObj->tfDTObjSample->Text();
my $pattern = $winDTObj->tfDTObjPattern->Text();
my $regex = $winDTObj->tfDTObjRegex->Text();
my $comment = $winDTObj->tfDTObjComment->Text();
$comment = 'NULL' if !$comment;
my $useAs = $winDTObj->cbDTObjUseAs->GetCurSel(); # 0 = Input, 1 = Output, 2 = Both, 3 = None (hidden)
my @useAsStr = ($STR{'Input'}, $STR{'Output'}, $STR{'Both'}, $STR{'None'});
my $DTDBFile = $winConfig->tfDTDB->Text();
my $timezone; # Default timezone, used if not specified in pattern
# Timezone
if ($winDTObj->rbDTObjTZLocal->Checked()) { $timezone = 'local'; } # Local
elsif ($winDTObj->rbDTObjTZUTC->Checked()) { $timezone = 'UTC'; } # UTC
elsif ($winDTObj->rbDTObjTZOtherOffset->Checked()) { # Other, offset
$timezone = $winDTObj->cbDTObjTZOffset->GetString($winDTObj->cbDTObjTZOffset->GetCurSel());
} elsif ($winDTObj->rbDTObjTZOtherName->Checked()) { # Other, name
$timezone = $winDTObj->cbDTObjTZName->GetString($winDTObj->cbDTObjTZName->GetCurSel());
} else { $timezone = 'NULL'; }
# Select or create Datetime database
if (!-f $DTDBFile or !&validSQLiteDB($DTDBFile, 'DT')) {
$DTDBFile = "$USERDIR\\DT.db";
$winConfig->tfDTDB->Text($DTDBFile) if &createDTDB($DTDBFile);
}
# Connect to DB
my $dsn = "DBI:SQLite:dbname=$DTDBFile";
if (my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1, AutoCommit => 1 })) {
# Add to database
# Database: table = DT, Fields = sample, pattern, regex, timezone, use_as, comment
my $sth = $dbh->prepare("INSERT INTO DT (sample,pattern,regex,timezone,use_as,comment) VALUES(?,?,?,?,?,?)");
my $rv = $sth->execute($sample, $pattern, $regex, $timezone, $useAs, $comment);
if ($rv < 0) {
Win32::GUI::MessageBox($winDTDB, $STR{'errorMsg'}.$DBI::errstr, $STR{'Error'}, 0x40010);
return(0);
} else {
# Add to Grid
if (my $newLine = $winDTDB->gridDT->InsertRow($sample, -1)) {
$winDTDB->gridDT->SetCellText($newLine, 0, $sample);
$winDTDB->gridDT->SetCellText($newLine, 1, $pattern);
$winDTDB->gridDT->SetCellText($newLine, 2, $regex);
$winDTDB->gridDT->SetCellText($newLine, 3, $timezone);
$winDTDB->gridDT->SetCellText($newLine, 4, $useAsStr[$useAs]);
$winDTDB->gridDT->SetCellText($newLine, 5, $comment) if $comment ne 'NULL';
# Refresh grid
$winDTDB->gridDT->SortCells(1, 0, \&sortGridDT);
$winDTDB->gridDT->AutoSizeColumns();
$winDTDB->gridDT->ExpandColumnsToFit();
$winDTDB->gridDT->SetListMode();
# Add to combobox
$win->cbInputDTFormat->Add($sample) if $useAs == 0 or $useAs == 2;
if ($useAs == 1 or $useAs == 2) {
$win->cbOutputDTFormat->Add($sample);
$winDTDB->cbDefaultOutput->Add($sample);
}
# Final message
&winDTObj_Terminate();
Win32::GUI::MessageBox($winDTDB, $STR{'addedDTObj'}, $STR{'DTDB'}, 0x40040);
} else { Win32::GUI::MessageBox($win, $STR{'errNewLine'}, $STR{'Error'}, 0x40010); }
}
}
} #--- End btnDTObjAdd_Click
#--------------------------#
sub btnDTObjEdit_Click
#--------------------------#
{
# Local variables
my $sample = $winDTObj->tfDTObjSample->Text();
my $pattern = $winDTObj->tfDTObjPattern->Text();
my $regex = $winDTObj->tfDTObjRegex->Text();
my $comment = $winDTObj->tfDTObjComment->Text();
$comment = 'NULL' if !$comment;
my $useAs = $winDTObj->cbDTObjUseAs->GetCurSel(); # 0 = Input, 1 = Output, 2 = Both, 3 = None (hidden)
my @useAsStr = ($STR{'Input'}, $STR{'Output'}, $STR{'Both'}, $STR{'None'});
my $DTDBFile = $winConfig->tfDTDB->Text();
my $timezone; # Default timezone, used if not specified in pattern
# Timezone
if ($winDTObj->rbDTObjTZLocal->Checked()) { $timezone = 'local'; } # Local
elsif ($winDTObj->rbDTObjTZUTC->Checked()) { $timezone = 'UTC'; } # UTC
elsif ($winDTObj->rbDTObjTZOtherOffset->Checked()) { # Other, offset
$timezone = $winDTObj->cbDTObjTZOffset->GetString($winDTObj->cbDTObjTZOffset->GetCurSel());
} elsif ($winDTObj->rbDTObjTZOtherName->Checked()) { # Other, name
$timezone = $winDTObj->cbDTObjTZName->GetString($winDTObj->cbDTObjTZName->GetCurSel());
} else { $timezone = 'NULL'; }
# Connect to DB
my $dsn = "DBI:SQLite:dbname=$DTDBFile";
if (my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1, AutoCommit => 1 })) {
# Update database
# Database: table = DT, Fields = sample, pattern, regex, timezone, use_as, comment
my $sth = $dbh->prepare("UPDATE DT SET pattern = ?, regex = ?, timezone = ?, use_as = ?, comment = ? WHERE ? == sample");
my $rv = $sth->execute($pattern, $regex, $timezone, $useAs, $comment, $sample);
if ($rv < 0) {
Win32::GUI::MessageBox($winDTDB, $STR{'errorMsg'}.$DBI::errstr, $STR{'Error'}, 0x40010);
return(0);
} else {
# Update Grid
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $curSampleRow = $winDTDB->gridDT->GetCellText($i, 0);
if ($curSampleRow eq $sample) {
$winDTDB->gridDT->SetCellText($i, 1, $pattern);
$winDTDB->gridDT->SetCellText($i, 2, $regex);
$winDTDB->gridDT->SetCellText($i, 3, $timezone);
$winDTDB->gridDT->SetCellText($i, 4, $useAsStr[$useAs]);
$winDTDB->gridDT->SetCellText($i, 5, $comment) if $comment ne 'NULL';
# Refresh grid
$winDTDB->gridDT->SortCells(1, 0, \&sortGridDT);
$winDTDB->gridDT->AutoSizeColumns();
$winDTDB->gridDT->ExpandColumnsToFit();
$winDTDB->gridDT->SetListMode();
# Add to combobox
if ($useAs == 0 or $useAs == 2) { # Add to input
if ((my $index = $win->cbInputDTFormat->FindStringExact($sample)) > 1) { # Already in Combobox ?
my $inComboboxSample = $win->cbInputDTFormat->GetString($index);
$win->cbInputDTFormat->Add($sample) if $inComboboxSample ne $sample;
} else { $win->cbInputDTFormat->Add($sample); }
} elsif ((my $index = $win->cbInputDTFormat->FindStringExact($sample)) > 1) {
my $inComboboxSample = $win->cbInputDTFormat->GetString($index);
$win->cbInputDTFormat->DeleteString($index) if $inComboboxSample eq $sample;
}
if ($useAs == 1 or $useAs == 2) { # Add to output
if ((my $index = $win->cbOutputDTFormat->FindStringExact($sample)) > 1) { # Already in Combobox ?
my $inComboboxSample = $win->cbOutputDTFormat->GetString($index);
if ($inComboboxSample ne $sample) {
$win->cbOutputDTFormat->Add($sample);
$winDTDB->cbDefaultOutput->Add($sample);
}
} else { $win->cbOutputDTFormat->Add($sample); $winDTDB->cbDefaultOutput->Add($sample); }
} elsif ((my $index = $win->cbOutputDTFormat->FindStringExact($sample)) > 1) {
my $inComboboxSample = $win->cbOutputDTFormat->GetString($index);
if ($inComboboxSample eq $sample) {
$win->cbOutputDTFormat->DeleteString($index);
$winDTDB->cbDefaultOutput->DeleteString($index);
}
}
# Final message
&winDTObj_Terminate();
Win32::GUI::MessageBox($winDTDB, $STR{'updatedDTObj'}, $STR{'DTDB'}, 0x40040);
last;
}
}
&winDTObj_Terminate();
}
}
} #--- End btnDTObjEdit_Click
#--------------------------#
sub btnDTDel_Click
#--------------------------#
{
# Local variables
my $DTDBFile = $winConfig->tfDTDB->Text();
# Get selected row
my $selRow = ($winDTDB->gridDT->GetSelectedCellRange())[0];
my $sample = $winDTDB->gridDT->GetCellText($selRow, 0);
# Delete in Datetime database
my $dsn = "DBI:SQLite:dbname=$DTDBFile";
if (my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1, AutoCommit => 1 })) {
my $sth = $dbh->prepare("DELETE FROM DT WHERE sample == ?");
my $rv = $sth->execute($sample);
if ($rv < 0) { Win32::GUI::MessageBox($winDTDB, $STR{'errorMsg'}.$DBI::errstr, $STR{'Error'}, 0x40010); }
else {
# Find the entry in grid and delete
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $curSampleRow = $winDTDB->gridDT->GetCellText($i, 0);
if ($curSampleRow eq $sample) {
$winDTDB->gridDT->DeleteRow($i);
# Refresh grid
$winDTDB->gridDT->SortCells(1, 0, \&sortGridDT);
$winDTDB->gridDT->AutoSizeColumns();
$winDTDB->gridDT->ExpandColumnsToFit();
$winDTDB->gridDT->SetListMode();
# If entry is in combobox, delete it
$win->cbInputDTFormat->DeleteString($win->cbInputDTFormat->FindStringExact($sample));
$win->cbOutputDTFormat->DeleteString($win->cbOutputDTFormat->FindStringExact($sample));
Win32::GUI::MessageBox($winDTDB, $STR{'deletedDTObj'}, $STR{'DTDB'}, 0x40040);
last;
}
}
}
}
} #--- End btnDTDel_Click
#--------------------------#
sub btnDTObjCancel_Click { &winDTObj_Terminate(); }
#--------------------------#
#--------------------------#
sub winDTObj_Terminate
#--------------------------#
{
$winDTObj->Hide();
$winDTDB->Enable();
$winDTDB->SetForegroundWindow();
return(0);
} #--- End winDTObj_Terminate
#--------------------------#
sub winDTDB_Resize
#--------------------------#
{
$winDTDB->gridDT->Width($winDTDB->ScaleWidth()-39);
$winDTDB->gridDT->Height($winDTDB->ScaleHeight()-40);
$winDTDB->gridDT->AutoSizeColumns();
$winDTDB->gridDT->ExpandLastColumn();
$winDTDB->gridDT->Refresh();
$winDTDB->btnDTAdd->Left($winDTDB->ScaleWidth()-32);
$winDTDB->btnDTEdit->Left($winDTDB->ScaleWidth()-32);
$winDTDB->btnDTDel->Left($winDTDB->ScaleWidth()-32);
$winDTDB->lblDefaultOutput->Top($winDTDB->ScaleHeight()-27);
$winDTDB->cbDefaultOutput->Top($winDTDB->ScaleHeight()-30);
} #--- End winDTDB_Resize
#--------------------------#
sub winDTDB_Terminate
#--------------------------#
{
$winDTDB->Hide();
$win->Enable();
$win->SetForegroundWindow();
return(0);
} #--- End winDTDB_Terminate
#--------------------------#
sub cbInputDTFormatAddITems
#--------------------------#
{
# Local variables
my @inputFormats;
# Browse Datetime grid and list available Datetime object for input
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $useAs = $winDTDB->gridDT->GetCellText($i, 4);
push(@inputFormats, $winDTDB->gridDT->GetCellText($i, 0)) if $useAs eq $STR{'Input'} or $useAs eq $STR{'Both'};
}
# Update the combobox
if (scalar(@inputFormats)) {
$win->cbInputDTFormat->Add($STR{'guessORVar'}); # First is "Guess (or variables)"
foreach (@inputFormats) { $win->cbInputDTFormat->Add($_); }
}
} #--- End cbInputDTFormatAddITems
#--------------------------#
sub cbOutputDTFormatAddITems
#--------------------------#
{
# Local variables
my @outputFormats;
# Browse Datetime grid and list available Datetime object for output
for (my $i = 1; $i < $winDTDB->gridDT->GetRows(); $i++) {
my $useAs = $winDTDB->gridDT->GetCellText($i, 4);
push(@outputFormats, $winDTDB->gridDT->GetCellText($i, 0)) if $useAs eq $STR{'Output'} or $useAs eq $STR{'Both'};
}
# Update the combobox (Current output and Default output selection)
if (scalar(@outputFormats)) {
$win->cbOutputDTFormat->Add($STR{'default'}); # Default
$winDTDB->cbDefaultOutput->Add($STR{'same'}); # Same as input
foreach (@outputFormats) { $win->cbOutputDTFormat->Add($_); $winDTDB->cbDefaultOutput->Add($_); }
}
} #--- End cbOutputDTFormatAddITems
#--------------------------#
sub cbConv_Change
#--------------------------#
{
&hideList2();
&isProcessReady(0);
} #--- End cbConv_Change
#--------------------------#
sub cbTime_Change
#--------------------------#
{
# Local variables
my $selFunc = $win->cbTime->GetCurSel();
# Possibles value are 0 = 'Anytime to Anytime', 1 = 'Time difference', 2 = 'Add time', 3 = 'Substract time'
# Except for 'Anytime to Anytime', all other function operate on Datetime only
if ($selFunc) {
$win->cbInputTimeType->ResetContent();
$win->cbInputTimeType->Add($STR{'Datetime'});
$win->cbInputTimeType->SetCurSel(0);
$win->lblDTParser->Hide(); # Parse context
$win->cbDTParser->Hide();
} else {
$win->cbInputTimeType->ResetContent();
$win->cbInputTimeType->Add($STR{'Datetime'}, $STR{'chromeTime'}, $STR{'LDAPTime'}, $STR{'Filetime'},
$STR{'SystemTime'}, $STR{'MacAbsTime'}, $STR{'MacHFS'});
$win->cbInputTimeType->SetCurSel(0);
$win->lblDTParser->Show(); # Parse context
$win->cbDTParser->Show();
}
# Time difference options
if ($selFunc == 1) {
$win->chSingleDate->Show();
$win->dtTimeDiffDate->Show();
$win->dtTimeDiffTime->Show();
$win->cbOutputDTDiff->Show();
$win->cbOutputDTFormat->Hide();
if ($win->chSingleDate->Checked()) { &hideList2(); }
else { &showList2(); }
} else {
$win->chSingleDate->Hide();
$win->dtTimeDiffDate->Hide();
$win->dtTimeDiffTime->Hide();
$win->cbOutputDTDiff->Hide();
$win->cbOutputDTFormat->Show();
&hideList2();
}
# Show Add or substract time controls
if ($selFunc == 2 or $selFunc == 3) {
$win->lblDeltaYears->Show();
$win->tfDeltaYears->Show();
$win->upDownDeltaYears->Show();
$win->lblDeltaMonths->Show();
$win->tfDeltaMonths->Show();
$win->upDownDeltaMonths->Show();
$win->lblDeltaDays->Show();
$win->tfDeltaDays->Show();
$win->upDownDeltaDays->Show();
$win->lblDeltaTime->Show();
$win->tfDeltaHours->Show();
$win->upDownDeltaHours->Show();
$win->lblSeparator1->Show();
$win->tfDeltaMinutes->Show();
$win->upDownDeltaMinutes->Show();
$win->lblSeparator2->Show();
$win->tfDeltaSecondes->Show();
$win->upDownDeltaSecondes->Show();
} else {
$win->lblDeltaYears->Hide();
$win->tfDeltaYears->Hide();
$win->upDownDeltaYears->Hide();
$win->lblDeltaMonths->Hide();
$win->tfDeltaMonths->Hide();
$win->upDownDeltaMonths->Hide();
$win->lblDeltaDays->Hide();
$win->tfDeltaDays->Hide();
$win->upDownDeltaDays->Hide();
$win->lblDeltaTime->Hide();
$win->tfDeltaHours->Hide();
$win->upDownDeltaHours->Hide();
$win->lblSeparator1->Hide();
$win->tfDeltaMinutes->Hide();
$win->upDownDeltaMinutes->Hide();
$win->lblSeparator2->Hide();
$win->tfDeltaSecondes->Hide();
$win->upDownDeltaSecondes->Hide();
}
&isProcessReady(0);
} #--- End cbTime_Change
#--------------------------#
sub cbInputTimeType_Change
#--------------------------#
{
# Possibles value are 0 = 'Datetime', 1 = 'ChromeTime', 2 = 'LDAPTime', 3 = 'Filetime', 4 = 'SystemTime', 5 = 'MacAbsTime', 6 = 'MacHFS'
if (!$win->cbInputTimeType->GetCurSel()) { $win->cbInputDTFormat->Enable(); } # Datetime
else { $win->cbInputDTFormat->Disable(); } # Else
&isProcessReady(0);
} #--- End cbInputTimeType_Change
#--------------------------#
sub cbOutputDTFormat_Change { &isProcessReady(0); }
#--------------------------#
#--------------------------#
sub chSingleDate_Click
#--------------------------#
{
if ($win->chSingleDate->Checked()) { &hideList2(); } # Hide List 2
else { &showList2(); } # Show List 2
&isProcessReady(0);
} #--- End chSingleDate_Click
#--------------------------#
sub cbUtils_Change
#--------------------------#
{
# Local variables
my $selFunc = $win->cbUtils->GetCurSel();
# Possibles value are 0 = 'NSLookup', 1 = 'CIDR to IP Range', 2 = 'IP Range to CIDR', 3 = 'CIDR to IP list',
# 4 = 'IP to Arpa', 5 = 'Arpa to IP', 6 = 'Resolve MAC Address', 7 = 'Resolve GeoIP', 8 = 'Resolve ISP',
# 9 = 'Resolve User-agent', 10 = 'Credit Card to issuing company', 11 = 'Address to GPS coordinates',
# 12 = 'GPS to address', 13 = 'Distance between locations', 14 = 'Custom functions'
# Show or Hide List 2
if ($selFunc != 13) { &hideList2(); }
elsif ($win->chSingleLocation->Checked()) { &hideList2(); }
else { &showList2(); }
# Show Resolve MAC Address options
if ($selFunc == 6) {
$win->lblCurrMACOUIdbDate->Show();
$win->btnMACOUIdbUpdate->Show();
if (!$win->lblCurrMACOUIdbDate->Text()) {
my $localMACOUIDB = $winConfig->tfMACOUIDB->Text();
if (!$localMACOUIDB or !-f $localMACOUIDB) { # No database
$win->lblCurrMACOUIdbDate->Text($STR{'noDB'});
$win->btnMACOUIdbUpdate->Text($STR{'Download'}.'...');
} else { # Show current DB date
my $localFileT = DateTime->from_epoch(epoch => (stat($localMACOUIDB))[9]);
$win->lblCurrMACOUIdbDate->Text("$STR{'currDBDate'}: ". $localFileT->ymd());
$win->btnMACOUIdbUpdate->Text($STR{'Update'}.'...');
}
}
} else { $win->lblCurrMACOUIdbDate->Hide(); $win->btnMACOUIdbUpdate->Hide(); }
# Add headers option
if ($selFunc == 7 or $selFunc == 9 or ($selFunc == 12 and $win->cbGPS2AddrOutput->GetCurSel())) {
$win->chAddHeaders->Show();
} else { $win->chAddHeaders->Hide(); }
# Show Resolve GeoIP options
if ($selFunc == 7) {
$win->lblGeoIPLang->Show();
$win->cbGeoIPLang->Show();
$win->chGeoIPOptAll->Show();
$win->gridGeoIPOpts->Show();
} else {
$win->lblGeoIPLang->Hide();
$win->cbGeoIPLang->Hide();
$win->chGeoIPOptAll->Hide();
$win->gridGeoIPOpts->Hide();
}
# Valid XL-Whois Database
&tfXLWHOISDB_Change() if $selFunc == 8;
# Show User-Agent options
if ($selFunc == 9) {
$win->chUAOptAll->Show();
$win->gridUAOpts->Show();
} else {
$win->chUAOptAll->Hide();
$win->gridUAOpts->Hide();
}
# Show Credit Card to Issuing Company options
if ($selFunc == 10) { $win->rbIINLocalDB->Show(); $win->rbBinlist->Show(); }
else { $win->rbIINLocalDB->Hide(); $win->rbBinlist->Hide(); }
# Show Address to GPS options
if ($selFunc == 11) { $win->chAddr2GPSInc->Show(); }
else { $win->chAddr2GPSInc->Hide(); }
# Show GPS to Address options
if ($selFunc == 12) {
$win->lblGPS2AddrZL->Show();
$win->cbGPS2AddrZL->Show();
$win->cbGPS2AddrOutput->Show();
$win->gridGPS2AddrOpts->Show() if $win->cbGPS2AddrOutput->GetCurSel() == 2;
} else {
$win->lblGPS2AddrZL->Hide();
$win->cbGPS2AddrZL->Hide();
$win->cbGPS2AddrOutput->Hide();
$win->gridGPS2AddrOpts->Hide();
}
# Distance between locations options
if ($selFunc == 13) { $win->chSingleLocation->Show(); $win->tfSingleLocation->Show(); }
else { $win->chSingleLocation->Hide(); $win->tfSingleLocation->Hide(); }
# Custom Functions options
if ($selFunc == 14) {
$win->cbCFLists->Show();
$win->cbCFLists->Enable();
$win->btnCFAdd->Show();
$win->btnCFRem->Show();
$win->btnCFEdit->Show();
$win->btnCFNew->Show();
} else {
$win->cbCFLists->Hide();
$win->btnCFAdd->Hide();
$win->btnCFRem->Hide();
$win->btnCFEdit->Hide();
$win->btnCFNew->Hide();
$win->chCFMatchCase->Hide();
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
}
&isProcessReady(0);
} #--- End cbUtils_Change
#--------------------------#
sub btnMACOUIdbUpdate_Click { &btnMACOUIDBUpt_Click(); }
sub rbIINLocalDB_Click { &isProcessReady(0); }
sub rbBinlist_Click { &isProcessReady(0); }
#--------------------------#
#--------------------------#
sub btnList1File_Click
#--------------------------#
{
# Show OpenFile dialog window
my $file = Win32::GUI::GetOpenFileName( -owner => $win ,
-title => $STR{'selectFile'} ,
-filter => ["$STR{'text'} (*.txt)", "*.txt"] ,
-defaultfilter => 0 ,
-filemustexist => 1 ,
-explorer => 1 , );
# Text format only
if ($file and -T $file) {
$win->tfList1->Enable();
$win->tfList1->Text('');
$win->tfList1->Text("$STR{'useFile'}: \"$file\"");
&tfList1_Change();
} elsif ($file) { Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010); }
&isProcessReady(0);
} #--- End btnList1File_Click
#--------------------------#
sub btnList1Del_Click
#--------------------------#
{
$win->tfList1->Text('');
$win->tfList1->Enable();
$win->lblList1Count->Text(0);
&isProcessReady(0);
} #--- End btnList1Del_Click
#--------------------------#
sub btnList1UseRes_Click
#--------------------------#
{
$win->tfList1->Text($win->tfList3->Text()) if $win->tfList3->Text();
&tfList1_Change();
&isProcessReady(0);
} #--- End btnList1UseRes_Click
#--------------------------#
sub tfList1_Change
#--------------------------#
{
# Count items
my $count = 0;
my $first = $win->tfList1->GetLine(0);
my $file;
# Items are in a file?
if ($first =~ /^$STR{'useFile'}: \"([^\"]+)\"$/) { $file = $1; }
if ($file and -T $file) {
# Items are in a file
if (open my $fh, '<', $file) {
while (sysread $fh, my $buffer, 4096) { $count += ($buffer =~ tr/\n//); }
close($fh);
} else { Win32::GUI::MessageBox($win, "$STR{'errorReading'}: ".$!, $STR{'Error'}, 0x40010); }
# Items are in the textfield
} else { $count = $win->tfList1->GetLineCount(); }
# Update counter
$count = 0 if $count == 1 and $win->tfList1->GetLine(0) eq '';
$win->lblList1Count->Text($count);
# If New Custom Function
&validNewFunc(\$win, \%STR) if $win->tfCFTitle->IsVisible();
&isProcessReady(0);
} #--- End tfList1_Change
#--------------------------#
sub tfList1_MaxText { Win32::GUI::MessageBox($win, $STR{'maxSizeReached'}, $STR{'Warning'}, 0x40030); } # Popup warning
#--------------------------#
#--------------------------#
sub btnList2File_Click
#--------------------------#
{
# Show OpenFile dialog window
my $file = Win32::GUI::GetOpenFileName( -owner => $win ,
-title => $STR{'selectFile'} ,
-filter => ["$STR{'text'} (*.txt)", "*.txt"] ,
-defaultfilter => 0 ,
-filemustexist => 1 ,
-explorer => 1 , );
# Text format only
if ($file and -T $file) {
$win->tfList2->Enable();
$win->tfList2->Text('');
$win->tfList2->Text("$STR{'useFile'}: \"$file\"");
&tfList2_Change();
} elsif ($file) { Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010); }
&isProcessReady(0);
} #--- End btnList2File_Click
#--------------------------#
sub btnList2Del_Click
#--------------------------#
{
$win->tfList2->Text('');
$win->tfList2->Enable();
$win->lblList2Count->Text(0);
&isProcessReady(0);
} #--- End btnList2Del_Click
#--------------------------#
sub tfList2_Change
#--------------------------#
{
# Count items
my $count = 0;
my $first = $win->tfList2->GetLine(0);
my $file;
# Items are in a file?
if ($first =~ /^$STR{'useFile'}: \"([^\"]+)\"$/) { $file = $1; }
if ($file and -T $file) {
# Items are in a file
if (open my $fh, '<', $file) {
while (sysread $fh, my $buffer, 4096) { $count += ($buffer =~ tr/\n//); }
close($fh);
} else { Win32::GUI::MessageBox($win, "$STR{'errorReading'}: ".$!, $STR{'Error'}, 0x40010); }
# Items are in the textfield
} else { $count = $win->tfList2->GetLineCount(); }
# Update counter
$count = 0 if $count == 1 and $win->tfList2->GetLine(0) eq '';
$win->lblList2Count->Text($count);
# If New Custom Function
&validNewFunc(\$win, \%STR) if $win->tfCFTitle->IsVisible();
&isProcessReady(0);
} #--- End tfList2_Change
#--------------------------#
sub tfList2_MaxText { Win32::GUI::MessageBox($win, $STR{'maxSizeReached'}, $STR{'Warning'}, 0x40030); } # Popup warning
#--------------------------#
#--------------------------#
sub btnList3Open_Click
#--------------------------#
{
# Local variables
my $file = $win->tfList3->GetLine(0);
if ($file =~ /^\"([^\"]+)\"$/) { $file = $1; }
# Open file with default program
if ($file and -T $file) {
$win->ShellExecute('open', $file,'','',1) or
Win32::GUI::MessageBox($win, "$STR{'errorOpening'}: ".Win32::FormatMessage(Win32::GetLastError()), $STR{'Error'}, 0x40010);
}
} #--- End btnList3Open_Click
#--------------------------#
sub tfList3_Change
#--------------------------#
{
if ($win->tfList3->Text()) { $win->btnList1UseRes->Enable(); }
else { $win->btnList1UseRes->Disable(); }
} #--- End tfList3_Change
#--------------------------#
# CTRL + A (Select All)
#--------------------------#
sub tfList1_GotFocus { $LISTNO = 1; }
sub tfList2_GotFocus { $LISTNO = 2; }
sub tfList3_GotFocus { $LISTNO = 3; }
sub tfList1_LostFocus { $LISTNO = 0; }
sub tfList2_LostFocus { $LISTNO = 0; }
sub tfList3_LostFocus { $LISTNO = 0; }
#--------------------------#
sub selectAll_Click
#--------------------------#
{
if ($LISTNO == 1) { $win->tfList1->SelectAll(); }
elsif ($LISTNO == 2) { $win->tfList2->SelectAll(); }
elsif ($LISTNO == 3) { $win->tfList3->SelectAll(); }
} #--- End selectAll_Click
#--------------------------#
sub fontSizeS_Click
#--------------------------#
{
if ($LISTNO) {
# Get current font details
if (my $currFont = $win->tfList1->GetFont()) {
my @details = Win32::GUI::Font::Info($currFont);
# Decrease font size
my $i = 0;
foreach (@details) {
if (/-height/) { $details[$i+1]--; last; }
$i++;
}
$fontTF = new Win32::GUI::Font(@details);
$win->tfList1->Change(-font => $fontTF);
$win->tfList1->Update();
$win->tfList2->Change(-font => $fontTF);
$win->tfList2->Update();
$win->tfList3->Change(-font => $fontTF);
$win->tfList3->Update();
my $customFont;
foreach (@details) { $customFont .= $_ . ','; }
chop($customFont);
$CONFIG{'TFLIST_FONT'} = $customFont;
&saveConfig(\%CONFIG, $CONFIG_FILE);
# Update all textfields
if ($LISTNO == 1) { $win->tfList2->SetFocus(); $win->tfList3->SetFocus(); $win->tfList1->SetFocus(); }
elsif ($LISTNO == 2) { $win->tfList1->SetFocus(); $win->tfList3->SetFocus(); $win->tfList2->SetFocus(); }
elsif ($LISTNO == 3) { $win->tfList1->SetFocus(); $win->tfList2->SetFocus(); $win->tfList3->SetFocus(); }
}
}
return(1);
} #--- End fontSizeS_Click
#--------------------------#
sub fontSizeB_Click
#--------------------------#
{
if ($LISTNO) {
# Get current font details
if (my $currFont = $win->tfList1->GetFont()) {
my @details = Win32::GUI::Font::Info($currFont);
# Increase font size
my $i = 0;
foreach (@details) {
if (/-height/) { $details[$i+1]++; last; }
$i++;
}
$fontTF = new Win32::GUI::Font(@details);
$win->tfList1->Change(-font => $fontTF);
$win->tfList1->Update();
$win->tfList2->Change(-font => $fontTF);
$win->tfList2->Update();
$win->tfList3->Change(-font => $fontTF);
$win->tfList3->Update();
my $customFont;
foreach (@details) { $customFont .= $_ . ','; }
chop($customFont);
$CONFIG{'TFLIST_FONT'} = $customFont;
&saveConfig(\%CONFIG, $CONFIG_FILE);
# Update all textfields
if ($LISTNO == 1) { $win->tfList2->SetFocus(); $win->tfList3->SetFocus(); $win->tfList1->SetFocus(); }
elsif ($LISTNO == 2) { $win->tfList1->SetFocus(); $win->tfList3->SetFocus(); $win->tfList2->SetFocus(); }
elsif ($LISTNO == 3) { $win->tfList1->SetFocus(); $win->tfList2->SetFocus(); $win->tfList3->SetFocus(); }
}
}
return(1);
} #--- End fontSizeB_Click
#--------------------------#
sub lblNotReady_Click { &isProcessReady(1); }
#--------------------------#
#--------------------------#
sub isProcessReady
#--------------------------#
{
# Local variables
my $confirm = shift;
my $nextStep;
# Status of List1 and List2
my $nbrList1 = $win->lblList1Count->Text();
my $nbrList2 = $win->lblList2Count->Text();
# Every function require items in List1, except some functions in Lists
if (!$nbrList1 and $win->Tab->SelectedItem() != 0) { $nextStep = "$STR{'insertList1'} $STR{'seeDoc'}"; }
else {
$win->btnInputFormatGuess->Enable();
# Lists tab selected
if ($win->Tab->SelectedItem() == 0) {
my $selFunc = $win->cbLists->GetCurSel();
# Possibles value are 0 = 'No duplicate', 1 = 'Only duplicates', 2 = 'Count items', 3 = 'Count characters',
# 4 = 'L1-L2', 5 = 'Column to row', 6 = 'Row to column', 7 = 'List to regex', 8 = 'Concat', 9 = 'Split strings',
# 10 = 'Split and extract', 11 = 'Merge lines', 12 = 'Split and merge', 13 = 'Replace', 14 = 'Reverse string',
# 15 = 'Transliterate', 16 = 'Lowercase', 17 = 'Uppercase', 18 = 'Add line number'
# Some functions require items in List 1 or in List 2
if ($selFunc == 1 or $selFunc == 4 or $selFunc == 8) {
$nextStep = $STR{'insertLists'} if !$nbrList1 and !$nbrList2;
# Other require items in List 1 only
} elsif (!$nbrList1) { $nextStep = $STR{'insertList1'}; }
# Some functions require a value in With textfield
if (($selFunc == 9 or $selFunc == 10 or $selFunc == 12) and !$win->tfWith->Text()) {
$nextStep = "$STR{'insertWith'} $STR{'seeDoc'}";
}
# Some functions require a value in Columns textfield
if (($selFunc == 10 or $selFunc == 11 or $selFunc == 12) and !$win->tfColumnsNo->Text()) {
$nextStep = "$STR{'insertColumns'} $STR{'seeDoc'}";
}
# Replace function require value in Replace textfield
if (($selFunc == 13 or $selFunc == 15) and !$win->tfReplace->Text()) {
$nextStep = $STR{'insertReplace'};
} elsif ($selFunc == 12 and ($win->chRegex->Checked() or $win->chEval->Checked())) { # Valid regex
# Regex is valid?
if ($win->chRegex->Checked()) {
if ($win->tfReplace->Text()) {
my ($status, $msg) = &validRegex($win->tfReplace->Text());
if ($status and $status == 1) {
$nextStep = $STR{'errRegex'} . ' ' . $STR{'errRegexReplace'} . ":\n\n";
$nextStep .= $msg if $msg;
}
}
# Replacement expression is valid?
if ($win->tfReplBy->Text()) {
my ($status, $msg) = &validReplacement(\$win);
if ($status and $status == 1) {
$nextStep = $STR{'errBy'} . ' ' . $STR{'errRegexReplaceBy'} . ":\n\n";
$nextStep .= $msg if $msg;
}
}
}
}
# Sorting tab selected
} elsif ($win->Tab->SelectedItem() == 1) { # No special condition for now
# Conversion tab selected
} elsif ($win->Tab->SelectedItem() == 2) { # No special condition for now
# Time tab selected
} elsif ($win->Tab->SelectedItem() == 3) {
my $selFunc = $win->cbTime->GetCurSel();
# Possibles value are 0 = 'Anytime to Anytime', 1 = 'Time difference', 2 = 'Add time', 3 = 'Substract time'
# If InputType is not a Datetime object, Output format can't be "Same as input"
# Possibles value are 0 = 'Datetime', 1 = 'ChromeTime', 2 = 'LDAPTime', 3 = 'Filetime', 4 = 'SystemTime', 5 = 'MacAbsTime', 6 = 'MacHFS'
if ($win->cbInputTimeType->GetCurSel() and !$win->cbOutputDTFormat->GetCurSel() and !$winDTDB->cbDefaultOutput->GetCurSel()) {
$nextStep = $STR{'setOutputFormat'};
}
# 'Time difference' can be used with a single date or with items in List 2
# If so, number of items in List 1 and List 2 must be the same
if ($selFunc == 1 and !$win->chSingleDate->Checked()) {
my $refList1 = &enumItems(\$win->tfList1, \$win, \%STR);
my $refList2 = &enumItems(\$win->tfList2, \$win, \%STR);
$nextStep = $STR{'insertSameNbr'} if scalar(@{$refList1}) != scalar(@{$refList2});
}
# Utils tab selected
} elsif ($win->Tab->SelectedItem() == 4) {
my $selFunc = $win->cbUtils->GetCurSel();
# Possibles value are 0 = 'NSLookup', 1 = 'CIDR to IP Range', 2 = 'IP Range to CIDR', 3 = 'CIDR to IP list',
# 4 = 'IP to Arpa', 5 = 'Arpa to IP', 6 = 'Resolve MAC Address', 7 = 'Resolve GeoIP', 8 = 'Resolve ISP',
# 9 = 'Resolve User-agent', 10 = 'Credit Card to issuing company', 11 = 'Address to GPS coordinates',
# 12 = 'Address to GPS coordinates', 13 = 'Distance between locations', 14 = 'Custom functions'
# 'Resolve MAC Address' requires MACOUI database
if ($selFunc == 6) {
my $MACOUIDB = $winConfig->tfMACOUIDB->Text();
$nextStep = "$STR{'validDB1'} $STR{'MACOUIDB'} $STR{'validDB2'} $STR{'seeDoc'}" if !-e $MACOUIDB;
# 'Resolve GeoIP' requires GeoIP database and at least one detail
} elsif ($selFunc == 7) {
my $GeoIPDB = $winConfig->tfGeoIPDB->Text();
$nextStep = "$STR{'validDB1'} $STR{'GeoIPDB'} $STR{'validDB2'} $STR{'seeDoc'}" if !-e $GeoIPDB;
# Browse grid and check if at least one checked option
my $check = 0;
for (my $i = 0; $i < 5; $i++) {
$check = 1 if $win->gridGeoIPOpts->GetCellCheck(0, $i) or $win->gridGeoIPOpts->GetCellCheck(1, $i);
}
$nextStep = $STR{'checkOpt'} if !$check;
# 'Resolve ISP' requires XL-Whois database
} elsif ($selFunc == 8) {
my $XLWHOISDBFile = $winConfig->tfXLWHOISDB->Text();
$nextStep = "$STR{'validDB1'} $STR{'XLWhoisDB'} $STR{'validDB2'} $STR{'seeDoc'}" if !-e $XLWHOISDBFile;
# 'Resolve Useragent' require at least one detail
} elsif ($selFunc == 9) {
# Browse grid and check if at least one checked option
my $check = 0;
for (my $i = 0; $i < 3; $i++) {
$check = 1 if $win->gridUAOpts->GetCellCheck(0, $i) or $win->gridUAOpts->GetCellCheck(1, $i);
}
$nextStep = $STR{'checkOpt'} if !$check;
# 'Credit Card to issuing company' requires IIN database if local option is checked
} elsif ($selFunc == 10 and $win->rbIINLocalDB->Checked()) {
my $IINFile = $winConfig->tfIINDB->Text();
$nextStep = "$STR{'validDB1'} $STR{'IINDB'} $STR{'validDB2'} $STR{'seeDoc'}" if !-e $IINFile;
# 'Address to GPS' and 'GPS to Address' requirements
} elsif ($selFunc == 11 or $selFunc == 12) {
if ($selFunc == 12) {
my $selOutput = $win->cbGPS2AddrOutput->GetString($win->cbGPS2AddrOutput->GetCurSel());
my $OSMFile = $winConfig->tfOSMDB->Text();
$nextStep = "$STR{'validDB1'} $STR{'OSMDB'} $STR{'validDB2'} $STR{'seeDoc'}" if !-e $OSMFile;
if ($selOutput and $selOutput eq $STR{'AddressEl'}) {
# Browse grid and check if at least one checked option
my $check = 0;
for (my $i = 0; $i < 6; $i++) {
$check = 1 if $win->gridGPS2AddrOpts->GetCellCheck(0, $i) or $win->gridGPS2AddrOpts->GetCellCheck(1, $i);
}
$nextStep = $STR{'checkOpt'} if !$check;
}
}
$nextStep = $STR{'emailRequired'} if $nbrList1 > 25 and !$CONFIG{'EMAIL'};
# Distance between locations
} elsif ($selFunc == 13) {
if ($win->chSingleLocation->Checked()) {
if (!$win->tfSingleLocation->Text()) { $nextStep = $STR{'reqLocation'}; }
} else { # A list of location in list 1 to compare with list 2, must be the same number of items
my $refList1 = &enumItems(\$win->tfList1, \$win, \%STR);
my $refList2 = &enumItems(\$win->tfList2, \$win, \%STR);
$nextStep = $STR{'insertSameNbr'} if scalar(@{$refList1}) != scalar(@{$refList2});
}
# In 'Custom functions', a function must be selected, except if we are adding or modifying a function
} elsif ($selFunc == 14 and !$win->cbCFLists->GetCurSel() and !$win->tfCFTitle->IsVisible()) {
$nextStep = $STR{'selectFunc'};
}
}
}
# Return an error message or enable the button
if ($nextStep) {
$win->btnInputFormatGuess->Disable();
$win->btnProcess->Disable();
$win->lblNotReady->Show();
Win32::GUI::MessageBox($win, "$STR{'notReady'}?\n\n$STR{'nextStep'}: $nextStep", $STR{'notReady'}, 0x40040) if $confirm;
} else {
$win->btnProcess->Enable() if $win->cbCFLists->IsEnabled();
$win->lblNotReady->Hide();
}
} #--- End isProcessReady
#--------------------------#
sub btnProcess_Click
#--------------------------#
{
# Avoid new thread
if ($THR_PROCESS and $THR_PROCESS->is_running()) { Win32::GUI::MessageBox($win, $STR{'processRunning'}, $STR{'Error'}, 0x40010); }
else {
$THR_PROCESS = threads->create(sub {
# Thread cancel signal handler
$SIG{'KILL'} = sub {
$win->lblPbCurr->Text('');
$win->pb->SetPos(0);
$win->lblPbCount->Text('');
$win->lblPbCurr->Hide();
$win->pb->Hide();
$win->lblPbCount->Hide();
$win->btnProcess->Show();
$win->btnStop->Hide();
$win->ChangeCursor($ARROW);
threads->exit();
};
# Thread die signal handler
$SIG{__DIE__} = sub {
return if $_ and $_[0] =~ /Invalid version format/;
return if $_[0] and ($_[0]->isa('GeoIP2::Error::Generic') or $_[0]->isa('GeoIP2::Error::IPAddressNotFound'));
my $errMsg = (split(/ at /, $_[0]))[0];
$errMsg =~ s/[\t\r\n]/ /g;
$win->lblPbCurr->Text('');
$win->pb->SetPos(0);
$win->lblPbCount->Text('');
$win->lblPbCurr->Hide();
$win->pb->Hide();
$win->lblPbCount->Hide();
$win->btnProcess->Show();
$win->btnStop->Hide();
$win->ChangeCursor($ARROW);
Win32::GUI::MessageBox($win, "$STR{'errorMsg'}: $errMsg", $STR{'Error'}, 0x40010);
threads->exit();
};
# Local variables
my $refList3;
# Reset list 3
$win->tfList3->Text('');
$win->lblList3Count->Text(0);
# Gather items
my $refList1 = &enumItems(\$win->tfList1, \$win, \%STR);
my $refList2 = &enumItems(\$win->tfList2, \$win, \%STR);
# Show progress
$win->lblPbCurr->Text('');
$win->pb->SetPos(0);
$win->lblPbCount->Text('');
$win->lblPbCurr->Show();
$win->pb->Show();
$win->lblPbCount->Show();
$win->lblPbCurr->Text($STR{'startingProcess'}.'...');
$win->btnProcess->Hide();
$win->btnStop->Show();
$win->ChangeCursor($HOURGLASS);
# Lists tab selected
if (!$win->Tab->SelectedItem()) {
my $selFunc = $win->cbLists->GetCurSel();
# Possibles value are 0 = 'No duplicate', 1 = 'Only duplicates', 2 = 'Count items', 3 = 'Count characters',
# 4 = 'L1-L2', 5 = 'Column to row', 6 = 'Row to column', 7 = 'List to regex', 8 = 'Concat', 9 = 'Split strings',
# 10 = 'Split and extract', 11 = 'Merge lines', 12 = 'Split and merge', 13 = 'Replace', 14 = 'Reverse string',
# 15 = 'Transliterate', 16 = 'Lowercase', 17 = 'Uppercase', 18 = 'Add line number'
if (!$selFunc) { $refList3 = &noDuplicates($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 1) { $refList3 = &onlyDuplicates($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 2) { $refList3 = &countDuplicates($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 3) { $refList3 = &countChars($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 4) { $refList3 = &L1_less_L2($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 5) { $refList3 = &col2row($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 6) { $refList3 = &row2col($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 7) { $refList3 = &list2regex($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 8) { $refList3 = &concatStr($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 9) { $refList3 = &splitStr($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 10) { $refList3 = &splitExtract($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 11) { $refList3 = &mergeLines($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 12) { $refList3 = &splitMerge($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 13) { $refList3 = &replace($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 14) { $refList3 = &reverseStr($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 15) { $refList3 = &transliterate($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 16) { $refList3 = &lowercase($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 17) { $refList3 = &uppercase($refList1, $refList2, \$win, \%STR); }
elsif ($selFunc == 18) { $refList3 = &addLineNumber($refList1, $refList2, \$win, \%STR); }
# Sorting tab selected
} elsif ($win->Tab->SelectedItem() == 1) { $refList3 = &sortingTabFunc($refList1, $refList2);
# Conversion tab selected
} elsif ($win->Tab->SelectedItem() == 2) { $refList3 = &conversionTabFunc($refList1, $refList2);
# Time tab selected
} elsif ($win->Tab->SelectedItem() == 3) { $refList3 = &timeTabFunc($refList1, $refList2);
# Utils tab selected
} elsif ($win->Tab->SelectedItem() == 4) {
my $selFunc = $win->cbUtils->GetCurSel();
$refList3 = &utilsTabFunc($refList1, $refList2, \$winConfig, \%CONFIG, $CONFIG_FILE, \$win, \%STR);
}
# Progress
$win->lblPbCurr->Text('');
$win->pb->SetPos(0);
$win->lblPbCount->Text('');
$win->lblPbCurr->Hide();
$win->pb->Hide();
$win->lblPbCount->Hide();
$win->btnProcess->Show();
$win->btnStop->Hide();
$win->ChangeCursor($ARROW);
# Write resulting list
&writeResults($refList3, \%CONFIG, \$win, \%STR);
});
}
} #--- End btnProcess_Click
#--------------------------#
sub btnStop_Click
#--------------------------#
{
# Stop requests
if ($THR_PROCESS and $THR_PROCESS->is_running()) { $THR_PROCESS->kill('KILL')->detach(); }
return(1);
} #--- End btnStop_Click
#--------------------------#
sub btnHelp_Click
#--------------------------#
{
# Open XL-Tools documentation page with default browser
$win->ShellExecute('open', $URL_DOC,'','',1) or Win32::GUI::MessageBox($win, Win32::FormatMessage(Win32::GetLastError()), $STR{'Error'}, 0x40010);
} #--- End btnHelp_Click
#--------------------------#
sub btnAbout_Click
#--------------------------#
{
# Create the window
my $winAbout = Win32::GUI::DialogBox->new( -name => 'winAbout' ,
-parent => $win ,
-text => $STR{'About'}.' XL-Tools' ,
-pos => [$winPosX, $winPosY] ,
-size => [520, 170] ,
-background => [255, 255, 255] ,
-hasmaximize => 0 ,
-hasminimize => 1 ,
-helpbutton => 0 ,
-resizable => 0 ,
-dialogui => 1 , );
$winAbout->SetIcon($winICO);
# About tab
$winAbout->AddLabel( -name => 'lblLogo128' ,
-size => [128,128] ,
-pos => [ 0, 5] ,
-background => [255, 255, 255] ,
-bitmap => $logo128Bmp , );
$winAbout->AddLabel( -name => 'lblAbout1' ,
-size => [ 90, 75] ,
-pos => [140, 10] ,
-font => $font10 ,
-background => [255, 255, 255] ,
-text => "$STR{'Version'}:\n$STR{'Website'}:\n$STR{'Author'}:\n$STR{'TranslatedBy'}:", );
$winAbout->AddLabel( -name => 'lblAbout2' ,
-size => [230, 75] ,
-pos => [235, 10] ,
-font => $font10b ,
-foreground => [204, 0, 51] ,
-background => [255, 255, 255] ,
-text => "$VERSION\nhttp://www.le-tools.com\nAlain Rioux (admin\@le-tools.com)\n$STR{'translatorName'}", );
$winAbout->AddLabel( -name => 'lblAbout3' ,
-size => [300, 20] ,
-pos => [140, 80] ,
-font => $font10 ,
-background => [255, 255, 255] ,
-text => '© Copyright 2015-2020 Alain Rioux', );
$winAbout->Center($win);
$winAbout->DoModal();
return(1);
} #--- End btnAbout_Click
#--------------------------#
sub sortingTabFunc
#--------------------------#
{
# Local variables
my ($refList1, $refList2) = @_;
push(@{$refList1}, @{$refList2}); # Merge lists
my $nbrItems = scalar(@{$refList1});
my $selFunc = $win->cbSorts->GetCurSel();
# Possibles value are 0 = 'Alphabetical order', 1 = 'Numerical order', 2 = 'String length', 3 = 'IPv4 Address', 4 = 'Date and time'
my $order;
if ($win->rbAsc->Checked()) { $order = 0; } # Ascending
else { $order = 1; } # Descending
my @items;
# Sort items
# Alphabetical
if (!$selFunc and !$order) { @items = sort {lc $a cmp lc $b} @{$refList1}; } # Ascending
elsif (!$selFunc and $order) { @items = sort {lc $b cmp lc $a} @{$refList1}; } # Descending
# Numerical
elsif ($selFunc == 1 and !$order) { # Ascending
@items = map $_->[0],
sort { $a->[1] <=> $b->[1] }
map [ $_, /(\d+)/ ], @{$refList1};
}
elsif ($selFunc == 1 and $order) { # Descending
@items = map $_->[0],
sort { $b->[1] <=> $a->[1] }
map [ $_, /(\d+)/ ], @{$refList1};
}
# String length
elsif ($selFunc == 2 and !$order) { @items = sort {length($a) <=> length($b)} @{$refList1}; } # Ascending
elsif ($selFunc == 2 and $order) { @items = sort {length($b) <=> length($a)} @{$refList1}; } # Descending
# IPv4 Address
elsif ($selFunc == 3 and !$order) { # Ascending
@items = map substr($_, 4) => sort {$a cmp $b} map pack('C4'
=> /(\d+)\.(\d+)\.(\d+)\.(\d+)/) . $_
=> @{$refList1};
}
elsif ($selFunc == 3 and $order) { # Descending
@items = map substr($_, 4) => sort {$b cmp $a} map pack('C4'
=> /(\d+)\.(\d+)\.(\d+)\.(\d+)/) . $_
=> @{$refList1};
}
# Date and time
elsif ($selFunc == 4) {
my ($sample, $pattern, $regex, $timezone);
# Input Datetime format
my $inputFormat = $win->cbInputDTFormat->GetString($win->cbInputDTFormat->GetCurSel());
if ($inputFormat ne $STR{'guessORVar'}) {
($sample, $pattern, $regex, $timezone) = &findInputDTFormat($$refList1[0]);
} else { $sample = $inputFormat; }
if (!$order) { # Ascending
@items = map { $_->[0] }
sort {$a->[1] cmp $b->[1]}
map { [$_, (str2Epoch($_, $sample, $pattern, $regex, 0, $timezone))[0]] } @{$refList1};
} else { # Descending
@items = map { $_->[0] }
sort {$b->[1] cmp $a->[1]}
map { [$_, (str2Epoch($_, $sample, $pattern, $regex, 0, $timezone))[0]] } @{$refList1};
}
# Random
} elsif ($selFunc == 5) {
for (my $i = $nbrItems; $i > 0; $i--) { push(@items, splice(@{$refList1}, rand($i), 1)); }
}
# Format results
my $itemsRes;
foreach (@items) { s/[\r\n]//g; $itemsRes .= "$_\r\n"; }
return(\$itemsRes);
} #--- End sortingTabFunc
#--------------------------#
sub str2Epoch
#--------------------------#
{
# Local variables
my ($str, $sample, $pattern, $regex, $parseContext, $timezone) = @_;
my $strp;
# Guess Input Datetime format if not unique
($sample, $pattern, $regex, $timezone) = &findInputDTFormat($str) if $sample eq $STR{'guessORVar'};
# Format
if ($pattern and $str =~ /($regex)/) {
my $extract = $1;
my $before;
my $after;
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
$strp = DateTime::Format::Strptime->new(pattern => $pattern, zone_map => \%ZONE_MAP, locale => $CONFIG{'DEFAULT_LANG'},);
if (my $dt = $strp->parse_datetime($extract)) {
my $inputTimezone = $dt->time_zone_long_name();
$dt->set_time_zone($timezone) if $timezone and $pattern !~ /%s/;
return($dt->epoch(), $inputTimezone, $pattern, $before, $after);
} else { return(2); } # Error conversion
} else { return(1); } # Invalid input
} #--- End str2Epoch
#--------------------------#
sub conversionTabFunc
#--------------------------#
{
# Local variables
my ($refList1, $refList2) = @_;
push(@{$refList1}, @{$refList2}); # Merge lists
my $nbrItems = scalar(@{$refList1});
my $selFunc = $win->cbConv->GetCurSel();
my $noResultOpt = $winConfig->rbNoResultOpt2->Checked();
# Possibles value are 0 = 'Hex to ASCII', 1 = 'ASCII to Hex', 2 = 'Hex to Base10', 3 = 'Base10 to ASCII', 4 = 'URI Decode',
# 5 = 'URI Encode', 6 = 'HTML Decode', 7 = 'HTML Encode', 8 = 'Base64 to ASCII', 9 = 'ASCII to Base64', 10 = 'SHA1 - Base32 to Base16',
# 11 = 'SHA1 - Base16 to Base32'
my $curr = 0;
my @items;
# Progress
$win->pb->SetRange(0, $nbrItems);
$win->pb->SetPos(0);
$win->pb->SetStep(1);
$win->lblPbCurr->Text($STR{'runningProcess'}.'...');
$win->lblPbCount->Text("0 / $nbrItems");
# 0 = 'Hex to ASCII'
if ($selFunc == 0) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
$item =~ s/[^0-9a-fA-F]//g; # Remove non hexadecimal
if ($item) {
#$item =~ s/(?:0x)?((?:[0-9a-fA-F]{2} ?)+)/pack 'H*', $1/ge;
my $ascii = hex_to_ascii($item);
$ascii =~ s/[\x00-\x1F\x80-\xFF]/./g; # Remove non printable characters
push(@items, $ascii);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 1 = 'ASCII to Hex'
elsif ($selFunc == 1) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my $ascii = ascii_to_hex($item);
push(@items, $ascii);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 2 = 'Hex to Base10'
elsif ($selFunc == 2) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
$item =~ s/[^0-9a-fA-F\s]//g;
if ($item) {
# Convert string to a array of chars
my @chars;
if ($item =~ /\s/) { @chars = split(/\s/ , $item); }
else { @chars = split(/(.{1})/, $item); }
# Keep spaces
my $newItem = '';
foreach (@chars) { $newItem .= hex($_) . " " if /[0-9a-fA-F]+/; }
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 3 = 'Base10 to ASCII'
elsif ($selFunc == 3) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my @tab;
while ($item =~ /(\d{1,3})/) {
push(@tab, $1);
my $longLigne = length($item);
my $long = length($1);
my $pos = index($item, $1);
my $offset = $pos+$long;
$item = substr($item,$offset,$longLigne-$offset);
}
my $newItem;
foreach (@tab) { $newItem .= chr($_).' '; }
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 4 = 'URI Decode'
elsif ($selFunc == 4) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
$item =~ s/ /\%20/g;
# UTF-8
my $newItem = uri_unescape($item);
$newItem = decode('utf8' , $newItem);
$newItem = encode('cp1252', $newItem);
# Unicode
$newItem =~ s/\\u([0-9a-fA-F]{4})/%u$1/g;
$newItem = unescape($newItem);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 5 = 'URI Encode'
elsif ($selFunc == 5) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my $newItem = uri_escape_utf8($item);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 6 = 'HTML Decode'
elsif ($selFunc == 6) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my $newItem = decode_entities($item);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 7 = 'HTML Encode'
elsif ($selFunc == 7) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my $newItem = encode_entities($item);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 8 = 'Base64 to ASCII'
elsif ($selFunc == 8) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
$item =~ s/ //g;
if ($item) {
my $newItem = MIME::Base64::decode($item);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 9 = 'ASCII to Base64'
elsif ($selFunc == 9) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my $newItem = MIME::Base64::encode($item);
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 10 = 'SHA1 - Base32 to Base16'
elsif ($selFunc == 10) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item and $item =~ /^(\w{32})/) {
my $newItem = uc(unpack('H*', decode_base32($1)));
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 11 = 'SHA1 - Base16 to Base32'
elsif ($selFunc == 11) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item and $item =~ /^(\w{40})/) {
my $newItem = uc(encode_base32(pack('H40', $1)));
push(@items, $newItem);
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# Format results
my $itemsRes;
foreach (@items) { $itemsRes .= $_ if $_; $itemsRes .= "\r\n"; }
return(\$itemsRes);
} #--- End conversionTabFunc
#--------------------------#
sub timeTabFunc
#--------------------------#
{
# Local variables
my ($refList1, $refList2) = @_;
my $selFunc = $win->cbTime->GetCurSel(); # Possibles value are 0 = 'Anytime to Anytime', 1 = 'Time difference',
# 2 = 'Add time' , 3 = 'Substract time'
my $noResultOpt = $winConfig->rbNoResultOpt2->Checked();
my $selInputType = $win->cbInputTimeType->GetCurSel(); # Possibles value are 0 = 'Datetime', 1 = 'ChromeTime', 2 = 'LDAPTime' ,
# 3 = 'Filetime', 4 = 'SystemTime', 5 = 'MacAbsTime',
# 6 = 'MacHFS'
my $localTZ = $winConfig->cbLocalTZ->GetString($winConfig->cbLocalTZ->GetCurSel());
my $selOutputDTFormat = $win->cbOutputDTFormat->GetCurSel();
my ($sample, $pattern, $regex, $timezone); # Input
my ($outPutPattern, $outputTZ); # Output
my $sameAsInput = 0; # If == 1, don't use outputPattern, use input pattern instead
my $parseContext = $win->cbDTParser->GetCurSel(); # Possibles value are 0 = None, 1 = Before, 2 = After, 3 = Both
my $curr = 0;
my @items;
# Merge lists (except time difference)
push(@{$refList1}, @{$refList2}) if $selFunc != 1;
# Input Datetime format
if (!$selInputType) {
my $inputFormat = $win->cbInputDTFormat->GetString($win->cbInputDTFormat->GetCurSel());
if ($inputFormat ne $STR{'guessORVar'}) {
($sample, $pattern, $regex, $timezone) = &findInputDTFormat($$refList1[0]);
} else { $sample = $inputFormat; }
}
# Output format
if (!$selOutputDTFormat) { # Default selected
my $index = $winDTDB->cbDefaultOutput->GetCurSel();
if (!$index) {
if ($pattern and $timezone) {
$outPutPattern = $pattern;
$outputTZ = $timezone;
} else { $sameAsInput = 1; }
} else {
($outPutPattern, $outputTZ) = (&infoDTFormat($winDTDB->cbDefaultOutput->GetString($index)))[1,3];
$outputTZ = $localTZ if $outputTZ eq 'local';
}
} else {
($outPutPattern, $outputTZ) = (&infoDTFormat($win->cbOutputDTFormat->GetString($win->cbOutputDTFormat->GetCurSel())))[1,3];
$outputTZ = $localTZ if $outputTZ eq 'local';
}
# Progress
my $nbrItems = scalar(@{$refList1});
$win->pb->SetRange(0, $nbrItems);
$win->pb->SetPos(0);
$win->pb->SetStep(1);
$win->lblPbCurr->Text($STR{'runningProcess'}.'...');
$win->lblPbCount->Text("0 / $nbrItems");
# 0 = 'Anytime to Anytime'
if (!$selFunc) {
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my ($epoch, $inputTimezone, $before, $after);
# Datetime Input
if (!$selInputType) {
if ($pattern) {
($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, $pattern, $regex, $parseContext, $timezone);
} else {
($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, undef , undef , $parseContext, undef );
}
# ChromeTime Input
} elsif ($selInputType == 1) {
if ($item =~ /([0-9]{17})/) {
$epoch = ($1/1000000)-11644473600; # Convert to unixtime
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
# LDAPTime Input
} elsif ($selInputType == 2) {
if ($item =~ /([0-9]{18})/) {
$epoch = ($1/10000000)-11644473600; # Convert to unixtime
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
# Windows FILETIME (64 bits hexadecimal) (Ex.: 88 33 9d cb 38 36 d0 01)
} elsif ($selInputType == 3) {
my $extract;
if ($item =~ /((?:[0-9a-fA-F]{2} ?){7}[0-9a-fA-F]{2})/) {
$extract = $1;
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
if ($extract) {
$extract =~ s/ //g; # Remove space
my $int64bits = string_to_int64(join('', reverse(split(/([0-9a-fA-F]{2})/, $extract))), 16); # All-in-one!
$epoch = int(($int64bits-116444736000000000)/10000000); # Convert to unixtime
}
# Windows SYSTEMTIME (128 bits hexadecimal, ex.: D9070B00010002000600090013000000)
} elsif ($selInputType == 4) {
my $extract;
if ($item =~ /((?:[0-9a-fA-F]{2} ?){15}[0-9a-fA-F]{2})/) {
$extract = $1;
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
if ($extract) {
$extract =~ s/ //g; # Remove space
my @parts = split(/([0-9a-fA-F]{4} ?)/, $extract);
my $y = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[1]))));
my $m = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[3]))));
my $d = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[7]))));
my $h = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[9]))));
my $min = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[11]))));
my $s = hex(join('', reverse(split(/([0-9a-fA-F]{2})/, $parts[13]))));
my $dt = DateTime->new(year => $y ,
month => $m ,
day => $d ,
hour => $h ,
minute => $min ,
second => $s ,
time_zone => $localTZ, );
$epoch = $dt->epoch; # Convert to unixtime
}
# Mac Absolute time Input (01/01/2001)
} elsif ($selInputType == 5) {
if ($item =~ /([0-9]+)/) {
$epoch = $1 + 978307200; # Adjust to unixtime
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
# Mac HFS+ Input (01/01/1904)
} elsif ($selInputType == 6) {
if ($item =~ /([0-9]+)/) {
$epoch = $1 - 2082844800; # Adjust to unixtime
$before = $` if $parseContext == 1 or $parseContext == 3;
$after = $' if $parseContext == 2 or $parseContext == 3;
} else { $epoch = 1; } # Invalid input
}
# Convert to output
if ($epoch == 1) {
if ($noResultOpt) { push(@items, $STR{'invalidInput'}); }
else { push(@items, undef); }
} elsif ($epoch == 2) {
if ($noResultOpt) { push(@items, $STR{'errorConversion'}); }
else { push(@items, undef); }
} else {
if (my $dt = DateTime->from_epoch(epoch => $epoch)) {
if ($sameAsInput) { $inputTimezone = $localTZ if $inputTimezone eq 'floating'; $dt->set_time_zone($inputTimezone); }
else { $dt->set_time_zone($outputTZ); }
$dt->set(locale => $CONFIG{'DEFAULT_LANG'});
my $newItem;
$newItem .= $before if $before;
if ($sameAsInput) { $newItem .= $dt->strftime($pattern); }
else { $newItem .= $dt->strftime($outPutPattern); }
$newItem .= $after if $after;
push(@items, encode($CONFIG{'OUTPUT_CHARSET'}, $newItem));
} else {
if ($noResultOpt) { push(@items, $STR{'errorConversion'}); }
else { push(@items, undef); }
}
}
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 1 = 'Time difference'
elsif ($selFunc == 1) {
my $timeDiff;
my $dt2;
# Local timezone
$localTZ = $winConfig->cbLocalTZ->GetString($winConfig->cbLocalTZ->GetCurSel());
$outputTZ = DateTime::TimeZone->new(name => $localTZ);
# If "Use a single date" option is checked
if ($win->chSingleDate->Checked()) {
my ($d, $m, $y) = $win->dtTimeDiffDate->GetDate();
my ($h, $min, $s) = $win->dtTimeDiffTime->GetTime();
$dt2 = DateTime->new(year => $y, month => $m , day => $d,
hour => $h, minute => $min, second => $s, time_zone => $outputTZ);
push(@{$refList1}, @{$refList2}); # Merge lists
}
my $outputFormat = $win->cbOutputDTDiff->GetCurSel(); # Formats : 0 = string, 1 = years, 2 = months, 3 = weeks, 4 = days, 5 = hours, 6 = minutes, 7 = seconds
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
# Gather date in list 2
if (!$win->chSingleDate->Checked() and my $item2 = $$refList2[$curr]) {
$item2 =~ s/[\r\n]//g; # Remove any line break
if ($item2) {
my ($epoch, $inputTimezone, $before, $after);
if ($pattern) { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item2, $sample, $pattern, $regex, $parseContext, $timezone); }
else { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item2, $sample, undef , undef , $parseContext, undef ); }
if ($epoch) {
$dt2 = DateTime->from_epoch(epoch => $epoch);
$dt2->set_time_zone($outputTZ);
}
}
}
# Gather date in list 1 and calculate difference
if ($dt2) {
my $dt1;
my ($epoch, $inputTimezone, $before, $after);
if ($pattern) { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, $pattern, $regex, $parseContext, $timezone); }
else { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, undef , undef , $parseContext, undef ); }
if ($epoch) {
$dt1 = DateTime->from_epoch(epoch => $epoch);
$dt1->set_time_zone($outputTZ);
}
if ($dt1 and $dt2) {
my $oldestDT = $dt1->epoch < $dt2->epoch ? $dt1 : $dt2;
my $d = DateTime::Format::Duration->new(pattern => "%Y $STR{'years'}, %m $STR{'months'}, %e $STR{'days'}, %H $STR{'hours'}, %M $STR{'minutes'}, %S $STR{'seconds'}",
normalize => 1,
base => $oldestDT
);
my $diffInSec = $dt1->subtract_datetime_absolute($dt2);
if ($outputFormat) { # Absolute values
my $val = Time::Seconds->new($diffInSec->{seconds});
if ($outputFormat == 1) { push(@items, abs(int($val->years))); }
elsif ($outputFormat == 2) { push(@items, abs(int($val->months))); }
elsif ($outputFormat == 3) { push(@items, abs(int($val->weeks))); }
elsif ($outputFormat == 4) { push(@items, abs(int($val->days))); }
elsif ($outputFormat == 5) { push(@items, abs(int($val->hours))); }
elsif ($outputFormat == 6) { push(@items, abs(int($val->minutes))); }
elsif ($outputFormat == 7) { push(@items, abs(int($val->seconds))); }
} else { push(@items, $d->format_duration($diffInSec)); } # Output string (normalized)
} else {
if ($noResultOpt) { push(@items, $STR{'errorConversion'}); }
else { push(@items, undef); }
}
} else {
if ($noResultOpt) { push(@items, $STR{'invalidInput'}); }
else { push(@items, undef); }
}
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# 2 = 'Add time' and 3 = 'Substract time'
elsif ($selFunc == 2 or $selFunc == 3) {
my $offsetY = $win->tfDeltaYears->Text();
my $offsetM = $win->tfDeltaMonths->Text();
my $offsetD = $win->tfDeltaDays->Text();
my $offsetH = $win->tfDeltaHours->Text();
my $offsetMin = $win->tfDeltaMinutes->Text();
my $offsetS = $win->tfDeltaSecondes->Text();
my $offset = DateTime::Duration->new(years => $offsetY ,
months => $offsetM ,
days => $offsetD ,
hours => $offsetH ,
minutes => $offsetMin,
seconds => $offsetS , );
foreach my $item (@{$refList1}) {
$item =~ s/[\r\n]//g; # Remove any line break
if ($item) {
my ($epoch, $inputTimezone, $before, $after);
if ($pattern) { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, $pattern, $regex, $parseContext, $timezone); }
else { ($epoch, $inputTimezone, $pattern, $before, $after) = &str2Epoch($item, $sample, undef , undef , $parseContext, undef ); }
if ($epoch == 1) {
if ($noResultOpt) { push(@items, $STR{'invalidInput'}); }
else { push(@items, undef); }
} elsif ($epoch == 2) {
if ($noResultOpt) { push(@items, $STR{'errorConversion'}); }
else { push(@items, undef); }
} elsif ($epoch) {
my $dt = DateTime->from_epoch(epoch => $epoch);
if ($sameAsInput) { $inputTimezone = $localTZ if $inputTimezone eq 'floating'; $dt->set_time_zone($inputTimezone); }
else { $dt->set_time_zone($outputTZ); }
$dt->set(locale => $CONFIG{'DEFAULT_LANG'});
if ($selFunc == 2) { $dt->add_duration($offset); }
else { $dt->subtract_duration($offset); }
# Output
my $newItem;
$newItem .= $before if $before;
if ($sameAsInput) { $newItem .= $dt->strftime($pattern); }
else { $newItem .= $dt->strftime($outPutPattern); }
$newItem .= $after if $after;
push(@items, encode($CONFIG{'OUTPUT_CHARSET'}, $newItem));
}
} else {
if ($noResultOpt) { push(@items, $STR{'noInput'}); }
else { push(@items, undef); }
}
# Progress
$curr++;
$win->lblPbCount->Text("$curr / $nbrItems");
$win->pb->StepIt();
}
}
# Format results
my $itemsRes;
foreach (@items) { $itemsRes .= $_ if $_; $itemsRes .= "\r\n"; }
return(\$itemsRes);
} #--- End timeTabFunc
#--------------------------#
sub cbCFLists_Change
#--------------------------#
{
# Local variables
my $selFuncStr = $win->cbCFLists->GetString($win->cbCFLists->GetCurSel());
if ($selFuncStr and $selFuncStr ne $STR{'cbCFLists'}.'...') {
$win->chCFMatchCase->Show();
$win->btnCFRem->Enable();
$win->btnCFEdit->Enable();
} else {
$win->chCFMatchCase->Hide();
$win->btnCFRem->Disable();
$win->btnCFEdit->Disable();
}
&isProcessReady(0);
} #--- End cbCFLists_Change
#--------------------------#
sub chGeoIPOptAll_Click
#--------------------------#
{
if ($win->chGeoIPOptAll->Checked()) {
for (my $i = 0; $i < 5; $i++) {
$win->gridGeoIPOpts->SetCellCheck(0, $i, 1);
$win->gridGeoIPOpts->SetCellCheck(1, $i, 1);
}
} else {
for (my $i = 0; $i < 5; $i++) {
$win->gridGeoIPOpts->SetCellCheck(0, $i, 0);
$win->gridGeoIPOpts->SetCellCheck(1, $i, 0);
}
}
&isProcessReady(0);
} #--- End chGeoIPOptAll_Click
#--------------------------#
sub chUAOptAll_Click
#--------------------------#
{
if ($win->chUAOptAll->Checked()) {
for (my $i = 0; $i < 3; $i++) {
$win->gridUAOpts->SetCellCheck(0, $i, 1);
$win->gridUAOpts->SetCellCheck(1, $i, 1);
}
} else {
for (my $i = 0; $i < 3; $i++) {
$win->gridUAOpts->SetCellCheck(0, $i, 0);
$win->gridUAOpts->SetCellCheck(1, $i, 0);
}
}
&isProcessReady(0);
} #--- End chUAOptAll_Click
#--------------------------#
sub cbGPS2AddrOutput_Change
#--------------------------#
{
# Local variables
my $selOutput = $win->cbGPS2AddrOutput->GetString($win->cbGPS2AddrOutput->GetCurSel());
if ($selOutput and $selOutput eq $STR{'AddressEl'}) {
$win->gridGPS2AddrOpts->Show();
$win->chAddHeaders->Show();
} else {
$win->gridGPS2AddrOpts->Hide();
$win->chAddHeaders->Hide();
}
&isProcessReady(0);
} #--- End cbGPS2AddrOutput_Change
#--------------------------#
sub gridGeoIPOpts_Click { &isProcessReady(0); }
sub gridGPS2AddrOpts_Click { &isProcessReady(0); }
sub gridUAOpts_Click { &isProcessReady(0); }
sub tfSingleLocation_Change { &isProcessReady(0); }
#--------------------------#
#--------------------------#
sub chSingleLocation_Click
#--------------------------#
{
if ($win->chSingleLocation->Checked()) { &hideList2(); } # Hide List 2
else { &showList2(); } # Show List 2
&isProcessReady(0);
} #--- End chSingleLocation_Click
#--------------------------#
sub btnCFAdd_Click
#--------------------------#
{
# Show OpenFile dialog window
if (my $CFDBFile = Win32::GUI::GetOpenFileName( -owner => $win ,
-title => $STR{'selectDBFile'} ,
-filter => [$STR{'dbFile'}.' - .db', '*.db'] ,
-filemustexist => 1 ,
-explorer => 1 , )) {
if (-f $CFDBFile and &validCFDB($CFDBFile)) {
# Connect to DB
my $dsn = "DBI:SQLite:dbname=$CFDBFile";
if (my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1, AutoCommit => 1 })) {
my $sth = $dbh->prepare("SELECT title FROM TITLE");
my $rv = $sth->execute();
my @fields = $sth->fetchrow_array();
if (scalar(@fields) > 0) {
my $title = join('',@fields);
$sth->finish();
$dbh->disconnect();
# Copy to the Customs folder
my $pathQuoted = quotemeta($USERDIR);
if ($CFDBFile !~ /$pathQuoted\\Customs/) {
mkdir("$USERDIR\\Customs") if !-d "$USERDIR\\Customs";
my $funcFileName = pop @{[split m|\\|, $CFDBFile]};
# Do not overwrite if already exists
if (!-e "$USERDIR\\Customs\\$funcFileName") {
$CFDBFile = "$USERDIR\\Customs\\$funcFileName" if copy($CFDBFile, "$USERDIR\\Customs\\$funcFileName");
}
}
# Verify that the title doesn't already exist
if (&validUniqueCFName($title, \$win)) {
# Update window and config
my $j = 1;
while (exists($CONFIG{'CF'.$j})) { $j++; }
$CONFIG{'CF'.$j} = $title.'|'.$CFDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
$win->cbCFLists->Add($title);
Win32::GUI::MessageBox($win, $STR{'funcAdded'}, "XL-Tools $VERSION", 0x40040);
# Function must be modified
} else {
Win32::GUI::MessageBox($win, $STR{'funcExists'}, $STR{'Warning'}, 0x40030);
&editCF($title, $CFDBFile, \$HOURGLASS, \$ARROW, \$win, \%STR);
}
} else { Win32::GUI::MessageBox($win, $STR{'funcNoTitle'}, $STR{'Error'}, 0x40010); }
} else { Win32::GUI::MessageBox($win, $STR{'errorConnectDB'}, $STR{'Error'}, 0x40010); }
} else { Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010); }
}
return(1);
} #--- End btnCFAdd_Click
#--------------------------#
sub btnCFRem_Click
#--------------------------#
{
# Local variables
my $selFuncStr = $win->cbCFLists->GetString($win->cbCFLists->GetCurSel());
my ($title, $dbFile, $index);
# Ask a confirmation
my $answer = Win32::GUI::MessageBox($win, "$STR{'remConfirm'} \"$selFuncStr\" $STR{'func'}?", $STR{'remConfirmT'}, 0x40024);
if ($answer == 6) {
# Gather path to database
if ($selFuncStr and $selFuncStr ne $STR{'cbCFLists'}.'...') {
my $j = 1;
while (exists($CONFIG{'CF'.$j})) {
my $selFuncStrQuoted = quotemeta($selFuncStr);
if ($CONFIG{'CF'.$j} =~ /$selFuncStrQuoted\|/) {
($title, $dbFile) = split(/\|/, $CONFIG{'CF'.$j});
$index = $j;
delete($CONFIG{'CF'.$j});
&saveConfig(\%CONFIG, $CONFIG_FILE);
last;
}
$j++;
}
# Update index (Ex.: if CF3 is deleted, CF4 becomes CF3, CF5 becomes CF 4 and so on)
$j++;
while (exists($CONFIG{'CF'.$j})) {
my $k = $j-1;
$CONFIG{'CF'.$k} = $CONFIG{'CF'.$j};
$j++;
}
$j--;
delete($CONFIG{'CF'.$j}); # Remove the last one
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
# Remove function from list
$win->cbCFLists->DeleteString($index) if $index;
# Ask confirmation to delete the file
$answer = Win32::GUI::MessageBox($win, "$STR{'delConfirm'}?", $STR{'delConfirmT'}, 0x40024);
# Delete the file
if ($answer == 6) {
unlink($dbFile) if -e $dbFile;
Win32::GUI::MessageBox($win, $STR{'funcDeleted'}, "XL-Tools $VERSION", 0x40040) if !-e $dbFile;
}
$win->cbCFLists->SetCurSel(0);
}
} #--- End btnCFRem_Click
#--------------------------#
sub btnCFEdit_Click
#--------------------------#
{
# Local variables
my $selFuncStr = $win->cbCFLists->GetString($win->cbCFLists->GetCurSel());
my ($title, $dbFile);
# Gather path to database
if ($selFuncStr and $selFuncStr ne $STR{'cbCFLists'}.'...') {
my $j = 1;
while (exists($CONFIG{'CF'.$j})) {
my $selFuncStrQuoted = quotemeta($selFuncStr);
if ($CONFIG{'CF'.$j} =~ /$selFuncStrQuoted\|/) {
($title, $dbFile) = split(/\|/, $CONFIG{'CF'.$j});
last;
}
$j++;
}
&editCF($title, $dbFile, \$HOURGLASS, \$ARROW, \$win, \%STR);
}
} #--- End btnCFEdit_Click
#--------------------------#
sub btnCFNew_Click
#--------------------------#
{
# Show options and message
$win->lblCFTitle->Show();
$win->tfCFTitle->Show();
$win->btnCFSave->Show();
$win->btnCFCancel->Show();
$win->chCFMatchCase->Hide();
$win->cbCFLists->Disable();
$win->btnProcess->Disable();
# Show List 2
&showList2();
} #--- End btnCFNew_Click
#--------------------------#
sub tfCFTitle_Change { &validNewFunc(\$win, \%STR); }
#--------------------------#
#--------------------------#
sub btnCFSave_Click
#--------------------------#
{
threads->create(sub {
# Local variables
my $title = $win->tfCFTitle->Text();
my $refList1 = &enumItems(\$win->tfList1, \$win, \%STR);
my $refList2 = &enumItems(\$win->tfList2, \$win, \%STR);
my $nbrItems1 = scalar(@{$refList1});
my $nbrItems2 = scalar(@{$refList2});
my $dbFile;
my $indexCF;
# Verify if function already exists
my $j = 1;
while (exists($CONFIG{'CF'.$j})) {
my $titleQuoted = quotemeta($title);
if ($CONFIG{'CF'.$j} =~ /$titleQuoted\|/) {
$dbFile = (split(/\|/, $CONFIG{'CF'.$j}))[1];
$indexCF = $j;
last;
}
$j++;
}
# List 1 must not contain duplicates
my %items;
my $containsDuplicate;
foreach my $item (@{$refList1}) {
if (exists($items{$item})) { $containsDuplicate = 1; last; }
else { $items{$item} = 1; }
}
# Error duplicates
if ($containsDuplicate) { Win32::GUI::MessageBox($win, $STR{'CFErrorDupl'}, $STR{'Error'}, 0x40010); }
else {
# If function already exist, confirm replacement
if ($dbFile and -f $dbFile) {
my $answer = Win32::GUI::MessageBox($win, "$STR{'funcExists2'}?", $STR{'replConfirmT'}, 0x40024);
if ($answer == 6) { # If function exists, we modify the database
&modCF($title, $dbFile, $indexCF, $refList1, $refList2, $nbrItems1, $nbrItems2, \$HOURGLASS, \$ARROW,
\$win, \%STR);
} else { return(); } # Cancel
# If function doesn't exist, we create a new one
} else { &newCF($title, $refList1, $refList2, $nbrItems1, $nbrItems2, $USERDIR, \$HOURGLASS, \$ARROW,
\%CONFIG, $CONFIG_FILE, \$win, \%STR); }
# Clean Lists and Hide control
$win->tfCFTitle->Text('');
$win->tfList1->Text('');
$win->tfList2->Text('');
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
$win->cbCFLists->Enable();
$win->btnProcess->Enable();
$win->chCFMatchCase->Show() if $win->cbCFLists->GetCurSel() > 0;
&tfList1_Change();
&tfList2_Change();
# Hide List 2
&hideList2();
}
});
} #--- End btnCFSave_Click
#--------------------------#
sub btnCFCancel_Click
#--------------------------#
{
# Clean Lists and Hide control
$win->tfCFTitle->Text('');
$win->tfList1->Text('');
$win->tfList2->Text('');
$win->lblCFTitle->Hide();
$win->tfCFTitle->Hide();
$win->btnCFSave->Hide();
$win->btnCFCancel->Hide();
$win->cbCFLists->Enable();
$win->btnProcess->Enable();
$win->chCFMatchCase->Show() if $win->cbCFLists->GetCurSel() > 0;
&tfList1_Change();
&tfList2_Change();
# Hide List 2
&hideList2();
} #--- End btnCFCancel_Click
#--------------------------#
sub btnCancel_Click
#--------------------------#
{
# Stop requests
$THR_UPDATE->kill('KILL')->detach() if $THR_UPDATE and $THR_UPDATE->is_running();
return(1);
} #--- End btnCancel_Click
#--------------------------#
sub createCW
#--------------------------#
{
# Create Config Wizard Window
my $winCW = Win32::GUI::DialogBox->new(-name => 'winCW' ,
-parent => $win , # May be open from many Window
-text => $STR{'winCW'} ,
-pos => [$winPosX, $winPosY] ,
-size => [400, 195] ,
-background => [255, 255, 255] ,
-hasmaximize => 0 ,
-hasminimize => 1 ,
-helpbutton => 0 ,
-resizable => 0 ,
-dialogui => 1 , );
$winCW->SetIcon($winICO);
$winCW->AddLabel( -name => 'lblConfigLogo' ,
-size => [128,128] ,
-pos => [ 0, 5] ,
-bitmap => $config128Bmp , );
$winCW->AddLabel( -name => 'lblSetGenOpt' ,
-size => [220, 22] ,
-pos => [140, 10] ,
-font => $font10 ,
-text => $STR{'SetGenOpt'}.'...',
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblSetGenOptDone' ,
-size => [ 20, 20] ,
-pos => [365, 10] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblLocXLWhoisDB' ,
-size => [220, 22] ,
-pos => [140, 30] ,
-font => $font10 ,
-text => "$STR{'Locate'} $STR{'XLWhoisDB'}...",
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblLocXLWhoisDBDone' ,
-size => [ 20, 20] ,
-pos => [365, 30] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblLocXLWhoisDBError',
-size => [ 20, 20] ,
-pos => [365, 30] ,
-bitmap => $errorBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLIINDB' ,
-size => [220, 22] ,
-pos => [140, 50] ,
-font => $font10 ,
-text => "$STR{'Locate'} $STR{'IINDB'}...",
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLIINDBDone' ,
-size => [ 20, 20] ,
-pos => [365, 50] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLIINDBError' ,
-size => [ 20, 20] ,
-pos => [365, 50] ,
-bitmap => $errorBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLDTDB' ,
-size => [220, 22] ,
-pos => [140, 70] ,
-font => $font10 ,
-text => "$STR{'Locate'} $STR{'DTDB'}...",
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLDTDBDone' ,
-size => [ 20, 20] ,
-pos => [365, 70] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLDTDBError' ,
-size => [ 20, 20] ,
-pos => [365, 70] ,
-bitmap => $errorBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLGeoIPDB' ,
-size => [220, 22] ,
-pos => [140, 90] ,
-font => $font10 ,
-text => "$STR{'Locate'} $STR{'GeoIPDB'}...",
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLGeoIPDBDone' ,
-size => [ 20, 20] ,
-pos => [365, 90] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLGeoIPDBError' ,
-size => [ 20, 20] ,
-pos => [365, 90] ,
-bitmap => $errorBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLMACOUIDB' ,
-size => [220, 22] ,
-pos => [140,110] ,
-font => $font10 ,
-text => "$STR{'Locate'} $STR{'MACOUIDB'}...",
-background => [255, 255, 255] ,
-foreground => [ 0, 102, 204] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLMACOUIDBDone' ,
-size => [ 20, 20] ,
-pos => [365,110] ,
-bitmap => $checkBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
$winCW->AddLabel( -name => 'lblDLMACOUIDBError' ,
-size => [ 20, 20] ,
-pos => [365,110] ,
-bitmap => $errorBmp ,
-background => [255, 255, 255] ,
-visible => 0 , );
return(\$winCW);
} #--- End createCW
#--------------------------#
sub firstStart
#--------------------------#
{
# Local variables
my $refWinCW = shift;
# Thread 'cancellation' signal handler
$SIG{'KILL'} = sub {
# Delete temp files if converting was in progress
if (-e $winConfig->tfMACOUIDB->Text().'-journal') {
my $localMACOUIDB = $winConfig->tfMACOUIDB->Text();
unlink($localMACOUIDB.'-journal');
unlink($localMACOUIDB);
}
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
$$refWinCW->Hide();
Win32::GUI::MessageBox($win, $STR{'configSetPart'}, "XL-Tools $VERSION", 0x40040);
threads->exit();
};
# Thread 'die' signal handler
$SIG{__DIE__} = sub {
# Delete temp files if converting was in progress
if (-e $winConfig->tfMACOUIDB->Text().'-journal') {
my $localMACOUIDB = $winConfig->tfMACOUIDB->Text();
unlink($localMACOUIDB.'-journal');
unlink($localMACOUIDB);
}
my $errMsg = (split(/ at /,$_[0]))[0];
chomp($errMsg);
$errMsg =~ s/[\t\r\n]/ /g;
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
$$refWinCW->Hide();
Win32::GUI::MessageBox($win, "$STR{'errorMsg'}: $errMsg", $STR{'Error'}, 0x40010);
};
# Yes (6), No (7)
my $answer = Win32::GUI::MessageBox($win, $STR{'firstStart'}, $STR{'Settings'}, 0x1024);
if ($answer == 6) {
my $dir;
# Use default directory? (program directory)
$answer = Win32::GUI::MessageBox($win, $STR{'defaultDir'}.'('.$USERDIR.')?', $STR{'Settings'}, 0x1024);
# Answer is no, open popup to let user choose a different location
if ($answer == 7) {
# Select a folder
$dir = Win32::GUI::BrowseForFolder( -owner => $$refWinCW ,
-title => $STR{'selectFolder'}.':' ,
-folderonly => 1 ,
-newui => 1 ,
-directory => $USERDIR , );
# Answer is yes, use default dir
} else { $dir = $USERDIR; }
# Selected folder
if ($dir and -d $dir) {
$$refWinCW->Top($win->Top()+5);
$$refWinCW->Left($win->Left()+310);
$$refWinCW->Show();
# Set General options
$$refWinCW->lblSetGenOpt->Show();
# Tool
$winConfig->chAutoUpdate->Checked(1);
$CONFIG{'TOOL_AUTO_UPDATE'} = 1;
# Functions
$winConfig->tfMaxSize->Text(5000000); # Set Max Size (List) to 5 000 000 chars
$CONFIG{'MAX_SIZE_LIST'} = 5000000;
$winConfig->tfLookupTO->Text(10); # Set Nslookup timeout to 10 seconds
$CONFIG{'NSLOOKUP_TIMEOUT'} = 10;
$winConfig->tfUserAgent->Text('XL-Tools (http://www.le-tools.com)'); # Set default User-Agent
$CONFIG{'USERAGENT'} = 'XL-Tools (http://www.le-tools.com)';
$winConfig->rbNoResultOpt1->Checked(1); # Set "When no result" to "Leave a blank"
$winConfig->rbNoResultOpt2->Checked(0);
$winConfig->chMACOUIDBAutoUpt->Checked(0); # Uncheck auto update for MACOUI Database
$CONFIG{'MACOUI_DB_AUTO_UPDATE'} = 0;
&saveConfig(\%CONFIG, $CONFIG_FILE);
$$refWinCW->lblSetGenOptDone->Show();
# Select the XL-Whois DB
my $defaultPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Whois\\Whois.db";
my $XLWHOISDBFile;
$$refWinCW->lblLocXLWhoisDB->Show();
if (-f $defaultPath) { $XLWHOISDBFile = $defaultPath; }
else {
# Is XL-Whois installed on this system?
$answer = Win32::GUI::MessageBox($$refWinCW, $STR{'XLWhoisExists'}.'?', $STR{'Settings'}, 0x1024);
# Answer is yes, select the XL-Whois database
if ($answer == 6) {
$XLWHOISDBFile = Win32::GUI::GetOpenFileName( -title => $STR{'locXLWhoisDB'}.':',
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'Whois.db' ,
-explorer => 1 , );
}
}
if ($XLWHOISDBFile and -f $XLWHOISDBFile) {
$winConfig->tfXLWHOISDB->Text($XLWHOISDBFile);
$CONFIG{'XLWHOIS_DB_FILE'} = $XLWHOISDBFile;
$$refWinCW->lblLocXLWhoisDBDone->Show();
} else { $$refWinCW->lblLocXLWhoisDBError->Show(); }
# Download or select Database files
my ($status, $return);
# Download IINDB Database
$$refWinCW->lblDLIINDB->Show();
$defaultPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Parser\\IIN.db";
if (-f $defaultPath and &validSQLiteDB($defaultPath, 'IIN')) { # Database exists in XL-Parser user dir
$winConfig->tfIINDB->Text($defaultPath);
$$refWinCW->lblDLIINDBDone->Show();
} else {
$$refWinCW->lblDLIINDB->Text("$STR{'Downloading'} $STR{'IINDB'}");
($status, $return) = &downloadDB($refWinCW, 'IIN', $STR{'IINDB'}, "$dir\\IIN.db", 'le-tools.com', \$HOURGLASS,
\$ARROW, \%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { $$refWinCW->lblDLIINDBDone->Show(); } # Success
else { # Error
$$refWinCW->lblDLIINDBError->Show();
Win32::GUI::MessageBox($$refWinCW, $return, $STR{'Error'}, 0x40010);
}
}
if ($return) {
$$refWinCW->lblDLIINDBError->Show();
Win32::GUI::MessageBox($win, $return, $STR{'Error'}, 0x40010);
} else { $$refWinCW->lblDLIINDBDone->Show(); }
&saveConfig(\%CONFIG, $CONFIG_FILE);
# Download DTDB Database
$$refWinCW->lblDLDTDB->Show();
$defaultPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Parser\\DT.db";
if (-f $defaultPath and &validSQLiteDB($defaultPath, 'DT')) { # Valid DTDB in XL-Parser user dir
$winConfig->tfDTDB->Text($defaultPath);
&loadDTDB(\$winDTDB, \$winConfig, \$refWinCW, \%STR);
&cbInputDTFormatAddITems();
$win->cbInputDTFormat->SetCurSel(0);
&cbOutputDTFormatAddITems();
$win->cbOutputDTFormat->SetCurSel(0);
$$refWinCW->lblDLDTDBDone->Show();
} else { # No DTDB, download it
$$refWinCW->lblDLDTDB->Text("$STR{'Downloading'} $STR{'DTDB'}");
($status, $return) = &downloadDB($refWinCW, 'DT', $STR{'DTDB'}, "$dir\\DT.db", 'le-tools.com', \$HOURGLASS, \$ARROW,
\%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { $$refWinCW->lblDLDTDBDone->Show(); } # Success
else { # Error
$$refWinCW->lblDLDTDBError->Show();
Win32::GUI::MessageBox($$refWinCW, $return, $STR{'Error'}, 0x40010);
}
}
my $index = 0;
my $localTZ;
eval { $localTZ = DateTime::TimeZone->new(name => 'local'); }; # Find local timezone
if (!$@) { $index = $winConfig->cbLocalTZ->FindStringExact($localTZ->{name}); }
else { $index = 107; } # Default is America/New_York
$winConfig->cbLocalTZ->SetCurSel($index);
$CONFIG{'LOCAL_TIMEZONE'} = $index;
$winConfig->cbDefaultLang->SetCurSel($winConfig->cbDefaultLang->FindStringExact('en-US')); # Default language to en-US
$CONFIG{'DEFAULT_LANG'} = 'en-US';
$winConfig->cbOutputCharset->SetCurSel(0); # Set default charset to cp1252
$CONFIG{'OUTPUT_CHARSET'} = 'cp1252';
&saveConfig(\%CONFIG, $CONFIG_FILE);
# GeoIP Database
$$refWinCW->lblDLGeoIPDB->Show();
$defaultPath = &findXLTKfile('GeoIPDB');
if (-f $defaultPath and &validGeoIPDB($defaultPath)) {
$winConfig->tfGeoIPDB->Text($defaultPath);
$$refWinCW->lblDLGeoIPDBDone->Show();
} else {
$$refWinCW->lblDLGeoIPDBError->Show();
Win32::GUI::MessageBox($$refWinCW, $return, $STR{'Error'}, 0x40010);
}
# Download MACOUI Database
$$refWinCW->lblDLMACOUIDB->Show();
$defaultPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Parser\\oui.db";
if (-f $defaultPath and &validSQLiteDB($defaultPath, 'MACOUI')) { # Database exists in XL-Parser user dir, check if update available
$winConfig->tfMACOUIDB->Text($defaultPath);
$$refWinCW->lblDLMACOUIDB->Text("$STR{'Update'} $STR{'MACOUIDB'}");
&updateDB(1, 'MACOUI', $STR{'MACOUIDB'}, $winConfig->tfMACOUIDB->Text(), 'ieee.org', 'oui.db', $USERDIR, \$HOURGLASS, \$ARROW,
\%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
$$refWinCW->lblDLMACOUIDBDone->Show();
} else {
$$refWinCW->lblDLMACOUIDB->Text("$STR{'Downloading'} $STR{'MACOUIDB'}");
($status, $return) = &downloadDB($refWinCW, 'MACOUI', $STR{'MACOUIDB'}, "$dir\\oui.db", 'ieee.org', \$HOURGLASS, \$ARROW,
\%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { $$refWinCW->lblDLMACOUIDBDone->Show(); } # Success
else { # Error
$$refWinCW->lblDLMACOUIDBError->Show();
Win32::GUI::MessageBox($$refWinCW, $return, $STR{'Error'}, 0x40010);
}
}
&saveConfig(\%CONFIG, $CONFIG_FILE);
# Close Configuration Wizard
$$refWinCW->Hide();
$win->ChangeCursor($ARROW);
Win32::GUI::MessageBox($win, $STR{'configSet'}, "XL-Tools $VERSION", 0x40040);
}
}
} #--- End firstStart
#--------------------------#
sub findXLTKfile
#--------------------------#
{
my $file = shift;
my $defPath;
if ($file eq 'GeoIPDB') {
if (-e "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Parser\\GeoLite2-City.mmdb") { # In XL-Parser dir
$defPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Parser\\GeoLite2-City.mmdb";
} elsif (-e "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Whois\\GeoLite2-City.mmdb" ) { # In XL-Whois dir
$defPath = "$ENV{'APPDATA'}\\XL-Toolkit\\XL-Whois\\GeoLite2-City.mmdb";
} elsif (-e "$ENV{'PROGRAMDATA'}\\Maxmind\\GeoIPUpdate\\GeoIP\\GeoLite2-City.mmdb" ) { # Default Maxmind GeoIP dir
$defPath = "$ENV{'PROGRAMDATA'}\\Maxmind\\GeoIPUpdate\\GeoIP\\GeoLite2-City.mmdb";
}
return($defPath) if $defPath;
}
return('');
} #--- End findXLTKfile
#--------------------------#
sub btnWinConfig_Click
#--------------------------#
{
# Show Config window with General Tab
$winConfig->configTab->SetCurSel(0);
&configTab_Click;
$winConfig->Center();
$winConfig->DoModal();
} #--- End btnWinConfig_Click
#--------------------------#
sub configTab_Click
#--------------------------#
{
# Show General tab
if (!$winConfig->configTab->SelectedItem()) {
# General tab
$winConfig->lblToolShadowT->Show();
$winConfig->lblToolT->Show();
$winConfig->btnCheckUpdate->Show();
$winConfig->chAutoUpdate->Show();
$winConfig->btnExportLang->Show();
$winConfig->btnOpenUserDir->Show();
$winConfig->lblOptFunctionsShadowT->Show();
$winConfig->lblOptFunctionsT->Show();
$winConfig->chFullScreen->Show();
$winConfig->chRememberPos->Show();
$winConfig->lblMaxSize1->Show();
$winConfig->tfMaxSize->Show();
$winConfig->lblMaxSize2->Show();
$winConfig->btnChooseFont->Show();
$winConfig->lblLocalTZ->Show();
$winConfig->cbLocalTZ->Show();
$winConfig->lblOutputLang->Show();
$winConfig->cbDefaultLang->Show();
$winConfig->lblOutputCharset->Show();
$winConfig->cbOutputCharset->Show();
$winConfig->lblNsLookupTO1->Show();
$winConfig->tfLookupTO->Show();
$winConfig->lblNsLookupTO2->Show();
$winConfig->lblUserAgent->Show();
$winConfig->tfUserAgent->Show();
$winConfig->lblNoResultOpt->Show();
$winConfig->rbNoResultOpt1->Show();
$winConfig->rbNoResultOpt2->Show();
# Databases tab
$winConfig->lblMACOUIDBShadowT->Hide();
$winConfig->lblMACOUIDBT->Hide();
$winConfig->chMACOUIDBAutoUpt->Hide();
$winConfig->tfMACOUIDB->Hide();
$winConfig->btnMACOUIDB->Hide();
$winConfig->btnMACOUIDBUpt->Hide();
$winConfig->lblGeoIPDBShadowT->Hide();
$winConfig->lblGeoIPDBT->Hide();
$winConfig->tfGeoIPDB->Hide();
$winConfig->btnGeoIPDB->Hide();
$winConfig->lblGeoIPNotice->Hide();
$winConfig->lblIINDBShadowT->Hide();
$winConfig->lblIINDBT->Hide();
$winConfig->tfIINDB->Hide();
$winConfig->btnIINDB->Hide();
$winConfig->btnIINDBUpt->Hide();
$winConfig->lblOSMDBShadowT->Hide();
$winConfig->lblOSMDBT->Hide();
$winConfig->tfOSMDB->Hide();
$winConfig->btnOSMDB->Hide();
$winConfig->btnNewOSMDB->Hide();
$winConfig->lblOSMEmail->Hide();
$winConfig->tfOSMEmailDB->Hide();
$winConfig->lblOSMNotice->Hide();
# XL-Toolkit databases tab
$winConfig->lblXLWHOISDBShadowT->Hide();
$winConfig->lblXLWHOISDBT->Hide();
$winConfig->tfXLWHOISDB->Hide();
$winConfig->btnXLWHOISDB->Hide();
$winConfig->lblDTDBShadowT->Hide();
$winConfig->lblDTDBT->Hide();
$winConfig->tfDTDB->Hide();
$winConfig->btnDTDB->Hide();
$winConfig->btnDTDBUpt->Hide();
# Show Databases tab
} elsif ($winConfig->configTab->SelectedItem() == 1) {
# Databases tab
$winConfig->lblMACOUIDBShadowT->Show();
$winConfig->lblMACOUIDBT->Show();
$winConfig->chMACOUIDBAutoUpt->Show();
$winConfig->tfMACOUIDB->Show();
$winConfig->btnMACOUIDB->Show();
$winConfig->btnMACOUIDBUpt->Show();
$winConfig->lblGeoIPDBShadowT->Show();
$winConfig->lblGeoIPDBT->Show();
$winConfig->tfGeoIPDB->Show();
$winConfig->btnGeoIPDB->Show();
$winConfig->lblGeoIPNotice->Show();
$winConfig->lblIINDBShadowT->Show();
$winConfig->lblIINDBT->Show();
$winConfig->tfIINDB->Show();
$winConfig->btnIINDB->Show();
$winConfig->btnIINDBUpt->Show();
$winConfig->lblOSMDBShadowT->Show();
$winConfig->lblOSMDBT->Show();
$winConfig->tfOSMDB->Show();
$winConfig->btnOSMDB->Show();
$winConfig->btnNewOSMDB->Show();
$winConfig->lblOSMEmail->Show();
$winConfig->tfOSMEmailDB->Show();
$winConfig->lblOSMNotice->Show();
# General tab
$winConfig->lblToolShadowT->Hide();
$winConfig->lblToolT->Hide();
$winConfig->btnCheckUpdate->Hide();
$winConfig->chAutoUpdate->Hide();
$winConfig->btnExportLang->Hide();
$winConfig->btnOpenUserDir->Hide();
$winConfig->lblOptFunctionsShadowT->Hide();
$winConfig->lblOptFunctionsT->Hide();
$winConfig->chFullScreen->Hide();
$winConfig->chRememberPos->Hide();
$winConfig->lblMaxSize1->Hide();
$winConfig->tfMaxSize->Hide();
$winConfig->lblLocalTZ->Hide();
$winConfig->cbLocalTZ->Hide();
$winConfig->lblOutputLang->Hide();
$winConfig->cbDefaultLang->Hide();
$winConfig->lblOutputCharset->Hide();
$winConfig->cbOutputCharset->Hide();
$winConfig->lblMaxSize2->Hide();
$winConfig->btnChooseFont->Hide();
$winConfig->lblNsLookupTO1->Hide();
$winConfig->tfLookupTO->Hide();
$winConfig->lblNsLookupTO2->Hide();
$winConfig->lblUserAgent->Hide();
$winConfig->tfUserAgent->Hide();
$winConfig->lblNoResultOpt->Hide();
$winConfig->rbNoResultOpt1->Hide();
$winConfig->rbNoResultOpt2->Hide();
# XL-Toolkit databases tab
$winConfig->lblXLWHOISDBShadowT->Hide();
$winConfig->lblXLWHOISDBT->Hide();
$winConfig->tfXLWHOISDB->Hide();
$winConfig->btnXLWHOISDB->Hide();
$winConfig->lblDTDBShadowT->Hide();
$winConfig->lblDTDBT->Hide();
$winConfig->tfDTDB->Hide();
$winConfig->btnDTDB->Hide();
$winConfig->btnDTDBUpt->Hide();
# Show XL-Toolkit databases tab
} elsif ($winConfig->configTab->SelectedItem() == 2) {
# XL-Toolkit databases tab
$winConfig->lblXLWHOISDBShadowT->Show();
$winConfig->lblXLWHOISDBT->Show();
$winConfig->tfXLWHOISDB->Show();
$winConfig->btnXLWHOISDB->Show();
$winConfig->lblDTDBShadowT->Show();
$winConfig->lblDTDBT->Show();
$winConfig->tfDTDB->Show();
$winConfig->btnDTDB->Show();
$winConfig->btnDTDBUpt->Show();
# General tab
$winConfig->lblToolShadowT->Hide();
$winConfig->lblToolT->Hide();
$winConfig->btnCheckUpdate->Hide();
$winConfig->chAutoUpdate->Hide();
$winConfig->btnExportLang->Hide();
$winConfig->btnOpenUserDir->Hide();
$winConfig->lblOptFunctionsShadowT->Hide();
$winConfig->lblOptFunctionsT->Hide();
$winConfig->chFullScreen->Hide();
$winConfig->chRememberPos->Hide();
$winConfig->lblMaxSize1->Hide();
$winConfig->tfMaxSize->Hide();
$winConfig->lblLocalTZ->Hide();
$winConfig->cbLocalTZ->Hide();
$winConfig->lblOutputLang->Hide();
$winConfig->cbDefaultLang->Hide();
$winConfig->lblOutputCharset->Hide();
$winConfig->cbOutputCharset->Hide();
$winConfig->lblMaxSize2->Hide();
$winConfig->btnChooseFont->Hide();
$winConfig->lblNsLookupTO1->Hide();
$winConfig->tfLookupTO->Hide();
$winConfig->lblNsLookupTO2->Hide();
$winConfig->lblUserAgent->Hide();
$winConfig->tfUserAgent->Hide();
$winConfig->lblNoResultOpt->Hide();
$winConfig->rbNoResultOpt1->Hide();
$winConfig->rbNoResultOpt2->Hide();
# Databases tab
$winConfig->lblMACOUIDBShadowT->Hide();
$winConfig->lblMACOUIDBT->Hide();
$winConfig->chMACOUIDBAutoUpt->Hide();
$winConfig->tfMACOUIDB->Hide();
$winConfig->btnMACOUIDB->Hide();
$winConfig->btnMACOUIDBUpt->Hide();
$winConfig->lblGeoIPDBShadowT->Hide();
$winConfig->lblGeoIPDBT->Hide();
$winConfig->tfGeoIPDB->Hide();
$winConfig->btnGeoIPDB->Hide();
$winConfig->lblGeoIPNotice->Hide();
$winConfig->lblIINDBShadowT->Hide();
$winConfig->lblIINDBT->Hide();
$winConfig->tfIINDB->Hide();
$winConfig->btnIINDB->Hide();
$winConfig->btnIINDBUpt->Hide();
$winConfig->lblOSMDBShadowT->Hide();
$winConfig->lblOSMDBT->Hide();
$winConfig->tfOSMDB->Hide();
$winConfig->btnOSMDB->Hide();
$winConfig->btnNewOSMDB->Hide();
$winConfig->lblOSMEmail->Hide();
$winConfig->tfOSMEmailDB->Hide();
$winConfig->lblOSMNotice->Hide();
}
} #--- End configTab_Click
#--------------------------#
sub btnCheckUpdate_Click { &updateTool(1, $VERSION, \$winConfig, \$win, \%STR); }
#--------------------------#
#--------------------------#
sub chAutoUpdate_Click
#--------------------------#
{
# Save the choice
if ($winConfig->chAutoUpdate->Checked()) {
$CONFIG{'TOOL_AUTO_UPDATE'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'TOOL_AUTO_UPDATE'} = 0;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End chAutoUpdate_Click
#--------------------------#
sub btnExportLang_Click
#--------------------------#
{
# Save strings in Lang.ini
open(LANG, ">$LANG_FILE");
flock(LANG, 2);
foreach my $cle (keys %STR) { print LANG "$cle = $STR{$cle}\n"; }
close(LANG);
$win->ShellExecute('open', $LANG_FILE,'','',1); # Open the page
} #--- End btnExportLang_Click
#--------------------------#
sub btnOpenUserDir_Click
#--------------------------#
{
# Open Window Explorer
Win32::Process::Create(my $ProcessObj, "$ENV{'WINDIR'}\\explorer.exe", "explorer $USERDIR", 0, NORMAL_PRIORITY_CLASS, ".") if -d $USERDIR;
} #--- End btnOpenUserDir_Click
#--------------------------#
sub chFullScreen_Click
#--------------------------#
{
# Save the choice
if ($winConfig->chFullScreen->Checked()) {
$CONFIG{'FULL_SCREEN'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'FULL_SCREEN'} = 0;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End chFullScreen_Click
#--------------------------#
sub chRememberPos_Click
#--------------------------#
{
# Save the choice
if ($winConfig->chRememberPos->Checked()) {
$CONFIG{'REMEMBER_POS'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'REMEMBER_POS'} = 0;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End chRememberPos_Click
#--------------------------#
sub tfMaxSize_Change
#--------------------------#
{
# Remember
if (my $maxSize = $winConfig->tfMaxSize->Text()) {
$CONFIG{'MAX_SIZE_LIST'} = $maxSize;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End tfMaxSize_Change
#--------------------------#
sub btnChooseFont_Click
#--------------------------#
{
# Show Choose Font dialog
my @font = Win32::GUI::ChooseFont(-owner => $winConfig, $fontTF->Info() );
if ($#font) {
$fontTF = new Win32::GUI::Font(@font);
$win->tfList1->Change(-font => $fontTF);
$win->tfList1->Update();
$win->tfList2->Change(-font => $fontTF);
$win->tfList2->Update();
$win->tfList3->Change(-font => $fontTF);
$win->tfList3->Update();
my $customFont;
foreach (@font) { $customFont .= $_ . ','; }
chop($customFont);
$CONFIG{'TFLIST_FONT'} = $customFont;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
return(1);
} #--- End btnChooseFont_Click
#--------------------------#
sub tfLookupTO_Change
#--------------------------#
{
# Local variables
my $lookupTO = $winConfig->tfLookupTO->Text();
# Remember
if ($lookupTO) {
$CONFIG{'NSLOOKUP_TIMEOUT'} = $lookupTO;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End tfLookupTO_Change
#--------------------------#
sub rbNoResultOpt1_Click
#--------------------------#
{
# Save the choice
if ($winConfig->rbNoResultOpt1->Checked()) {
$CONFIG{'NO_RESULT_OPT'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'NO_RESULT_OPT'} = 2;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End rbNoResultOpt1_Click
#--------------------------#
sub rbNoResultOpt2_Click
#--------------------------#
{
# Save the choice
if ($winConfig->rbNoResultOpt1->Checked()) {
$CONFIG{'NO_RESULT_OPT'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'NO_RESULT_OPT'} = 2;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End rbNoResultOpt2_Click
#--------------------------#
sub tfUserAgent_Change
#--------------------------#
{
# Remember
if (my $userAgent = $winConfig->tfUserAgent->Text()) {
$CONFIG{'USERAGENT'} = $userAgent;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End tfUserAgent_Change
#--------------------------#
sub cbLocalTZ_Change
#--------------------------#
{
# Remember
$CONFIG{'LOCAL_TIMEZONE'} = $winConfig->cbLocalTZ->GetCurSel();
&saveConfig(\%CONFIG, $CONFIG_FILE);
} #--- End cbLocalTZ_Change
#--------------------------#
sub cbDefaultLang_Change
#--------------------------#
{
# Remember
$CONFIG{'DEFAULT_LANG'} = $winConfig->cbDefaultLang->GetString($winConfig->cbDefaultLang->GetCurSel());
&saveConfig(\%CONFIG, $CONFIG_FILE);
} #--- End cbDefaultLang_Change
#--------------------------#
sub cbOutputCharset_Change
#--------------------------#
{
# Remember
$CONFIG{'OUTPUT_CHARSET'} = $winConfig->cbOutputCharset->GetString($winConfig->cbOutputCharset->GetCurSel());
&saveConfig(\%CONFIG, $CONFIG_FILE);
} #--- End cbOutputCharset_Change
#--------------------------#
sub cbDefaultOutput_Change
#--------------------------#
{
# Remember
$CONFIG{'DEFAULT_OUTPUT'} = $winDTDB->cbDefaultOutput->GetCurSel();
&saveConfig(\%CONFIG, $CONFIG_FILE);
} #--- End cbDefaultOutput_Change
#--------------------------#
sub chMACOUIDBAutoUpt_Click
#--------------------------#
{
# Save the choice
if ($winConfig->chMACOUIDBAutoUpt->Checked() == 1) {
$CONFIG{'MACOUI_DB_AUTO_UPDATE'} = 1;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
$CONFIG{'MACOUI_DB_AUTO_UPDATE'} = 0;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End chMACOUIDBAutoUpt_Click
#--------------------------#
sub tfMACOUIDB_Change
#--------------------------#
{
# Local variables
my $MACOUIDBFile = $winConfig->tfMACOUIDB->Text();
# Remember
if ($MACOUIDBFile and -f $MACOUIDBFile and &validSQLiteDB($MACOUIDBFile, 'MACOUI')) {
$CONFIG{'MACOUI_DB_FILE'} = $MACOUIDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'MACOUI_DB_FILE'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($MACOUIDBFile) {
$winConfig->tfMACOUIDB->Text('');
Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START;
}
}
} #--- End tfMACOUIDB_Change
#--------------------------#
sub btnMACOUIDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfMACOUIDB->Text();
my $MACOUIDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my(@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$MACOUIDBFile = Win32::GUI::GetOpenFileName(-owner => $winConfig ,
-title => $STR{'selectDBFile'}.':',
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'OUI.db' ,
-explorer => 1 , );
} else {
$MACOUIDBFile = Win32::GUI::GetOpenFileName(-owner => $winConfig ,
-title => $STR{'selectDBFile'}.':',
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'OUI.db' ,
-explorer => 1 , );
}
# Selected file
$winConfig->tfMACOUIDB->Text($MACOUIDBFile) if $MACOUIDBFile and -f $MACOUIDBFile;
return(1);
} #--- End btnMACOUIDB_Click
#--------------------------#
sub btnMACOUIDBUpt_Click
#--------------------------#
{
if ($THR_UPDATE and $THR_UPDATE->is_running()) { Win32::GUI::MessageBox($win, $STR{'processRunning'}, $STR{'Error'}, 0x40010); }
else {
$THR_UPDATE = threads->create(sub {
# Thread 'cancellation' signal handler
$SIG{'KILL'} = sub {
# Delete temp files if converting was in progress
if (-e $winConfig->tfMACOUIDB->Text().'-journal') {
my $localMACOUIDB = $winConfig->tfMACOUIDB->Text();
unlink($localMACOUIDB.'-journal');
unlink($localMACOUIDB);
}
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
threads->exit();
};
# Thread 'die' signal handler
$SIG{__DIE__} = sub {
# Delete temp files if converting was in progress
if (-e $winConfig->tfMACOUIDB->Text().'-journal') {
my $localMACOUIDB = $winConfig->tfMACOUIDB->Text();
unlink($localMACOUIDB.'-journal');
unlink($localMACOUIDB);
}
my $errMsg = (split(/ at /,$_[0]))[0];
chomp($errMsg);
$errMsg =~ s/[\t\r\n]/ /g;
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
Win32::GUI::MessageBox($win, "$STR{'errorMsg'}: $errMsg", $STR{'Error'}, 0x40010);
};
&updateDB(1, 'MACOUI', $STR{'MACOUIDB'}, $winConfig->tfMACOUIDB->Text(), 'ieee.org', 'oui.db', $USERDIR, \$HOURGLASS, \$ARROW,
\%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
});
}
return(1);
} #--- End btnMACOUIDBUpt_Click
#--------------------------#
sub tfGeoIPDB_Change
#--------------------------#
{
# Local variables
my $GeoIPDBFile = $winConfig->tfGeoIPDB->Text();
# Remember
if ($GeoIPDBFile and -f $GeoIPDBFile and &validGeoIPDB($GeoIPDBFile)) {
$CONFIG{'GEOIP_DB_FILE'} = $GeoIPDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'GEOIP_DB_FILE'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($GeoIPDBFile) {
$winConfig->tfGeoIPDB->Text('');
Win32::GUI::MessageBox($winConfig, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START;
}
}
} #--- End tfGeoIPDB_Change
#--------------------------#
sub btnGeoIPDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfGeoIPDB->Text();
my $GeoIPDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my(@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$GeoIPDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.mmdb)', '.mmdb'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'GeoLite2-City.mmdb' ,
-explorer => 1 , );
} else {
$GeoIPDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.mmdb)', '.mmdb'],
-filemustexist => 1 ,
-file => 'GeoLite2-City.mmdb' ,
-explorer => 1 , );
}
# Selected file
$winConfig->tfGeoIPDB->Text($GeoIPDBFile) if $GeoIPDBFile and -f $GeoIPDBFile;
return(1);
} #--- End btnGeoIPDB_Click
#--------------------------#
sub tfXLWHOISDB_Change
#--------------------------#
{
# Local variables
my $XLWHOISDBFile = $winConfig->tfXLWHOISDB->Text();
# Remember
if ($XLWHOISDBFile and -f $XLWHOISDBFile and &validSQLiteDB($XLWHOISDBFile, 'WHOIS_DB')) {
$CONFIG{'XLWHOIS_DB_FILE'} = $XLWHOISDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'XLWHOIS_DB_FILE'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($XLWHOISDBFile) {
$winConfig->tfXLWHOISDB->Text('');
Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START;
}
}
} #--- End tfXLWHOISDB_Change
#--------------------------#
sub btnXLWHOISDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfXLWHOISDB->Text();
my $XLWHOISDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my(@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$XLWHOISDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'Whois.db' ,
-explorer => 1 , );
} else {
$XLWHOISDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'Whois.db' ,
-explorer => 1 , );
}
# Selected file
$winConfig->tfXLWHOISDB->Text($XLWHOISDBFile);
return(1);
} #--- End btnXLWHOISDB_Click
#--------------------------#
sub tfIINDB_Change
#--------------------------#
{
# Local variables
my $IINDBFile = $winConfig->tfIINDB->Text();
# Remember
if ($IINDBFile and -f $IINDBFile and &validSQLiteDB($IINDBFile, 'IIN')) {
$CONFIG{'IIN_DB_FILE'} = $IINDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'IIN_DB_FILE'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($IINDBFile) {
$winConfig->tfIINDB->Text('');
Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START;
}
}
} #--- End tfIINDB_Change
#--------------------------#
sub btnIINDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfIINDB->Text();
my $IINDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my(@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$IINDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'IIN.db' ,
-explorer => 1 , );
} else {
$IINDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'IIN.db' ,
-explorer => 1 , );
}
# Selected file
if ($IINDBFile and -f $IINDBFile) {
$winConfig->tfIINDB->Text($IINDBFile);
$CONFIG{'IIN_DB_FILE'} = $IINDBFile;
}
return(1);
} #--- End btnIINDB_Click
#--------------------------#
sub btnIINDBUpt_Click
#--------------------------#
{
if ($THR_UPDATE and $THR_UPDATE->is_running()) { Win32::GUI::MessageBox($win, $STR{'processRunning'}, $STR{'Error'}, 0x40010); }
else {
$THR_UPDATE = threads->create(sub {
# Thread 'cancellation' signal handler
$SIG{'KILL'} = sub {
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
threads->exit();
};
# Thread 'die' signal handler
$SIG{__DIE__} = sub {
my $errMsg = (split(/ at /,$_[0]))[0];
chomp($errMsg);
$errMsg =~ s/[\t\r\n]/ /g;
$win->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
Win32::GUI::MessageBox($win, "$STR{'errorMsg'}: $errMsg", $STR{'Error'}, 0x40010);
};
my ($status, $return) = &downloadDB(\$winConfig, 'IIN', $STR{'IINDB'}, "$USERDIR\\IIN.db", 'le-tools.com', \$HOURGLASS,
\$ARROW, \%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { Win32::GUI::MessageBox($winConfig, "$STR{'IINDB'} $STR{'HasBeenUpdated'}", "XL-Tools $VERSION", 0x40040); }
else { Win32::GUI::MessageBox($winConfig, $return, $STR{'Error'}, 0x40010); }
});
}
return(1);
} #--- End btnIINDBUpt_Click
#--------------------------#
sub tfOSMDB_Change
#--------------------------#
{
# Local variables
my $OSMDBFile = $winConfig->tfOSMDB->Text();
# Remember
if ($OSMDBFile and -f $OSMDBFile and &validSQLiteDB($OSMDBFile, 'GPS2ADDR')) {
$CONFIG{'OSM_DB'} = $OSMDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'OSM_DB'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($OSMDBFile) {
$winConfig->tfOSMDB->Text('');
Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START == 1;
}
}
} #--- End tfOSMDB_Change
#--------------------------#
sub btnOSMDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfOSMDB->Text();
$lastDir = $USERDIR if !$lastDir and $USERDIR;
my $OSMDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my (@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$OSMDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':',
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'OSM.db' ,
-explorer => 1 , );
} else {
$OSMDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':',
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'OSM.db' ,
-explorer => 1 , );
}
# Selected file
$winConfig->tfOSMDB->Text($OSMDBFile) if $OSMDBFile and -f $OSMDBFile;
return(1);
} #--- End btnOSMDB_Click
#--------------------------#
sub btnNewOSMDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfOSMDB->Text();
$lastDir = $USERDIR if !$lastDir and $USERDIR;
my $OSMDBFile;
# Show SaveFileWindow for database
if ($lastDir) {
my (@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$OSMDBFile = Win32::GUI::GetSaveFileName( -owner => $winConfig ,
-title => $STR{'selPathDB'}.':' ,
-file => 'OSM.db' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-directory => $lastDir ,
-overwriteprompt => 1 , );
} else {
$OSMDBFile = Win32::GUI::GetSaveFileName( -owner => $winConfig ,
-title => $STR{'selPathDB'}.':' ,
-file => 'OSM.db' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-overwriteprompt => 1 , );
}
if ($OSMDBFile and &createOSMDB($OSMDBFile)) {
my $dbFolder = $OSMDBFile;
while ($dbFolder =~ /[^\\]$/) { chop($dbFolder); }
mkdir("$dbFolder\\osm") if !-d "$dbFolder\\osm"; # Create subfolder for JSON file
Win32::GUI::MessageBox($winConfig, $STR{'createdDB'}, $STR{'OSMDB'}, 0x40040);
$winConfig->tfOSMDB->Text($OSMDBFile);
}
return(1);
} #--- End btnNewOSMDB_Click
#--------------------------#
sub createOSMDB
#--------------------------#
{
# Local variables
my $OSMDBFile = shift;
# Create a new database
$OSMDBFile = encode('utf8', $OSMDBFile);
my $dsn = "DBI:SQLite:dbname=$OSMDBFile";
my $dbh = DBI->connect($dsn, undef, undef, { RaiseError => 1, AutoCommit => 1 }) or return(0);
# Create main table
# Bounding box: lat_s, lat_n, lon_w, lon_e
# Original query: lat, lon
my $stmt = qq(CREATE TABLE IF NOT EXISTS GPS2ADDR
(lat REAL NOT NULL,
lon REAL NOT NULL,
lat_s REAL NOT NULL,
lat_n REAL NOT NULL,
lon_w REAL NOT NULL,
lon_e REAL NOT NULL,
zoom_level TEXT NOT NULL,
jsonFile TEXT NOT NULL,
PRIMARY KEY (lat, lon, zoom_level)));
my $rv = $dbh->do($stmt);
$dbh->disconnect();
return(0) if $rv < 0;
return(1);
} #--- End createOSMDB
#--------------------------#
sub tfOSMEmailDB_Change
#--------------------------#
{
# Remember
if (my $email = $winConfig->tfOSMEmailDB->Text()) {
$CONFIG{'EMAIL'} = $email;
&saveConfig(\%CONFIG, $CONFIG_FILE);
}
} #--- End tfUserAgent_Change
#--------------------------#
sub tfDTDB_Change
#--------------------------#
{
# Local variables
my $DTDBFile = $winConfig->tfDTDB->Text();
# Remember
if ($DTDBFile and -f $DTDBFile and &validSQLiteDB($DTDBFile, 'DT')) {
$CONFIG{'DT_DB_FILE'} = $DTDBFile;
&saveConfig(\%CONFIG, $CONFIG_FILE);
} else {
delete($CONFIG{'DT_DB_FILE'});
&saveConfig(\%CONFIG, $CONFIG_FILE);
if ($DTDBFile) {
$winConfig->tfDTDB->Text('');
Win32::GUI::MessageBox($win, $STR{'invalidFile'}, $STR{'Error'}, 0x40010) if $START;
}
}
} #--- End tfDTDB_Change
#--------------------------#
sub btnDTDB_Click
#--------------------------#
{
# Local variables
my $lastDir = $winConfig->tfDTDB->Text();
my $DTDBFile;
# Show OpenFile dialog window
if ($lastDir) {
my(@parts) = split(/\\/, $lastDir);
if (pop(@parts) =~ /\./) { while ($lastDir =~ /[^\\]$/) { chop($lastDir); } }
$DTDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-directory => $lastDir ,
-file => 'DT.db' ,
-explorer => 1 , );
} else {
$DTDBFile = Win32::GUI::GetOpenFileName( -owner => $winConfig ,
-title => $STR{'selectDBFile'}.':' ,
-filter => [$STR{'dbFile'}.' (*.db)', '.db'],
-filemustexist => 1 ,
-file => 'DT.db' ,
-explorer => 1 , );
}
# Selected file
if ($DTDBFile and -f $DTDBFile) {
$winConfig->tfDTDB->Text($DTDBFile);
$CONFIG{'DT_DB_FILE'} = $DTDBFile;
}
return(1);
} #--- End btnDTDB_Click
#--------------------------#
sub btnDTDBUpt_Click
#--------------------------#
{
if ($THR_UPDATE and $THR_UPDATE->is_running()) { Win32::GUI::MessageBox($winConfig, $STR{'processRunning'}, $STR{'Error'}, 0x40010); }
else {
$THR_UPDATE = threads->create(sub {
# Thread 'cancellation' signal handler
$SIG{'KILL'} = sub {
$winConfig->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
threads->exit();
};
# Thread 'die' signal handler
$SIG{__DIE__} = sub {
my $errMsg = (split(/ at /,$_[0]))[0];
chomp($errMsg);
$errMsg =~ s/[\t\r\n]/ /g;
$winConfig->ChangeCursor($ARROW);
# Turn off progress bar
$winPb->lblPbCurr->Text('');
$winPb->lblCount->Text('');
$winPb->pbWinPb->SetPos(0);
$winPb->Hide();
Win32::GUI::MessageBox($winConfig, "$STR{'errorMsg'}: $errMsg", $STR{'Error'}, 0x40010);
};
my ($status, $return) = &downloadDB(\$winConfig, 'DT', $STR{'DTDB'}, "$USERDIR\\DT.db", 'le-tools.com', \$HOURGLASS,
\$ARROW, \%CONFIG, $CONFIG_FILE, \$winConfig, \$winDTDB, \$winPb, \$win, \%STR);
if ($status) { Win32::GUI::MessageBox($winConfig, "$STR{'DTDB'} $STR{'HasBeenUpdated'}", "XL-Tools $VERSION", 0x40040); }
else { Win32::GUI::MessageBox($winConfig, $return, $STR{'Error'}, 0x40010); }
});
}
return(1);
} #--- End btnDTDBUpt_Click