[BACK]Return to wxkeyring CVS log [TXT][DIR] Up to [local] / palm / Palm-Keyring / examples

File: [local] / palm / Palm-Keyring / examples / Attic / wxkeyring (download)

Revision 1.2, Thu Feb 1 04:44:55 2007 UTC (17 years, 5 months ago) by andrew
Branch: MAIN
Changes since 1.1: +85 -75 lines

Now it "works" with mine.  The clipboard still has "trouble"

#!/usr/bin/perl -w -- 
# generated by wxGlade 0.4.1cvs on Fri Jan 26 18:24:52 2007
# To get wxPerl visit http://wxPerl.sourceforge.net/

$VERSION = 0.92;

use Wx 0.15 qw[:allclasses];
use strict;

package MainFrame;

use Wx qw[:everything];
use base qw(Wx::Frame);
use strict;

our $cb;

sub new {
	my( $self, $parent, $id, $title, $pos, $size, $style, $name ) = @_;
	$parent = undef              unless defined $parent;
	$id     = -1                 unless defined $id;
	$title  = ""                 unless defined $title;
	$pos    = wxDefaultPosition  unless defined $pos;
	$size   = wxDefaultSize      unless defined $size;
	$name   = ""                 unless defined $name;

# begin wxGlade: MainFrame::new

	$style = wxDEFAULT_FRAME_STYLE 
		unless defined $style;

	$self = $self->SUPER::new( $parent, $id, $title, $pos, $size, $style, $name );
	$self->{sizer_account_staticbox} = Wx::StaticBox->new($self, -1, "Account" );
	$self->{sizer_passwd_staticbox} = Wx::StaticBox->new($self, -1, "Password" );
	$self->{sizer_note_staticbox} = Wx::StaticBox->new($self, -1, "Note" );
	$self->{sizer_mod_staticbox} = Wx::StaticBox->new($self, -1, "Last update" );
	$self->{sizer_category_staticbox} = Wx::StaticBox->new($self, -1, "Category" );
	

	# Menu Bar

	$self->{menubar} = Wx::MenuBar->new();
	$self->SetMenuBar($self->{menubar});
	my $wxglade_tmp_menu;
	$wxglade_tmp_menu = Wx::Menu->new();
	$wxglade_tmp_menu->Append(wxID_OPEN, "&Open...\tCtrl-O", "Select a file");
	$wxglade_tmp_menu->AppendSeparator();
	$wxglade_tmp_menu->Append(wxID_EXIT, "&Quit\tCtrl-Q", "Exit program");
	$self->{menubar}->Append($wxglade_tmp_menu, "&File");
	$wxglade_tmp_menu = Wx::Menu->new();
	$wxglade_tmp_menu->AppendSeparator();
	$wxglade_tmp_menu->Append(6001, "Select all", "Display all categories");
	$wxglade_tmp_menu->Append(6002, "Deselect all", "Deselect all");
	$self->{menubar}->Append($wxglade_tmp_menu, "&Categories");
	$wxglade_tmp_menu = Wx::Menu->new();
	$wxglade_tmp_menu->Append(wxID_ABOUT, "&About...", "About...");
	$self->{menubar}->Append($wxglade_tmp_menu, "&Help");
	
# Menu Bar end

	$self->{statusbar} = $self->CreateStatusBar(1, wxST_SIZEGRIP);
	$self->{list_box_topic} = Wx::ListBox->new($self, -1, wxDefaultPosition, wxDefaultSize, [], wxLB_SINGLE|wxLB_ALWAYS_SB);
	$self->{button_fetch} = Wx::Button->new($self, -1, "Fetch");
	$self->{text_ctrl_category} = Wx::TextCtrl->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
	$self->{text_ctrl_account} = Wx::TextCtrl->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
	$self->{text_ctrl_passwd} = Wx::TextCtrl->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
	$self->{checkbox_pw_veil} = Wx::CheckBox->new($self, -1, "Veil", wxDefaultPosition, wxDefaultSize, );
	$self->{checkbox_pw_clip} = Wx::CheckBox->new($self, -1, "Clip", wxDefaultPosition, wxDefaultSize, );
	$self->{text_ctrl_note} = Wx::TextCtrl->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
	$self->{text_ctrl_mod} = Wx::TextCtrl->new($self, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);

	$self->__set_properties();
	$self->__do_layout();

	Wx::Event::EVT_MENU($self, wxID_OPEN, \&OnOpen);
	Wx::Event::EVT_MENU($self, wxID_EXIT, \&OnQuit);
	Wx::Event::EVT_MENU($self, 6001, \&OnSelectAllCategories);
	Wx::Event::EVT_MENU($self, 6002, \&OnDeselectAllCategories);
	Wx::Event::EVT_MENU($self, wxID_ABOUT, \&OnAbout);
	Wx::Event::EVT_LISTBOX_DCLICK($self, $self->{list_box_topic}->GetId, \&OnTopicActivate);
	Wx::Event::EVT_LISTBOX($self, $self->{list_box_topic}->GetId, \&OnTopicSelect);
	Wx::Event::EVT_BUTTON($self, $self->{button_fetch}->GetId, \&OnFetch);
	Wx::Event::EVT_CHECKBOX($self, $self->{checkbox_pw_veil}->GetId, \&OnPwVeil);
	Wx::Event::EVT_CHECKBOX($self, $self->{checkbox_pw_clip}->GetId, \&OnPwClip);

# end wxGlade
	$self->SetSize($size);
	return $self;

}


