################################################################################
#-- NAME:      KJV_Bible_SDBM.pl (or compiled to .exe)
#--
#-- AUTHOR:    Eric Hansen  U.S.A
#--
#-- DATE:      August 29, 2017
#--
#-- LANGUAGE:  Win32 Perl - ActiveState ActivePerl v5.6.1, binary build 638
#--            Win32 GUI Module (by Aldo Calpini) release 1.02
#--
#-- COMPILER:  IndigoSTAR Perl2EXE v5.03, Win32 Perl Application Compiler
#--
#-- FUNCTION:  KJV Bible Navigator Software. FlatFile/SDBM Database Version.
#--            DB User-Interface is a TreeView/RichEdit set of GUI widgets.
#--
#-- DATABASE:  3 input Files (JOINT DATABASE TECHNOLOGY - ISAM/NoSQL):
#--
#--            KJV_Bible_SDBM.dat (16,037 KB) Fixed-length(528 characters)
#--                records (no CR/LF), Flat File of 31102 KJV Bible verses
#--                extracted from a total of 66 books and 1189 chapters.
#--            KJV_Bible_SDBM.dir (4 KB)   SDBM Binary File (part 1 of 2)
#--            KJV_Bible_SDBM.pag (128 KB) SDBM Binary File (part 2 of 2)
#--                Both used for random access indexing within the Flat File
#--                to the byte offset of the first verse within each chapter.
#--                Verses within a Chapter are read sequentially from there.
#--            These 3 files (named as shown) must reside in the application
#--                directory with program file KJV_Bible_SDBM.pl or .exe
#--                if compiled to a standalone executable.
#--
#-- OUTPUT:    KJV_Bible_Genesis_Chp_3.rtf would be a Rich Edit (Wordpad) output
#--            file created in the Program/Application DIR containing all the
#--            verses for the Book of Genesis, Chapter 3. This output file is
#--            automatically created for each Book&Chapter the end-user selects.
#--
#-- HASH:      Format of SDBM tied to hash table BibleIDX (for Books 1 to 66)
#--            KEY         VALUE              DESCRIPTION
#--            =============================================================
#--            ...
#--            10          II Samuel,2Sa,24   Bk10 = name,abbrev,nbr_chps
#--            10|1        4236144,27         Bk10|Chp1  = offset,nbr_verses
#--            ...
#--            10|10       4351248,19         Bk10|Chp10 = offset,nbr_verses
#--            ...
#--            10|24       4589904,25         Bk10|Chp24 = offset,nbr_verses
#--            ...
#--
#-- ABORTED:   Should the program abort, run from a command prompt to see error.
#--            This would most likely occur if one or more of the 3 database
#--            files are missing from the application directory, or they have
#--            been renamed.
#--
#-- NO VERSES
#--  DISPLAY:  If you do not see Bible verses displayed in the RichEdit widget
#--            after you have DBL-clicked your mouse on a particular chapter
#--            within the TreeView widget, it is likely due to the associated
#--            *.rtf output file already existing and having been manually
#--            set to a READ ONLY status. If the file exists, it must have
#--            WRITE permission. An Error Msg Box will pop up on the screen.
#--            To correct this problem, either delete or rename the
*.rtf file.
#--            If you wish to write personal notes within any of the *.rtf
#--            files generated, and prevent them from being stepped on
#--            (i.e. overwritten), then instead of making the file(s) READ ONLY,
#--            simply rename them.   Example:
#--            KJV_Bible_Genesis_Chp_3.rtf to
KJV_Bible_Genesis_Chp3_Edited.rtf
#--            Or, you can make a subdirectory and store your edited files there
################################################################################
use Win32;
use Win32::GUI;     #-- module extension by Aldo Calpini. Native Windows GUI.
use IO::Handle;
use SDBM_File;
use Fcntl;
use Win32API::File 0.08 qw( :ALL );

$SFont = new Win32::GUI::Font(
    -name => "Courier New",
    -size => 8,
    -height => -11,
    -weight => 700
);

$M1 = new Win32::GUI::Menu(
    "&File"      => "File1",
    " > &Exit"  => "Exit1",
    "&Help"     => "Help1",
    " > &About" => "About1",
);

