App-Music-ChordPro-Wx
view release on metacpan or search on metacpan
lib/App/Music/ChordPro/Wx/Main.pm view on Meta::CPAN
#! perl
use strict;
use warnings;
# Implementation of App::Music::ChordPro::Wx::Main_wxg details.
package App::Music::ChordPro::Wx::Main;
# App::Music::ChordPro::Wx::Main_wxg is generated by wxGlade and contains
# all UI associated code.
use base qw( App::Music::ChordPro::Wx::Main_wxg );
use Wx qw[:everything];
use Wx::Locale gettext => '_T';
use App::Music::ChordPro::Wx;
use App::Music::ChordPro;
use App::Packager;
use File::Temp qw( tempfile );
use Encode qw(decode_utf8);
our $VERSION = $App::Music::ChordPro::Wx::VERSION;
sub new {
my $self = bless $_[0]->SUPER::new(), __PACKAGE__;
Wx::Event::EVT_IDLE($self, $self->can('OnIdle'));
$self;
}
use constant FONTSIZE => 12;
my @fonts =
( { name => "Monospace",
font => Wx::Font->new( FONTSIZE, wxFONTFAMILY_TELETYPE,
wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_NORMAL ),
},
{ name => "Serif",
font => Wx::Font->new( FONTSIZE, wxFONTFAMILY_ROMAN,
wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_NORMAL ),
},
{ name => "Sans serif",
font => Wx::Font->new( FONTSIZE, wxFONTFAMILY_SWISS,
wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_NORMAL ),
},
);
my $prefctl;
# Explicit (re)initialisation of this class.
sub init {
my ( $self, $options ) = @_;
$prefctl ||=
{
cfgpreset => lc(_T("Default")),
xcode => "",
notation => "",
skipstdcfg => 1,
configfile => "",
pdfviewer => "",
editfont => 0,
editsize => FONTSIZE,
};
if ( $^O =~ /^mswin/i ) {
Wx::ConfigBase::Get->SetPath("/wxchordpro");
}
else {
my $cb;
if ( -d "$ENV{HOME}/.config" ) {
$cb = "$ENV{HOME}/.config/wxchordpro/wxchordpro";
mkdir("$ENV{HOME}/.config/wxchordpro");
}
else {
$cb = "$ENV{HOME}/.wxchordpro";
}
unless ( -f $cb ) {
open( my $fd, '>', $cb );
}
Wx::ConfigBase::Set
(Wx::FileConfig->new
( "WxChordPro",
"ChordPro_ORG",
$cb,
'',
wxCONFIG_USE_LOCAL_FILE,
));
}
$self->{_verbose} = $options->{verbose};
$self->{_trace} = $options->{trace};
$self->{_debug} = $options->{debug};
$self->GetPreferences;
my $font = $fonts[$self->{prefs_editfont}]->{font};
$font->SetPointSize($self->{prefs_editsize});
$self->{t_source}->SetFont($font);
# Disable menu items if we cannot.
$self->{main_menubar}->FindItem(wxID_UNDO)
->Enable($self->{t_source}->CanUndo);
$self->{main_menubar}->FindItem(wxID_REDO)
->Enable($self->{t_source}->CanRedo);
Wx::Log::SetTimestamp(' ');
if ( @ARGV && -s $ARGV[0] ) {
$self->openfile( shift(@ARGV) );
return 1;
}
$self->opendialog;
$self->newfile unless $self->{_currentfile};
return 1;
}
################ Internal methods ################
# List of available config presets (styles).
my $stylelist;
sub stylelist {
return $stylelist if $stylelist && @$stylelist;
my $cfglib = getresource("config");
$stylelist = [];
if ( -d $cfglib ) {
opendir( my $dh, $cfglib );
foreach ( sort readdir($dh) ) {
$_ = decode_utf8($_);
next unless /^(.*)\.json$/;
my $base = $1;
unshift( @$stylelist, $base ), next
if $base eq "chordpro"; # default
push( @$stylelist, $base );
}
}
push( @$stylelist, "custom" );
return $stylelist;
}
# List of available notation systems.
my $notationlist;
sub notationlist {
return $notationlist if $notationlist && @$notationlist;
my $cfglib = getresource("notes");
$notationlist = [ undef ];
if ( -d $cfglib ) {
opendir( my $dh, $cfglib );
foreach ( sort readdir($dh) ) {
$_ = decode_utf8($_);
next unless /^(.*)\.json$/;
my $base = $1;
$notationlist->[0] = "common", next
if $base eq "common";
push( @$notationlist, $base )
}
}
return $notationlist;
}
sub fonts { \@fonts }
sub opendialog {
my ($self) = @_;
my $fd = Wx::FileDialog->new
($self, _T("Choose ChordPro file"),
"", "",
"ChordPro files (*.cho,*.crd,*.chopro,*.chord,*.chordpro,*.pro)|*.cho;*.crd;*.chopro;*.chord;*.chordpro;*.pro|All files|*.*",
0|wxFD_OPEN|wxFD_FILE_MUST_EXIST,
wxDefaultPosition);
my $ret = $fd->ShowModal;
if ( $ret == wxID_OK ) {
$self->openfile( $fd->GetPath );
}
$fd->Destroy;
}
sub openfile {
my ( $self, $file ) = @_;
unless ( $self->{t_source}->LoadFile($file) ) {
my $md = Wx::MessageDialog->new
( $self,
"Error opening $file: $!",
"File open error",
wxOK | wxICON_ERROR );
$md->ShowModal;
$md->Destroy;
return;
}
#### TODO: Get rid of selection on Windows
$self->{_currentfile} = $file;
if ( $self->{t_source}->GetValue =~ /^\{\s*t(?:itle)[: ]+([^\}]*)\}/m ) {
my $n = $self->{t_source}->GetNumberOfLines;
Wx::LogStatus("Loaded: $1 ($n line" .
( $n == 1 ? "" : "s" ) .
")");
$self->{sz_source}->GetStaticBox->SetLabel($1);
}
$self->SetTitle( $self->{_windowtitle} = $file);
$self->{prefs_xpose} = 0;
$self->{prefs_xposesharp} = 0;
}
sub newfile {
my ( $self ) = @_;
undef $self->{_currentfile};
$self->{t_source}->SetValue( <<EOD );
{title: New Song}
EOD
Wx::LogStatus("New file");
$self->{prefs_xpose} = 0;
$self->{prefs_xposesharp} = 0;
}
my ( $preview_cho, $preview_pdf );
my ( $msgs, $fatal, $died );
sub _warn {
Wx::LogWarning(@_);
( run in 1.027 second using v1.01-cache-2.11-cpan-5b529ec07f3 )