sub __set_properties {
	my $self = shift;

# begin wxGlade: MainFrame::__set_properties

	$self->SetTitle("GNU Keyring");
	$self->{statusbar}->SetStatusWidths(-1);
	
	my( @statusbar_fields ) = (
		""
	);

	if( @statusbar_fields ) {
		$self->{statusbar}->SetStatusText($statusbar_fields[$_], $_) 	
		for 0 .. $#statusbar_fields ;
	}
	$self->{list_box_topic}->SetSelection(0);
	$self->{button_fetch}->Enable(0);
	$self->{checkbox_pw_veil}->SetValue(1);

# end wxGlade

	
}

sub __do_layout {
	my $self = shift;

# begin wxGlade: MainFrame::__do_layout

	$self->{outer_sizer} = Wx::BoxSizer->new(wxHORIZONTAL);
	$self->{info_sizer} = Wx::BoxSizer->new(wxVERTICAL);
	$self->{sizer_mod}= Wx::StaticBoxSizer->new($self->{sizer_mod_staticbox}, wxHORIZONTAL);
	$self->{sizer_note}= Wx::StaticBoxSizer->new($self->{sizer_note_staticbox}, wxHORIZONTAL);
	$self->{sizer_passwd}= Wx::StaticBoxSizer->new($self->{sizer_passwd_staticbox}, wxVERTICAL);
	$self->{sizer_pwprefs} = Wx::BoxSizer->new(wxHORIZONTAL);
	$self->{sizer_account}= Wx::StaticBoxSizer->new($self->{sizer_account_staticbox}, wxHORIZONTAL);
	$self->{sizer_category}= Wx::StaticBoxSizer->new($self->{sizer_category_staticbox}, wxHORIZONTAL);
	$self->{sizer_list_box} = Wx::BoxSizer->new(wxVERTICAL);
	$self->{sizer_list_box}->Add($self->{list_box_topic}, 1, wxEXPAND|wxFIXED_MINSIZE, 0);
	$self->{sizer_list_box}->Add(1, 3, 0, wxADJUST_MINSIZE, 0);
	$self->{sizer_list_box}->Add($self->{button_fetch}, 0, wxEXPAND|wxADJUST_MINSIZE, 0);
	$self->{outer_sizer}->Add($self->{sizer_list_box}, 1, wxLEFT|wxTOP|wxBOTTOM|wxEXPAND, 5);
	$self->{sizer_category}->Add($self->{text_ctrl_category}, 1, wxEXPAND|wxADJUST_MINSIZE, 0);
	$self->{info_sizer}->Add($self->{sizer_category}, 0, wxEXPAND, 0);
	$self->{sizer_account}->Add($self->{text_ctrl_account}, 1, wxADJUST_MINSIZE, 0);
	$self->{info_sizer}->Add($self->{sizer_account}, 0, wxEXPAND, 0);
	$self->{sizer_passwd}->Add($self->{text_ctrl_passwd}, 1, wxEXPAND|wxADJUST_MINSIZE, 0);
	$self->{sizer_pwprefs}->Add($self->{checkbox_pw_veil}, 1, wxADJUST_MINSIZE, 0);
	$self->{sizer_pwprefs}->Add($self->{checkbox_pw_clip}, 1, wxADJUST_MINSIZE, 0);
	$self->{sizer_passwd}->Add($self->{sizer_pwprefs}, 0, wxEXPAND, 0);
	$self->{info_sizer}->Add($self->{sizer_passwd}, 0, wxEXPAND, 0);
	$self->{sizer_note}->Add($self->{text_ctrl_note}, 1, wxEXPAND|wxADJUST_MINSIZE, 0);
	$self->{info_sizer}->Add($self->{sizer_note}, 1, wxEXPAND, 0);
	$self->{sizer_mod}->Add($self->{text_ctrl_mod}, 1, wxADJUST_MINSIZE, 0);
	$self->{info_sizer}->Add($self->{sizer_mod}, 0, wxEXPAND, 0);
	$self->{outer_sizer}->Add($self->{info_sizer}, 1, wxALL|wxEXPAND, 5);
	$self->SetAutoLayout(1);
	$self->SetSizer($self->{outer_sizer});
	$self->{outer_sizer}->Fit($self);
	$self->{outer_sizer}->SetSizeHints($self);
	$self->Layout();

# end wxGlade
}

