#======================================================== # TkPlotWindow #======================================================== package TkPlotWindow; use MyTk::MyMainWindow; @ISA = qw(MyMainWindow); use strict; use Jcode; use Tk; use Tk::Balloon; use MyTk::Dialog; use MyTk::MyFrame; use MyTk::MyLabel; use MyTk::MyEntry; use MyTk::MyListbox; use MyTk::MyBrowseEntry; use MyTk::MyText; use MyTk::MyButton; use MyTk::MyMenubutton; use MyTk::MyCanvas; use MyTk::MyAdjuster; use MyTk::GraphFrameArray; use Sci::GeneralFileFormat; #============================================================ # 変数等取得関数 #============================================================ # TkData sub TkData { return shift->App()->TkData(); } sub SetTkData { my ($this,$d)=@_; return shift->App()->SetTkData($d); } # TkPlotModuleクラスから変更できるフレームウィジェット sub DataClassFrame { return shift->{'DataClassFrame'}; } sub Canvas { my ($this, $canvas) = @_; if($canvas) { return $canvas; } return $this->{'GraphCanvas'}; } sub GetGraphFrameArray { my ($this) = @_; my $App = $this->App(); return $App->TkData()->GetGraphFrameArray() if($App->TkData()); return shift->{'GraphFrameArray'}; } #sub GetGraphFrameArray { return shift->{'GraphFrameArray'}; } sub GetGraphFrame { my ($this, $idx) = @_; $idx = 0 unless($idx); my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame = $GraphFrameArray->GetGraphFrame($idx); return $GraphFrame; } sub SectionListBox { return shift->{'SectionListbox'}; } sub FileContentTextBox { return shift->{'FileContentText'}; } sub Redraw { return shift->Draw(); } sub ShowMousePosition { return shift->App()->{'ShowMousePosition'}; } sub SetShowMousePosition { my ($this,$f)=@_; return $this->App()->{'ShowMousePosition'} = $f; } #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my $class = shift; my $self = MyMainWindow->new(@_); my $this = bless $self, $class; $this->protocol('WM_DELETE_WINDOW' => sub { $this->Close(0); }); # $this->bind(, # sub { &Close(1) if(Ev{'K'} eq 'Escape'); print Ev{'K'} . "\n"; } ); return $this; } sub DESTROY { my $this = shift; $this->SUPER::DESTROY(@_); } #============================================================ # 継承クラスで定義しなおす関数 #  以下、TkData()から呼び返される設定関数の頭にはInitがついている。 #  そうでない関数は、TkAppplicationあるいはTkWindowから呼び出される #============================================================ #TkApplicationからCreateMenuが呼び出される。 #デフォルトでは、TkData()->CreateMenu()がInitCreateMenu()を呼び返す sub CreateMenu { my ($this) = @_; $this->App()->TkData()->CreateMenu(); } sub InitCreateMenu { my ($this) = @_; my $IniFile = $this->IniFile()->IniFile(); my $Editor = $this->App()->{'EditorPath'}; my $menu = $this->CreateMainMenu(); # メニュー作成 my $FileInfoMenu = [ [command => 'Environment Vars', -underline => 0, -command => sub { Dialog::ShowEnvDialog($this); } ], [command => 'Information', -underline => 0, -command => sub { $this->App()->ShowInfoDialog($this); } ], ]; my $FileMenu = $menu->cascade( -label => 'File', -underline => 0, -tearoff => 'no', -menuitems => [ [command => 'Make Clone', -underline => 0, -command => [ \&MakeClone, $this ] ], [command => 'IniFile', -underline => 0, -command => sub { system("$Editor $IniFile"); } ], [command => 'Option', -underline => 0, -command => [\&SetupOption, $this] ], "separator", [cascade => 'Info', -underline => 2, -tearoff => 'no', -menuitems => $FileInfoMenu], [command => 'Close', -underline => 0, -accelerator => "Ctrl+X", -command => [\&Close, $this, 0] ], ]); $this->bind("", sub { $this->Close(1); } ); my $ViewMenu = $menu->cascade( -label => 'View', -underline => 0, -tearoff => 'no', -menuitems => [ [command => 'Restore scale', -underline => 8, -command => [\&RestoreViewScale, $this] ], [command => 'Redraw', -underline => 0, -command => sub { $this->Redraw(); } ], ]); my $HelpMenu = $menu->cascade( -label => 'Help', -underline => 0, -tearoff => 'no', -menuitems => [ [command => 'About', -underline => 0, -command => [\&About, $this]], ]); return $this->MainMenu(); } # TkApplicationから呼び出される # デフォルトでは、TkData()->CreateWidgets()はInitCreateWidgets()を呼び返す sub CreateWidgets { my ($this) = @_; $this->App()->TkData()->CreateWidgets(); } sub InitCreateWidgets { my ($this) = @_; my $App = $this->App(); my $args = $App->Args(); #Paneの設定 $this->set('IsVertical', 0); my $ConfigSide = "left"; my $GraphSide = "right"; my @args = (-expand => 'yes', -fill => 'both'); if(defined $args->GetGetArg("vertical")) { $this->set('IsVertical', 1); $ConfigSide = "top"; $GraphSide = "bottom"; @args = (-fill => 'x'); } # StatusBarの作成 $this->{'StatusBar'} = $this->TkData()->CreateStatusBar('bottom'); # ToolBarの作成 $this->{'ToolBar'} = $this->TkData()->CreateToolBar('top'); # Balloonの作成。StatusBarにも表示する。 my $balloon = $this->Balloon(-statusbar => $this->StatusBar() ); $this->SetBalloon($balloon); # 左枠作成 $this->{'LeftFrame1'} = $this->MyFrame( -width => $App->{'LeftFrameWidth'}, )->pack(-side => $ConfigSide, @args); # データファイル処理クラスで使えるように余計な枠を作成 $this->{'DataClassFrame'} = $this->{'LeftFrame1'}->MyFrame( )->pack(-anchor => 'nw', -fill => 'x'); # 左枠1列目ファイル選択ペイン作成 $this->TkData()->CreateSelectFilePane(); # ファイル内容リストボックス、テキストボックス $this->TkData()->CreateFileContentPane(); # Canvasペイン $this->TkData()->CreateCanvasPane(); # ウィンドウ位置を設定 $this->TkData()->InitWindowPosition(); # GraphFrameの初期化 $this->TkData()->InitCreateGraphFrameArray($this->Canvas()); #=================================================== # コマンドラインオプションの処理 #=================================================== if(defined $this->GetGetArg("WorkDir")) { my $WorkDir = $this->GetGetArg("WorkDir"); if(-d $WorkDir) { $App->print("Read --WorkDir=[$WorkDir].\n"); $this->ReadDirectory($WorkDir); } } elsif(defined $this->GetGetArg("ReadPrev")) { my $WorkDir = $App->{'WorkDir'}; if(-d $WorkDir) { $App->print("Read Previous Dir=[$WorkDir].\n"); $this->ReadDirectory($WorkDir); } } #=================================================== # 小さくなり過ぎないように設定 #=================================================== $this->SetMinSize(); #=================================================== # ウィンドウを更新する #=================================================== $this->update(); #=================================================== # 引数にファイルが指定されていた場合 #=================================================== my $filepath = $this->GetGetArg(0); if($filepath) { unless(-f $filepath) { print "\nError: $filepath does not exist.\n"; exit 1; } my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($filepath); $dir = Deps::MakePath($drive, $dir); $this->ReadDirectory($dir); $this->{'FileListbox'}->SetText($filename); $this->ReadFile($filepath); # この時点ではCanvas sizeが未確定なので、1秒後に再描画する # $this->after(1000, sub { $this->Draw(); } ); # afterIdleを使う方法はうまくいかなかった # $this->{'IdleProcId'} = $this->afterIdle( # sub { $this->Draw(); $this->{'IdleProcId'}->cancel(); } # ); } #=================================================== #Windowが初めて表示されたときに、InitWindowを実行する #=================================================== $this->TkData()->ConfigureInitialBind(); return $this; } sub InitCreateStatusBar { my ($this, $position) = @_; #TkWindow::CreateStatusBarを呼び出す return $this->CreateStatusBar($position); } sub InitCreateToolBar { my ($this, $position) = @_; # 枠作成 $this->{'ToolBarFrame'} = $this->MyFrame( -borderwidth => 2, -relief => 'groove', )->pack(-side => $position, -fill => 'x'); $this->{'OpenButton'} = $this->{'ToolBarFrame'}->MyButton( -text => 'Open', -takefocus => 1, -command => [ \&ChooseFile, $this ], )->pack(-side => 'left', -fill => 'x'); my $spb = $this->{'ShowPosButton'} = $this->{'ToolBarFrame'}->Checkbutton( -text => 'ShowPos', -takefocus => 1, -indicatoron => 0, )->pack(-side => 'left', -fill => 'x'); $spb->bind('' => sub { $this->ToggleShowMousePosition(); } ); if($this->ShowMousePosition()) { $spb->select(); } else { $spb->deselect(); } $this->{'RestoreScaleButton'} = $this->{'ToolBarFrame'}->MyButton( -text => 'Restore Scale', -takefocus => 1, -command => [\&RestoreViewScale, $this], )->pack(-side => 'left', -fill => 'x'); $this->{'SetupOptionButton'} = $this->{'ToolBarFrame'}->MyButton( -text => 'Setup Option', -takefocus => 1, -command => [\&SetupOption, $this], )->pack(-side => 'left', -fill => 'x'); $this->{'CloseButton'} = $this->{'ToolBarFrame'}->MyButton( -text => 'Close', -takefocus => 1, -command => [ \&Close, $this, 1 ], )->pack(-side => 'left', -fill => 'x'); my $balloon = $this->Balloon(); $balloon->attach($this->{'OpenButton'}, -msg => "Open directory", -balloonposition => 'mouse'); $balloon->attach($this->{'ShowPosButton'}, -msg => "Toggle Show Mouse Poisition", -balloonposition => 'mouse'); } #=================================================== # ファイル選択ペイン #=================================================== sub InitCreateSelectFilePane { my ($this) = @_; my $App = $this->App(); my $balloon = $this->Balloon(); # 左枠1列目作成 $this->{'FileFrame'} = $this->{'LeftFrame1'}->MyFrame( -width => $App->{'LeftFrameWidth'}, )->pack(-anchor => 'nw', -fill => 'x'); #, -expand => 'yes', -fill => 'x'); $this->{'FileLabel'} = $this->{'FileFrame'}->MyLabel( -text => 'Dir:' )->pack(-side => 'left'); $this->{'FileEntry'} = $this->{'FileFrame'}->MyEntry( -width => $App->{'LeftFrameWidth'}, -takefocus => 1, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $this->{'FileEntry'}->focus(); $balloon->attach($this->{'FileEntry'}, -msg => "Data directory", -balloonposition => 'mouse'); $this->{'FilePathButton'} = $this->{'FileFrame'}->MyButton( -text => '&Choose', -takefocus => 1, -command => [ \&ChooseFile, $this ], )->pack(-side => 'left'); $balloon->attach($this->{'FilePathButton'}, -msg => "Choose data directory", -balloonposition => 'mouse'); # 左枠2列目作成: ファイルを選択するドロップダウンリストボックス $this->{'FileListFrame'} = $this->{'LeftFrame1'}->MyFrame( -width => $App->{'LeftFrameWidth'}, )->pack(-side => 'top', -fill => 'x'); #, -expand => 'yes', -fill => 'x'); $this->{'FileListbox'} = $this->{'FileListFrame'}->MyBrowseEntry( -label => "Files:", -state => "readonly", # -setgrid => 1, # -height => 6, # -width => $App->{'LeftFrameWidth'}, # -scrollbars => 'e', -takefocus => 1, -browsecmd => [\&SelChangeFileListBox, "", $this], )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $balloon->attach($this->{'FileListbox'}, -msg => "Choose data to show", -balloonposition => 'mouse'); # $this->{'FileReadButton'} = $this->{'FileListFrame'}->MyButton( # -text => "&Read", # )->pack(-side => 'right'); # $this->{"FileReadButton"}->bind('' => [\&ReadFromFileListbox, $this] ); } #=================================================== # ファイル内容リストボックス、テキストボックスは # Verticalの時は表示しない #=================================================== sub InitCreateFileContentPane { my ($this) = @_; if(!$this->get('IsVertical',0)) { # 左枠3列目作成: ファイルの内容を表示するセクションリストボックス $this->CreateSectionListBox(); # 左枠4列目作成: ファイルの内容を表示するテキストボックス $this->CreateFileContentTextBox(); } } #=================================================== # キャンバスペイン #=================================================== sub RefleshCanvas { my ($this, $f) = @_; my $canvas = $this->Canvas(); unless($f) { $canvas->ClearAll(); # $canvas->InitClass($this); # $canvas->InitObject(); return 1; } else { my $w = $canvas->width(); my $h = $canvas->height(); $this->packPropagate(0); $this->Canvas()->destroy() if($this->Canvas()); my $ret = $this->{'GraphCanvas'} = $this->{'RightFrame1'}->MyCanvas( -background => 'white', -width => $w, -height => $h, -relief => 'groove', -borderwidth => 3, -cursor => 'crosshair', #'cross', 'tcross' )->pack(-expand => 'yes', -fill => 'both'); $this->packPropagate(1); return $ret; } } sub InitCreateCanvasPane { my ($this) = @_; my $App = $this->App(); my $args = $App->Args(); my $balloon = $this->Balloon(); my $ConfigSide = "left"; my $GraphSide = "right"; my @args = (-expand => 'yes', -fill => 'both'); if(defined $args->GetGetArg("vertical")) { $ConfigSide = "top"; $GraphSide = "bottom"; @args = (-fill => 'x'); } # 右枠作成 $this->{'RightFrame1'} = $this->MyFrame() ->pack(-side => $GraphSide, -expand => 'yes', -fill => 'both'); $this->{'GraphCanvas'} = $this->{'RightFrame1'}->MyCanvas( -background => 'white', -width => 500, # -height => 500, -relief => 'groove', -borderwidth => 3, -cursor => 'crosshair', #'cross', 'tcross' )->pack(-expand => 'yes', -fill => 'both'); if(!$this->get('IsVertical',0)) { $this->{'LeftFrameAdjusterLeft'} = $this->Adjuster()->packAfter($this->{'LeftFrame1'}, -side => 'left'); } # キャンバス下枠作成: フォントボタン $this->{'RightBottomFrame1'} = $this->{'RightFrame1'}->MyFrame() ->pack(-side => 'bottom', -fill => 'x'); $this->{'CanvasFontButton'} = $this->{'RightBottomFrame1'}->MyButton( -text => "GraphFrame Font", -takefocus => 1, -command => [ \&SelectCanvasFont, $this, $this->{'GraphCanvas'}, "GraphFrameFont" ], )->pack(-side => 'left'); $balloon->attach($this->{'CanvasFontButton'}, -msg => "Change Canvas Font", -balloonposition => 'mouse'); $this->{'ReplotButton'} = $this->{'RightBottomFrame1'}->MyButton( -text => "&Replot", -takefocus => 1, -command => [ \&Draw, $this ], )->pack(-side => 'left'); $balloon->attach($this->{'ReplotButton'}, -msg => "Redraw Graph", -balloonposition => 'mouse'); $this->{'SavePSButton'} = $this->{'RightBottomFrame1'}->MyButton( -text => "Save &PS", -takefocus => 1, -command => sub { $this->{'GraphCanvas'}->SavePostScript(); }, )->pack(-side => 'left'); $balloon->attach($this->{'SavePSButton'}, -msg => "Save Graph as PostScript file", -balloonposition => 'mouse'); my @CommandList; if($App->{"PSViewer1Name"} and $App->{"PSViewer1Path"}) { my $cmd = [ 'command' => $App->{"PSViewer1Name"}, -command => sub { $this->{'GraphCanvas'}->SavePostScript( $App->{"PSViewer1Path"}, $App->{'StartAppPath'}); }, ]; push(@CommandList, $cmd); } if($App->{"PSViewer2Name"} and $App->{"PSViewer2Path"}) { my $cmd = [ 'command' => $App->{"PSViewer2Name"}, -command => sub { $this->{'GraphCanvas'}->SavePostScript( $App->{"PSViewer2Path"}, $App->{'StartAppPath'}); }, ]; push(@CommandList, $cmd); } $this->{'OpenPSMenuButton'} = $this->{'RightBottomFrame1'}->MyMenubutton( -text => 'Open PS', -underline => 0, -tearoff => 'no', -relief => 'raised', -direction => 'above', -indicatoron => 'yes', -menuitems => \@CommandList, # -takefocus => 1, )->pack(-side => 'left'); $balloon->attach($this->{'OpenPSMenuButton'}, -msg => "Open Graph by PostScript Viewer", -balloonposition => 'mouse'); $this->{'SaveCSVButton'} = $this->{'RightBottomFrame1'}->MyButton( -text => "Save &CSV", -takefocus => 1, -command => [ \&SaveCSVFile, $this], )->pack(-side => 'left'); $balloon->attach($this->{'SaveCSVButton'}, -msg => "Save Graph as CSV file", -balloonposition => 'mouse'); $this->{'RefleshButton'} = $this->{'RightBottomFrame1'}->MyButton( -text => "Reflesh", -takefocus => 1, -command => sub { $this->mw()->RefleshCanvas(1); }, )->pack(-side => 'right'); $this->mw()->RefleshCanvas(); $balloon->attach($this->{'RefleshButton'}, -msg => "Remake Canvas: does not have an effect", -balloonposition => 'mouse'); } sub InitWindowPosition { my ($this, $geo) = @_; my $App = $this->App(); # return unless($App->{'SetWindowPos'}); $geo = $App->{'geometry'}; if($geo) { # $geo =~ s/^(\d+x\d+)\+/\+/ if($geo); $App->print("geometry in IniFile: $geo\n"); return unless($App->{'SetWindowPos'}); # $this->SetGeometry($geo); my ($w, $h, $x, $y) = ($geo =~ /^(\d+)x(\d+)([\+-]\d+)([\+-]\d+)$/); #print "wh: $w $h $x $y\n"; $this->configure(-width => $w, -height => $h); $this->geometry("$x$y"); # $this->configure(-x, $x); # $this->configure(-y, $y); } } sub InitConfigureInitialBind { my ($this) = @_; $this->bind('', [ \&InitWindow, $this ] ); } # CreateWidgesの最後で、に対するbindで呼び出される sub InitWindow { my ($this) = @_; #Windowが初めて表示されたときだけ、InitWindowを実行する return if($this->{'Initialized'}); $this->{'Initialized'} = 1; #App()が定義されていない場合でもInitWindowが呼ばれるので、 #Hash変数として取得する my $App = $this->{'Application'}; return unless($App); # ウィンドウサイズの変更に対するbind # $this->bind( "", [ \&Draw, $this ]); } #=================================================== # ウィジェット関連関数 #=================================================== sub CreateSectionListBox() { my ($this) = @_; my $App = $this->App(); $this->{'SectionListbox'} = $this->{'LeftFrame1'}->Scrolled( 'MyListbox', -setgrid => 1, -width => $App->{'LeftFrameWidth'}, -height => 6, -scrollbars => 'e', -takefocus => 1, )->pack(-side => 'top', -fill => 'x'); #, -expand => 'yes', -fill => 'x'); # $this->{'SectionListbox'}->focus; $this->{'SectionListbox'}->bind('' => [\&SelChangeSectionListBox, $this]); $this->{'SectionListbox'}->bind('' => [\&SelChangeSectionListBox, $this]); $this->{'SectionListbox'}->bind('' => [\&DBLClickSectionListbox, $this]); $this->{'SectionListbox'}->SetCurSel(0); return 1; } sub CreateFileContentTextBox() { my ($this) = @_; my $App = $this->App(); $this->{'FileContentText'} = $this->{'LeftFrame1'}->Scrolled( 'MyText', # -readonly => 1, -width => $App->{'LeftFrameWidth'}, -height => 20, -scrollbars => 'e', -takefocus => 1, )->pack(-side => 'top', -expand => 'yes', -fill => 'both'); if($App->{'FileContentFontName'}) { $this->{'FileContentText'}->configure( -font => [ $App->{'FileContentFontName'}, $App->{'FileContentFontSize'}, $App->{'FileContentFontStyle'} ], ); } # 左下枠作成: ファイル内容テキストボックスボタン $this->{'BottomFrame1'} = $this->{'LeftFrame1'}->MyFrame() ->pack(-side => 'bottom'); $this->{'FontButton'} = $this->{'BottomFrame1'}->MyButton( -text => "Font", -command => [ \&SelectFileContentFont, $this, $this->{'FileContentText'}, "FileContentFont" ], )->pack(-side => 'left'); $this->Balloon()->attach($this->{'FontButton'}, -msg => "Change FileContent Font", -balloonposition => 'mouse'); return 1; } #=================================================== # 一般関数 #=================================================== sub Draw { my ($this, $keyword) = @_; my $App = $this->App(); $this->mw()->RefleshCanvas(); $App->TkData()->Draw($this->Canvas(), $keyword); } sub ReadFile { my ($this, $path) = @_; my $App = $this->App(); #すでにデータを読み込んでいれば、それが作ったウィジェットを削除する $this->TkData()->DeleteWidget($this->DataClassFrame()) if($this->TkData()); my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($path); print "\nRead [$path]\n"; $this->SetFilePath($path); $this->SetTitle("$filename:" . $this->AppTitle()); #データファイル書式のチェック my $TkData = $App->SetTkData( GeneralFileFormat::CheckFileType($path), ""); #対応しないデータファイルであればundefを返す unless($TkData) { print "\n Error: $path could not be identified.\n"; return undef; } #対応するデータファイルであれば、データを読み込む $TkData->SetApplication($this->App()); # $TkData->SetCanvas($this->Canvas()); $TkData->Read($path); my $FileType = $TkData->FileType(); $FileType = 'unknown' unless($FileType); $this->WriteStatusBar($FileType, "left"); print " $path is $FileType.\n"; #対応するデータファイルであれば、必要なウィジェットを作る #  ファイル型によって処理が変わるため、Read()の後で呼び出す $TkData->AddWidget($this->DataClassFrame()); #グラフ設定 $TkData->CreateGraphFrame($this->Canvas()); $TkData->AssignGraphData(); #必要であれば、ファイル内容テキストボックスを更新 $TkData->SetFileInfo($this->{'SectionListbox'}, $this->{'FileContentText'}); #Canvasの再描画 $this->Draw(); } sub UpdateGraphFramePosition { my ($this) = @_; my $App = $this->App(); return undef unless(defined $App->TkData()); my $can = $this->Canvas(); my $w = $can->width(); my $h = $can->height(); my $pGraphFrameArray = $App->{'DataArray'}->GetGraphFrameArray()->GetpGraphFrameArray(); for(my $i = 0 ; $i < @$pGraphFrameArray ; $i++) { my $frame = $pGraphFrameArray->[$i]; my ($x0, $y0, $x1, $y1) = $frame->GetPosition(); my $curpos = $App->{"GraphFrame${i}Position"}; my $str = "$x0,$y0,$x1,$y1"; if($curpos =~ /^r/i) { my $rx0 = sprintf("%5.2f", $x0 / $w); my $rx1 = sprintf("%5.2f", $x1 / $w); my $ry0 = sprintf("%5.2f", $y0 / $h); my $ry1 = sprintf("%5.2f", $y1 / $h); $str = "r$rx0,$ry0,$rx1,$ry1"; $str =~ s/\s//g; } $App->{"GraphFrame${i}Position"} = $str; $frame->SetPositionByStr($str); } } sub GetFilePathFromFileListbox { my ($this) = @_; my $flbox = $this->{'FileListbox'}; my $filename = $flbox->GetText(); my $dir = $this->{'FileEntry'}->GetText(); return undef if(!$filename or !$dir); my $path = Deps::MakePath($dir, $filename); return $path; } #======================================================================= # bindされた応答関数 #======================================================================= sub ToggleShowMousePosition { my ($this) = @_; my $f = $this->ShowMousePosition(); my ($gfa) = $this->GetGraphFrameArray(); return unless($gfa); if($f) { $this->SetShowMousePosition(0); $gfa->SetShowMousePosition(0); } else { $this->SetShowMousePosition(1); $gfa->SetShowMousePosition(1); } } sub ReadDirectory { my ($this, $dir) = @_; chdir($dir); $this->{'FileEntry'}->SetText($dir); $ENV{'o'} = $dir; $this->App()->{'WorkDir'} = $dir; my $filelist = $this->{'FileListbox'}; my $FileMask = $this->App()->{'FileMask'}; $FileMask = ".*" unless($FileMask); $filelist->ReadFileList($dir, $FileMask, 'file', 0, 1); } sub ChooseFile { my ($this, $widget) = @_; my $dir = ''; unless($widget) { $dir = $this->App()->{'WorkDir'}; chdir($dir); } my $fmask = '*.*'; my $defstr = ''; my $message = 'Choose file'; my $filepath = Dialog::OpenFileDialog($this, 'open', $fmask, $defstr, $message, $dir); if($filepath) { my $DirPath = $this->SetWorkDir($filepath); $this->ReadDirectory($DirPath); if($widget) { $widget->SetText($filepath); } } return $filepath; } sub SelChangeFileListBox { my ($listbox, $this, $buttonstate) = @_; my $path = $this->GetFilePathFromFileListbox(); return undef unless($path); return $this->ReadFile($path); } sub SelChangeSectionListBox { my ($listbox, $this) = @_; my $lbox = $this->{'SectionListbox'}; return undef unless($lbox); my $sel = $lbox->get('active'); my $App = $this->App(); if($App->TkData()) { $App->TkData()->Draw($this->Canvas(), $sel); } } sub DBLClickSectionListbox { my ($listbox, $this) = @_; my $lbox = $this->{'SectionListbox'}; return undef unless($lbox); my $sel = $lbox->get('active'); # $this->ExecuteScript("DBLClick.$sel"); } sub SaveCSVFile { my ($this) = @_; my $App = $this->App(); my $pGraphFrameArray = $this->GetGraphFrameArray(); # if($App->TkData()) { # $pGraphFrameArray = $App->TkData()->GetGraphFrameArray(); # } my $dir = ''; my $fmask = '*.csv'; my $defstr = ''; my $message = 'Choose CSV file name'; chdir($dir) if($dir); my $filepath = Dialog::OpenFileDialog($this, 'save', $fmask, $defstr, $message, $dir); return undef unless($filepath); return $pGraphFrameArray->SaveCSVFile($filepath); } sub RestoreViewScale { my ($this, $a) = @_; my $App = $this->App(); $this->GetGraphFrameArray()->AdjustViewRange(); if($App->TkData()) { $App->TkData()->GetGraphFrameArray()->AdjustViewRange(); $App->TkData()->AdjustViewRange(); } $this->Redraw(); } sub SelectCanvasFont { my ($this, $widget, $VarName) = @_; my $App = $this->App(); return undef unless($App); my ($FontName, $FontSize, $FontStyle) = ("times", 10.5, "normal"); ($FontName, $FontSize, $FontStyle) = split(/,/, $App->{$VarName}) if($App->{$VarName}); ($FontName, $FontSize, $FontStyle) = Dialog::ShowFontDialog($this, $FontName, $FontSize, $FontStyle); if($FontName) { $App->{$VarName} = "$FontName,$FontSize,$FontStyle"; if($widget) { $widget->UpdateFont($FontName, $FontSize, $FontStyle); # $widget->Update(); } my @font = ($FontName, $FontSize, $FontStyle); $this->Canvas()->SetFont(\@font); $this->GetGraphFrameArray()->SetFont(\@font); $this->Redraw(); } return $App->{$VarName}; } sub SelectFileContentFont { my ($this, $widget, $VarName) = @_; my $App = $this->App(); return undef unless($App); my $textbox = $this->{'FileContentText'}; return undef unless($textbox); my ($FontName, $FontSize, $FontStyle) = ("times", 10.5, "normal"); ($FontName, $FontSize, $FontStyle) = split(/,/, $App->{$VarName}) if($App->{$VarName}); ($FontName, $FontSize, $FontStyle) = Dialog::ShowFontDialog($this, $FontName, $FontSize, $FontStyle); if($FontName) { $App->{$VarName} = "$FontName,$FontSize,$FontStyle"; if($widget) { $widget->UpdateFont($FontName, $FontSize, $FontStyle); # $widget->Update(); } } return $App->{$VarName}; } sub MakeClone { my ($this) = @_; my $args = $this->App()->Args(); my $command = $args->BuildCommandLine(); $command = "perl.exe $command"; Deps::ExecBackground($command); } sub SetupOption { my ($this) = @_; my $App = $this->App(); my $dlg = $this->DialogBox( -title => "Setup Option", -default_button => 'OK', -buttons => ['OK', 'Cancel'], ); my $width = 50; my $Frame1 = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'x'); my $EditorLabel = $Frame1->Label(-text => "Editor Path:")->pack(-side => 'left'); my $EditorText = $Frame1->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, ); my $EditorPathButton = $Frame1->MyButton( -text => "Path", -command => [ \&ChooseFile, $this, $EditorText ], )->pack(-side => 'right'); $EditorText->pack(-side => 'right', -fill => 'x'); $EditorText->focus; my $Frame2 = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'x'); my $StartAppLabel = $Frame2->Label(-text => "Start App Path:")->pack(-side => 'left'); my $StartAppText = $Frame2->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, ); my $StartAppPathButton = $Frame2->MyButton( -text => "Path", -command => [ \&ChooseFile, $this, $StartAppText ], )->pack(-side => 'right'); $StartAppText->pack(-side => 'right', -fill => 'x'); my $Frame3a = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'x'); my $PSView1NameLabel = $Frame3a->Label(-text => "PS Viewer1 Name:" )->pack(-side => 'left', -fill => 'x'); my $PSView1NameText = $Frame3a->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, )->pack(-side => 'left', -fill => 'x'); my $Frame3b = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'x'); my $PSView1Label = $Frame3b->Label(-text => " Path:" )->pack(-side => 'left', -fill => 'x'); my $PSView1Text = $Frame3b->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, ); my $PSView1PathButton = $Frame3b->MyButton( -text => "Path", -command => [ \&ChooseFile, $this, $PSView1Text ], )->pack(-side => 'right'); $PSView1Text->pack(-side => 'right'); my $Frame4a = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'x'); my $PSView2NameLabel = $Frame4a->Label(-text => "PS Viewer2 Name:" )->pack(-side => 'left', -fill => 'x'); my $PSView2NameText = $Frame4a->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, )->pack(-side => 'left', -fill => 'x'); my $Frame4b = $dlg->add('Frame')->pack(-expand => 'yes', -fill => 'both'); my $PSView2Label = $Frame4b->Label(-text => " Path:" )->pack(-side => 'left', -fill => 'x'); my $PSView2Text = $Frame4b->MyEntry( -relief => 'sunken', -takefocus => 1, -width => $width, ); my $PSView2PathButton = $Frame4b->MyButton( -text => "Path", -command => [ \&ChooseFile, $this, $PSView2Text ], )->pack(-side => 'right'); $PSView2Text->pack(-side => 'right'); $EditorText->SetText($App->{"EditorPath"}); $StartAppText->SetText($App->{"StartAppPath"}); $PSView1Text->SetText($App->{"PSViewer1Path"}); $PSView1NameText->SetText($App->{"PSViewer1Name"}); $PSView2Text->SetText($App->{"PSViewer2Path"}); $PSView2NameText->SetText($App->{"PSViewer2Name"}); my $ret = $dlg->Show; if($ret eq 'OK') { $App->{"EditorPath"} = $EditorText->GetText(); $App->{"StartAppPath"} = $StartAppText->GetText(); $App->{"PSViewer1Path"} = $PSView1Text->GetText(); $App->{"PSViewer1Name"} = $PSView1NameText->GetText(); $App->{"PSViewer2Path"} = $PSView2Text->GetText(); $App->{"PSViewer2Name"} = $PSView2NameText->GetText(); } } sub About { my ($this) = @_; Dialog::ShowAboutDialog($this, ucfirst $this->{'Program'} . " 2005/pl"); } sub Close { my ($this, $DoConfirm) = @_; my $App = $this->{'Application'}; my $geo; if($App) { my $w = $this->width(); my $h = $this->height(); my $x = $this->x(); #rootx(); my $y = $this->y(); #rooty(); $geo = "${w}x$h+$x+$y"; $App->print("Current geometry from whxy: $geo\n"); # $geo = $this->geometry(); #$App->print("Current geometry: $geo\n"); $App->{'geometry'} = $geo if($this->IsValidGeometry($geo)); my $textbox = $this->{'FileContentText'}; if($textbox) { # $App->{'LeftFrameWidth'} = $textbox->width(); } } $App->SaveSetting(); if($DoConfirm) { my $button = $this->messageBox( -icon => 'warning', -type => 'YesNo', -default => 'No', -title => 'Confirm', -message => 'Really quit?'); return if($button eq 'No'); } $this->destroy(); } 1;