$W1 = new Win32::GUI::Window (
    -title    => "KJV Bible Navigator (FlatFile/SDBM Database Version)",
    -menu     => $M1,
    -name     => "Window1",
    -minsize  => [400, 200],
);

$TV = $W1->AddTreeView (
    -name => "TV",
    -font => $SFont,
    -left      => 10,
    -top       => 5,
    -width     => 180,
    -height    => $W1->ScaleHeight()-10,
    -lines     => 0,
    -rootlines => 1,
    -buttons   => 1,
    -visible   => 1,
    -checkboxes => 0,
    -onMouseDblClick => \&TVDblClick,
);

$RE = $W1->AddRichEdit(
    -name => "RE",
    -height => $W1->ScaleHeight()-10,
    -width  => $W1->ScaleWidth()-205,
    -wrap => 1,
    -top   => 5,
    -left  => 195,
    -style  => WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE,
    -readonly => 1,
);

########################
########################
###  Initialization  ###
########################
########################
$DOS = Win32::GUI::GetPerlWindow();
Win32::GUI::Hide($DOS);

$PWD=Win32::GetCwd(); #-- program(p)/current(c) working(w) directory(d) location

$W1->Show();
$W1->Maximize();
Window1_Maint();

Database_Connect();
Load_TreeView();

$W1->Maximize();
Window1_Maint();

#######################
#######################
###  Event Handler  ###
#######################
#######################
Win32::GUI::Dialog();  #-- Enter event handler, and wait for end-user responses

#-- Logical End-of-Program is Here, although the END{} routine is performed last
#-- as cleanup.

################################################################################
################################################################################
############                     SUBROUTINES                        ############
################################################################################
################################################################################

######################
sub Database_Connect {
######################
$hFILE = createFile("$PWD\\KJV_Bible_SDBM.dat", "r");
unless ( $hFILE ) {
  die "Can't open Flat File: $PWD\\KJV_Bible_SDBM.dat (ERROR: ",
      fileLastError(),")\n";
}
tie( %BibleIDX, "SDBM_File", '.\KJV_BIBLE_SDBM', O_RDONLY, 0444 );
unless ( tied %BibleIDX ) {
  die "Can't tie hash tbl to SDBM Files: $PWD\\KJV_Bible_SDBM.pag (& .dir) $!";
}
}

###################
sub Load_TreeView {
###################
$TV->Clear();       $RE->Text("");
for my $bk (1 .. 66) {
  my ($name, $short_name, $nbr_chps) = split(/,/,$BibleIDX{$bk});
  my $node = $TV->InsertItem(-text => "$bk:$name");   #-- insert a Parent node
  for my $chp (1 .. $nbr_chps) {
    Win32::GUI::DoEvents();   #-- keep window from perhaps freezing up
    my $key = $bk . "|" . $chp;
    my ($offset, $nbr_vers) = split(/,/,$BibleIDX{$key});
    $TV->InsertItem(-parent => $node, -text => "$short_name $chp:1-$nbr_vers");
  }
}
}

###################
sub Window1_Maint {
###################
#-- Perform some Window Maintenance.  A bit redundant (and overkill?) perhaps.
#-- Not sure how much of this is necessary?  Better safe than sorry.
#-- Does not hurt performance.
$W1->BringWindowToTop();    #-- Brings window to the foreground
$W1->SetForegroundWindow(); #-- Brings window to the foreground
$W1->SetActiveWindow();     #-- Activates window
$W1->Redraw(1);             #-- Same as InvalidateRect
$W1->InvalidateRect(1);     #-- Redraw the Window
$W1->Update();              #-- similar to Redraw and InvalidateRect
$W1->SetFocus();
}

################################################################################
################################################################################
############                        EVENTS                       ###############
################################################################################
################################################################################