sub OnFetch {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnFetch <event_handler>

	# Get the desired topic. Note it can be undefined.
	my $topic = ($self->{list_box_topic}->GetSelections)[0];
	unless ( defined($topic) ) {
	    $self->{button_fetch}->Enable(0);
	    return;
	}

	# Get the topic name from the list.
	my $rec = $self->{_keyringsortedrecs}->[$topic];

	# Create the password dialog, if needed.
	my $d_passwd;
	if ( !$self->{_keyringdecryptor} ) {
	    $d_passwd = Wx::TextEntryDialog->new
	      ($self,
	       "Enter password for $self->{_keyringfile}",
	       "Enter Keyring password",
	       "",
	       wxOK|wxCANCEL|wxTE_PASSWORD,
	       wxDefaultPosition);
	}

	# Forever...
	while ( 1 ) {

	    # If there's no decryptor, start the password dialog.
	    if ( !$self->{_keyringdecryptor} ) {
		my $ret = $d_passwd->ShowModal;
		if ( $ret != wxID_OK ) {
		    # Cancelled.
		    $d_passwd->Destroy;
		    return;
		}
		$ret = $d_passwd->GetValue;
		$self->{_keyringdecryptor} = $self->{_keyringdb}->Password($ret);
		# Check for a valid decryptor.
		if ( !$self->{_keyringdecryptor} ) {
		    my $md = Wx::MessageDialog->new
		      ($self, "Incorrect password",
		       "Password error",
		       wxOK|wxICON_ERROR,
		       wxDefaultPosition);
		    $md->ShowModal;
		    $md->Destroy;
		    next;
		}
		# It's valid, get rid of the dialog.
		$d_passwd->Destroy;
	    }

	    # Get the record.
	    if ( !$rec ) {
		my $md = Wx::MessageDialog->new
		  ($self, "Topic \"$topic\" not found",
		   "Database error",
		   wxOK|wxICON_ERROR,
		   wxDefaultPosition);
		$md->ShowModal;
		$md->Destroy;
		next;
	    }
	    # Decrypt it.
	    my ($acct) = $self->{_keyringdb}->Decrypt($rec);

	    # Show values.
        $self->{text_ctrl_category}->SetValue(
            $self->{_keyringcategories}->[$rec->{category}]);
        $self->{text_ctrl_account}->SetValue($acct->{account});
	    if ( $self->{checkbox_pw_veil}->IsChecked ) {
		$self->{text_ctrl_passwd}->SetValue("\x{2022}" x 8);
	    }
	    else {
		$self->{text_ctrl_passwd}->SetValue($acct->{password});
	    }
	    if ( $self->{checkbox_pw_clip}->IsChecked ) {
		$self->PutOnClipboard($acct->{password});
	    }
	    else {
		$self->PutOnClipboard(undef);
	    }
	    $acct->{notes} =~ s/\n+$//;
	    $self->{text_ctrl_note}->SetValue($acct->{notes});

	    if ( $acct->{lastchange} ) {
		$self->{text_ctrl_mod}->SetValue
		  (sprintf("%d-%02d-%02d",
			   1900 + $acct->{lastchange}->{year},
			   1 + $acct->{lastchange}->{month},
			   $acct->{lastchange}->{day}));

	    }
	    # Exit.
	    last;
	}
# end wxGlade
}



