Minimal DocView sample
From WxPerl wiki
This is a minimal Document/View sample. It's not very tidy, since I originally wrote it to test the wxPerl's DocView as I was writing it. So it's a bit of a patchwork quilt, but I hope it demonstrates successfully using Document/View in wxPerl.
For more information on Document/View in wxWindows, I suggest looking at the _docview_ and _docvwmdi_ samples that come in the wxWindows dist and the Document/View overview: http://www.lpthe.jussieu.fr/~zeitlin/wxWindows/docs/wxwin488.htm#docviewoverview
- NB*: You'll find the bitmaps I used for the toolbar in wxperl's samples/toolbar/bitmaps folder
<code>
#!/usr/bin/perl
#############################################################################
## Name: docvwmdi.pl
## Purpose: Basic MDI Document/View sample
## Author: Simon Flack
## Modified by: 13/09/2002
## Created: 28/08/2002
## RCS-ID:
## Copyright: (c) 2002 Simon Flack
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
#############################################################################
use strict;
use Wx 0.12;
use Wx::MDI;
use Wx::DocView;
package MyApp;
use vars qw(@ISA);
@ISA = qw(Wx::App);
use Wx qw( :docview :frame :misc :toolbar :bitmap :id );
use Wx::Event qw( EVT_MENU );
sub OnInit {
my $self = shift;
# Create a document manager and load a document template
$self->{'.docman'} = MyDocManager->new( wxDOC_MDI );
Wx::DocTemplate->new($self->{'.docman'}, "Text Files", "*.txt", "", "txt",
"Text Document", "Text View", "MyDoc", "MyView", 1 );
# Create the parent frame. For this app, we'll use MDI
# We get a "Window" menu for free under MSW. You can turn that off with
# wxFRAME_NO_WINDOW_MENU flag
my $frame = new Wx::DocMDIParentFrame( $self->{'.docman'},
undef , -1, "DocView Demo" );
$frame->SetIcon( Wx::GetWxPerlIcon() );
my $file_menu = new Wx::Menu;
my $edit_menu = new Wx::Menu;
my $help_menu = new Wx::Menu;
# Using these special contants will automatically use the doc/view
$file_menu->Append(wxID_NEW, "&New\tCtrl+N");
$file_menu->Append(wxID_OPEN, "&Open\tCtrl+O");
$file_menu->Append(wxID_SAVE, "&Save\tCtrl+S");
$file_menu->Append(wxID_SAVEAS, "Save &As");
$file_menu->Append(wxID_CLOSE, "&Close\tCtrl+W");
$file_menu->AppendSeparator;
$file_menu->Append(wxID_PRINT, "&Print\tCtrl+P");
$file_menu->Append(wxID_PRINT_SETUP, "Print Set&up");
$file_menu->Append(wxID_PREVIEW, "Print Pre&view");
$file_menu->Append(wxID_EXIT, "E&xit");
$self->{'.docman'}->FileHistoryUseMenu( $file_menu );
$edit_menu->Append(wxID_UNDO, "&Undo\tCtrl+Z");
$edit_menu->Append(wxID_REDO, "&Redo\tCtrl+R");
$edit_menu->AppendSeparator;
use constant MYABOUT => 1;
$help_menu->Append(MYABOUT, "&About");
EVT_MENU( $frame, MYABOUT, \&OnAbout );
my $menu_bar = new Wx::MenuBar;
$menu_bar->Append($file_menu, "&File");
$menu_bar->Append($edit_menu, "&Edit");
$menu_bar->Append($help_menu, "&Help");
$frame->SetMenuBar($menu_bar);
$frame->Centre(wxBOTH);
$frame->Show( 1 );
$self->SetTopWindow( $frame );
my $toolbar = $frame->CreateToolBar( wxTB_HORIZONTAL | wxNO_BORDER |
wxTB_FLAT | wxTB_DOCKABLE, 5050 );
$toolbar->AddTool( wxID_NEW, BITMAP('new'), wxNullBitmap, 0, undef,
'New File' );
$toolbar->AddTool( wxID_OPEN, BITMAP('open'), wxNullBitmap, 0, undef,
'Open File' );
$toolbar->AddTool( wxID_CLOSE, BITMAP('help'), wxNullBitmap, 0, undef,
'Close File' );
$toolbar->AddTool( wxID_SAVE, BITMAP('save'), wxNullBitmap, 1, undef,
'Toggle button 1' );
$toolbar->AddTool( wxID_COPY, BITMAP('copy'), wxNullBitmap, 1, undef,
'Toggle button 1' );
$toolbar->AddTool( wxID_CUT, BITMAP('cut'), wxNullBitmap, 0, undef,
'Toggle button 1' );
$toolbar->AddTool( wxID_PASTE, BITMAP('paste'), wxNullBitmap, 0, undef,
'Toggle button 1' );
$toolbar->AddTool( wxID_PRINT, BITMAP('print'), wxNullBitmap, 0, undef,
'Toggle button 1' );
$toolbar->AddSeparator();
$toolbar->Realize();
$self->{'.menubar'} = $menu_bar;
$self->{'.frame'} = $frame;
return 1;
}
sub OnAbout
{
my $self = shift;
use Wx qw( wxOK wxCENTRE wxVERSION_STRING );
Wx::MessageBox( "Perl Document / View Framework sample\n by Simon Flack\n"
. wxVERSION_STRING, "Wx::DocView",wxOK|wxCENTRE, $self );
}
sub CreateChildFrame {
my ($self, $doc, $view, $flags) = @_;
# Get the filename for the window title
my $filename = $doc->GetFilename;
my $child_frame = new Wx::DocMDIChildFrame( $doc, $view,
Wx::wxTheApp()->GetTopWindow(), -1,
$filename, [10,10], [300,300],
wxDEFAULT_FRAME_STYLE | wxMAXIMIZE );
return $child_frame;
}
sub BITMAP {
(my $nixPath = $0) =~ s/\\/\//g;
my ($prog_path) = $nixPath =~ /(.*)\/[^\/]+$/;
if( $Wx::_platform == $Wx::_msw ) {
Wx::Bitmap->new( "$prog_path/bitmaps/$_[0].bmp", wxBITMAP_TYPE_BMP );
} else {
Wx::Bitmap->new( "$prog_path/bitmaps/$_[0].xpm", wxBITMAP_TYPE_XPM );
}
}
# ---- Wx::DocManager -------------------------------------------------------
package MyDocManager;
use vars qw(@ISA);
@ISA = qw(Wx::DocManager);
{
# The default wxWindows untitled name is "unnamedN" (where N is a number)
# It's a bit ugly, and you can customise it...
my $unnamed_doc_count = 0;
sub MakeDefaultName {
my ($docmgr, $name) = @_;
return "Untitled" . ++$unnamed_doc_count;
}
}
# ---- Wx::Document ---------------------------------------------------------
package MyDoc;
use vars qw(@ISA);
@ISA = qw(Wx::Document);
sub OnSaveDocument {
my ($doc, $filename) = @_;
my $view = $doc->GetFirstView();
$view->Activate(0);
return unless $view->{'.editor'}->SaveFile( $filename );
$doc->Modify(0);
$view->Activate(1);
return 1;
}
sub OnOpenDocument {
my ($doc, $filename) = @_;
my $view = $doc->GetFirstView();
return 0 unless $view->{'.editor'}->LoadFile( $filename );
$doc->UpdateAllViews();
$doc->Modify(0);
return 1;
}
sub IsModified {
# This is called internally to see if the document has been modified
# since it was last saved.
my ($doc) = @_;
my $view = $doc->GetFirstView();
if (defined $view->{'.editor'}) {
return $view->{'.editor'}->IsModified;
}
return;
}
# ---- Wx::View -------------------------------------------------------------
package MyView;
use vars qw(@ISA);
@ISA = qw(Wx::View);
use Wx qw( wxTE_MULTILINE wxDefaultPosition wxDefaultSize );
sub OnCreate {
my ($view, $doc, $flags) = @_;
my $child_frame = Wx::wxTheApp()->CreateChildFrame($doc, $view);
$view->{'.editor'} = new Wx::TextCtrl($child_frame, -1, "", [0,0],
[200,300], wxTE_MULTILINE);
$view->Activate(1);
return 1;
}
sub OnClose {
my ($view, $deletewindow) = @_;
if ($deletewindow) {
$view->{'.editor'}->Show(0);
delete $view->{'.editor'};
$view->GetFrame->Destroy;
my $app = Wx::wxTheApp();
$app->{'.frame'}->SetMenuBar( $app->{'.menubar'} );
} else {
$view->GetDocument->Close();
}
$view->Activate(0);
return 1;
}
##################################################################
package main;
my $docview = new MyApp;
$docview->MainLoop;
# Local variables: #
# mode: cperl #
# End: #
</code>