################
sub TVDblClick {
################
my ($self, $x, $y) = @_;
my $node = $self->HitTest($x,$y);
$self->Select($node);

my $parent_node = $self->GetParent($node);
if ($node == 0 || $parent_node == 0) {
   return;
}

$RE->Text("");

my %parentinfo = $self->ItemInfo($parent_node);
my ($bk, $bkname) = split(/:/,$parentinfo{-text});

my %nodeinfo = $self->ItemInfo($node);
my ($abbrev, $string) = split(/ /,$nodeinfo{-text});
my ($chp, $range) = split(/:/,$string);

my $outputfile="$PWD\\KJV_Bible_" . $bkname . "_Chp_" . $chp . ".rtf";
my $ret=0;

open(BibleRTF,"> $outputfile") || do {$ret=1;};
if (! $ret) {
   BibleRTF->autoflush(1);  #-- flush the output buffer each print
} else {
   Win32::GUI::MessageBox($W1,"Can't open file\n$outputfile\nfor output\n$!",
         "KJV Bible Navigator - Error",16,);
   return;
}

print BibleRTF '{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033'
             . '{\fonttbl{\f0\fswiss\fcharset0 Tahoma;}}'
             . '{\colortbl ;\red255\green0\blue0;}'
             . '\viewkind4\uc1\pard\f0\fs18' . "\n";

my $key=$bk . "|" . $chp;
my ($offset, $nbr_verses) = split(/,/,$BibleIDX{$key});
my $rec = "Hello Dolly";   my $txt = "Hello Dolly";

for (my $ver=1;$ver<=$nbr_verses;$ver++) {

   Win32::GUI::DoEvents();     #-- keep window from perhaps freezing up

   if ($ver == 1) {
     my $pos=SetFilePointer( $hFILE, $offset, [], FILE_BEGIN); #-- random access
     unless ( $pos ) {
       my $error = fileLastError();
       my $msg = "Can't set file pointer at byte offset $offset within:\n" .
                "$PWD\\KJV_Bible_SDBM.dat" .
                "\nat Book of $bkname chapter $chp verse $ver\n" . $error;
       Win32::GUI::MessageBox($W1,$msg,"KJV Bible Navigator - Error",16,);
       last;
     }
   }

   $ret = ReadFile( $hFILE, $rec, 528, [], [] ); #-- sequential access
   unless ( $ret ) {
      my $error = fileLastError();
      my $msg = "Can't read input file:\n" . "$PWD\\KJV_Bible_SDBM.dat" .
                "\nat Book of $bkname chapter $chp verse $ver\n" . $error;
      Win32::GUI::MessageBox($W1,$msg,"KJV Bible Navigator - Error",16,);
      last;
   }

   #-- Next, we want to trim the length of $rec before printing.
   #-- Buffer $rec is initialized to fixed-length 528, and can't be trimmed.

   $txt=sprintf("%s", $rec); #-- required step in removing trailing spaces
   $txt=~s/  *$//; #-- remove trailing spaces      or you can ...
   $txt=~s/\s+$//; #-- remove trailing spaces (redundant here just to show)
  #$txt=~s/^\s+//; #-- if we had needed to remove leading spaces, if any

  #print BibleRTF '\ul\b\i0\highlight1 '
   print BibleRTF '\ul\b0\i\highlight0 '
        . "$bkname $chp:$ver (KJV)"
        . '\par\ulnone\b\i0\highlight0' . $txt . '\par\par' . "\n";
}

print BibleRTF '}' . "\n";
close(BibleRTF);
$RE->Load("$outputfile");

#-- Perform some Window Maintenance.
#-- We don't want to Maximize Window because end-user may have adjusted size.
Window1_Maint();
}

##################
sub About1_Click {
##################
my $about_text="Written by Eric Hansen, U.S.A., August 29, 2017\n" .
   "In the Win32 PERL language - ActiveState ActivePerl v5.6.1, build 638\n" .
   "Compiled with the IndigoSTAR Perl2Exe compiler v5.03\n" .
   "Perl Win32-GUI module (by Aldo Calpini) release 1.02\n" .
   "Expand a Book, then DblClick a Chapter to view it.\n" .
   "Close this message box to proceed.";
my $about = "About - KJV Bible Navigator - FlatFile/SDBM Database Version";
Win32::GUI::MessageBox($W1,$about_text,$about,64,);
}

#################
sub Exit1_Click {
#################
return -1;               #-- stops the event handler and exits
}

#######################
sub Window1_Terminate {
#######################
return -1;               #-- stops the event handler and exits
}

####################
sub Window1_Resize {
####################
my $width  = $W1->ScaleWidth();
my $height = $W1->ScaleHeight();
$TV->Resize(180,$height-10);
$RE->Resize($width-205,$height-10);
}