sub OnQuit {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnQuit <event_handler>

	$self->Destroy;

# end wxGlade
}


sub OnTopicSelect {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnTopicSelect <event_handler>

	# We can fetch now.
	$self->{button_fetch}->Enable(1);

	# Clear values.
	foreach ( qw(category account passwd note mod) ) {
	    $self->{"text_ctrl_$_"}->SetValue("");
	}

	# Display the current topic category.
	my $topic = ($self->{list_box_topic}->GetSelections)[0];
	unless ( defined($topic) ) {
	    $self->{button_fetch}->Enable(0);
	    return;
	}
	my $rec = $self->{_keyringsortedrecs}->[$topic];
	$self->{text_ctrl_category}->SetValue($self->{_keyringcategories}->[ $rec->{category} ]);

# end wxGlade
}


sub OnTopicActivate {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnTopicActivate <event_handler>

	$self->OnFetch($event);

# end wxGlade
}

sub LoadKeyring {
    my ($self, $file) = @_;

    # Load the database.
    eval {
	$self->{_keyringdb} = ::loadKeyring($file);
    };
    if ( $@ ) {
	my $msg = $@;
	$msg =~ s/\n.*//;
	my $md = Wx::MessageDialog->new
	  ($self, $msg,
	   "Database error",
	   wxOK|wxICON_ERROR,
	   wxDefaultPosition);
	$md->ShowModal;
	$md->Destroy;
	return;
    }
    $self->{_keyringfile} = $file;

    my @cats;
    foreach my $i (0..$#{ $self->{_keyringdb}->{appinfo}->{categories} }) { 
        push @cats, { 
            id   => $i, 
            name => $self->{_keyringdb}->{appinfo}->{categories}->[$i]->{name},
        }
    }

    $self->{_keyringcategories} = [ map { $_->{name} } @cats ];
    $self->{_keyringsortedcategoryids} = [
        map { $_->{id} } sort { $a->{name} cmp $b->{name} } @cats ];


    undef($self->{_keyringdecryptor});

    # It's no use to remember the cat mask, since codes will differ
    # from file to file.
    $self->{_catmask} = ~0;

    # From the Categories menu, remove all but the last 3 (separator + ena/dis all).
    my $catmenux = $self->{menubar}->FindMenu("Categories");
    my Wx::Menu $catmenu = $self->{menubar}->GetMenu($catmenux);
    my $count = $catmenu->GetMenuItemCount;
    my $i;
    for ( $i = 0; $i < $count-3; $i++ ) {
	#### MEMORY LEAK ####
	$catmenu->Remove($catmenu->FindItemByPosition(0));
    }

    # Prepend new choices to the Categories menu.
    my $did = 0;
    $self->{_catmaskids} = [];
    foreach my $i (reverse 0..$#{ $self->{_keyringsortedcategoryids} }) {
        my $cat_id = $self->{_keyringsortedcategoryids}->[$i];
        my $name   = $self->{_keyringcategories}->[$cat_id];
        next if !$name;
        $name ||= "<Unknown $i>";
        my $id = ::next_id();
        my $m = $catmenu->PrependCheckItem($id, $name, $name);

        # Remember for toggle access.
        $self->{_catmaskids}->[$i] = $m;

        # Set check status.
        $m->Check($self->{_catmask} & (1 << $i));

        # Handler.
        my $maskno = $i;	# lexical copy
        Wx::Event::EVT_MENU($self, $id, sub { 
                OnToggleCategory($self, $_[1], $maskno) });

        # Yes.
        $did++;
    }

    $self->UpdateCatMask;
    $self->{statusbar}->SetStatusText("File: $file, ".
				      (@{ $self->{_keyringdb}->{records} })." entries.",
				      0);
}

sub OnOpen {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnOpen <event_handler>

	my $fd = Wx::FileDialog->new
	  ($self,
	   "Choose Keyring",
	   "", "",
	   "*.pdb",
	   0,
	   wxDefaultPosition);
	my $ret = $fd->ShowModal;
	if ( $ret == wxID_OK ) {
	    $self->LoadKeyring($fd->GetPath);
	}
	$fd->Destroy;

# end wxGlade
}


sub OnAbout {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnAbout <event_handler>

	my $md = Wx::MessageDialog->new
	  ($self,
	   "wxKeyring version $::VERSION\n".
	   ::COPYRIGHT() . "\n\n".
	   "Written by Johan Vromans\n".
	   "<jvromans\@squirrel.nl>\n".
	   "http://www.squirrel.nl\n\n".
	   "GUI design with wxGlade, http://www.wxglade.org\n\n".
	   "Perl version ".sprintf("%vd",$^V)."\n".
	   "WxPerl version $Wx::VERSION\n".
	   "wxWidgets version ".Wx::wxVERSION."\n".
	   "Palm::Keyring version $Palm::Keyring::VERSION\n",
	   "About wxKeyring",
	   wxOK|wxICON_INFORMATION,
	   wxDefaultPosition);
	$md->ShowModal;
	$md->Destroy;

# end wxGlade
}

sub UpdateCatMask {
    my ($self) = @_;

    # Update check status on the category menu.
    for ( my $i = 0; $i < 16; $i++ ) {
        my $m = $self->{_catmaskids}->[$i];
        next unless $m;
        $m->Check($self->{_catmask} & (1 << $i));
    }

    # Update the list of displayed items.
    my %id_by_cat;
    foreach (0..$#{ $self->{_keyringsortedcategoryids} }) {
        $id_by_cat{ $self->{_keyringsortedcategoryids}->[$_]} = $_;
    }
	$self->{_keyringsortedrecs} = [];
	foreach my $rec ( sort { lc($a->{name}) cmp lc($b->{name}) } 
            @{ $self->{_keyringdb}->{records} } ) {
        next unless $rec->{name};
        if ($self->{_catmask} != ~0) {
	        next unless $self->{_catmask} & (1 << 
                $id_by_cat{ $rec->{category} });
        }
	    push @{$self->{_keyringsortedrecs}}, $rec;
    }
    $self->{list_box_topic}->Set( [ map { $_->{name} } 
        @{ $self->{_keyringsortedrecs} } ]);
}

sub OnSelectAllCategories {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnSelectAllCategories <event_handler>

	$self->{_catmask} = ~0;
	$self->UpdateCatMask;

# end wxGlade
}

sub OnToggleCategory {
	my ($self, $event, $cat) = @_;
# wxGlade: MainFrame::OnToggleCategory <event_handler>

	$self->{_catmask} ^= (1 << $cat);
	$self->UpdateCatMask;

# end wxGlade
}


sub OnDeselectAllCategories {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnDeselectAllCategories <event_handler>

	$self->{_catmask} = 0;
	$self->UpdateCatMask;

# end wxGlade
}