#####
END {
#####
CloseHandle($hFILE);   untie(%BibleIDX);   close(BibleRTF);
Win32::GUI::Show($DOS);
return -1;               #-- stops the event handler and exits
}

=====================================================================

======================================================================

ALTERNATE TreeView Double Click Event to replace the ORIGINAL:

################
sub TVDblClick {
################
my ($self, $x, $y) = @_;
my $node = $self->HitTest($x,$y);
$self->Select($node);

my $parent_node = $self->GetParent($node);
if ($node == 0 || $parent_node == 0) {
   return;
}

$RE->Text("");

my %parentinfo = $self->ItemInfo($parent_node);
my ($bk, $bkname) = split(/:/,$parentinfo{-text});

my %nodeinfo = $self->ItemInfo($node);
my ($abbrev, $string) = split(/ /,$nodeinfo{-text});
my ($chp, $range) = split(/:/,$string);

my $outputfile="$PWD\\KJV_Bible_" . $bkname . "_Chp_" . $chp . ".rtf";
my $ret=0;

open(BibleRTF,"> $outputfile") || do {$ret=1;};
if (! $ret) {
   BibleRTF->autoflush(1);  #-- flush the output buffer each print
} else {
   Win32::GUI::MessageBox($W1,"Can't open file\n$outputfile\nfor output\n$!",
         "KJV Bible Navigator - Error",16,);
   return;
}

my $key=$bk . "|" . $chp;
my ($offset, $nbr_verses) = split(/,/,$BibleIDX{$key});

my $pos=SetFilePointer( $hFILE, $offset, [], FILE_BEGIN); #-- random access
unless ( $pos ) {
   my $error = fileLastError();
   my $msg = "Can't set file pointer at byte offset $offset within:\n" .
             "$PWD\\KJV_Bible_SDBM.dat" .
             "\nat Book of $bkname chapter $chp verse 1\n" . $error;
   Win32::GUI::MessageBox($W1,$msg,"KJV Bible Navigator - Error",16,);
   close(BibleRTF);
   return;
}

my $BIB_Tmpl = "";  #-- build a template to unpack an entire chapter of verses
for (my $i=1; $i<= $nbr_verses; $i++) {
   $BIB_Tmpl = $BIB_Tmpl . "A528, ";
}
chop $BIB_Tmpl;   chop $BIB_Tmpl;   #-- remove trailing ", "
$nbr_chars=(528 * $nbr_verses);

my $buff = "Hello Dolly";
$ret=ReadFile( $hFILE, $buff, $nbr_chars, [], [] ); #-- read in a whole chapter
unless ( $ret ) {
   my $error = fileLastError();
   my $msg = "Can't read input file:\n" . "$PWD\\KJV_Bible_SDBM.dat" .
       "\nat Book of $bkname chapter $chp verses 1 to $nbr_verses\n" . $error;
   Win32::GUI::MessageBox($W1,$msg,"KJV Bible Navigator - Error",16,);
   close(BibleRTF);
   return;
}

my @verses=();
@verses=unpack($BIB_Tmpl,$buff);

print BibleRTF '{\rtf1\ansi\ansicpg1252\deff0\deflang1033\deflangfe1033'
             . '{\fonttbl{\f0\fswiss\fcharset0 Tahoma;}}'
             . '{\colortbl ;\red255\green0\blue0;}'
             . '\viewkind4\uc1\pard\f0\fs18' . "\n";

for (my $j=0; $j<$nbr_verses; $j++) {
   Win32::GUI::DoEvents();     #-- keep window from perhaps freezing up
   $verses[$j]=~s/ *$//;       #-- remove trailing spaces from ea. verse
   $ver=$j+1;
  #print BibleRTF '\ul\b\i0\highlight1 '
   print BibleRTF '\ul\b0\i\highlight0 '
        . "$bkname $chp:$ver (KJV)"
        . '\par\ulnone\b\i0\highlight0' . $verses[$j] . '\par\par' . "\n";
}

print BibleRTF '}' . "\n";
close(BibleRTF);
$RE->Load("$outputfile");

#-- Perform some Window Maintenance.
#-- We don't want to Maximize Window because end-user may have adjusted size.
Window1_Maint();
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
http://perl-win32-gui.sourceforge.net/

Reply via email to