sub OnPwVeil {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnPwVeil <event_handler>

	if ( $self->{checkbox_pw_veil}->IsChecked ) {
	    $self->{text_ctrl_passwd}->SetValue("\x{2022}" x 8);
	}
	else {
	    $self->OnFetch($event);
	}
# end wxGlade
}

sub PutOnClipboard {
    my ($self, $data) = @_;

    for ( 0, 1 ) {
	# Put it on the Clipboard as well as the Primary Selection.
    wxTheClipboard->UsePrimarySelection($_);
	if ( $data ) {
	    my $cb = Wx::TextDataObject->new($data);
	    wxTheClipboard->Open;
	    wxTheClipboard->SetData($cb);
	    wxTheClipboard->Close;
	    $self->{statusbar}->SetStatusText
	      ("Password stored on Clipboard", 0);
	    $self->{_pwstored}++;
	}
	elsif ( $self->{_pwstored} ) {
	    wxTheClipboard->Open;
	    wxTheClipboard->Clear;
	    wxTheClipboard->Close;
	    $self->{statusbar}->SetStatusText
	      ("Clipboard cleared", 0);
	    $self->{_pwstored} = 0 if $_;
	}
    }
}

sub OnPwClip {
	my ($self, $event) = @_;
# wxGlade: MainFrame::OnPwClip <event_handler>

	if ( $self->{checkbox_pw_clip}->IsChecked ) {
	    if ( $self->{checkbox_pw_veil}->IsChecked ) {
		$self->OnFetch($event);
	    }
	    else {
		$self->PutOnClipboard($self->{text_ctrl_passwd}->GetValue);
	    }
	}
	else {
	    $self->PutOnClipboard(undef);
	}
# end wxGlade
}

# end of class MainFrame

1;

package main;

use Palm::Keyring;

use Wx qw(wxID_HIGHEST);

my $next_id;
sub next_id {
    $next_id ||= wxID_HIGHEST;
    ++$next_id;
}

sub loadKeyring {
    my $file = shift;
    my $pdb = new Palm::Keyring;
    $pdb->Load($file);
}

sub COPYRIGHT() {
    "Copyright 2007 Squirrel Consultancy";
}

use Getopt::Long;

my $keyringfile;
my $geo = "450x300";
my $veil = 1;
my $clip = 0;
my $passwd;

# Note: Using --password is dangerous, and meant for testing only!
GetOptions("geometry=s"	 => \$geo,
	   "veil!"	 => \$veil,
	   "clip!"	 => \$clip,
	   "password=s"  => \$passwd,
	  ) && @ARGV <= 1
  or die("Usage: $0 [ -geometry WxH+X+Y ] [ Keyring ]\n");

my ($w, $h, $x, $y) = (450, 300, -1, -1);
if ( $geo =~ /^(?:(\d+)x(\d+))?(?:\+(\d+)\+(\d+))?$/ ) {
    $w = $1 if defined $1;
    $h = $2 if defined $2;
    $x = $3 if defined $3;
    $y = $4 if defined $4;
}
else {
    die("Invalid geometry: $geo\n");
}

$keyringfile = shift if @ARGV;

no warnings 'redefine';
local *Wx::App::OnInit = sub{1};
use warnings 'redefine';

my $app = Wx::App->new();
Wx::InitAllImageHandlers();

my $frame = MainFrame->new(undef,undef,undef,[$x,$y],[$w,$h]);
$app->SetTopWindow($frame);
$frame->Show(1);

$frame->LoadKeyring($keyringfile) if $keyringfile;
$frame->{statusbar}->SetStatusText(COPYRIGHT, 0);

# Presets.
$frame->{checkbox_pw_clip}->SetValue($clip);
$frame->{checkbox_pw_veil}->SetValue($veil);
if ( $passwd ) {
    $frame->{_keyringdecryptor} = $frame->{_keyringdb}->Password($passwd);
    $frame->{list_box_topic}->SetSelection(0);
    $frame->OnFetch;
}

# And go...
$app->MainLoop();